using MijnBesluit.Application.Models; using MijnBesluit.Application.Services; using MijnBesluit.Domain.Entities; using MijnBesluit.Domain.Enums; namespace MijnBesluit.SelfCheck; /// /// De versiehistorie uit de database: wie hem mag beheren en wat een gebruiker te zien krijgt. /// /// De afspraak is eenvoudig: één bron voor site en app. Een gebruiker leest alleen de zichtbare /// regels, nieuwste dag bovenaan; alleen een beheerder maakt, wijzigt, verbergt of verwijdert. /// public static class VersiehistorieChecks { private static async Task BeheerderAsync(World w, string email = "beheer@example.nl") { var u = await w.MaakGebruikerAsync(email, "Beheer", "Er"); w.Store.Users.Single(x => x.Id == u.Id).IsBeheerder = true; return u; } private static async Task MaakAsync(World w, User beheerder, DateOnly datum, string kop, string? versie = null, string tekst = "Uitleg.", bool zichtbaar = true) { var r = await w.Versiehistorie.MaakAsync(beheerder.Id, datum, versie, kop, tekst, zichtbaar); if (!r.Succeeded) throw new AssertionException($"regel maken mislukte: {r.Error}"); return r.Value; } public static void Register(Runner runner) { runner.TestAsync("Versiehistorie: zonder regels is de lijst leeg", async () => { var w = new World(); Assert.True((await w.Versiehistorie.ZichtbaarAsync()).Count == 0, "een lege tabel geeft een lege lijst"); }); runner.TestAsync("Versiehistorie: alleen een beheerder maakt, wijzigt of verwijdert", async () => { var w = new World(); var jan = await w.MaakGebruikerAsync("jan@example.nl", "Jan"); var beheer = await BeheerderAsync(w); var dag = new DateOnly(2026, 3, 1); var id = await MaakAsync(w, beheer, dag, "Eerste"); Assert.True(!(await w.Versiehistorie.MaakAsync(jan.Id, dag, null, "Tweede", "Uitleg")).Succeeded, "een gewone gebruiker maakt geen regel"); Assert.True(!(await w.Versiehistorie.OverzichtAsync(jan.Id)).Succeeded, "en ziet het beheeroverzicht niet"); Assert.True(!(await w.Versiehistorie.WijzigAsync(jan.Id, id, dag, null, "Anders", "Uitleg", true)).Succeeded, "en wijzigt niets"); Assert.True(!(await w.Versiehistorie.VerwijderAsync(jan.Id, id)).Succeeded, "en verwijdert niets"); Assert.True((await w.Versiehistorie.ZichtbaarAsync()).Single().Kop == "Eerste", "de regel is onaangetast"); }); runner.TestAsync("Versiehistorie: nieuwste dag bovenaan, binnen een dag in invoervolgorde", async () => { var w = new World(); var beheer = await BeheerderAsync(w); await MaakAsync(w, beheer, new DateOnly(2026, 2, 1), "Oud, eerste"); await MaakAsync(w, beheer, new DateOnly(2026, 4, 1), "Nieuw, eerste", "1.1"); await MaakAsync(w, beheer, new DateOnly(2026, 2, 1), "Oud, tweede"); await MaakAsync(w, beheer, new DateOnly(2026, 4, 1), "Nieuw, tweede", "1.1"); var lijst = await w.Versiehistorie.ZichtbaarAsync(); Assert.True(lijst.Select(r => r.Kop).SequenceEqual( new[] { "Nieuw, eerste", "Nieuw, tweede", "Oud, eerste", "Oud, tweede" }), "de nieuwste dag staat bovenaan en binnen een dag de volgorde van invoer"); Assert.True(lijst[0].Datum == "2026-04-01" && lijst[0].Versie == "1.1", "datum als jjjj-mm-dd, met versie"); Assert.True(lijst[2].Versie is null, "een regel zonder versie heeft er geen"); }); runner.TestAsync("Versiehistorie: een verborgen regel ziet alleen de beheerder", async () => { var w = new World(); var beheer = await BeheerderAsync(w); var dag = new DateOnly(2026, 3, 1); await MaakAsync(w, beheer, dag, "Zichtbaar"); var verborgen = await MaakAsync(w, beheer, dag, "Nog niet", zichtbaar: false); Assert.True((await w.Versiehistorie.ZichtbaarAsync()).Select(r => r.Kop).SequenceEqual(new[] { "Zichtbaar" }), "gebruikers zien de verborgen regel niet"); var overzicht = (await w.Versiehistorie.OverzichtAsync(beheer.Id)).Value!; Assert.True(overzicht.Count == 2, "de beheerder ziet beide"); var w2 = await w.Versiehistorie.WijzigAsync(beheer.Id, verborgen, dag, null, "Nog niet", "Uitleg.", true); Assert.True(w2.Succeeded, "tonen lukt"); Assert.True((await w.Versiehistorie.ZichtbaarAsync()).Count == 2, "daarna staat hij er ook voor gebruikers"); }); runner.TestAsync("Versiehistorie: wat niet klopt wordt geweigerd", async () => { var w = new World(); var beheer = await BeheerderAsync(w); var dag = new DateOnly(2026, 3, 1); Assert.True(!(await w.Versiehistorie.MaakAsync(beheer.Id, dag, null, " ", "Uitleg")).Succeeded, "een lege kop mag niet"); Assert.True(!(await w.Versiehistorie.MaakAsync(beheer.Id, dag, null, "Kop", "")).Succeeded, "een lege uitleg mag niet"); Assert.True(!(await w.Versiehistorie.MaakAsync(beheer.Id, dag, null, new string('k', VersiehistorieService.MaxKop + 1), "Uitleg")).Succeeded, "een te lange kop mag niet"); Assert.True(!(await w.Versiehistorie.MaakAsync(beheer.Id, dag, null, "Kop", new string('t', VersiehistorieService.MaxTekst + 1))).Succeeded, "een te lange uitleg mag niet"); Assert.True(!(await w.Versiehistorie.MaakAsync(beheer.Id, dag, new string('1', VersiehistorieService.MaxVersie + 1), "Kop", "Uitleg")).Succeeded, "een te lang versienummer mag niet"); Assert.True(!(await w.Versiehistorie.MaakAsync(beheer.Id, new DateOnly(2090, 1, 1), null, "Kop", "Uitleg")).Succeeded, "een datum ver in de toekomst is een typefout"); Assert.True(!(await w.Versiehistorie.MaakAsync(beheer.Id, new DateOnly(1999, 1, 1), null, "Kop", "Uitleg")).Succeeded, "een datum van lang geleden ook"); await MaakAsync(w, beheer, dag, "Dubbel"); Assert.True(!(await w.Versiehistorie.MaakAsync(beheer.Id, dag, null, "dubbel", "Uitleg")).Succeeded, "dezelfde kop op dezelfde dag staat er al"); Assert.True((await w.Versiehistorie.MaakAsync(beheer.Id, dag.AddDays(1), null, "Dubbel", "Uitleg")).Succeeded, "op een andere dag mag dezelfde kop wel"); }); runner.TestAsync("Versiehistorie: wijzigen en verwijderen, en het blijft vastgelegd", async () => { var w = new World(); var beheer = await BeheerderAsync(w); var dag = new DateOnly(2026, 3, 1); var id = await MaakAsync(w, beheer, dag, "Eerste", tekst: "Oude uitleg"); Assert.True((await w.Versiehistorie.WijzigAsync(beheer.Id, id, dag, " 1.2 ", " Nieuwe kop ", " Nieuwe uitleg ", true)).Succeeded, "wijzigen lukt"); var regel = (await w.Versiehistorie.ZichtbaarAsync()).Single(); Assert.True(regel.Kop == "Nieuwe kop" && regel.Tekst == "Nieuwe uitleg" && regel.Versie == "1.2", "spaties eromheen verdwijnen"); Assert.True(!(await w.Versiehistorie.WijzigAsync(beheer.Id, 9999, dag, null, "Kop", "Uitleg", true)).Succeeded, "een regel die er niet is, is niet te wijzigen"); Assert.True((await w.Versiehistorie.VerwijderAsync(beheer.Id, id)).Succeeded, "verwijderen lukt"); Assert.True((await w.Versiehistorie.ZichtbaarAsync()).Count == 0, "en dan is hij weg"); var acties = w.Store.Audit.Count(a => a.Action == AuditAction.VersiehistorieBeheerd); Assert.True(acties == 3, "maken, wijzigen en verwijderen staan alle drie in het logboek"); }); } }