using System.Text.Json; namespace StellaOps.Scheduler.WebService.Tests; public sealed class PolicyRunEndpointTests : IClassFixture> { private readonly WebApplicationFactory _factory; public PolicyRunEndpointTests(WebApplicationFactory factory) { _factory = factory; } [Fact] public async Task CreateListGetPolicyRun() { using var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("X-Tenant-Id", "tenant-policy"); client.DefaultRequestHeaders.Add("X-Scopes", "policy:run"); var createResponse = await client.PostAsJsonAsync("/api/v1/scheduler/policy/runs", new { policyId = "P-7", policyVersion = 4, mode = "incremental", priority = "normal", metadata = new { source = "cli" }, inputs = new { sbomSet = new[] { "sbom:S-42", "sbom:S-99" }, advisoryCursor = "2025-10-26T13:59:00+00:00", vexCursor = "2025-10-26T13:58:30+00:00", environment = new { @sealed = false, exposure = "internet" }, captureExplain = true } }); createResponse.EnsureSuccessStatusCode(); Assert.Equal(System.Net.HttpStatusCode.Created, createResponse.StatusCode); var created = await createResponse.Content.ReadFromJsonAsync(); var runJson = created.GetProperty("run"); var runId = runJson.GetProperty("runId").GetString(); Assert.False(string.IsNullOrEmpty(runId)); Assert.Equal("queued", runJson.GetProperty("status").GetString()); Assert.Equal("P-7", runJson.GetProperty("policyId").GetString()); Assert.True(runJson.GetProperty("inputs").GetProperty("captureExplain").GetBoolean()); var listResponse = await client.GetAsync("/api/v1/scheduler/policy/runs?policyId=P-7"); listResponse.EnsureSuccessStatusCode(); var list = await listResponse.Content.ReadFromJsonAsync(); var runsArray = list.GetProperty("runs"); Assert.True(runsArray.GetArrayLength() >= 1); var getResponse = await client.GetAsync($"/api/v1/scheduler/policy/runs/{runId}"); getResponse.EnsureSuccessStatusCode(); var retrieved = await getResponse.Content.ReadFromJsonAsync(); Assert.Equal(runId, retrieved.GetProperty("run").GetProperty("runId").GetString()); } [Fact] public async Task MissingScopeReturnsForbidden() { using var client = _factory.CreateClient(); client.DefaultRequestHeaders.Add("X-Tenant-Id", "tenant-policy"); var response = await client.GetAsync("/api/v1/scheduler/policy/runs"); Assert.Equal(System.Net.HttpStatusCode.Unauthorized, response.StatusCode); } }