|
- using System.Net;
- using System.Net.Http.Headers;
- using System.Net.Http.Json;
-
- namespace Campaign_Tracker.Server.Tests;
-
- public sealed class MunicipalityProfileControllerTests
- {
- // ── AC #1: profile created and saved with legacy link ────────────────────
-
- [Fact]
- public async Task CreateProfile_ValidJCode_Returns200WithCombinedView_AC1_AC2()
- {
- await using var factory = new AuthIntegrationTestFactory();
- using var client = factory.CreateClient();
- client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
- "Bearer", AuthIntegrationTestFactory.CreateToken("cs@example.test", "client-services"));
-
- var response = await client.PostAsJsonAsync("/api/municipalities/profiles", new
- {
- jCode = "FAIR01",
- displayName = "Fairview Borough Profile",
- });
-
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- var body = await response.Content.ReadFromJsonAsync<MunicipalityProfileDto>();
- Assert.NotNull(body);
- Assert.Equal("FAIR01", body.JCode);
- Assert.Equal("Fairview Borough Profile", body.DisplayName);
- // AC #2: combined view includes resolved legacy name
- Assert.Equal("Fairview Borough", body.LegacyName);
- }
-
- // ── AC #2: list returns combined extension + legacy fields ────────────────
-
- [Fact]
- public async Task GetAllProfiles_ReturnsResolvedLegacyData_AC2()
- {
- await using var factory = new AuthIntegrationTestFactory();
- using var client = factory.CreateClient();
- client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
- "Bearer", AuthIntegrationTestFactory.CreateToken("cs@example.test", "client-services"));
-
- await client.PostAsJsonAsync("/api/municipalities/profiles", new { jCode = "LAKE02", displayName = (string?)null });
-
- var response = await client.GetAsync("/api/municipalities/profiles");
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
-
- var profiles = await response.Content.ReadFromJsonAsync<MunicipalityProfileDto[]>();
- Assert.NotNull(profiles);
- var lake = Assert.Single(profiles, p => p.JCode == "LAKE02");
- Assert.Equal("Lake Township", lake.LegacyName);
- }
-
- // ── AC #3: update audits the change (server-side; response includes actor) ─
-
- [Fact]
- public async Task UpdateProfile_ChangesDisplayName_Returns200_AC3()
- {
- await using var factory = new AuthIntegrationTestFactory();
- using var client = factory.CreateClient();
- client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
- "Bearer", AuthIntegrationTestFactory.CreateToken("cs@example.test", "client-services"));
-
- var created = await (await client.PostAsJsonAsync("/api/municipalities/profiles",
- new { jCode = "FAIR01", displayName = "Old Name" }))
- .Content.ReadFromJsonAsync<MunicipalityProfileDto>();
-
- var response = await client.PutAsJsonAsync(
- $"/api/municipalities/profiles/{created!.ProfileId}",
- new { displayName = "New Name" });
-
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- var updated = await response.Content.ReadFromJsonAsync<MunicipalityProfileDto>();
- Assert.Equal("New Name", updated!.DisplayName);
- }
-
- // ── AC #4: invalid JCode rejected before save ─────────────────────────────
-
- [Fact]
- public async Task CreateProfile_InvalidJCode_Returns422WithDescription_AC4()
- {
- await using var factory = new AuthIntegrationTestFactory();
- using var client = factory.CreateClient();
- client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
- "Bearer", AuthIntegrationTestFactory.CreateToken("cs@example.test", "client-services"));
-
- var response = await client.PostAsJsonAsync("/api/municipalities/profiles", new
- {
- jCode = "DOESNOTEXIST",
- displayName = (string?)null,
- });
-
- Assert.Equal(HttpStatusCode.UnprocessableEntity, response.StatusCode);
- var body = await response.Content.ReadFromJsonAsync<MunicipalityProfileProblemDto>();
- Assert.NotNull(body);
- Assert.Contains("DOESNOTEXIST", body.Error);
- }
-
- // ── Authorization: non-recognized role gets 403 ───────────────────────────
-
- [Fact]
- public async Task CreateProfile_NoToken_Returns401()
- {
- await using var factory = new AuthIntegrationTestFactory();
- using var client = factory.CreateClient();
-
- var response = await client.PostAsJsonAsync("/api/municipalities/profiles",
- new { jCode = "FAIR01", displayName = (string?)null });
-
- Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
- }
-
- // ── Local DTOs for deserialization ────────────────────────────────────────
-
- private sealed record MunicipalityProfileDto(
- string ProfileId,
- string JCode,
- string? DisplayName,
- string UpdatedAt,
- string UpdatedBy,
- string? LegacyName,
- string? LegacyMailingAddress,
- string? LegacyCityStateZip);
-
- private sealed record MunicipalityProfileProblemDto(string Error);
- }
|