using AuthApi.Models; using AuthApi.Services; using Microsoft.Extensions.Configuration; using Xunit; namespace AuthApi.Tests; public sealed class LegalPolicyTests { private static LegalPolicy Policy(string version = "2026-07-20") => new( new ConfigurationBuilder().AddInMemoryCollection(new Dictionary { ["Legal:TermsVersion"] = version, ["Legal:PrivacyVersion"] = version, ["Legal:EffectiveUtc"] = "2026-07-20T00:00:00Z" }).Build()); [Fact] public void ExistingUserWithoutAcceptanceRequiresAgreement() { Assert.True(Policy().Status(new User()).RequiresLegalAcceptance); } [Fact] public void AcceptRecordsVersionsTimestampAndSource() { var user = new User(); var acceptedUtc = new DateTime(2026, 7, 20, 12, 0, 0, DateTimeKind.Utc); Policy().Accept(user, "password_registration", acceptedUtc); Assert.Equal("2026-07-20", user.TermsAcceptedVersion); Assert.Equal("2026-07-20", user.PrivacyAcceptedVersion); Assert.Equal(acceptedUtc, user.LegalAcceptedUtc); var acceptance = Assert.Single(user.LegalAcceptances); Assert.Equal("password_registration", acceptance.Source); } [Fact] public void AcceptIsIdempotentForCurrentVersions() { var user = new User(); var policy = Policy(); var first = new DateTime(2026, 7, 20, 12, 0, 0, DateTimeKind.Utc); policy.Accept(user, "registration", first); policy.Accept(user, "prompt", first.AddHours(1)); Assert.Single(user.LegalAcceptances); Assert.Equal(first, user.LegalAcceptedUtc); } [Fact] public void NewPolicyVersionRequiresAcceptanceAgain() { var user = new User(); Policy().Accept(user, "registration"); Assert.True(Policy("2026-08-01").Status(user).RequiresLegalAcceptance); } }