synergy moats product advisory implementations
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// PostgresReportStorageServiceTests.cs
|
||||
// Sprint: SPRINT_20260117_025_Doctor_coverage_expansion
|
||||
// Task: DOC-EXP-005 - Persistent Report Storage Tests
|
||||
// Description: Unit tests for PostgresReportStorageService
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using StellaOps.Doctor.Models;
|
||||
using StellaOps.Doctor.WebService.Options;
|
||||
using StellaOps.Doctor.WebService.Services;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Doctor.WebService.Tests.Services;
|
||||
|
||||
public sealed class PostgresReportStorageServiceTests
|
||||
{
|
||||
[Fact]
|
||||
public void Constructor_WithMissingConnectionString_ThrowsException()
|
||||
{
|
||||
// Arrange
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>())
|
||||
.Build();
|
||||
|
||||
var options = Options.Create(new DoctorServiceOptions());
|
||||
var logger = new Mock<ILogger<PostgresReportStorageService>>();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
new PostgresReportStorageService(config, options, logger.Object));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WithValidConnectionString_Succeeds()
|
||||
{
|
||||
// Arrange
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["ConnectionStrings:StellaOps"] = "Host=localhost;Database=test"
|
||||
})
|
||||
.Build();
|
||||
|
||||
var options = Options.Create(new DoctorServiceOptions { ReportRetentionDays = 0 });
|
||||
var logger = new Mock<ILogger<PostgresReportStorageService>>();
|
||||
|
||||
// Act
|
||||
using var service = new PostgresReportStorageService(config, options, logger.Object);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(service);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WithRetentionDays_StartsCleanupTimer()
|
||||
{
|
||||
// Arrange
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["ConnectionStrings:StellaOps"] = "Host=localhost;Database=test"
|
||||
})
|
||||
.Build();
|
||||
|
||||
var options = Options.Create(new DoctorServiceOptions { ReportRetentionDays = 30 });
|
||||
var logger = new Mock<ILogger<PostgresReportStorageService>>();
|
||||
|
||||
// Act
|
||||
using var service = new PostgresReportStorageService(config, options, logger.Object);
|
||||
|
||||
// Assert - service should be created without error
|
||||
Assert.NotNull(service);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Dispose_CanBeCalledMultipleTimes()
|
||||
{
|
||||
// Arrange
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["Database:ConnectionString"] = "Host=localhost;Database=test"
|
||||
})
|
||||
.Build();
|
||||
|
||||
var options = Options.Create(new DoctorServiceOptions());
|
||||
var logger = new Mock<ILogger<PostgresReportStorageService>>();
|
||||
|
||||
var service = new PostgresReportStorageService(config, options, logger.Object);
|
||||
|
||||
// Act & Assert - should not throw
|
||||
service.Dispose();
|
||||
service.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Integration tests for PostgresReportStorageService.
|
||||
/// These require a PostgreSQL instance and are skipped in CI unless configured.
|
||||
/// </summary>
|
||||
public sealed class PostgresReportStorageServiceIntegrationTests
|
||||
{
|
||||
private static bool IsPostgresAvailable()
|
||||
{
|
||||
var connString = Environment.GetEnvironmentVariable("STELLA_TEST_POSTGRES");
|
||||
return !string.IsNullOrEmpty(connString);
|
||||
}
|
||||
|
||||
[Fact(Skip = "Requires PostgreSQL instance")]
|
||||
public async Task StoreAndRetrieveReport_RoundTrip()
|
||||
{
|
||||
if (!IsPostgresAvailable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Arrange
|
||||
var connString = Environment.GetEnvironmentVariable("STELLA_TEST_POSTGRES")!;
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["ConnectionStrings:StellaOps"] = connString
|
||||
})
|
||||
.Build();
|
||||
|
||||
var options = Options.Create(new DoctorServiceOptions { ReportRetentionDays = 1 });
|
||||
var logger = new Mock<ILogger<PostgresReportStorageService>>();
|
||||
|
||||
using var service = new PostgresReportStorageService(config, options, logger.Object);
|
||||
|
||||
var report = new DoctorReport
|
||||
{
|
||||
RunId = $"test-{Guid.NewGuid()}",
|
||||
StartedAt = DateTimeOffset.UtcNow,
|
||||
CompletedAt = DateTimeOffset.UtcNow.AddSeconds(5),
|
||||
OverallSeverity = DoctorSeverity.Pass,
|
||||
Summary = new DoctorSummary
|
||||
{
|
||||
Passed = 5,
|
||||
Warnings = 1,
|
||||
Failed = 0,
|
||||
Skipped = 2,
|
||||
Info = 1,
|
||||
Total = 9
|
||||
},
|
||||
Results = []
|
||||
};
|
||||
|
||||
// Act
|
||||
await service.StoreReportAsync(report, CancellationToken.None);
|
||||
var retrieved = await service.GetReportAsync(report.RunId, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(retrieved);
|
||||
Assert.Equal(report.RunId, retrieved.RunId);
|
||||
Assert.Equal(report.OverallSeverity, retrieved.OverallSeverity);
|
||||
Assert.Equal(report.Summary.Passed, retrieved.Summary.Passed);
|
||||
|
||||
// Cleanup
|
||||
await service.DeleteReportAsync(report.RunId, CancellationToken.None);
|
||||
}
|
||||
|
||||
[Fact(Skip = "Requires PostgreSQL instance")]
|
||||
public async Task ListReports_ReturnsPaginatedResults()
|
||||
{
|
||||
if (!IsPostgresAvailable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Arrange
|
||||
var connString = Environment.GetEnvironmentVariable("STELLA_TEST_POSTGRES")!;
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["ConnectionStrings:StellaOps"] = connString
|
||||
})
|
||||
.Build();
|
||||
|
||||
var options = Options.Create(new DoctorServiceOptions());
|
||||
var logger = new Mock<ILogger<PostgresReportStorageService>>();
|
||||
|
||||
using var service = new PostgresReportStorageService(config, options, logger.Object);
|
||||
|
||||
// Act
|
||||
var reports = await service.ListReportsAsync(limit: 10, offset: 0, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(reports);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user