using System.Net; using System.Net.Http.Json; using Microsoft.AspNetCore.Mvc.Testing; using StellaOps.VulnExplorer.Api.Models; using Xunit; namespace StellaOps.VulnExplorer.Api.Tests; public class VulnApiTests : IClassFixture> { private readonly WebApplicationFactory factory; public VulnApiTests(WebApplicationFactory factory) { this.factory = factory.WithWebHostBuilder(_ => { }); } [Fact] public async Task List_ReturnsDeterministicOrder() { var client = factory.CreateClient(); client.DefaultRequestHeaders.Add("x-stella-tenant", "tenant-a"); var response = await client.GetAsync("/v1/vulns"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var payload = await response.Content.ReadFromJsonAsync(); Assert.NotNull(payload); Assert.Equal(new[] { "vuln-0001", "vuln-0002" }, payload!.Items.Select(v => v.Id)); } [Fact] public async Task List_FiltersByCve() { var client = factory.CreateClient(); client.DefaultRequestHeaders.Add("x-stella-tenant", "tenant-a"); var response = await client.GetAsync("/v1/vulns?cve=CVE-2024-2222"); response.EnsureSuccessStatusCode(); var payload = await response.Content.ReadFromJsonAsync(); Assert.Single(payload!.Items); Assert.Equal("vuln-0002", payload.Items[0].Id); } [Fact] public async Task Detail_ReturnsNotFoundWhenMissing() { var client = factory.CreateClient(); client.DefaultRequestHeaders.Add("x-stella-tenant", "tenant-a"); var response = await client.GetAsync("/v1/vulns/missing"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Fact] public async Task Detail_ReturnsRationaleAndPaths() { var client = factory.CreateClient(); client.DefaultRequestHeaders.Add("x-stella-tenant", "tenant-a"); var response = await client.GetAsync("/v1/vulns/vuln-0001"); response.EnsureSuccessStatusCode(); var detail = await response.Content.ReadFromJsonAsync(); Assert.NotNull(detail); Assert.Equal("rat-0001", detail!.Rationale.Id); Assert.Contains("/src/app/Program.cs", detail.Paths); Assert.NotEmpty(detail.Evidence); } }