search and ai stabilization work, localization stablized.

This commit is contained in:
master
2026-02-24 23:29:36 +02:00
parent 4f947a8b61
commit b07d27772e
766 changed files with 55299 additions and 3221 deletions

View File

@@ -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

View File

@@ -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());
}
}

View File

@@ -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. |

View File

@@ -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();

View File

@@ -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();