Files
MijnBesluit/tests/MijnBesluit.SelfCheck/VersiehistorieChecks.cs
T
jfandClaude Sonnet 5.5 5446dd4170 Versiehistorie in een tabel, voor site en app
De versiehistorie stond als tekst in zowel de app als de website. Nu staat hij in
tabel version_history, met een beheerpagina (Beheer > Versiehistorie) op de site.
De site leest de tabel rechtstreeks, de app via de nieuwe actie app.versiehistorie.
Startrijen: db/handmatig/22b_versiehistorie_startrijen.sql (als root).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MGLqt1uKfNARQHut9ifcx
2026-10-20 11:47:06 +00:00

140 lines
8.0 KiB
C#

using MijnBesluit.Application.Models;
using MijnBesluit.Application.Services;
using MijnBesluit.Domain.Entities;
using MijnBesluit.Domain.Enums;
namespace MijnBesluit.SelfCheck;
/// <summary>
/// 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.
/// </summary>
public static class VersiehistorieChecks
{
private static async Task<User> 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<int> 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");
});
}
}