|
- using Campaign_Tracker.Server.ExtensionData;
- using Campaign_Tracker.Server.LegacyData;
- using Campaign_Tracker.Server.LegacyData.Models;
-
- namespace Campaign_Tracker.Server.Tests;
-
- public sealed class LegacyLinkIntegrityServiceTests
- {
- private static readonly DateTimeOffset FixedNow =
- new(2026, 5, 6, 12, 0, 0, TimeSpan.Zero);
-
- private static LegacyLinkIntegrityService BuildSut(
- ILegacyDataAccess data,
- params ILegacyLinkedRecordProvider[] providers)
- {
- var validator = new LegacyLinkValidator(data);
- var time = new FakeTimeProvider(FixedNow);
- return new LegacyLinkIntegrityService(providers, validator, time);
- }
-
- // ── AC #4 — nightly integrity check with no extension records ────────────
-
- [Fact]
- public async Task CheckAsync_NoProviders_ReturnsFullyConsistentReport_AC4()
- {
- var sut = BuildSut(new InMemoryLegacyDataAccess());
-
- var report = await sut.CheckAsync();
-
- Assert.True(report.IsConsistent);
- Assert.Equal(0, report.TotalRecords);
- Assert.Equal(0, report.FailedRecords);
- Assert.Equal(100.0, report.ConsistencyPercentage);
- Assert.Empty(report.Failures);
- Assert.Equal(FixedNow, report.CheckedAt);
- }
-
- // ── AC #4 — consistent records produce clean report ──────────────────────
-
- [Fact]
- public async Task CheckAsync_AllValidLinks_Reports100PercentConsistency_AC4()
- {
- var data = new InMemoryLegacyDataAccess(
- jurisdictions: [new("FAIR01", "Fairview", null, null, null, null)]);
-
- var provider = new StubProvider(
- [
- new StubRecord("MunicipalityProfile", "mp-001", LegacyLinkReference.ForJurisdiction("FAIR01")),
- new StubRecord("MunicipalityProfile", "mp-002", LegacyLinkReference.ForJurisdiction("FAIR01")),
- ]);
-
- var sut = BuildSut(data, provider);
- var report = await sut.CheckAsync();
-
- Assert.True(report.IsConsistent);
- Assert.Equal(2, report.TotalRecords);
- Assert.Equal(2, report.ConsistentRecords);
- Assert.Equal(0, report.FailedRecords);
- Assert.Equal(100.0, report.ConsistencyPercentage);
- Assert.Empty(report.Failures);
- }
-
- // ── AC #4 — failing links are flagged with descriptive reason ────────────
-
- [Fact]
- public async Task CheckAsync_InvalidLink_FlagsRecordWithReason_AC4()
- {
- var data = new InMemoryLegacyDataAccess(jurisdictions: []);
-
- var provider = new StubProvider(
- [
- new StubRecord("MunicipalityProfile", "mp-ghost", LegacyLinkReference.ForJurisdiction("GONE01")),
- ]);
-
- var sut = BuildSut(data, provider);
- var report = await sut.CheckAsync();
-
- Assert.False(report.IsConsistent);
- Assert.Equal(1, report.TotalRecords);
- Assert.Equal(0, report.ConsistentRecords);
- Assert.Equal(1, report.FailedRecords);
- Assert.Single(report.Failures);
-
- var failure = report.Failures[0];
- Assert.Equal("MunicipalityProfile", failure.RecordType);
- Assert.Equal("mp-ghost", failure.RecordId);
- Assert.Equal(LegacyLinkType.JurisdictionJCode, failure.Reference.Type);
- Assert.Equal("GONE01", failure.Reference.Value);
- Assert.Contains("GONE01", failure.Reason);
- }
-
- [Fact]
- public async Task CheckAsync_MixedValidity_ReportsCorrectConsistencyPercentage_AC4()
- {
- var data = new InMemoryLegacyDataAccess(
- jurisdictions: [new("GOOD01", "Good", null, null, null, null)]);
-
- var provider = new StubProvider(
- [
- new StubRecord("MunicipalityProfile", "mp-good", LegacyLinkReference.ForJurisdiction("GOOD01")),
- new StubRecord("MunicipalityProfile", "mp-bad", LegacyLinkReference.ForJurisdiction("MISSING")),
- ]);
-
- var sut = BuildSut(data, provider);
- var report = await sut.CheckAsync();
-
- Assert.False(report.IsConsistent);
- Assert.Equal(2, report.TotalRecords);
- Assert.Equal(1, report.ConsistentRecords);
- Assert.Equal(1, report.FailedRecords);
- Assert.Equal(50.0, report.ConsistencyPercentage);
- }
-
- // ── AC #4 — multiple providers aggregate correctly ───────────────────────
-
- [Fact]
- public async Task CheckAsync_MultipleProviders_AggregatesAllRecords_AC4()
- {
- var data = new InMemoryLegacyDataAccess(
- jurisdictions: [new("FAIR01", "Fairview", null, null, null, null)],
- kits: [new LegacyKit(101, "FAIR01", null, null, null, null, false, false, null, null, null, null, null, null)]);
-
- var providerA = new StubProvider(
- [
- new StubRecord("MunicipalityProfile", "mp-001", LegacyLinkReference.ForJurisdiction("FAIR01")),
- ]);
- var providerB = new StubProvider(
- [
- new StubRecord("ElectionJob", "ej-001", LegacyLinkReference.ForKit(101)),
- ]);
-
- var sut = BuildSut(data, providerA, providerB);
- var report = await sut.CheckAsync();
-
- Assert.True(report.IsConsistent);
- Assert.Equal(2, report.TotalRecords);
- Assert.Equal(0, report.FailedRecords);
- }
-
- // ── Helpers ───────────────────────────────────────────────────────────────
-
- private sealed class StubRecord(string recordType, string recordId, LegacyLinkReference link)
- : ILegacyLinkedRecord
- {
- public string RecordType => recordType;
- public string RecordId => recordId;
- public LegacyLinkReference LegacyLink => link;
- }
-
- private sealed class StubProvider(IReadOnlyList<ILegacyLinkedRecord> records)
- : ILegacyLinkedRecordProvider
- {
- public Task<IReadOnlyList<ILegacyLinkedRecord>> GetAllAsync(CancellationToken cancellationToken = default)
- => Task.FromResult(records);
- }
-
- private sealed class FakeTimeProvider(DateTimeOffset utcNow) : TimeProvider
- {
- public override DateTimeOffset GetUtcNow() => utcNow;
- }
- }
|