Tests fixes, audit progress, UI completions

This commit is contained in:
StellaOps Bot
2025-12-30 09:03:22 +02:00
parent 7a5210e2aa
commit 82e55c206a
318 changed files with 7232 additions and 1256 deletions

View File

@@ -0,0 +1,27 @@
# AirGap Importer Tests Guild Charter
## Working Directory
- `src/AirGap/__Tests/StellaOps.AirGap.Importer.Tests`
## Scope
- Unit and integration tests for AirGap Importer validation, quarantine, versioning, and reconciliation flows.
- Deterministic fixtures for DSSE, TUF, SBOM parsing, and evidence graph outputs.
- Offline-only inputs (no network, no external services).
## Required Reading
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/airgap/importer-scaffold.md`
- `docs/airgap/airgap-mode.md`
## Working Agreements
- Update task status in the sprint tracker and local `TASKS.md` for this directory.
- Keep tests deterministic (fixed time, fixed IDs, stable ordering).
- Prefer shared temp directory helpers and ensure cleanup.
- Do not silently skip fixture-based tests; mark explicit skip when fixtures are missing.
## Testing Rules
- Use `Unit` vs `Integration` trait categories consistently.
- Use WebApplicationFactory only when exercising HTTP endpoints.
- Keep fixtures and golden files under this directory; no downloads.

View File

@@ -0,0 +1,10 @@
# AirGap Importer Tests Task Board
This board mirrors active sprint tasks for this module.
Source of truth: `docs/implplan/SPRINT_20251229_049_BE_csproj_audit_maint_tests.md`.
| Task ID | Status | Notes |
| --- | --- | --- |
| AUDIT-0027-M | DONE | Maintainability audit for StellaOps.AirGap.Importer.Tests. |
| AUDIT-0027-T | DONE | Test coverage audit for StellaOps.AirGap.Importer.Tests. |
| AUDIT-0027-A | TODO | Pending approval for changes. |

View File

@@ -0,0 +1,25 @@
# AirGap Persistence Tests Guild Charter
## Working Directory
- `src/AirGap/__Tests/StellaOps.AirGap.Persistence.Tests`
## Scope
- Integration and unit tests for AirGap persistence stores and schema behavior.
- Deterministic validation of state and bundle version storage.
## Required Reading
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/airgap/bundle-repositories.md`
- `docs/airgap/airgap-mode.md`
## Working Agreements
- Update task status in the sprint tracker and local `TASKS.md`.
- Keep tests deterministic (fixed time, fixed IDs, stable ordering).
- Prefer shared temp directory helpers and ensure cleanup.
- Categorize integration tests correctly; avoid "Unit" for Postgres-backed tests.
## Testing Rules
- Use the AirGap Postgres fixture; no network.
- Validate schema names, indexes, and ordering explicitly in assertions.

View File

@@ -17,7 +17,7 @@ public sealed class AirGapPostgresFixture : PostgresIntegrationFixture, ICollect
protected override string GetModuleName() => "AirGap";
protected override string? GetResourcePrefix() => "Migrations";
protected override string? GetResourcePrefix() => null;
/// <summary>
/// Gets all table names in the test schema.

View File

@@ -37,7 +37,7 @@ public sealed class AirGapStorageIntegrationTests : IAsyncLifetime
var options = Options.Create(new PostgresOptions
{
ConnectionString = fixture.ConnectionString,
SchemaName = AirGapDataSource.DefaultSchemaName,
SchemaName = fixture.SchemaName,
AutoMigrate = false
});
@@ -64,9 +64,9 @@ public sealed class AirGapStorageIntegrationTests : IAsyncLifetime
// Arrange
var expectedTables = new[]
{
"airgap_state",
"airgap_bundles",
"airgap_import_log"
"state",
"bundle_versions",
"bundle_version_history"
};
// Act
@@ -88,7 +88,7 @@ public sealed class AirGapStorageIntegrationTests : IAsyncLifetime
var expectedColumns = new[] { "tenant_id", "sealed", "policy_hash", "time_anchor", "created_at", "updated_at" };
// Act
var columns = await _fixture.GetColumnNamesAsync("airgap_state");
var columns = await _fixture.GetColumnNamesAsync("state");
// Assert
foreach (var expectedColumn in expectedColumns)
@@ -117,7 +117,7 @@ public sealed class AirGapStorageIntegrationTests : IAsyncLifetime
public async Task Migration_HasTenantIndex()
{
// Act
var indexes = await _fixture.GetIndexNamesAsync("airgap_state");
var indexes = await _fixture.GetIndexNamesAsync("state");
// Assert
indexes.Should().Contain(i => i.Contains("tenant", StringComparison.OrdinalIgnoreCase),

View File

@@ -25,7 +25,7 @@ public sealed class PostgresAirGapStateStoreTests : IAsyncLifetime
var options = Options.Create(new PostgresOptions
{
ConnectionString = fixture.ConnectionString,
SchemaName = AirGapDataSource.DefaultSchemaName,
SchemaName = fixture.SchemaName,
AutoMigrate = false
});

View File

@@ -0,0 +1,10 @@
# AirGap Persistence Tests Task Board
This board mirrors active sprint tasks for this module.
Source of truth: `docs/implplan/SPRINT_20251229_049_BE_csproj_audit_maint_tests.md`.
| Task ID | Status | Notes |
| --- | --- | --- |
| AUDIT-0029-M | DONE | Maintainability audit for StellaOps.AirGap.Persistence.Tests. |
| AUDIT-0029-T | DONE | Test coverage audit for StellaOps.AirGap.Persistence.Tests. |
| AUDIT-0029-A | TODO | Pending approval for changes. |

View File

@@ -0,0 +1,22 @@
# AirGap Time Tests Charter
## Working Directory
- `src/AirGap/__Tests/StellaOps.AirGap.Time.Tests`
## Scope
- Unit and integration tests for time anchors, staleness evaluation, and verification services.
## Required Reading
- `docs/airgap/staleness-and-time.md`
- `docs/airgap/airgap-mode.md`
- `docs/modules/platform/architecture-overview.md`
- `src/AirGap/StellaOps.AirGap.Time/AGENTS.md`
## Working Agreements
- Update task status in the sprint tracker and local `TASKS.md`.
- Keep tests deterministic (fixed time and IDs).
- Clean up temp artifacts created during tests.
## Testing Rules
- Include happy-path verification tests with deterministic fixtures.
- Exercise health checks and controller endpoints where applicable.

View File

@@ -0,0 +1,10 @@
# AirGap Time Tests Task Board
This board mirrors active sprint tasks for this module.
Source of truth: `docs/implplan/SPRINT_20251229_049_BE_csproj_audit_maint_tests.md`.
| Task ID | Status | Notes |
| --- | --- | --- |
| AUDIT-0035-M | DONE | Maintainability audit for StellaOps.AirGap.Time.Tests. |
| AUDIT-0035-T | DONE | Test coverage audit for StellaOps.AirGap.Time.Tests. |
| AUDIT-0035-A | TODO | Pending approval for changes. |

View File

@@ -23,12 +23,12 @@ public class TimeAnchorLoaderTests
[Fact]
public void LoadsHexToken()
{
var loader = Build();
var loader = Build(allowUntrusted: true);
var hex = "01020304";
var trust = new[] { new TimeTrustRoot("k1", new byte[32], "ed25519") };
var result = loader.TryLoadHex(hex, TimeTokenFormat.Roughtime, trust, out var anchor);
var result = loader.TryLoadHex(hex, TimeTokenFormat.Roughtime, Array.Empty<TimeTrustRoot>(), out var anchor);
Assert.True(result.IsValid);
Assert.Equal("untrusted-no-trust-roots", result.Reason);
Assert.Equal("Roughtime", anchor.Format);
}
@@ -58,9 +58,9 @@ public class TimeAnchorLoaderTests
Assert.Equal("trust-roots-required", result.Reason);
}
private static TimeAnchorLoader Build()
private static TimeAnchorLoader Build(bool allowUntrusted = false)
{
var options = Options.Create(new AirGapOptions { AllowUntrustedAnchors = false });
var options = Options.Create(new AirGapOptions { AllowUntrustedAnchors = allowUntrusted });
return new TimeAnchorLoader(new TimeVerificationService(), new TimeTokenParser(), options);
}
}

View File

@@ -14,18 +14,18 @@ public class TimeVerificationServiceTests
var svc = new TimeVerificationService();
var result = svc.Verify(new byte[] { 0x01 }, TimeTokenFormat.Roughtime, Array.Empty<TimeTrustRoot>(), out _);
Assert.False(result.IsValid);
Assert.Equal("trust-roots-required", result.Reason);
Assert.Equal("roughtime-trust-roots-required", result.Reason);
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void SucceedsForRoughtimeWithTrustRoot()
public void FailsForRoughtimeWithInvalidToken()
{
var svc = new TimeVerificationService();
var trust = new[] { new TimeTrustRoot("k1", new byte[] { 0x01 }, "rsassa-pss-sha256") };
var result = svc.Verify(new byte[] { 0x01, 0x02 }, TimeTokenFormat.Roughtime, trust, out var anchor);
Assert.True(result.IsValid);
Assert.Equal("Roughtime", anchor.Format);
Assert.Equal("k1", anchor.SignatureFingerprint);
Assert.False(result.IsValid);
Assert.Equal("roughtime-message-too-short", result.Reason);
Assert.Equal("unknown", anchor.Format);
}
}