search and ai stabilization work, localization stablized.
This commit is contained in:
@@ -21,6 +21,10 @@ public sealed class GatesEndpointsIntegrationTests : IClassFixture<TestPolicyGat
|
||||
{
|
||||
_factory = factory;
|
||||
_client = _factory.CreateClient();
|
||||
// All endpoints are wrapped in RequireTenant(). The bypass network covers scope auth but
|
||||
// tenant resolution still needs a source. Provide it via the canonical header so every
|
||||
// request in this fixture automatically satisfies the tenant filter.
|
||||
_client.DefaultRequestHeaders.Add("X-StellaOps-Tenant", TestPolicyGatewayFactory.DefaultTestTenant);
|
||||
}
|
||||
|
||||
#region GET /gates/{bom_ref} Tests
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace StellaOps.Policy.Gateway.Tests;
|
||||
|
||||
public sealed class LocalizationEndpointsTests : IClassFixture<TestPolicyGatewayFactory>
|
||||
{
|
||||
private readonly TestPolicyGatewayFactory _factory;
|
||||
|
||||
public LocalizationEndpointsTests(TestPolicyGatewayFactory factory)
|
||||
{
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", "Integration")]
|
||||
[Trait("Intent", "Safety")]
|
||||
public async Task Readyz_WithGermanLocale_ReturnsLocalizedStatus()
|
||||
{
|
||||
using var client = _factory.CreateClient();
|
||||
using var request = new HttpRequestMessage(HttpMethod.Get, "/readyz");
|
||||
request.Headers.TryAddWithoutValidation("X-Locale", "de-DE");
|
||||
|
||||
var response = await client.SendAsync(request);
|
||||
var payload = await response.Content.ReadAsStringAsync();
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
using var json = JsonDocument.Parse(payload);
|
||||
Assert.Equal(
|
||||
"bereit",
|
||||
json.RootElement.GetProperty("status").GetString());
|
||||
}
|
||||
}
|
||||
@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
|
||||
| AUDIT-0446-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Policy.Gateway.Tests. |
|
||||
| AUDIT-0446-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Policy.Gateway.Tests. |
|
||||
| AUDIT-0446-A | DONE | Waived (test project; revalidated 2026-01-07). |
|
||||
| SPRINT-20260224-002-LOC-101-T | DONE | `SPRINT_20260224_002_Platform_translation_rollout_phase3_phase4.md`: added focused Policy Gateway locale-aware readiness test and validated German locale response text. |
|
||||
|
||||
@@ -111,6 +111,12 @@ public sealed class TestPolicyGatewayFactory : WebApplicationFactory<GatewayProg
|
||||
/// Generates a test JWT token with the specified claims.
|
||||
/// The token is signed with <see cref="TestSigningKey"/> and accepted by the test host.
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// Default tenant identifier used when no explicit tenant is passed to <see cref="CreateTestJwt"/>.
|
||||
/// All endpoints decorated with <c>RequireTenant()</c> need this claim present in the token.
|
||||
/// </summary>
|
||||
public const string DefaultTestTenant = "test-tenant";
|
||||
|
||||
public static string CreateTestJwt(
|
||||
string[]? scopes = null,
|
||||
string? tenantId = null,
|
||||
@@ -119,10 +125,16 @@ public sealed class TestPolicyGatewayFactory : WebApplicationFactory<GatewayProg
|
||||
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(TestSigningKey));
|
||||
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
||||
|
||||
// Resolve effective tenant: use supplied value, or fall back to the shared default.
|
||||
// The stellaops:tenant claim is required by every endpoint wrapped in RequireTenant().
|
||||
var effectiveTenant = tenantId ?? DefaultTestTenant;
|
||||
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new(JwtRegisteredClaimNames.Sub, "test-user"),
|
||||
new(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
|
||||
new(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||
// Canonical tenant claim consumed by StellaOpsTenantResolver.TryResolve().
|
||||
new("stellaops:tenant", effectiveTenant)
|
||||
};
|
||||
|
||||
if (scopes is { Length: > 0 })
|
||||
@@ -130,11 +142,6 @@ public sealed class TestPolicyGatewayFactory : WebApplicationFactory<GatewayProg
|
||||
claims.Add(new Claim("scope", string.Join(" ", scopes)));
|
||||
}
|
||||
|
||||
if (tenantId is not null)
|
||||
{
|
||||
claims.Add(new Claim("tenant_id", tenantId));
|
||||
}
|
||||
|
||||
var expires = DateTime.UtcNow.Add(expiresIn ?? TimeSpan.FromHours(1));
|
||||
|
||||
var handler = new JsonWebTokenHandler();
|
||||
|
||||
@@ -350,18 +350,19 @@ public sealed class PolicyGatewayIntegrationTests : IAsyncLifetime
|
||||
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(PolicyGatewayTestFactory.TestSigningKey));
|
||||
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
||||
|
||||
// Resolve effective tenant: use supplied value, or fall back to the shared default.
|
||||
// The stellaops:tenant claim is required by every endpoint wrapped in RequireTenant().
|
||||
var effectiveTenant = tenantId ?? "test-tenant";
|
||||
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new(JwtRegisteredClaimNames.Sub, "test-user"),
|
||||
new(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||||
new("scope", string.Join(" ", scopes))
|
||||
new("scope", string.Join(" ", scopes)),
|
||||
// Canonical tenant claim consumed by StellaOpsTenantResolver.TryResolve().
|
||||
new("stellaops:tenant", effectiveTenant)
|
||||
};
|
||||
|
||||
if (tenantId != null)
|
||||
{
|
||||
claims.Add(new Claim("tenant_id", tenantId));
|
||||
}
|
||||
|
||||
var expires = DateTime.UtcNow.Add(expiresIn ?? TimeSpan.FromHours(1));
|
||||
|
||||
var handler = new JsonWebTokenHandler();
|
||||
|
||||
Reference in New Issue
Block a user