// -----------------------------------------------------------------------------
// BaselineEndpointsTests.cs
// Sprint: SPRINT_4200_0002_0006_delta_compare_api
// Description: Integration tests for baseline selection endpoints.
// -----------------------------------------------------------------------------
using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using StellaOps.Scanner.WebService.Contracts;
namespace StellaOps.Scanner.WebService.Tests;
///
/// Integration tests for baseline selection endpoints.
///
public sealed class BaselineEndpointsTests
{
private static readonly JsonSerializerOptions SerializerOptions = new(JsonSerializerDefaults.Web);
[Fact]
public async Task GetRecommendations_ValidDigest_ReturnsRecommendations()
{
using var factory = new ScannerApplicationFactory();
using var client = factory.CreateClient();
var response = await client.GetAsync("/api/v1/baselines/recommendations/sha256:artifact123");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var result = await response.Content.ReadFromJsonAsync(SerializerOptions);
Assert.NotNull(result);
Assert.Equal("sha256:artifact123", result!.ArtifactDigest);
Assert.NotEmpty(result.Recommendations);
Assert.Contains(result.Recommendations, r => r.IsDefault);
}
[Fact]
public async Task GetRecommendations_WithEnvironment_FiltersCorrectly()
{
using var factory = new ScannerApplicationFactory();
using var client = factory.CreateClient();
var response = await client.GetAsync("/api/v1/baselines/recommendations/sha256:artifact123?environment=production");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var result = await response.Content.ReadFromJsonAsync(SerializerOptions);
Assert.NotNull(result);
Assert.NotEmpty(result!.Recommendations);
}
[Fact]
public async Task GetRecommendations_IncludesRationale()
{
using var factory = new ScannerApplicationFactory();
using var client = factory.CreateClient();
var response = await client.GetAsync("/api/v1/baselines/recommendations/sha256:artifact123");
var result = await response.Content.ReadFromJsonAsync(SerializerOptions);
Assert.NotNull(result);
foreach (var rec in result!.Recommendations)
{
Assert.NotEmpty(rec.Rationale);
Assert.NotEmpty(rec.Type);
Assert.NotEmpty(rec.Label);
}
}
[Fact]
public async Task GetRationale_ValidDigests_ReturnsDetailedRationale()
{
using var factory = new ScannerApplicationFactory();
using var client = factory.CreateClient();
var response = await client.GetAsync("/api/v1/baselines/rationale/sha256:base123/sha256:head456");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var result = await response.Content.ReadFromJsonAsync(SerializerOptions);
Assert.NotNull(result);
Assert.Equal("sha256:base123", result!.BaseDigest);
Assert.Equal("sha256:head456", result.HeadDigest);
Assert.NotEmpty(result.SelectionType);
Assert.NotEmpty(result.Rationale);
Assert.NotEmpty(result.DetailedExplanation);
}
[Fact]
public async Task GetRationale_IncludesSelectionCriteria()
{
using var factory = new ScannerApplicationFactory();
using var client = factory.CreateClient();
var response = await client.GetAsync("/api/v1/baselines/rationale/sha256:baseline-base123/sha256:head456");
var result = await response.Content.ReadFromJsonAsync(SerializerOptions);
Assert.NotNull(result);
Assert.NotNull(result!.SelectionCriteria);
Assert.NotEmpty(result.SelectionCriteria);
}
[Fact]
public async Task GetRecommendations_DefaultIsFirst()
{
using var factory = new ScannerApplicationFactory();
using var client = factory.CreateClient();
var response = await client.GetAsync("/api/v1/baselines/recommendations/sha256:artifact123");
var result = await response.Content.ReadFromJsonAsync(SerializerOptions);
Assert.NotNull(result);
Assert.NotEmpty(result!.Recommendations);
Assert.True(result.Recommendations[0].IsDefault);
}
}