diff --git a/src/AssociationRegistry.Admin.Api/Verenigingen/Lidmaatschap/VerwijderLidmaatschap/VerwijderLidmaatschapController.cs b/src/AssociationRegistry.Admin.Api/Verenigingen/Lidmaatschap/VerwijderLidmaatschap/VerwijderLidmaatschapController.cs index 66db15a35..e806f0992 100644 --- a/src/AssociationRegistry.Admin.Api/Verenigingen/Lidmaatschap/VerwijderLidmaatschap/VerwijderLidmaatschapController.cs +++ b/src/AssociationRegistry.Admin.Api/Verenigingen/Lidmaatschap/VerwijderLidmaatschap/VerwijderLidmaatschapController.cs @@ -1,15 +1,19 @@ namespace AssociationRegistry.Admin.Api.Verenigingen.Lidmaatschap.VerwijderLidmaatschap; +using Acties.VerwijderLidmaatschap; using Asp.Versioning; using Be.Vlaanderen.Basisregisters.Api; using Be.Vlaanderen.Basisregisters.Api.Exceptions; +using Framework; using Hosts.Configuration.ConfigurationBindings; using Infrastructure; +using Infrastructure.Extensions; using Infrastructure.Middleware; using Infrastructure.Swagger.Annotations; using Infrastructure.Swagger.Examples; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Filters; +using Vereniging; using Wolverine; using ProblemDetails = Be.Vlaanderen.Basisregisters.BasicApiProblem.ProblemDetails; using ValidationProblemDetails = Be.Vlaanderen.Basisregisters.BasicApiProblem.ValidationProblemDetails; @@ -69,12 +73,15 @@ public async Task VerwijderLidmaatschap( [FromServices] ICommandMetadataProvider metadataProvider, [FromHeader(Name = "If-Match")] string? ifMatch = null) { - // var metaData = metadataProvider.GetMetadata(IfMatchParser.ParseIfMatch(ifMatch)); - // var envelope = new CommandEnvelope(request.ToCommand(vCode, lidmaatschapId), metaData); - // var commandResult = await _messageBus.InvokeAsync(envelope); - // - // return this.AcceptedEntityCommand(_appSettings, WellKnownHeaderEntityNames.Lidmaatschappen, commandResult); + var metaData = metadataProvider.GetMetadata(IfMatchParser.ParseIfMatch(ifMatch)); + var envelope = new CommandEnvelope( + new VerwijderLidmaatschapCommand(VCode.Create(vCode), new LidmaatschapId(lidmaatschapId)), + metaData); + var commandResult = await _messageBus.InvokeAsync(envelope); - return new EmptyResult(); + Response.AddSequenceHeader(commandResult.Sequence); + Response.AddETagHeader(commandResult.Version); + + return Accepted(); } } diff --git a/src/AssociationRegistry.Admin.Api/Verenigingen/Lidmaatschap/VoegLidmaatschapToe/RequestModels/VoegLidmaatschapToeRequest.cs b/src/AssociationRegistry.Admin.Api/Verenigingen/Lidmaatschap/VoegLidmaatschapToe/RequestModels/VoegLidmaatschapToeRequest.cs index 2c5f7fb19..45745288c 100644 --- a/src/AssociationRegistry.Admin.Api/Verenigingen/Lidmaatschap/VoegLidmaatschapToe/RequestModels/VoegLidmaatschapToeRequest.cs +++ b/src/AssociationRegistry.Admin.Api/Verenigingen/Lidmaatschap/VoegLidmaatschapToe/RequestModels/VoegLidmaatschapToeRequest.cs @@ -38,11 +38,11 @@ public class VoegLidmaatschapToeRequest public string Beschrijving { get; set; } public VoegLidmaatschapToeCommand ToCommand(string vCode) => new( - VCode: VCode.Create(vCode), - Lidmaatschap.Create(VCode.Create(AndereVereniging), - new Geldigheidsperiode(new GeldigVan(Van), new GeldigTot(Tot)), - Identificatie, - Beschrijving - ) - ); + VCode.Create(vCode), + new VoegLidmaatschapToeCommand.ToeTeVoegenLidmaatschap( + VCode.Create(AndereVereniging), + new Geldigheidsperiode(new GeldigVan(Van), new GeldigTot(Tot)), + Identificatie, + Beschrijving + )); } diff --git a/src/AssociationRegistry.Admin.ProjectionHost/Projections/Detail/BeheerVerenigingDetailProjection.cs b/src/AssociationRegistry.Admin.ProjectionHost/Projections/Detail/BeheerVerenigingDetailProjection.cs index 2f1ce145e..1bfeb85fa 100644 --- a/src/AssociationRegistry.Admin.ProjectionHost/Projections/Detail/BeheerVerenigingDetailProjection.cs +++ b/src/AssociationRegistry.Admin.ProjectionHost/Projections/Detail/BeheerVerenigingDetailProjection.cs @@ -211,6 +211,9 @@ public async Task Project(IEvent @ public async Task Project(IEvent @event, IDocumentOperations ops) => await Update(@event, ops, BeheerVerenigingDetailProjector.Apply); + public async Task Project(IEvent @event, IDocumentOperations ops) + => await Update(@event, ops, BeheerVerenigingDetailProjector.Apply); + private async Task SoftDelete(string? streamKey, IDocumentOperations ops) => ops.Delete(streamKey); diff --git a/src/AssociationRegistry.Admin.ProjectionHost/Projections/Detail/BeheerVerenigingDetailProjector.cs b/src/AssociationRegistry.Admin.ProjectionHost/Projections/Detail/BeheerVerenigingDetailProjector.cs index d11c3a3bf..6078d2f5b 100644 --- a/src/AssociationRegistry.Admin.ProjectionHost/Projections/Detail/BeheerVerenigingDetailProjector.cs +++ b/src/AssociationRegistry.Admin.ProjectionHost/Projections/Detail/BeheerVerenigingDetailProjector.cs @@ -50,7 +50,7 @@ public static BeheerVerenigingDetailDocument Create(IEvent vertegenwoordigerWerdToegevoegd, BeheerVerenigingDetailDocument document) @@ -688,11 +687,19 @@ public static void Apply( public static void Apply(IEvent lidmaatschapWerdToegevoegd, BeheerVerenigingDetailDocument document) { + document.Lidmaatschappen = document.Lidmaatschappen + .Append(BeheerVerenigingDetailMapper.MapLidmaatschap( + lidmaatschapWerdToegevoegd.Data.Lidmaatschap, + document.VCode)) + .OrderBy(l => l.LidmaatschapId) + .ToArray(); + } + public static void Apply(IEvent lidmaatschapWerdToegevoegd, BeheerVerenigingDetailDocument document) + { document.Lidmaatschappen = document.Lidmaatschappen - .Append(BeheerVerenigingDetailMapper.MapLidmaatschap(lidmaatschapWerdToegevoegd.Data.Lidmaatschap, - document.VCode)) - .OrderBy(l => l.LidmaatschapId) - .ToArray(); + .Where(l => l.LidmaatschapId != lidmaatschapWerdToegevoegd.Data.Lidmaatschap.LidmaatschapId) + .OrderBy(l => l.LidmaatschapId) + .ToArray(); } } diff --git a/src/AssociationRegistry/Acties/VerwijderLidmaatschap/VerwijderLidmaatschapCommand.cs b/src/AssociationRegistry/Acties/VerwijderLidmaatschap/VerwijderLidmaatschapCommand.cs new file mode 100644 index 000000000..f86be0d96 --- /dev/null +++ b/src/AssociationRegistry/Acties/VerwijderLidmaatschap/VerwijderLidmaatschapCommand.cs @@ -0,0 +1,5 @@ +namespace AssociationRegistry.Acties.VerwijderLidmaatschap; + +using Vereniging; + +public record VerwijderLidmaatschapCommand(VCode VCode, LidmaatschapId LidmaatschapId); diff --git a/src/AssociationRegistry/Acties/VerwijderLidmaatschap/VerwijderLidmaatschapCommandHandler.cs b/src/AssociationRegistry/Acties/VerwijderLidmaatschap/VerwijderLidmaatschapCommandHandler.cs new file mode 100644 index 000000000..888e2d576 --- /dev/null +++ b/src/AssociationRegistry/Acties/VerwijderLidmaatschap/VerwijderLidmaatschapCommandHandler.cs @@ -0,0 +1,30 @@ +namespace AssociationRegistry.Acties.VerwijderLidmaatschap; + +using Framework; +using Vereniging; + +public class VerwijderLidmaatschapCommandHandler +{ + private readonly IVerenigingsRepository _verenigingRepository; + + public VerwijderLidmaatschapCommandHandler(IVerenigingsRepository verenigingRepository) + { + _verenigingRepository = verenigingRepository; + } + + public async Task Handle( + CommandEnvelope envelope, + CancellationToken cancellationToken = default) + { + var vereniging = + await _verenigingRepository.Load( + VCode.Create(envelope.Command.VCode), + envelope.Metadata.ExpectedVersion); + + vereniging.VerwijderLidmaatschap(envelope.Command.LidmaatschapId); + + var result = await _verenigingRepository.Save(vereniging, envelope.Metadata, cancellationToken); + + return CommandResult.Create(VCode.Create(envelope.Command.VCode), result); + } +} diff --git a/src/AssociationRegistry/Acties/VoegLidmaatschapToe/VoegLidmaatschapToeCommand.cs b/src/AssociationRegistry/Acties/VoegLidmaatschapToe/VoegLidmaatschapToeCommand.cs index e04a97710..a22d6385d 100644 --- a/src/AssociationRegistry/Acties/VoegLidmaatschapToe/VoegLidmaatschapToeCommand.cs +++ b/src/AssociationRegistry/Acties/VoegLidmaatschapToe/VoegLidmaatschapToeCommand.cs @@ -2,4 +2,14 @@ using Vereniging; -public record VoegLidmaatschapToeCommand(VCode VCode, Lidmaatschap Lidmaatschap); +public record VoegLidmaatschapToeCommand( + VCode VCode, + VoegLidmaatschapToeCommand.ToeTeVoegenLidmaatschap Lidmaatschap) +{ + public record ToeTeVoegenLidmaatschap( + VCode AndereVereniging, + Geldigheidsperiode Geldigheidsperiode, + string Identificatie, + string Beschrijving); +} + diff --git a/src/AssociationRegistry/Events/LidmaatschapWerdToegevoegd.cs b/src/AssociationRegistry/Events/LidmaatschapWerdToegevoegd.cs index 88b70dbb6..f64407f47 100644 --- a/src/AssociationRegistry/Events/LidmaatschapWerdToegevoegd.cs +++ b/src/AssociationRegistry/Events/LidmaatschapWerdToegevoegd.cs @@ -1,14 +1,13 @@ namespace AssociationRegistry.Events; using Framework; -using System.Runtime.Serialization; using Vereniging; -using Vereniging.Bronnen; -public record LidmaatschapWerdToegevoegd(Registratiedata.Lidmaatschap Lidmaatschap) : IEvent +public record LidmaatschapWerdToegevoegd(string VCode, Registratiedata.Lidmaatschap Lidmaatschap) : IEvent { - public static LidmaatschapWerdToegevoegd With(Lidmaatschap lidmaatschap) + public static LidmaatschapWerdToegevoegd With(VCode vCode ,Lidmaatschap lidmaatschap) => new( + vCode, Registratiedata.Lidmaatschap.With(lidmaatschap) ); } diff --git a/src/AssociationRegistry/Events/LidmaatschapWerdVerwijderd.cs b/src/AssociationRegistry/Events/LidmaatschapWerdVerwijderd.cs new file mode 100644 index 000000000..44b870782 --- /dev/null +++ b/src/AssociationRegistry/Events/LidmaatschapWerdVerwijderd.cs @@ -0,0 +1,11 @@ +namespace AssociationRegistry.Events; + +using Framework; +using Vereniging; + +public record LidmaatschapWerdVerwijderd(string VCode, + Registratiedata.Lidmaatschap Lidmaatschap) : IEvent +{ + public static LidmaatschapWerdVerwijderd With(VCode vCode, Lidmaatschap lidmaatschap) + => new(vCode, Registratiedata.Lidmaatschap.With(lidmaatschap)); +} diff --git a/src/AssociationRegistry/Resources/ExceptionMessages.Designer.cs b/src/AssociationRegistry/Resources/ExceptionMessages.Designer.cs index 62722e1f3..54ba1d543 100644 --- a/src/AssociationRegistry/Resources/ExceptionMessages.Designer.cs +++ b/src/AssociationRegistry/Resources/ExceptionMessages.Designer.cs @@ -439,6 +439,15 @@ public static string LaatsteVertegenwoordigerKanNietVerwijderdWorden { } } + /// + /// Looks up a localized string similar to Lidmaatschap met lidmaatschapId '{0}' is niet gekend. + /// + public static string LidmaatschapIsNietGekend { + get { + return ResourceManager.GetString("LidmaatschapIsNietGekend", resourceCulture); + } + } + /// /// Looks up a localized string similar to Een lidmaatschap mag niet overlappen voor eenzelfde vereniging.. /// diff --git a/src/AssociationRegistry/Resources/ExceptionMessages.resx b/src/AssociationRegistry/Resources/ExceptionMessages.resx index 8f9a215a6..036fc7d35 100644 --- a/src/AssociationRegistry/Resources/ExceptionMessages.resx +++ b/src/AssociationRegistry/Resources/ExceptionMessages.resx @@ -190,6 +190,9 @@ Een lidmaatschap mag niet verwijzen naar de vereniging waarbij hij wordt toegevoegd. + + Lidmaatschap met lidmaatschapId '{0}' is niet gekend + Deze vereniging werd verwijderd. diff --git a/src/AssociationRegistry/Vereniging/Lidmaatschappen/Exceptions/LidmaatschapIsNietGekend.cs b/src/AssociationRegistry/Vereniging/Lidmaatschappen/Exceptions/LidmaatschapIsNietGekend.cs new file mode 100644 index 000000000..996f6c2cf --- /dev/null +++ b/src/AssociationRegistry/Vereniging/Lidmaatschappen/Exceptions/LidmaatschapIsNietGekend.cs @@ -0,0 +1,17 @@ +namespace AssociationRegistry.Vereniging.Exceptions; + +using Be.Vlaanderen.Basisregisters.AggregateSource; +using Resources; +using System.Runtime.Serialization; + +[Serializable] +public class LidmaatschapIsNietGekend : DomainException +{ + public LidmaatschapIsNietGekend(string lidmaatschapId) : base(string.Format(ExceptionMessages.LidmaatschapIsNietGekend, lidmaatschapId)) + { + } + + protected LidmaatschapIsNietGekend(SerializationInfo info, StreamingContext context) : base(info, context) + { + } +} diff --git a/src/AssociationRegistry/Vereniging/Lidmaatschappen/Lidmaatschap.cs b/src/AssociationRegistry/Vereniging/Lidmaatschappen/Lidmaatschap.cs index eae9bfa0d..70f47929b 100644 --- a/src/AssociationRegistry/Vereniging/Lidmaatschappen/Lidmaatschap.cs +++ b/src/AssociationRegistry/Vereniging/Lidmaatschappen/Lidmaatschap.cs @@ -1,28 +1,27 @@ namespace AssociationRegistry.Vereniging; +using Acties.VoegLidmaatschapToe; + public record Lidmaatschap { - public int LidmaatschapId { get; init; } + public LidmaatschapId LidmaatschapId { get; init; } public VCode AndereVereniging { get; init; } public Geldigheidsperiode Geldigheidsperiode { get; init; } public string Identificatie { get; init; } public string Beschrijving { get; init; } - private Lidmaatschap(VCode andereVereniging, Geldigheidsperiode geldigheidsperiode, string identificatie, string beschrijving) - { - AndereVereniging = andereVereniging; - Geldigheidsperiode = geldigheidsperiode; - Identificatie = identificatie; - Beschrijving = beschrijving; - } - - public static Lidmaatschap Create( + private Lidmaatschap( + LidmaatschapId lidmaatschapId, VCode andereVereniging, Geldigheidsperiode geldigheidsperiode, string identificatie, string beschrijving) { - return new Lidmaatschap(andereVereniging, geldigheidsperiode, identificatie, beschrijving); + LidmaatschapId = lidmaatschapId; + AndereVereniging = andereVereniging; + Geldigheidsperiode = geldigheidsperiode; + Identificatie = identificatie; + Beschrijving = beschrijving; } public static Lidmaatschap Hydrate( @@ -31,10 +30,7 @@ public static Lidmaatschap Hydrate( Geldigheidsperiode geldigheidsperiode, string identificatie, string beschrijving) - => new(andereVereniging, geldigheidsperiode, identificatie, beschrijving) - { - LidmaatschapId = lidmaatschapId - }; + => new(new LidmaatschapId(lidmaatschapId), andereVereniging, geldigheidsperiode, identificatie, beschrijving); public virtual bool Equals(Lidmaatschap? other) { @@ -58,4 +54,13 @@ public virtual bool Equals(Lidmaatschap? other) public override int GetHashCode() => HashCode.Combine(LidmaatschapId, AndereVereniging, Geldigheidsperiode, Identificatie, Beschrijving); + + public static Lidmaatschap Create( + LidmaatschapId lidmaatschapId, + VoegLidmaatschapToeCommand.ToeTeVoegenLidmaatschap lidmaatschap) + => new(lidmaatschapId, + lidmaatschap.AndereVereniging, + lidmaatschap.Geldigheidsperiode, + lidmaatschap.Identificatie, + lidmaatschap.Beschrijving); } diff --git a/src/AssociationRegistry/Vereniging/Lidmaatschappen/LidmaatschapId.cs b/src/AssociationRegistry/Vereniging/Lidmaatschappen/LidmaatschapId.cs new file mode 100644 index 000000000..d029778a3 --- /dev/null +++ b/src/AssociationRegistry/Vereniging/Lidmaatschappen/LidmaatschapId.cs @@ -0,0 +1,16 @@ +namespace AssociationRegistry.Vereniging; + +using Be.Vlaanderen.Basisregisters.AggregateSource; + +public class LidmaatschapId : IntegerValueObject +{ + public static readonly LidmaatschapId InitialId = new(1); + public LidmaatschapId Next + => new LidmaatschapId(Value + 1); + public LidmaatschapId(int id) : base(id) + { + } + + public static LidmaatschapId Max(LidmaatschapId id1, LidmaatschapId id2) + => new(Math.Max(id1.Value, id2.Value)); +} diff --git a/src/AssociationRegistry/Vereniging/Lidmaatschappen/Lidmaatschappen.cs b/src/AssociationRegistry/Vereniging/Lidmaatschappen/Lidmaatschappen.cs index bbfab460c..657aa7d3f 100644 --- a/src/AssociationRegistry/Vereniging/Lidmaatschappen/Lidmaatschappen.cs +++ b/src/AssociationRegistry/Vereniging/Lidmaatschappen/Lidmaatschappen.cs @@ -1,20 +1,19 @@ namespace AssociationRegistry.Vereniging; +using Acties.VoegLidmaatschapToe; using Exceptions; using Framework; using System.Collections.ObjectModel; public class Lidmaatschappen : ReadOnlyCollection { - - private const int InitialId = 1; - public int NextId { get; } + public LidmaatschapId NextId { get; } public static Lidmaatschappen Empty - => new(Array.Empty(), InitialId); + => new(Array.Empty(), LidmaatschapId.InitialId); - private Lidmaatschappen(IEnumerable lidmaatschappen, int nextId) + private Lidmaatschappen(IEnumerable lidmaatschappen, LidmaatschapId nextId) : base(lidmaatschappen.ToArray()) { NextId = nextId; @@ -25,33 +24,36 @@ public Lidmaatschappen Hydrate(IEnumerable lidmaatschappen) lidmaatschappen = lidmaatschappen.ToArray(); if (!lidmaatschappen.Any()) - return new Lidmaatschappen(Empty, Math.Max(InitialId, NextId)); + return new Lidmaatschappen(Empty, LidmaatschapId.Max(LidmaatschapId.InitialId, NextId)); - return new Lidmaatschappen(lidmaatschappen, Math.Max(lidmaatschappen.Max(x => x.LidmaatschapId) + 1, NextId)); + return new Lidmaatschappen(lidmaatschappen, CalculateNextId(lidmaatschappen)); } - public Lidmaatschap[] VoegToe(params Lidmaatschap[] toeTeVoegenLidmaatschappen) + private LidmaatschapId CalculateNextId(IEnumerable lidmaatschappen) { - var lidmaatschappen = this; - var toegevoegdeLidmaatschappen = Array.Empty(); + return new LidmaatschapId(Math.Max(lidmaatschappen.Max(x => x.LidmaatschapId), NextId)).Next; + } - foreach (var toeTeVoegenLidmaatschap in toeTeVoegenLidmaatschappen) - { - var lidmaatschapMetId = lidmaatschappen.VoegToe(toeTeVoegenLidmaatschap); + public Lidmaatschap VoegToe(VoegLidmaatschapToeCommand.ToeTeVoegenLidmaatschap lidmaatschap) + { + var toeTeVoegenLidmaatschap = Lidmaatschap.Create( + new LidmaatschapId(NextId), + lidmaatschap); - lidmaatschappen = new Lidmaatschappen(lidmaatschappen.Append(lidmaatschapMetId), lidmaatschappen.NextId + 1); + ThrowIfCannotAppendOrUpdate(toeTeVoegenLidmaatschap); + return toeTeVoegenLidmaatschap; + } - toegevoegdeLidmaatschappen = toegevoegdeLidmaatschappen.Append(lidmaatschapMetId).ToArray(); - } + public Lidmaatschap Verwijder(LidmaatschapId lidmaatschapId) + { + MustContain(lidmaatschapId); - return toegevoegdeLidmaatschappen; + return this[lidmaatschapId]; } - public Lidmaatschap VoegToe(Lidmaatschap toeTeVoegenLidmaatschap) + private void MustContain(LidmaatschapId lidmaatschapId) { - ThrowIfCannotAppendOrUpdate(toeTeVoegenLidmaatschap); - - return toeTeVoegenLidmaatschap with { LidmaatschapId = NextId }; + Throw.If(!HasKey(lidmaatschapId), lidmaatschapId.ToString()); } private void ThrowIfCannotAppendOrUpdate(Lidmaatschap lidmaatschap) @@ -70,7 +72,6 @@ private void MustNotOverlapForSameAndereVereniging(Lidmaatschap lidmaatschap) public new Lidmaatschap this[int lidmaatschapId] => this.Single(l => l.LidmaatschapId == lidmaatschapId); - public bool HasKey(int lidmaatschapId) => this.Any(lidmaatschap => lidmaatschap.LidmaatschapId == lidmaatschapId); } diff --git a/src/AssociationRegistry/Vereniging/VerenigingOfAnyKind.cs b/src/AssociationRegistry/Vereniging/VerenigingOfAnyKind.cs index 717b7ac87..8ac965847 100644 --- a/src/AssociationRegistry/Vereniging/VerenigingOfAnyKind.cs +++ b/src/AssociationRegistry/Vereniging/VerenigingOfAnyKind.cs @@ -1,5 +1,6 @@ namespace AssociationRegistry.Vereniging; +using Acties.VoegLidmaatschapToe; using Emails; using Events; using Exceptions; @@ -102,13 +103,13 @@ public void VerwijderLocatie(int locatieId) AddEvent(LocatieWerdVerwijderd.With(State.VCode, locatie)); } - public Lidmaatschap VoegLidmaatschapToe(Lidmaatschap toeTeVoegenLidmaatschap) + public Lidmaatschap VoegLidmaatschapToe(VoegLidmaatschapToeCommand.ToeTeVoegenLidmaatschap lidmaatschap) { - Throw.If(VCode == toeTeVoegenLidmaatschap.AndereVereniging); + Throw.If(VCode == lidmaatschap.AndereVereniging); - var toegevoegdLidmaatschap = State.Lidmaatschappen.VoegToe(toeTeVoegenLidmaatschap); + var toegevoegdLidmaatschap = State.Lidmaatschappen.VoegToe(lidmaatschap); - AddEvent(LidmaatschapWerdToegevoegd.With(toegevoegdLidmaatschap)); + AddEvent(LidmaatschapWerdToegevoegd.With(VCode, toegevoegdLidmaatschap)); return toegevoegdLidmaatschap; } @@ -368,4 +369,10 @@ public void Hydrate(VerenigingState obj) } public long Version => State.Version; + + public void VerwijderLidmaatschap(LidmaatschapId lidmaatschapId) + { + var locatie = State.Lidmaatschappen.Verwijder(lidmaatschapId); + AddEvent(LidmaatschapWerdVerwijderd.With(State.VCode, locatie)); + } } diff --git a/src/AssociationRegistry/Vereniging/VerenigingState.cs b/src/AssociationRegistry/Vereniging/VerenigingState.cs index 6aeea453e..33df0bc6a 100644 --- a/src/AssociationRegistry/Vereniging/VerenigingState.cs +++ b/src/AssociationRegistry/Vereniging/VerenigingState.cs @@ -309,6 +309,7 @@ public VerenigingState Apply(LocatieWerdToegevoegd @event) .AppendFromEventData(@event.Locatie) ), }; + public VerenigingState Apply(LidmaatschapWerdToegevoegd @event) => this with { @@ -318,6 +319,15 @@ public VerenigingState Apply(LidmaatschapWerdToegevoegd @event) ), }; + public VerenigingState Apply(LidmaatschapWerdVerwijderd @event) + => this with + { + Lidmaatschappen = Lidmaatschappen.Hydrate( + Lidmaatschappen + .Without(@event.Lidmaatschap.LidmaatschapId) + ), + }; + public VerenigingState Apply(LocatieWerdGewijzigd @event) => this with { diff --git a/test/AssociationRegistry.Test.Admin.Api/Commands/FeitelijkeVereniging/When_Adding_Lidmaatschap/CommandHandling/Given_The_AndereVereniging_Is_Verwijderd.cs b/test/AssociationRegistry.Test.Admin.Api/Commands/FeitelijkeVereniging/When_Adding_Lidmaatschap/CommandHandling/Given_The_AndereVereniging_Is_Verwijderd.cs index e7c538570..29cf48b3c 100644 --- a/test/AssociationRegistry.Test.Admin.Api/Commands/FeitelijkeVereniging/When_Adding_Lidmaatschap/CommandHandling/Given_The_AndereVereniging_Is_Verwijderd.cs +++ b/test/AssociationRegistry.Test.Admin.Api/Commands/FeitelijkeVereniging/When_Adding_Lidmaatschap/CommandHandling/Given_The_AndereVereniging_Is_Verwijderd.cs @@ -23,17 +23,16 @@ public async Task Then_It_Saves_A_Lidmaatschap() var repositoryMock = new Mock(); var scenario = new FeitelijkeVerenigingWerdGeregistreerdScenario(); - var lidmaatschap = fixture.Create(); - + var command = fixture.Create() with + { + VCode = scenario.VCode, + }; repositoryMock - .Setup(x => x.IsVerwijderd(lidmaatschap.AndereVereniging)) + .Setup(x => x.IsVerwijderd(command.Lidmaatschap.AndereVereniging)) .ReturnsAsync(true); var commandHandler = new VoegLidmaatschapToeCommandHandler(repositoryMock.Object); - var command = new VoegLidmaatschapToeCommand(scenario.VCode, - lidmaatschap); - await Assert.ThrowsAsync( async () => await commandHandler.Handle( new CommandEnvelope(command, fixture.Create()))); diff --git a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Lidmaatschap/CommandHandling/Given_A_Lidmaatschap.cs b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Lidmaatschap/CommandHandling/Given_A_Lidmaatschap.cs index a8e7737ef..bd73921a5 100644 --- a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Lidmaatschap/CommandHandling/Given_A_Lidmaatschap.cs +++ b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Lidmaatschap/CommandHandling/Given_A_Lidmaatschap.cs @@ -25,21 +25,22 @@ public async Task Then_It_Saves_A_Lidmaatschap() var commandHandler = new VoegLidmaatschapToeCommandHandler(verenigingRepositoryMock); - var lidmaatschap = fixture.Create(); - - var command = new VoegLidmaatschapToeCommand(scenario.VCode, - lidmaatschap); + var command = fixture.Create() with + { + VCode = scenario.VCode, + }; await commandHandler.Handle(new CommandEnvelope(command, fixture.Create())); verenigingRepositoryMock.ShouldHaveSaved( new LidmaatschapWerdToegevoegd( + scenario.VCode, new Registratiedata.Lidmaatschap( 1, - lidmaatschap.AndereVereniging, - lidmaatschap.Geldigheidsperiode.Van.DateOnly, - lidmaatschap.Geldigheidsperiode.Tot.DateOnly, - lidmaatschap.Identificatie, - lidmaatschap.Beschrijving))); + command.Lidmaatschap.AndereVereniging, + command.Lidmaatschap.Geldigheidsperiode.Van.DateOnly, + command.Lidmaatschap.Geldigheidsperiode.Tot.DateOnly, + command.Lidmaatschap.Identificatie, + command.Lidmaatschap.Beschrijving))); } } diff --git a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Removing_Lidmaatschap/CommandHandling/Given_A_Lidmaatschap.cs b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Removing_Lidmaatschap/CommandHandling/Given_A_Lidmaatschap.cs new file mode 100644 index 000000000..07507dd21 --- /dev/null +++ b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Removing_Lidmaatschap/CommandHandling/Given_A_Lidmaatschap.cs @@ -0,0 +1,40 @@ +namespace AssociationRegistry.Test.Admin.Api.Commands.VerenigingOfAnyKind.When_Removing_Lidmaatschap.CommandHandling; + +using Acties.VerwijderLidmaatschap; +using AssociationRegistry.Acties.VoegLidmaatschapToe; +using AssociationRegistry.Events; +using AssociationRegistry.Framework; +using AssociationRegistry.Test.Common.AutoFixture; +using AssociationRegistry.Test.Common.Framework; +using AssociationRegistry.Test.Common.Scenarios.CommandHandling; +using AssociationRegistry.Vereniging; +using AutoFixture; +using Xunit; +using Xunit.Categories; + +[UnitTest] +public class Given_A_Lidmaatschap +{ + [Fact] + public async Task Then_It_Saves_A_Lidmaatschap() + { + var fixture = new Fixture().CustomizeDomain(); + + var scenario = new LidmaatschapWerdGeregistreerdScenario(); + + var verenigingRepositoryMock = new VerenigingRepositoryMock(scenario.GetVerenigingState()); + + var commandHandler = new VerwijderLidmaatschapCommandHandler(verenigingRepositoryMock); + + + var command = new VerwijderLidmaatschapCommand(scenario.VCode, + new LidmaatschapId(scenario.LidmaatschapWerdToegevoegd.Lidmaatschap.LidmaatschapId)); + + await commandHandler.Handle(new CommandEnvelope(command, fixture.Create())); + + verenigingRepositoryMock.ShouldHaveSaved( + new LidmaatschapWerdVerwijderd( + scenario.VCode, + scenario.LidmaatschapWerdToegevoegd.Lidmaatschap)); + } +} diff --git a/test/AssociationRegistry.Test.Admin.Api/Projections/V2/Beheer/Detail/Given_LidmaatschapWerdVerwijderd.cs b/test/AssociationRegistry.Test.Admin.Api/Projections/V2/Beheer/Detail/Given_LidmaatschapWerdVerwijderd.cs new file mode 100644 index 000000000..b62fde0b0 --- /dev/null +++ b/test/AssociationRegistry.Test.Admin.Api/Projections/V2/Beheer/Detail/Given_LidmaatschapWerdVerwijderd.cs @@ -0,0 +1,48 @@ +namespace AssociationRegistry.Test.Admin.Api.Projections.V2.Beheer.Detail; + +using AssociationRegistry.Admin.Schema.Detail; +using FluentAssertions; +using Marten; +using ScenarioClassFixtures; +using Xunit; + +[Collection(nameof(ProjectionContext))] +public class Given_LidmaatschapWerdVerwijderd : IClassFixture +{ + private readonly ProjectionContext _context; + private readonly LidmaatschapWerdVerwijderdScenario _scenario; + + public Given_LidmaatschapWerdVerwijderd( + ProjectionContext context, + LidmaatschapWerdVerwijderdScenario scenario) + { + _context = context; + _scenario = scenario; + } + + [Fact] + public async Task Metadata_Is_Updated() + { + var document = + await _context + .Session + .Query() + .Where(w => w.VCode == _scenario.LidmaatschapWerdVerwijderd.VCode) + .SingleAsync(); + + document.Metadata.Version.Should().Be(3); + } + + [Fact] + public async Task Document_Is_Updated() + { + var document = + await _context + .Session + .Query() + .Where(w => w.VCode == _scenario.LidmaatschapWerdVerwijderd.VCode) + .SingleAsync(); + + document.Lidmaatschappen.Should().BeEmpty(); + } +} diff --git a/test/AssociationRegistry.Test.Admin.Api/Projections/V2/Beheer/ScenarioClassFixtures/LidmaatschapWerdVerwijderdScenario.cs b/test/AssociationRegistry.Test.Admin.Api/Projections/V2/Beheer/ScenarioClassFixtures/LidmaatschapWerdVerwijderdScenario.cs new file mode 100644 index 000000000..30610e902 --- /dev/null +++ b/test/AssociationRegistry.Test.Admin.Api/Projections/V2/Beheer/ScenarioClassFixtures/LidmaatschapWerdVerwijderdScenario.cs @@ -0,0 +1,30 @@ +namespace AssociationRegistry.Test.Admin.Api.Projections.V2.Beheer.ScenarioClassFixtures; + +using Events; + +public class LidmaatschapWerdVerwijderdScenario : ProjectionScenarioFixture +{ + public LidmaatschapWerdVerwijderd LidmaatschapWerdVerwijderd { get; } + + public LidmaatschapWerdVerwijderdScenario(ProjectionContext context): base(context) + { + var scenario = new LidmaatschapWerdToegevoegdScenario(context); + scenario.Given().GetAwaiter().GetResult(); + + LidmaatschapWerdVerwijderd = new LidmaatschapWerdVerwijderd( + Lidmaatschap: scenario.LidmaatschapWerdToegevoegd.Lidmaatschap, + VCode: scenario.VerenigingWerdGeregistreerd.VCode); + } + + public override async Task Given() + { + await using var session = await Context.DocumentSession(); + + session.Events.Append(LidmaatschapWerdVerwijderd.VCode, + LidmaatschapWerdVerwijderd); + await session.SaveChangesAsync(); + + await Context.WaitForNonStaleProjectionDataAsync(); + } + +} diff --git a/test/AssociationRegistry.Test.Common/AutoFixture/AdminApiAutoFixtureCustomizations.cs b/test/AssociationRegistry.Test.Common/AutoFixture/AdminApiAutoFixtureCustomizations.cs index 5855a3674..a2abee95b 100644 --- a/test/AssociationRegistry.Test.Common/AutoFixture/AdminApiAutoFixtureCustomizations.cs +++ b/test/AssociationRegistry.Test.Common/AutoFixture/AdminApiAutoFixtureCustomizations.cs @@ -10,6 +10,7 @@ namespace AssociationRegistry.Test.Common.AutoFixture; using Admin.Api.Verenigingen.Registreer.MetRechtspersoonlijkheid.RequestModels; using Admin.Api.Verenigingen.Vertegenwoordigers.FeitelijkeVereniging.WijzigVertegenwoordiger.RequestModels; using Admin.Api.Verenigingen.WijzigBasisgegevens.FeitelijkeVereniging.RequestModels; +using Events; using global::AutoFixture; using Primitives; using Vereniging; @@ -45,6 +46,7 @@ public static Fixture CustomizeAdminApi(this Fixture fixture) fixture.CustomizeVoegLidmaatschapToeRequest(); fixture.CustomizeWijzigLidmaatschapRequest(); + fixture.CustomizeLidmaatschapRegistratieData(); fixture.CustomizeTestEvent(typeof(TestEvent<>)); fixture.CustomizeMagdaResponses(); @@ -276,4 +278,19 @@ private static void CustomizeWijzigLidmaatschapRequest(this IFixture fixture) }).OmitAutoProperties()); } + private static void CustomizeLidmaatschapRegistratieData(this IFixture fixture) + { + var date = fixture.Create(); + + fixture.Customize( + composerTransformation: composer => composer.FromFactory( + factory: () => new Registratiedata.Lidmaatschap( + fixture.Create(), + fixture.Create(), + date, + date.AddDays(value: new Random().Next(minValue: 1, maxValue: 99)), + fixture.Create(), fixture.Create() + )).OmitAutoProperties()); + } + } diff --git a/test/AssociationRegistry.Test.Common/AutoFixture/AutoFixtureCustomizations.cs b/test/AssociationRegistry.Test.Common/AutoFixture/AutoFixtureCustomizations.cs index 4c34cd1c4..d01a76889 100644 --- a/test/AssociationRegistry.Test.Common/AutoFixture/AutoFixtureCustomizations.cs +++ b/test/AssociationRegistry.Test.Common/AutoFixture/AutoFixtureCustomizations.cs @@ -308,7 +308,8 @@ private static void CustomizeLidmaatschap(this IFixture fixture) fixture.Customize( composer => composer.FromFactory( - () => Lidmaatschap.Create( + () => Lidmaatschap.Hydrate( + fixture.Create(), fixture.Create(), fixture.Create(), fixture.Create(), diff --git a/test/AssociationRegistry.Test.Common/AutoFixture/EventCustomizations.cs b/test/AssociationRegistry.Test.Common/AutoFixture/EventCustomizations.cs index f76f607f2..31496e426 100644 --- a/test/AssociationRegistry.Test.Common/AutoFixture/EventCustomizations.cs +++ b/test/AssociationRegistry.Test.Common/AutoFixture/EventCustomizations.cs @@ -28,6 +28,7 @@ private static void CustomizeLidmaatschapWerdToegevoegd(this IFixture fixture) composer => composer.FromFactory( () => new LidmaatschapWerdToegevoegd( + fixture.Create(), Registratiedata.Lidmaatschap.With( Lidmaatschap.Hydrate( fixture.Create(), diff --git a/test/AssociationRegistry.Test.Common/Scenarios/CommandHandling/LidmaatschapWerdGeregistreerdScenario.cs b/test/AssociationRegistry.Test.Common/Scenarios/CommandHandling/LidmaatschapWerdGeregistreerdScenario.cs new file mode 100644 index 000000000..a9902542c --- /dev/null +++ b/test/AssociationRegistry.Test.Common/Scenarios/CommandHandling/LidmaatschapWerdGeregistreerdScenario.cs @@ -0,0 +1,30 @@ +namespace AssociationRegistry.Test.Common.Scenarios.CommandHandling; + +using AssociationRegistry.Framework; +using AutoFixture; +using Events; +using global::AutoFixture; +using Vereniging; + +public class LidmaatschapWerdGeregistreerdScenario : CommandhandlerScenarioBase +{ + public override VCode VCode => VCode.Create("V0009002"); + public readonly FeitelijkeVerenigingWerdGeregistreerd FeitelijkeVerenigingWerdGeregistreerd; + public LidmaatschapWerdToegevoegd LidmaatschapWerdToegevoegd { get; } + + public LidmaatschapWerdGeregistreerdScenario() + { + var fixture = new Fixture().CustomizeAdminApi(); + FeitelijkeVerenigingWerdGeregistreerd = fixture.Create() with { VCode = VCode }; + + LidmaatschapWerdToegevoegd = + new LidmaatschapWerdToegevoegd(FeitelijkeVerenigingWerdGeregistreerd.VCode, fixture.Create()); + } + + public override IEnumerable Events() + => + [ + FeitelijkeVerenigingWerdGeregistreerd, + LidmaatschapWerdToegevoegd, + ]; +} diff --git a/test/AssociationRegistry.Test.E2E/Framework/ApiSetup/FullBlownApiSetup.cs b/test/AssociationRegistry.Test.E2E/Framework/ApiSetup/FullBlownApiSetup.cs index 099f121bd..6b526580a 100644 --- a/test/AssociationRegistry.Test.E2E/Framework/ApiSetup/FullBlownApiSetup.cs +++ b/test/AssociationRegistry.Test.E2E/Framework/ApiSetup/FullBlownApiSetup.cs @@ -126,7 +126,7 @@ public async Task ExecuteGiven(IScenario scenario) session.Events.Append(eventsPerStream.Key, eventsPerStream.Value); } - if (givenEvents.Count == 0) + if (givenEvents.Length == 0) return; await session.SaveChangesAsync(); diff --git a/test/AssociationRegistry.Test.E2E/Framework/TestClasses/IScenario.cs b/test/AssociationRegistry.Test.E2E/Framework/TestClasses/IScenario.cs index ef6444505..37aeb227f 100644 --- a/test/AssociationRegistry.Test.E2E/Framework/TestClasses/IScenario.cs +++ b/test/AssociationRegistry.Test.E2E/Framework/TestClasses/IScenario.cs @@ -5,5 +5,5 @@ namespace AssociationRegistry.Test.E2E.Framework.TestClasses; public interface IScenario { - Task> GivenEvents(IVCodeService service); + Task[]> GivenEvents(IVCodeService service); } diff --git a/test/AssociationRegistry.Test.E2E/Scenarios/Givens/EmptyScenario.cs b/test/AssociationRegistry.Test.E2E/Scenarios/Givens/EmptyScenario.cs index 534f69d70..82897dfb3 100644 --- a/test/AssociationRegistry.Test.E2E/Scenarios/Givens/EmptyScenario.cs +++ b/test/AssociationRegistry.Test.E2E/Scenarios/Givens/EmptyScenario.cs @@ -22,8 +22,8 @@ public class EmptyScenario : Framework.TestClasses.IScenario public RegistreerFeitelijkeVerenigingRequest Request { get; private set; } public string VCode { get; private set; } - public Task> GivenEvents(IVCodeService requiredService) - => Task.FromResult(new Dictionary()); + public Task[]> GivenEvents(IVCodeService requiredService) + => Task.FromResult(Array.Empty>()); public async Task WhenCommand(FullBlownApiSetup setup) { diff --git a/test/AssociationRegistry.Test.E2E/Scenarios/Givens/FeitelijkeVereniging/LidmaatschapWerdToegevoegdScenario.cs b/test/AssociationRegistry.Test.E2E/Scenarios/Givens/FeitelijkeVereniging/LidmaatschapWerdToegevoegdScenario.cs new file mode 100644 index 000000000..2f85bce4e --- /dev/null +++ b/test/AssociationRegistry.Test.E2E/Scenarios/Givens/FeitelijkeVereniging/LidmaatschapWerdToegevoegdScenario.cs @@ -0,0 +1,38 @@ +namespace AssociationRegistry.Test.E2E.Scenarios.Givens.FeitelijkeVereniging; + +using Events; +using EventStore; +using AssociationRegistry.Framework; +using AssociationRegistry.Test.Common.AutoFixture; +using Vereniging; +using AutoFixture; + +public class LidmaatschapWerdToegevoegdScenario : Framework.TestClasses.IScenario +{ + private readonly MultipleWerdGeregistreerdScenario _baseScenario; + public LidmaatschapWerdToegevoegd LidmaatschapWerdToegevoegd { get; set; } + + public LidmaatschapWerdToegevoegdScenario(MultipleWerdGeregistreerdScenario baseScenario) + { + _baseScenario = baseScenario; + } + + public async Task[]> GivenEvents(IVCodeService service) + { + var fixture = new Fixture().CustomizeAdminApi(); + + var givenEvents = await _baseScenario.GivenEvents(service); + + LidmaatschapWerdToegevoegd = new LidmaatschapWerdToegevoegd( + VCode: _baseScenario.FeitelijkeVerenigingWerdGeregistreerd.VCode, + Lidmaatschap: fixture.Create() with + { + AndereVereniging = _baseScenario.AndereFeitelijkeVerenigingWerdGeregistreerd.VCode, + }); + + return givenEvents.Append(new KeyValuePair(LidmaatschapWerdToegevoegd.VCode, [LidmaatschapWerdToegevoegd])) + .ToArray(); + } + + public StreamActionResult Result { get; set; } = null!; +} diff --git a/test/AssociationRegistry.Test.E2E/Scenarios/Givens/FeitelijkeVereniging/MultipleWerdGeregistreerdScenario.cs b/test/AssociationRegistry.Test.E2E/Scenarios/Givens/FeitelijkeVereniging/MultipleWerdGeregistreerdScenario.cs index 6a0b5b181..099046ea3 100644 --- a/test/AssociationRegistry.Test.E2E/Scenarios/Givens/FeitelijkeVereniging/MultipleWerdGeregistreerdScenario.cs +++ b/test/AssociationRegistry.Test.E2E/Scenarios/Givens/FeitelijkeVereniging/MultipleWerdGeregistreerdScenario.cs @@ -18,7 +18,7 @@ public MultipleWerdGeregistreerdScenario() { } - public async Task> GivenEvents(IVCodeService service) + public async Task[]> GivenEvents(IVCodeService service) { var fixture = new Fixture().CustomizeAdminApi(); @@ -33,16 +33,13 @@ public async Task> GivenEvents(IVCodeService servic Metadata = fixture.Create() with { ExpectedVersion = null }; - return new Dictionary() - { - {FeitelijkeVerenigingWerdGeregistreerd.VCode, [FeitelijkeVerenigingWerdGeregistreerd] }, - {AndereFeitelijkeVerenigingWerdGeregistreerd.VCode, [AndereFeitelijkeVerenigingWerdGeregistreerd] }, - }; + return + [ + new(FeitelijkeVerenigingWerdGeregistreerd.VCode, [FeitelijkeVerenigingWerdGeregistreerd]), + new(AndereFeitelijkeVerenigingWerdGeregistreerd.VCode, [AndereFeitelijkeVerenigingWerdGeregistreerd]), + ]; } - public IEvent[] GivenEvents() - => [FeitelijkeVerenigingWerdGeregistreerd]; - public StreamActionResult Result { get; set; } = null!; public CommandMetadata GetCommandMetadata() diff --git a/test/AssociationRegistry.Test.E2E/Scenarios/Givens/FeitelijkeVereniging/WerdGeregistreerdScenario.cs b/test/AssociationRegistry.Test.E2E/Scenarios/Givens/FeitelijkeVereniging/WerdGeregistreerdScenario.cs index 93ddc8e54..1bb8af438 100644 --- a/test/AssociationRegistry.Test.E2E/Scenarios/Givens/FeitelijkeVereniging/WerdGeregistreerdScenario.cs +++ b/test/AssociationRegistry.Test.E2E/Scenarios/Givens/FeitelijkeVereniging/WerdGeregistreerdScenario.cs @@ -20,7 +20,7 @@ public FeitelijkeVerenigingWerdGeregistreerdScenario(bool isUitgeschreven = fals _isUitgeschreven = isUitgeschreven; } - public async Task> GivenEvents(IVCodeService service) + public async Task[]> GivenEvents(IVCodeService service) { var fixture = new Fixture().CustomizeAdminApi(); VCode = await service.GetNext(); @@ -100,15 +100,11 @@ public async Task> GivenEvents(IVCodeService servic Metadata = fixture.Create() with { ExpectedVersion = null }; - return new Dictionary() - { - {VCode, [FeitelijkeVerenigingWerdGeregistreerd] }, - }; + return [ + new(VCode, [FeitelijkeVerenigingWerdGeregistreerd]), + ]; } - public IEvent[] GivenEvents() - => [FeitelijkeVerenigingWerdGeregistreerd]; - public StreamActionResult Result { get; set; } = null!; public CommandMetadata GetCommandMetadata() diff --git a/test/AssociationRegistry.Test.E2E/Scenarios/Givens/MetRechtspersoonlijkheid/VerenigingMetRechtspersoonlijkheidWerdGeregistreerdScenario.cs b/test/AssociationRegistry.Test.E2E/Scenarios/Givens/MetRechtspersoonlijkheid/VerenigingMetRechtspersoonlijkheidWerdGeregistreerdScenario.cs index 8fc13bb84..8c88bddd0 100644 --- a/test/AssociationRegistry.Test.E2E/Scenarios/Givens/MetRechtspersoonlijkheid/VerenigingMetRechtspersoonlijkheidWerdGeregistreerdScenario.cs +++ b/test/AssociationRegistry.Test.E2E/Scenarios/Givens/MetRechtspersoonlijkheid/VerenigingMetRechtspersoonlijkheidWerdGeregistreerdScenario.cs @@ -21,7 +21,7 @@ public VerenigingMetRechtspersoonlijkheidWerdGeregistreerdScenario(bool isUitges _isUitgeschreven = isUitgeschreven; } - public async Task> GivenEvents(IVCodeService service) + public async Task[]> GivenEvents(IVCodeService service) { var fixture = new Fixture().CustomizeAdminApi(); VCode = await service.GetNext(); @@ -37,10 +37,9 @@ public async Task> GivenEvents(IVCodeService servic Metadata = fixture.Create() with { ExpectedVersion = null }; - return new Dictionary() - { - { VCode, [VerenigingMetRechtspersoonlijkheidWerdGeregistreerd] }, - }; + return [ + new(VCode, [VerenigingMetRechtspersoonlijkheidWerdGeregistreerd]) + ]; } public IEvent[] GivenEvents() diff --git a/test/AssociationRegistry.Test.E2E/Scenarios/Requests/FeitelijkeVereniging/VerwijderLidmaatschapRequestFactory.cs b/test/AssociationRegistry.Test.E2E/Scenarios/Requests/FeitelijkeVereniging/VerwijderLidmaatschapRequestFactory.cs new file mode 100644 index 000000000..ee4bb5527 --- /dev/null +++ b/test/AssociationRegistry.Test.E2E/Scenarios/Requests/FeitelijkeVereniging/VerwijderLidmaatschapRequestFactory.cs @@ -0,0 +1,36 @@ +namespace AssociationRegistry.Test.E2E.Scenarios.Requests.FeitelijkeVereniging; + +using Framework.ApiSetup; +using Givens.FeitelijkeVereniging; +using Marten.Events; +using System.Net; +using Vereniging; + +public class VerwijderLidmaatschapRequestFactory : ITestRequestFactory +{ + private readonly LidmaatschapWerdToegevoegdScenario _scenario; + + public VerwijderLidmaatschapRequestFactory(LidmaatschapWerdToegevoegdScenario scenario) + { + _scenario = scenario; + } + + public async Task> ExecuteRequest(IApiSetup apiSetup) + { + var vCode = _scenario.LidmaatschapWerdToegevoegd.VCode; + var lidmaatschapLidmaatschapId = _scenario.LidmaatschapWerdToegevoegd.Lidmaatschap.LidmaatschapId; + + await apiSetup.AdminApiHost.Scenario(s => + { + s.Delete + .Url($"/v1/verenigingen/{vCode}/lidmaatschappen/{lidmaatschapLidmaatschapId}"); + + s.StatusCodeShouldBe(HttpStatusCode.Accepted); + }); + + await apiSetup.AdminProjectionHost.WaitForNonStaleProjectionDataAsync(TimeSpan.FromSeconds(60)); + await apiSetup.PublicProjectionHost.WaitForNonStaleProjectionDataAsync(TimeSpan.FromSeconds(60)); + + return new RequestResult(VCode.Create(vCode), new NullRequest()); + } +} diff --git a/test/AssociationRegistry.Test.E2E/Scenarios/Requests/NullRequest.cs b/test/AssociationRegistry.Test.E2E/Scenarios/Requests/NullRequest.cs new file mode 100644 index 000000000..e09e812f8 --- /dev/null +++ b/test/AssociationRegistry.Test.E2E/Scenarios/Requests/NullRequest.cs @@ -0,0 +1,5 @@ +namespace AssociationRegistry.Test.E2E.Scenarios.Requests; + +public class NullRequest +{ +} diff --git a/test/AssociationRegistry.Test.E2E/When_Verwijder_Lidmaatschap/Beheer/Detail/Returns_Detail_Without_Lidmaatschap.cs b/test/AssociationRegistry.Test.E2E/When_Verwijder_Lidmaatschap/Beheer/Detail/Returns_Detail_Without_Lidmaatschap.cs new file mode 100644 index 000000000..fba07ef71 --- /dev/null +++ b/test/AssociationRegistry.Test.E2E/When_Verwijder_Lidmaatschap/Beheer/Detail/Returns_Detail_Without_Lidmaatschap.cs @@ -0,0 +1,40 @@ +namespace AssociationRegistry.Test.E2E.When_Verwijder_Lidmaatschap.Beheer.Detail; + +using Admin.Api.Verenigingen.Detail.ResponseModels; +using FluentAssertions; +using Framework.AlbaHost; +using KellermanSoftware.CompareNetObjects; +using When_Voeg_Lidmaatschap_Toe; +using Xunit; + +[Collection(FullBlownApiCollection.Name)] +public class Returns_Detail_Without_Lidmaatschap : IClassFixture, IAsyncLifetime +{ + private readonly VerwijderLidmaatschapContext _context; + + public Returns_Detail_Without_Lidmaatschap(VerwijderLidmaatschapContext context) + { + _context = context; + } + + [Fact] + public void JsonContentMatches() + { + var comparisonConfig = new ComparisonConfig(); + comparisonConfig.MaxDifferences = 10; + comparisonConfig.MaxMillisecondsDateDifference = (int)TimeSpan.FromSeconds(10).TotalMilliseconds; + + Response.Vereniging.Lidmaatschappen.Should().BeEmpty(); + } + + public DetailVerenigingResponse Response { get; set; } + + public async Task InitializeAsync() + { + Response = _context.ApiSetup.AdminApiHost.GetBeheerDetail(_context.VCode); + } + + public async Task DisposeAsync() + { + } +} diff --git a/test/AssociationRegistry.Test.E2E/When_Verwijder_Lidmaatschap/VerwijderLidmaatschapContext.cs b/test/AssociationRegistry.Test.E2E/When_Verwijder_Lidmaatschap/VerwijderLidmaatschapContext.cs new file mode 100644 index 000000000..aeb7a009b --- /dev/null +++ b/test/AssociationRegistry.Test.E2E/When_Verwijder_Lidmaatschap/VerwijderLidmaatschapContext.cs @@ -0,0 +1,28 @@ +namespace AssociationRegistry.Test.E2E.When_Verwijder_Lidmaatschap; + +using Framework.ApiSetup; +using Framework.TestClasses; +using Marten.Events; +using Scenarios.Givens.FeitelijkeVereniging; +using Scenarios.Requests; +using Scenarios.Requests.FeitelijkeVereniging; +using Vereniging; + +public class VerwijderLidmaatschapContext: TestContextBase +{ + public VCode VCode => RequestResult.VCode; + public LidmaatschapWerdToegevoegdScenario Scenario { get; } + + public VerwijderLidmaatschapContext(FullBlownApiSetup apiSetup) + { + ApiSetup = apiSetup; + Scenario = new(new MultipleWerdGeregistreerdScenario()); + } + + public override async Task InitializeAsync() + { + await ApiSetup.ExecuteGiven(Scenario); + RequestResult = await new VerwijderLidmaatschapRequestFactory(Scenario).ExecuteRequest(ApiSetup); + await ApiSetup.AdminProjectionHost.WaitForNonStaleProjectionDataAsync(TimeSpan.FromSeconds(10)); + } +} diff --git a/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_An_Overlapping_Periode_For_Another_Andere_Vereniging.cs b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_An_Overlapping_Periode_For_Another_Andere_Vereniging.cs index d598c9efc..36bd60cc7 100644 --- a/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_An_Overlapping_Periode_For_Another_Andere_Vereniging.cs +++ b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_An_Overlapping_Periode_For_Another_Andere_Vereniging.cs @@ -1,5 +1,6 @@ namespace AssociationRegistry.Test.LidmaatschappenTests.When_Adding_A_Lidmaatschap; +using Acties.VoegLidmaatschapToe; using AutoFixture; using Common.AutoFixture; using FluentAssertions; @@ -14,13 +15,15 @@ public void Then_It_Returns_With_Next_Id() var fixture = new Fixture().CustomizeDomain(); var andereVereniging = fixture.Create(); + var bestaandLidmaatschap = fixture.Create() with { - LidmaatschapId = 1, + LidmaatschapId = new LidmaatschapId(1), AndereVereniging = andereVereniging, Geldigheidsperiode = Geldigheidsperiode.Infinity, }; - var toeTeVoegenLidmaatschap = fixture.Create() with + + var toeTeVoegenLidmaatschap = fixture.Create() with { AndereVereniging = fixture.Create(), }; @@ -31,9 +34,11 @@ public void Then_It_Returns_With_Next_Id() var actual = sut.VoegToe(toeTeVoegenLidmaatschap); - actual.Should().BeEquivalentTo(toeTeVoegenLidmaatschap with - { - LidmaatschapId = bestaandLidmaatschap.LidmaatschapId + 1, - }); + actual.Should().BeEquivalentTo( + Lidmaatschap.Hydrate(new LidmaatschapId(bestaandLidmaatschap.LidmaatschapId + 1), + toeTeVoegenLidmaatschap.AndereVereniging, + toeTeVoegenLidmaatschap.Geldigheidsperiode, + toeTeVoegenLidmaatschap.Identificatie, + toeTeVoegenLidmaatschap.Beschrijving)); } } diff --git a/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_An_Overlapping_Periode_For_The_Same_Andere_Vereniging.cs b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_An_Overlapping_Periode_For_The_Same_Andere_Vereniging.cs index c23eb2659..7b8d86ec4 100644 --- a/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_An_Overlapping_Periode_For_The_Same_Andere_Vereniging.cs +++ b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_An_Overlapping_Periode_For_The_Same_Andere_Vereniging.cs @@ -1,5 +1,6 @@ namespace AssociationRegistry.Test.LidmaatschappenTests.When_Adding_A_Lidmaatschap; +using Acties.VoegLidmaatschapToe; using AutoFixture; using Common.AutoFixture; using FluentAssertions; @@ -21,7 +22,7 @@ public void Then_It_Throws() AndereVereniging = andereVereniging, Geldigheidsperiode = Geldigheidsperiode.Infinity, }; - var toeTeVoegenLidmaatschap = fixture.Create() with + var toeTeVoegenLidmaatschap = fixture.Create() with { AndereVereniging = andereVereniging, }; diff --git a/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_No_Overlapping_Periode_For_The_Same_Andere_Vereniging.cs b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_No_Overlapping_Periode_For_The_Same_Andere_Vereniging.cs index 8f3f4cb21..aff388853 100644 --- a/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_No_Overlapping_Periode_For_The_Same_Andere_Vereniging.cs +++ b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Adding_A_Lidmaatschap/Given_No_Overlapping_Periode_For_The_Same_Andere_Vereniging.cs @@ -1,5 +1,6 @@ namespace AssociationRegistry.Test.LidmaatschappenTests.When_Adding_A_Lidmaatschap; +using Acties.VoegLidmaatschapToe; using AutoFixture; using Common.AutoFixture; using FluentAssertions; @@ -21,7 +22,7 @@ public void Then_It_Adds() Geldigheidsperiode = new Geldigheidsperiode(new GeldigVan(1999, 10, 10), new GeldigTot(1999, 10, 10)), }; - var toeTeVoegenLidmaatschap = fixture.Create() with + var toeTeVoegenLidmaatschap = fixture.Create() with { AndereVereniging = andereVereniging, Geldigheidsperiode = new Geldigheidsperiode(new GeldigVan(2020, 10, 10), new GeldigTot(2020, 10, 10)), @@ -33,9 +34,11 @@ public void Then_It_Adds() var actual = sut.VoegToe(toeTeVoegenLidmaatschap); - actual.Should().BeEquivalentTo(toeTeVoegenLidmaatschap with - { - LidmaatschapId = bestaandLidmaatschap.LidmaatschapId + 1, - }); + actual.Should().BeEquivalentTo(Lidmaatschap.Hydrate( + new LidmaatschapId(bestaandLidmaatschap.LidmaatschapId + 1), + toeTeVoegenLidmaatschap.AndereVereniging, + toeTeVoegenLidmaatschap.Geldigheidsperiode, + toeTeVoegenLidmaatschap.Identificatie, + toeTeVoegenLidmaatschap.Beschrijving)); } } diff --git a/test/AssociationRegistry.Test/LidmaatschappenTests/When_Removing_A_Lidmaatschap/Given_A_Lidmaatschap_Exists.cs b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Removing_A_Lidmaatschap/Given_A_Lidmaatschap_Exists.cs new file mode 100644 index 000000000..d484e3f40 --- /dev/null +++ b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Removing_A_Lidmaatschap/Given_A_Lidmaatschap_Exists.cs @@ -0,0 +1,32 @@ +namespace AssociationRegistry.Test.LidmaatschappenTests.When_Removing_A_Lidmaatschap; + +using AutoFixture; +using Common.AutoFixture; +using FluentAssertions; +using Vereniging; +using Xunit; + +public class Given_A_Lidmaatschap_Exists +{ + [Fact] + public void Then_It_Returns_The_Removed_Lidmaatschap() + { + var fixture = new Fixture().CustomizeDomain(); + + var andereVereniging = fixture.Create(); + + var bestaandLidmaatschap = fixture.Create() with + { + AndereVereniging = andereVereniging, + Geldigheidsperiode = new Geldigheidsperiode(new GeldigVan(1999, 10, 10), new GeldigTot(1999, 10, 10)), + }; + + var sut = Lidmaatschappen.Empty.Hydrate([ + bestaandLidmaatschap, + ]); + + var actual = sut.Verwijder(bestaandLidmaatschap.LidmaatschapId); + + actual.Should().Be(bestaandLidmaatschap); + } +} diff --git a/test/AssociationRegistry.Test/LidmaatschappenTests/When_Removing_A_Lidmaatschap/Given_Another_Lidmaatschap.cs b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Removing_A_Lidmaatschap/Given_Another_Lidmaatschap.cs new file mode 100644 index 000000000..905d0384c --- /dev/null +++ b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Removing_A_Lidmaatschap/Given_Another_Lidmaatschap.cs @@ -0,0 +1,27 @@ +namespace AssociationRegistry.Test.LidmaatschappenTests.When_Removing_A_Lidmaatschap; + +using AutoFixture; +using Common.AutoFixture; +using FluentAssertions; +using Resources; +using Vereniging; +using Vereniging.Exceptions; +using Xunit; + +public class Given_Another_Lidmaatschap +{ + [Fact] + public void Then_It_Throws() + { + var fixture = new Fixture().CustomizeDomain(); + var bestaandLidmaatschap = fixture.Create(); + var nonExistingLidmaatschapId = new LidmaatschapId(bestaandLidmaatschap.LidmaatschapId + 1); + + var sut = Lidmaatschappen.Empty.Hydrate([ + bestaandLidmaatschap, + ]); + + var exception = Assert.Throws(() => sut.Verwijder(nonExistingLidmaatschapId)); + exception.Message.Should().Be(string.Format(ExceptionMessages.LidmaatschapIsNietGekend, nonExistingLidmaatschapId)); + } +} diff --git a/test/AssociationRegistry.Test/LidmaatschappenTests/When_Removing_A_Lidmaatschap/Given_No_Lidmaatschap_Ecists.cs b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Removing_A_Lidmaatschap/Given_No_Lidmaatschap_Ecists.cs new file mode 100644 index 000000000..2cedd9f61 --- /dev/null +++ b/test/AssociationRegistry.Test/LidmaatschappenTests/When_Removing_A_Lidmaatschap/Given_No_Lidmaatschap_Ecists.cs @@ -0,0 +1,21 @@ +namespace AssociationRegistry.Test.LidmaatschappenTests.When_Removing_A_Lidmaatschap; + +using FluentAssertions; +using Resources; +using Vereniging; +using Vereniging.Exceptions; +using Xunit; + +public class Given_No_Lidmaatschap_Exists +{ + [Fact] + public void Then_It_Throws() + { + var lidmaatschapId = new LidmaatschapId(1); + + var sut = Lidmaatschappen.Empty; + + var exception = Assert.Throws(() => sut.Verwijder(lidmaatschapId)); + exception.Message.Should().Be(string.Format(ExceptionMessages.LidmaatschapIsNietGekend, lidmaatschapId)); + } +} diff --git a/test/AssociationRegistry.Test/When_VoegLidmaatschapToe/Given_AndereVerwijstNaamEigenVereniging.cs b/test/AssociationRegistry.Test/When_VoegLidmaatschapToe/Given_AndereVerwijstNaamEigenVereniging.cs index 9f6e598c7..14facce2d 100644 --- a/test/AssociationRegistry.Test/When_VoegLidmaatschapToe/Given_AndereVerwijstNaamEigenVereniging.cs +++ b/test/AssociationRegistry.Test/When_VoegLidmaatschapToe/Given_AndereVerwijstNaamEigenVereniging.cs @@ -1,5 +1,6 @@ namespace AssociationRegistry.Test.When_VoegLidmaatschapToe; +using Acties.VoegLidmaatschapToe; using AutoFixture; using Common.AutoFixture; using Events; @@ -20,10 +21,14 @@ public void Then_Throws() var feitelijkeVerenigingWerdGeregistreerd = fixture.Create(); sut.Hydrate(new VerenigingState().Apply(feitelijkeVerenigingWerdGeregistreerd)); - var exception = Assert.Throws(() => sut.VoegLidmaatschapToe(fixture.Create() with - { - AndereVereniging = VCode.Create(feitelijkeVerenigingWerdGeregistreerd.VCode), - })); + var toeTeVoegenLidmaatschap = fixture.Create() + with + { + AndereVereniging = VCode.Create(feitelijkeVerenigingWerdGeregistreerd.VCode), + }; + + var exception = Assert.Throws( + () => sut.VoegLidmaatschapToe(toeTeVoegenLidmaatschap)); exception.Message.Should().Be(ExceptionMessages.LidmaatschapMagNietVerwijzenNaarEigenVereniging); }