T8: Add PostgresExceptionApplicationRepositoryTests

This commit is contained in:
StellaOps Bot
2025-12-21 09:36:55 +02:00
parent 2e98f6f3b2
commit 8a4edee665

View File

@@ -0,0 +1,95 @@
using System.Collections.Immutable;
using FluentAssertions;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using StellaOps.Policy.Exceptions.Models;
using StellaOps.Policy.Exceptions.Repositories;
using Xunit;
namespace StellaOps.Policy.Storage.Postgres.Tests;
[Collection(PolicyPostgresCollection.Name)]
public sealed class PostgresExceptionApplicationRepositoryTests : IAsyncLifetime
{
private readonly PolicyPostgresFixture _fixture;
private readonly PostgresExceptionApplicationRepository _repository;
private readonly Guid _tenantId = Guid.NewGuid();
public PostgresExceptionApplicationRepositoryTests(PolicyPostgresFixture fixture)
{
_fixture = fixture;
var options = fixture.Fixture.CreateOptions();
options.SchemaName = fixture.SchemaName;
var dataSource = new PolicyDataSource(Options.Create(options), NullLogger<PolicyDataSource>.Instance);
_repository = new PostgresExceptionApplicationRepository(dataSource.DataSource);
}
public Task InitializeAsync() => _fixture.TruncateAllTablesAsync();
public Task DisposeAsync() => Task.CompletedTask;
[Fact]
public async Task RecordAsync_ShouldPersist()
{
var app = CreateApp("EXC-001", "FIND-001");
var result = await _repository.RecordAsync(app);
result.Should().NotBeNull();
result.ExceptionId.Should().Be("EXC-001");
}
[Fact]
public async Task RecordBatchAsync_ShouldPersistMultiple()
{
var apps = new[] { CreateApp("EXC-B1", "F1"), CreateApp("EXC-B1", "F2"), CreateApp("EXC-B2", "F3") };
var result = await _repository.RecordBatchAsync(apps);
result.Should().HaveCount(3);
}
[Fact]
public async Task RecordBatchAsync_EmptyReturnsEmpty()
{
var result = await _repository.RecordBatchAsync(Array.Empty<ExceptionApplication>());
result.Should().BeEmpty();
}
[Fact]
public async Task GetByExceptionIdAsync_ReturnsMatches()
{
await _repository.RecordAsync(CreateApp("EXC-G1", "F1"));
await _repository.RecordAsync(CreateApp("EXC-G1", "F2"));
await _repository.RecordAsync(CreateApp("EXC-OTH", "F3"));
var results = await _repository.GetByExceptionIdAsync(_tenantId, "EXC-G1");
results.Should().HaveCount(2);
}
[Fact]
public async Task GetByFindingIdAsync_ReturnsMatches()
{
await _repository.RecordAsync(CreateApp("E1", "FIND-G1"));
await _repository.RecordAsync(CreateApp("E2", "FIND-G1"));
await _repository.RecordAsync(CreateApp("E3", "FIND-OTH"));
var results = await _repository.GetByFindingIdAsync(_tenantId, "FIND-G1");
results.Should().HaveCount(2);
}
[Fact]
public async Task GetByVulnerabilityIdAsync_ReturnsMatches()
{
await _repository.RecordAsync(CreateApp("E1", "F1", "CVE-2024-1234"));
await _repository.RecordAsync(CreateApp("E2", "F2", "CVE-2024-1234"));
await _repository.RecordAsync(CreateApp("E3", "F3", "CVE-2024-5678"));
var results = await _repository.GetByVulnerabilityIdAsync(_tenantId, "CVE-2024-1234");
results.Should().HaveCount(2);
}
[Fact]
public async Task CountAsync_WithFilter_ReturnsFiltered()
{
await _repository.RecordBatchAsync(new[] { CreateApp("E1", "F1", eff: "suppress"), CreateApp("E2", "F2", eff: "suppress"), CreateApp("E3", "F3", eff: "modify") });
var filter = new ExceptionApplicationFilter(EffectType: "suppress");
var count = await _repository.CountAsync(_tenantId, filter);
count.Should().Be(2);
}
private ExceptionApplication CreateApp(string excId, string findId, string? vulnId = null, string eff = "suppress") =>
ExceptionApplication.Create(_tenantId, excId, findId, "affected", "not_affected", "test", eff, vulnId);
}