|
- using Campaign_Tracker.Server.ExtensionData;
- using Campaign_Tracker.Server.LegacyData;
- using Campaign_Tracker.Server.LegacyData.Models;
- using Campaign_Tracker.Server.Municipalities;
-
- namespace Campaign_Tracker.Server.Tests;
-
- public sealed class MunicipalityProfileRepositoryTests
- {
- private static readonly DateTimeOffset FixedNow =
- new(2026, 5, 6, 12, 0, 0, TimeSpan.Zero);
-
- private static InMemoryMunicipalityProfileRepository BuildSut(
- ILegacyDataAccess? data = null)
- {
- data ??= new InMemoryLegacyDataAccess(
- jurisdictions:
- [
- new("FAIR01", "Fairview Borough", "100 Main St", "Fairview, PA 16415", null, null),
- new("LAKE02", "Lake Township", "200 Lake Rd", "Lake City, PA 16423", null, null),
- ]);
-
- return new InMemoryMunicipalityProfileRepository(
- new LegacyLinkValidator(data),
- data,
- new FakeTimeProvider(FixedNow));
- }
-
- // ── AC #1: profile saved with required JCode link ────────────────────────
-
- [Fact]
- public async Task CreateAsync_ValidJCode_SavesProfileWithLegacyLink_AC1()
- {
- var sut = BuildSut();
-
- var result = await sut.CreateAsync("FAIR01", "Fairview Profile", "user@test.com");
-
- Assert.True(result.Saved);
- Assert.NotNull(result.Profile);
- Assert.Equal("FAIR01", result.Profile.JCode);
- Assert.Equal("MunicipalityProfile", result.Profile.RecordType);
- Assert.Equal(LegacyLinkType.JurisdictionJCode, result.Profile.LegacyLink.Type);
- Assert.Equal("FAIR01", result.Profile.LegacyLink.Value);
- }
-
- [Fact]
- public async Task CreateAsync_ProfileIdIsGeneratedGuid_AC1()
- {
- var sut = BuildSut();
-
- var result = await sut.CreateAsync("FAIR01", null, "user@test.com");
-
- Assert.NotNull(result.Profile);
- Assert.True(Guid.TryParse(result.Profile.ProfileId, out _), "ProfileId should be a valid GUID.");
- }
-
- // ── AC #2: combined view resolves legacy jurisdiction data ────────────────
-
- [Fact]
- public async Task GetAllAsync_ReturnsLegacyJurisdictionFieldsAlongsideExtensionData_AC2()
- {
- var sut = BuildSut();
- await sut.CreateAsync("FAIR01", "Fairview Display", "user@test.com");
-
- var views = await sut.GetAllAsync();
-
- Assert.Single(views);
- var view = views[0];
- Assert.Equal("FAIR01", view.Profile.JCode);
- Assert.Equal("Fairview Borough", view.LegacyName);
- Assert.Equal("100 Main St", view.LegacyMailingAddress);
- Assert.Equal("Fairview, PA 16415", view.LegacyCityStateZip);
- }
-
- [Fact]
- public async Task GetByIdAsync_ReturnsLegacyAndExtensionDataCombined_AC2()
- {
- var sut = BuildSut();
- var created = await sut.CreateAsync("LAKE02", null, "user@test.com");
-
- var view = await sut.GetByIdAsync(created.Profile!.ProfileId);
-
- Assert.NotNull(view);
- Assert.Equal("LAKE02", view.Profile.JCode);
- Assert.Equal("Lake Township", view.LegacyName);
- }
-
- [Fact]
- public async Task GetByIdAsync_UnknownId_ReturnsNull_AC2()
- {
- var sut = BuildSut();
-
- var view = await sut.GetByIdAsync("does-not-exist");
-
- Assert.Null(view);
- }
-
- // ── AC #3: update records actor and timestamp ─────────────────────────────
-
- [Fact]
- public async Task UpdateAsync_ChangesDisplayNameAndCapturesActor_AC3()
- {
- var sut = BuildSut();
- var created = await sut.CreateAsync("FAIR01", "Old Name", "creator@test.com");
-
- var updated = await sut.UpdateAsync(created.Profile!.ProfileId, "New Name", "updater@test.com");
-
- Assert.True(updated.Saved);
- Assert.Equal("New Name", updated.Profile!.DisplayName);
- Assert.Equal("updater@test.com", updated.Profile.UpdatedBy);
- Assert.Equal(FixedNow, updated.Profile.UpdatedAt);
- }
-
- [Fact]
- public async Task UpdateAsync_UnknownId_ReturnsFailure_AC3()
- {
- var sut = BuildSut();
-
- var result = await sut.UpdateAsync("ghost-id", "name", "actor");
-
- Assert.False(result.Saved);
- Assert.Contains("ghost-id", result.Error);
- }
-
- // ── AC #4: invalid JCode rejected before save ─────────────────────────────
-
- [Fact]
- public async Task CreateAsync_InvalidJCode_ReturnsFailureWithDescription_AC4()
- {
- var sut = BuildSut(new InMemoryLegacyDataAccess(jurisdictions: []));
-
- var result = await sut.CreateAsync("UNKNOWN", null, "user@test.com");
-
- Assert.False(result.Saved);
- Assert.NotNull(result.Error);
- Assert.Contains("UNKNOWN", result.Error);
- }
-
- [Fact]
- public async Task CreateAsync_BlankJCode_ReturnsFailureWithDescription_AC4()
- {
- var sut = BuildSut();
-
- var result = await sut.CreateAsync("", null, "user@test.com");
-
- Assert.False(result.Saved);
- Assert.NotNull(result.Error);
- }
-
- [Fact]
- public async Task CreateAsync_DuplicateJCode_ReturnsFailure_AC4()
- {
- var sut = BuildSut();
- await sut.CreateAsync("FAIR01", null, "user@test.com");
-
- var second = await sut.CreateAsync("FAIR01", "Another", "user@test.com");
-
- Assert.False(second.Saved);
- Assert.Contains("FAIR01", second.Error);
- }
-
- // ── ILegacyLinkedRecordProvider participates in integrity check ──────────
-
- [Fact]
- public async Task GetAllAsync_AsLinkedRecordProvider_ReturnsProfilesForIntegrityCheck_AC1()
- {
- var sut = BuildSut();
- await sut.CreateAsync("FAIR01", null, "user@test.com");
- await sut.CreateAsync("LAKE02", null, "user@test.com");
-
- var provider = (ILegacyLinkedRecordProvider)sut;
- var records = await provider.GetAllAsync();
-
- Assert.Equal(2, records.Count);
- Assert.All(records, r =>
- {
- Assert.Equal("MunicipalityProfile", r.RecordType);
- Assert.Equal(LegacyLinkType.JurisdictionJCode, r.LegacyLink.Type);
- });
- }
-
- // ── Helpers ───────────────────────────────────────────────────────────────
-
- private sealed class FakeTimeProvider(DateTimeOffset utcNow) : TimeProvider
- {
- public override DateTimeOffset GetUtcNow() => utcNow;
- }
- }
|