Fix build and code structure improvements. New but essential UI functionality. CI improvements. Documentation improvements. AI module improvements.
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
using System.Reflection;
|
||||
using StellaOps.Infrastructure.Postgres.Testing;
|
||||
using StellaOps.PacksRegistry.Persistence.Postgres;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.PacksRegistry.Persistence.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// PostgreSQL integration test fixture for the PacksRegistry module.
|
||||
/// </summary>
|
||||
public sealed class PacksRegistryPostgresFixture : PostgresIntegrationFixture, ICollectionFixture<PacksRegistryPostgresFixture>
|
||||
{
|
||||
protected override Assembly? GetMigrationAssembly()
|
||||
=> typeof(PacksRegistryDataSource).Assembly;
|
||||
|
||||
protected override string GetModuleName() => "PacksRegistry";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Collection definition for PacksRegistry PostgreSQL integration tests.
|
||||
/// Tests in this collection share a single PostgreSQL container instance.
|
||||
/// </summary>
|
||||
[CollectionDefinition(Name)]
|
||||
public sealed class PacksRegistryPostgresCollection : ICollectionFixture<PacksRegistryPostgresFixture>
|
||||
{
|
||||
public const string Name = "PacksRegistryPostgres";
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
using System.Text;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using MicrosoftOptions = Microsoft.Extensions.Options;
|
||||
using StellaOps.PacksRegistry.Core.Models;
|
||||
using StellaOps.PacksRegistry.Persistence.Postgres;
|
||||
using StellaOps.PacksRegistry.Persistence.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.PacksRegistry.Persistence.Tests;
|
||||
|
||||
[Collection(PacksRegistryPostgresCollection.Name)]
|
||||
public sealed class PostgresPackRepositoryTests : IAsyncLifetime
|
||||
{
|
||||
private readonly PacksRegistryPostgresFixture _fixture;
|
||||
private readonly PostgresPackRepository _repository;
|
||||
private readonly string _tenantId = "tenant-" + Guid.NewGuid().ToString("N")[..8];
|
||||
|
||||
public PostgresPackRepositoryTests(PacksRegistryPostgresFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
|
||||
var options = fixture.Fixture.CreateOptions();
|
||||
options.SchemaName = fixture.SchemaName;
|
||||
var dataSource = new PacksRegistryDataSource(MicrosoftOptions.Options.Create(options), NullLogger<PacksRegistryDataSource>.Instance);
|
||||
_repository = new PostgresPackRepository(dataSource, NullLogger<PostgresPackRepository>.Instance);
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await _fixture.TruncateAllTablesAsync();
|
||||
}
|
||||
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task UpsertAndGet_RoundTripsPackRecord()
|
||||
{
|
||||
// Arrange
|
||||
var packId = "pack-" + Guid.NewGuid().ToString("N");
|
||||
var record = new PackRecord(
|
||||
PackId: packId,
|
||||
Name: "test-pack",
|
||||
Version: "1.0.0",
|
||||
TenantId: _tenantId,
|
||||
Digest: "sha256:abc123",
|
||||
Signature: "sig123",
|
||||
ProvenanceUri: "https://example.com/provenance",
|
||||
ProvenanceDigest: "sha256:prov456",
|
||||
CreatedAtUtc: DateTimeOffset.UtcNow,
|
||||
Metadata: new Dictionary<string, string> { ["author"] = "test" });
|
||||
var content = Encoding.UTF8.GetBytes("pack content here");
|
||||
var provenance = Encoding.UTF8.GetBytes("provenance data");
|
||||
|
||||
// Act
|
||||
await _repository.UpsertAsync(record, content, provenance);
|
||||
var fetched = await _repository.GetAsync(packId);
|
||||
|
||||
// Assert
|
||||
fetched.Should().NotBeNull();
|
||||
fetched!.PackId.Should().Be(packId);
|
||||
fetched.Name.Should().Be("test-pack");
|
||||
fetched.Version.Should().Be("1.0.0");
|
||||
fetched.TenantId.Should().Be(_tenantId);
|
||||
fetched.Metadata.Should().ContainKey("author");
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetContentAsync_ReturnsPackContent()
|
||||
{
|
||||
// Arrange
|
||||
var packId = "pack-" + Guid.NewGuid().ToString("N");
|
||||
var record = CreatePackRecord(packId, "content-test", "1.0.0");
|
||||
var expectedContent = Encoding.UTF8.GetBytes("this is the pack content");
|
||||
|
||||
await _repository.UpsertAsync(record, expectedContent, null);
|
||||
|
||||
// Act
|
||||
var content = await _repository.GetContentAsync(packId);
|
||||
|
||||
// Assert
|
||||
content.Should().NotBeNull();
|
||||
Encoding.UTF8.GetString(content!).Should().Be("this is the pack content");
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetProvenanceAsync_ReturnsProvenanceData()
|
||||
{
|
||||
// Arrange
|
||||
var packId = "pack-" + Guid.NewGuid().ToString("N");
|
||||
var record = CreatePackRecord(packId, "provenance-test", "1.0.0");
|
||||
var content = Encoding.UTF8.GetBytes("content");
|
||||
var expectedProvenance = Encoding.UTF8.GetBytes("provenance statement");
|
||||
|
||||
await _repository.UpsertAsync(record, content, expectedProvenance);
|
||||
|
||||
// Act
|
||||
var provenance = await _repository.GetProvenanceAsync(packId);
|
||||
|
||||
// Assert
|
||||
provenance.Should().NotBeNull();
|
||||
Encoding.UTF8.GetString(provenance!).Should().Be("provenance statement");
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ListAsync_ReturnsPacksForTenant()
|
||||
{
|
||||
// Arrange
|
||||
var pack1 = CreatePackRecord("pack-1-" + Guid.NewGuid().ToString("N")[..8], "pack-a", "1.0.0");
|
||||
var pack2 = CreatePackRecord("pack-2-" + Guid.NewGuid().ToString("N")[..8], "pack-b", "2.0.0");
|
||||
var content = Encoding.UTF8.GetBytes("content");
|
||||
|
||||
await _repository.UpsertAsync(pack1, content, null);
|
||||
await _repository.UpsertAsync(pack2, content, null);
|
||||
|
||||
// Act
|
||||
var packs = await _repository.ListAsync(_tenantId);
|
||||
|
||||
// Assert
|
||||
packs.Should().HaveCount(2);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task UpsertAsync_UpdatesExistingPack()
|
||||
{
|
||||
// Arrange
|
||||
var packId = "pack-" + Guid.NewGuid().ToString("N");
|
||||
var record1 = CreatePackRecord(packId, "original", "1.0.0");
|
||||
var record2 = CreatePackRecord(packId, "updated", "2.0.0");
|
||||
var content = Encoding.UTF8.GetBytes("content");
|
||||
|
||||
// Act
|
||||
await _repository.UpsertAsync(record1, content, null);
|
||||
await _repository.UpsertAsync(record2, content, null);
|
||||
var fetched = await _repository.GetAsync(packId);
|
||||
|
||||
// Assert
|
||||
fetched.Should().NotBeNull();
|
||||
fetched!.Name.Should().Be("updated");
|
||||
fetched.Version.Should().Be("2.0.0");
|
||||
}
|
||||
|
||||
private PackRecord CreatePackRecord(string packId, string name, string version) =>
|
||||
new(
|
||||
PackId: packId,
|
||||
Name: name,
|
||||
Version: version,
|
||||
TenantId: _tenantId,
|
||||
Digest: "sha256:" + Guid.NewGuid().ToString("N"),
|
||||
Signature: null,
|
||||
ProvenanceUri: null,
|
||||
ProvenanceDigest: null,
|
||||
CreatedAtUtc: DateTimeOffset.UtcNow,
|
||||
Metadata: null);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
<RootNamespace>StellaOps.PacksRegistry.Persistence.Tests</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\__Libraries\StellaOps.PacksRegistry.Persistence\StellaOps.PacksRegistry.Persistence.csproj" />
|
||||
<ProjectReference Include="..\..\..\__Tests\__Libraries\StellaOps.Infrastructure.Postgres.Testing\StellaOps.Infrastructure.Postgres.Testing.csproj" />
|
||||
<ProjectReference Include="..\..\..\__Libraries\StellaOps.TestKit\StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user