using System.Net; using System.Net.Http.Json; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; using StellaOps.SbomService.Models; using Xunit; using StellaOps.TestKit; namespace StellaOps.SbomService.Tests; public class ResolverFeedExportTests : IClassFixture> { private readonly WebApplicationFactory _factory; public ResolverFeedExportTests(WebApplicationFactory factory) { _factory = factory; } [Trait("Category", TestCategories.Unit)] [Fact] public async Task Export_returns_ndjson_in_deterministic_order() { var client = _factory.CreateClient(); // ensure feed populated await client.PostAsync("/internal/sbom/resolver-feed/backfill", null); var response = await client.GetAsync("/internal/sbom/resolver-feed/export"); response.StatusCode.Should().Be(HttpStatusCode.OK); response.Content.Headers.ContentType!.MediaType.Should().Be("application/x-ndjson"); var body = await response.Content.ReadAsStringAsync(); var lines = body.Split('\n', StringSplitOptions.RemoveEmptyEntries); lines.Length.Should().BeGreaterThan(0); // verify deterministic ordering by first and last line comparison var first = lines.First(); var last = lines.Last(); first.Should().BeLessOrEqualTo(last, Comparer.Create(StringComparer.Ordinal.Compare)); // spot-check a known candidate var candidates = await client.GetFromJsonAsync>("/internal/sbom/resolver-feed"); candidates.Should().NotBeNull(); candidates!.Any(c => c.Purl == "pkg:npm/lodash@4.17.21").Should().BeTrue(); } }