186 lines
8.1 KiB
C#
186 lines
8.1 KiB
C#
using MijnBesluit.Application.Abstractions;
|
|
using MijnBesluit.Application.Services;
|
|
|
|
namespace MijnBesluit.SelfCheck;
|
|
|
|
/// <summary>Alles wat één testscenario nodig heeft, klaargezet in het geheugen.</summary>
|
|
public class World
|
|
{
|
|
public Store Store { get; } = new();
|
|
public TestClock Clock { get; } = new();
|
|
public TestEmail Email { get; } = new();
|
|
public TestPush Push { get; } = new();
|
|
|
|
/// <summary>Standaard uit; zet hem aan in een test die het verkleinen wil nakijken.</summary>
|
|
public TestVerkleiner Verkleiner { get; } = new();
|
|
|
|
public AccountService Accounts { get; }
|
|
public FamilyService Families { get; }
|
|
public VaultService Vault { get; }
|
|
public MessageService Messages { get; }
|
|
public LegacyService Legacy { get; }
|
|
public MeldingService Meldingen { get; }
|
|
public OverzichtService Overzicht { get; }
|
|
public SamenvoegService Samenvoegen { get; }
|
|
public BeheerService Beheer { get; }
|
|
public AdvertentieService Adverteren { get; }
|
|
public AccountOpheffenService Opheffen { get; }
|
|
|
|
/// <summary>Maakt in één stap een account aan; scheelt in de scenario's het hele codegedoe.</summary>
|
|
public async Task<MijnBesluit.Domain.Entities.User> MaakGebruikerAsync(string email, string voornaam, string achternaam = "")
|
|
{
|
|
var resultaat = await Accounts.MaakAccountAsync(email, voornaam, achternaam);
|
|
if (!resultaat.Succeeded) throw new AssertionException($"account aanmaken mislukte: {resultaat.Error}");
|
|
return resultaat.Value!;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Maakt iemand met een echt account die ook écht in de familie van <paramref name="eigenaar"/>
|
|
/// staat: toevoegen, uitnodigen, aannemen. Dat laatste is nodig omdat toevoegen alleen een
|
|
/// aantekening maakt; pas door de uitnodiging aan te nemen wordt het profiel van hemzelf en
|
|
/// staat hij in de kring van de eigenaar.
|
|
///
|
|
/// Die kring bepaalt wie er iets mag zeggen over een overlijden, dus tests die dat nabootsen
|
|
/// moeten hem ook echt opbouwen.
|
|
/// </summary>
|
|
public async Task<MijnBesluit.Domain.Entities.User> MaakFamilielidAsync(
|
|
MijnBesluit.Domain.Entities.User eigenaar, string voornaam, string achternaam, string email,
|
|
MijnBesluit.Domain.Enums.RelationType relatie = MijnBesluit.Domain.Enums.RelationType.Kind)
|
|
{
|
|
var familie = Store.Families.Single(f => f.OwnerPersonId == eigenaar.PersonId);
|
|
|
|
var profiel = await Families.AddMemberAsync(familie.Id, eigenaar.Id, voornaam, achternaam, email, relatie);
|
|
if (!profiel.Succeeded) throw new AssertionException($"toevoegen mislukte: {profiel.Error}");
|
|
|
|
var token = await Families.InviteAsync(familie.Id, profiel.Value!.Id, eigenaar.Id);
|
|
if (!token.Succeeded) throw new AssertionException($"uitnodigen mislukte: {token.Error}");
|
|
|
|
var account = await Families.AcceptInvitationAsync(token.Value!, Accounts);
|
|
if (!account.Succeeded) throw new AssertionException($"aannemen mislukte: {account.Error}");
|
|
|
|
return account.Value!;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Wijst een of meer mensen aan als nalatenschapsbeheerder van <paramref name="betrokkene"/>.
|
|
///
|
|
/// Nodig in elke test die een overlijden meldt: alleen wie is aangewezen mag dat. Ze moeten
|
|
/// ook echt in zijn familie staan, dus gebruik hiervoor mensen uit MaakFamilielidAsync.
|
|
/// </summary>
|
|
public async Task BeheerderAsync(MijnBesluit.Domain.Entities.User betrokkene,
|
|
params MijnBesluit.Domain.Entities.User[] beheerders)
|
|
{
|
|
var volgorde = 1;
|
|
foreach (var beheerder in beheerders)
|
|
{
|
|
var r = await Legacy.AppointManagerAsync(betrokkene.Id, beheerder.PersonId, volgorde++);
|
|
if (!r.Succeeded) throw new AssertionException($"aanwijzen mislukte: {r.Error}");
|
|
}
|
|
}
|
|
|
|
/// <summary>Haalt de code uit de laatst verstuurde e-mail, zoals een gebruiker hem uit zijn postvak haalt.</summary>
|
|
public string LaatsteCodeUitMail(string email)
|
|
{
|
|
var mail = Email.Sent.Last(m => m.To == email);
|
|
var match = System.Text.RegularExpressions.Regex.Match(mail.Body, @"letter-spacing:5px;margin:20px 0"">(\d+)<");
|
|
if (!match.Success) throw new AssertionException("geen code gevonden in de e-mail");
|
|
return match.Groups[1].Value;
|
|
}
|
|
|
|
public World()
|
|
{
|
|
var uow = new Uow(Store);
|
|
var keys = new TestKeyProtector();
|
|
var files = new TestFiles();
|
|
var audit = new Audit(Store, Clock);
|
|
|
|
var users = new UserRepo(Store);
|
|
var people = new PersonRepo(Store);
|
|
var families = new FamilyRepo(Store);
|
|
var invitations = new InvitationRepo(Store);
|
|
var vault = new VaultRepo(Store);
|
|
var messages = new MessageRepo(Store);
|
|
var legacy = new LegacyRepo(Store);
|
|
var codes = new LoginCodeRepo(Store);
|
|
|
|
Accounts = new AccountService(users, people, families, codes, keys, Email, audit, uow, Clock, vault);
|
|
Families = new FamilyService(families, people, users, invitations, messages, legacy,
|
|
Email, audit, uow, Clock);
|
|
Vault = new VaultService(vault, people, messages, users, keys, files, audit, uow, Clock, Verkleiner, families, legacy);
|
|
Meldingen = new MeldingService(new ToestelRepo(Store), users, Push, uow, Clock);
|
|
Messages = new MessageService(messages, people, users, vault, keys, files, Email, audit, uow, Clock, Meldingen);
|
|
Legacy = new LegacyService(legacy, people, users, vault, messages, Email, audit, uow, Clock, Vault, families);
|
|
Overzicht = new OverzichtService(users, people, families, vault, messages, legacy, uow, Clock);
|
|
Samenvoegen = new SamenvoegService(people, families, invitations, messages, vault, legacy,
|
|
audit, uow, Clock, new SamenvoegRepo(Store));
|
|
Beheer = new BeheerService(users, people, legacy, audit, Clock, Legacy, Samenvoegen);
|
|
Adverteren = new AdvertentieService(new AdvertentieRepo(Store), users, Email, audit, uow,
|
|
Clock, Verkleiner);
|
|
Opheffen = new AccountOpheffenService(users, people, families, invitations, vault, messages,
|
|
legacy, codes, new ToestelRepo(Store), files, Email,
|
|
audit, uow, Clock);
|
|
}
|
|
}
|
|
|
|
public static class Assert
|
|
{
|
|
public static void True(bool condition, string what)
|
|
{
|
|
if (!condition) throw new AssertionException(what);
|
|
}
|
|
|
|
public static void Throws<TException>(Action action, string what) where TException : Exception
|
|
{
|
|
try { action(); }
|
|
catch (TException) { return; }
|
|
catch (Exception ex) { throw new AssertionException($"{what} (kreeg {ex.GetType().Name})"); }
|
|
throw new AssertionException($"{what} (er werd geen fout gegooid)");
|
|
}
|
|
}
|
|
|
|
public class AssertionException : Exception
|
|
{
|
|
public AssertionException(string message) : base(message) { }
|
|
}
|
|
|
|
/// <summary>Draait de scenario's en vat de uitkomst samen.</summary>
|
|
public class Runner
|
|
{
|
|
private int _passed, _failed;
|
|
|
|
public void Test(string name, Action body) => Run(name, () => { body(); return Task.CompletedTask; });
|
|
|
|
public void TestAsync(string name, Func<Task> body) => Run(name, body);
|
|
|
|
private void Run(string name, Func<Task> body)
|
|
{
|
|
try
|
|
{
|
|
body().GetAwaiter().GetResult();
|
|
_passed++;
|
|
Console.WriteLine($" OK {name}");
|
|
}
|
|
catch (AssertionException ex)
|
|
{
|
|
_failed++;
|
|
Console.WriteLine($" FOUT {name}");
|
|
Console.WriteLine($" verwacht: {ex.Message}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_failed++;
|
|
Console.WriteLine($" FOUT {name}");
|
|
Console.WriteLine($" {ex.GetType().Name}: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public int Summary()
|
|
{
|
|
Console.WriteLine();
|
|
Console.WriteLine(_failed == 0
|
|
? $"Alle {_passed} controles geslaagd."
|
|
: $"{_passed} geslaagd, {_failed} mislukt.");
|
|
return _failed == 0 ? 0 : 1;
|
|
}
|
|
}
|