diff --git a/src/AssociationRegistry.Admin.Api/Infrastructure/Extensions/ResponseExtensions.cs b/src/AssociationRegistry.Admin.Api/Infrastructure/Extensions/ResponseExtensions.cs index f2e02d4a2..5245e7a9c 100644 --- a/src/AssociationRegistry.Admin.Api/Infrastructure/Extensions/ResponseExtensions.cs +++ b/src/AssociationRegistry.Admin.Api/Infrastructure/Extensions/ResponseExtensions.cs @@ -22,12 +22,9 @@ public static void AddETagHeader(this HttpResponse source, long? version) responseHeaders.ETag = new EntityTagHeaderValue(new StringSegment($"\"{version}\""), isWeak: true); } - public static void AddLocationHeader(this HttpResponse source, string vCode, string location, string id, string baseUrl) + public static void AddLocationHeader(this HttpResponse source, string vCode, string entityName, int id, string baseUrl) { - if (string.IsNullOrEmpty(id)) - return; - var responseHeaders = source.GetTypedHeaders(); - responseHeaders.Location = new Uri($"{baseUrl}/v1/verenigingen/{vCode}/{location}/{id}"); + responseHeaders.Location = new Uri($"{baseUrl}/v1/verenigingen/{vCode}/{entityName}/{id}"); } } diff --git a/src/AssociationRegistry.Admin.Api/Infrastructure/WellKnownHeaderLocations.cs b/src/AssociationRegistry.Admin.Api/Infrastructure/WellKnownHeaderLocations.cs index 4a9ae6d39..11ef08a6f 100644 --- a/src/AssociationRegistry.Admin.Api/Infrastructure/WellKnownHeaderLocations.cs +++ b/src/AssociationRegistry.Admin.Api/Infrastructure/WellKnownHeaderLocations.cs @@ -4,4 +4,5 @@ public class WellKnownHeaderLocations { public const string Vertegenwoordigers = "vertegenwoordigers"; public const string Locaties = "locaties"; + public const string Contactgegevens = "contactgegevens"; } diff --git a/src/AssociationRegistry.Admin.Api/Verenigingen/Contactgegevens/FeitelijkeVereniging/VoegContactGegevenToe/VoegContactGegevenToeController.cs b/src/AssociationRegistry.Admin.Api/Verenigingen/Contactgegevens/FeitelijkeVereniging/VoegContactGegevenToe/VoegContactGegevenToeController.cs index ceb7be28e..aca611888 100644 --- a/src/AssociationRegistry.Admin.Api/Verenigingen/Contactgegevens/FeitelijkeVereniging/VoegContactGegevenToe/VoegContactGegevenToeController.cs +++ b/src/AssociationRegistry.Admin.Api/Verenigingen/Contactgegevens/FeitelijkeVereniging/VoegContactGegevenToe/VoegContactGegevenToeController.cs @@ -7,6 +7,7 @@ using Examples; using FluentValidation; using Framework; +using Hosts.Configuration.ConfigurationBindings; using Infrastructure; using Infrastructure.Extensions; using Infrastructure.Middleware; @@ -28,11 +29,13 @@ public class VoegContactgegevenToeController : ApiController { private readonly IMessageBus _messageBus; private readonly IValidator _validator; + private readonly AppSettings _appSettings; - public VoegContactgegevenToeController(IMessageBus messageBus, IValidator validator) + public VoegContactgegevenToeController(IMessageBus messageBus, IValidator validator, AppSettings appSettings) { _messageBus = messageBus; _validator = validator; + _appSettings = appSettings; } /// @@ -76,10 +79,11 @@ public async Task Post( var metaData = metadataProvider.GetMetadata(IfMatchParser.ParseIfMatch(ifMatch)); var envelope = new CommandEnvelope(request.ToCommand(vCode), metaData); - var commandResult = await _messageBus.InvokeAsync(envelope); + var commandResult = await _messageBus.InvokeAsync(envelope); Response.AddSequenceHeader(commandResult.Sequence); Response.AddETagHeader(commandResult.Version); + Response.AddLocationHeader(vCode, WellKnownHeaderLocations.Contactgegevens, commandResult.EntityId, _appSettings.BaseUrl); return Accepted(); } diff --git a/src/AssociationRegistry/Acties/VoegContactgegevenToe/VoegContactgegevenToeCommandHandler.cs b/src/AssociationRegistry/Acties/VoegContactgegevenToe/VoegContactgegevenToeCommandHandler.cs index dd005768b..142090e17 100644 --- a/src/AssociationRegistry/Acties/VoegContactgegevenToe/VoegContactgegevenToeCommandHandler.cs +++ b/src/AssociationRegistry/Acties/VoegContactgegevenToe/VoegContactgegevenToeCommandHandler.cs @@ -12,17 +12,17 @@ public VoegContactgegevenToeCommandHandler(IVerenigingsRepository verenigingRepo _verenigingRepository = verenigingRepository; } - public async Task Handle( + public async Task Handle( CommandEnvelope envelope, CancellationToken cancellationToken = default) { var vereniging = await _verenigingRepository.Load(VCode.Create(envelope.Command.VCode), envelope.Metadata.ExpectedVersion); - vereniging.VoegContactgegevenToe(envelope.Command.Contactgegeven); + var contactgegeven = vereniging.VoegContactgegevenToe(envelope.Command.Contactgegeven); var result = await _verenigingRepository.Save(vereniging, envelope.Metadata, cancellationToken); - return CommandResult.Create(VCode.Create(envelope.Command.VCode), result); + return EntityCommandResult.Create(VCode.Create(envelope.Command.VCode), contactgegeven.ContactgegevenId, result); } } diff --git a/src/AssociationRegistry/Acties/VoegLocatieToe/VoegLocatieToeCommandHandler.cs b/src/AssociationRegistry/Acties/VoegLocatieToe/VoegLocatieToeCommandHandler.cs index 97f0e150c..ae07c82c3 100644 --- a/src/AssociationRegistry/Acties/VoegLocatieToe/VoegLocatieToeCommandHandler.cs +++ b/src/AssociationRegistry/Acties/VoegLocatieToe/VoegLocatieToeCommandHandler.cs @@ -42,7 +42,7 @@ await _verenigingRepository.Load( var result = await _verenigingRepository.Save(vereniging, _session, envelope.Metadata, cancellationToken); - return EntityCommandResult.Create(VCode.Create(envelope.Command.VCode), toegevoegdeLocatie.LocatieId.ToString(), result); + return EntityCommandResult.Create(VCode.Create(envelope.Command.VCode), toegevoegdeLocatie.LocatieId, result); } private async Task SynchroniseerLocatie( diff --git a/src/AssociationRegistry/Acties/VoegVertegenwoordigerToe/VoegVertegenwoordigerToeCommandHandler.cs b/src/AssociationRegistry/Acties/VoegVertegenwoordigerToe/VoegVertegenwoordigerToeCommandHandler.cs index 1a5616492..ac48d88f6 100644 --- a/src/AssociationRegistry/Acties/VoegVertegenwoordigerToe/VoegVertegenwoordigerToeCommandHandler.cs +++ b/src/AssociationRegistry/Acties/VoegVertegenwoordigerToe/VoegVertegenwoordigerToeCommandHandler.cs @@ -25,6 +25,6 @@ public async Task Handle( var result = await _repository.Save(vereniging, envelope.Metadata, cancellationToken); - return EntityCommandResult.Create(VCode.Create(envelope.Command.VCode), vertegenwoordigerId.ToString(), result); + return EntityCommandResult.Create(VCode.Create(envelope.Command.VCode), vertegenwoordigerId.VertegenwoordigerId, result); } } diff --git a/src/AssociationRegistry/Vereniging/EntityCommandResult.cs b/src/AssociationRegistry/Vereniging/EntityCommandResult.cs index 82210365b..08967c214 100644 --- a/src/AssociationRegistry/Vereniging/EntityCommandResult.cs +++ b/src/AssociationRegistry/Vereniging/EntityCommandResult.cs @@ -4,7 +4,7 @@ namespace AssociationRegistry.Vereniging; public class EntityCommandResult { - private EntityCommandResult(VCode vcode, string entityId, long? sequence, long? version) + private EntityCommandResult(VCode vcode, int entityId, long? sequence, long? version) { Vcode = vcode; EntityId = entityId; @@ -13,13 +13,13 @@ private EntityCommandResult(VCode vcode, string entityId, long? sequence, long? } public VCode Vcode { get; } - public string EntityId { get; set; } + public int EntityId { get; set; } public long? Sequence { get; } public long? Version { get; } public bool HasChanges() => Sequence is not null; - public static EntityCommandResult Create(VCode vCode, string entityId, StreamActionResult streamActionResult) + public static EntityCommandResult Create(VCode vCode, int entityId, StreamActionResult streamActionResult) => new(vCode, entityId, streamActionResult.Sequence, streamActionResult.Version); } diff --git a/src/AssociationRegistry/Vereniging/Vereniging.cs b/src/AssociationRegistry/Vereniging/Vereniging.cs index cbf3bd44c..4ef0c6099 100644 --- a/src/AssociationRegistry/Vereniging/Vereniging.cs +++ b/src/AssociationRegistry/Vereniging/Vereniging.cs @@ -138,13 +138,13 @@ public void WijzigHoofdactiviteitenVerenigingsloket(HoofdactiviteitVerenigingslo AddEvent(HoofdactiviteitenVerenigingsloketWerdenGewijzigd.With(hoofdactiviteiten.ToArray())); } - public int VoegVertegenwoordigerToe(Vertegenwoordiger vertegenwoordiger) + public Vertegenwoordiger VoegVertegenwoordigerToe(Vertegenwoordiger vertegenwoordiger) { var toegevoegdeVertegenwoordiger = State.Vertegenwoordigers.VoegToe(vertegenwoordiger); AddEvent(VertegenwoordigerWerdToegevoegd.With(toegevoegdeVertegenwoordiger)); - return toegevoegdeVertegenwoordiger.VertegenwoordigerId; + return toegevoegdeVertegenwoordiger; } public void WijzigVertegenwoordiger( diff --git a/src/AssociationRegistry/Vereniging/VerenigingOfAnyKind.cs b/src/AssociationRegistry/Vereniging/VerenigingOfAnyKind.cs index f6b14f191..e24e7eb9a 100644 --- a/src/AssociationRegistry/Vereniging/VerenigingOfAnyKind.cs +++ b/src/AssociationRegistry/Vereniging/VerenigingOfAnyKind.cs @@ -31,11 +31,13 @@ private static Registratiedata.Vertegenwoordiger[] ToVertegenwoordigersLijst(Ver private static Registratiedata.Locatie[] ToLocatieLijst(Locatie[] locatieLijst) => locatieLijst.Select(Registratiedata.Locatie.With).ToArray(); - public void VoegContactgegevenToe(Contactgegeven contactgegeven) + public Contactgegeven VoegContactgegevenToe(Contactgegeven contactgegeven) { var toegevoegdContactgegeven = State.Contactgegevens.VoegToe(contactgegeven); AddEvent(ContactgegevenWerdToegevoegd.With(toegevoegdContactgegeven)); + + return toegevoegdContactgegeven; } public void WijzigContactgegeven(int contactgegevenId, string? waarde, string? beschrijving, bool? isPrimair) diff --git a/test/AssociationRegistry.Test.Admin.Api/Commands/FeitelijkeVereniging/When_Adding_Vertegenwoordiger/CommandHandling/Given_A_NietPrimair_Vertegenwoordiger.cs b/test/AssociationRegistry.Test.Admin.Api/Commands/FeitelijkeVereniging/When_Adding_Vertegenwoordiger/CommandHandling/Given_A_NietPrimair_Vertegenwoordiger.cs index 98415e7c8..586405f64 100644 --- a/test/AssociationRegistry.Test.Admin.Api/Commands/FeitelijkeVereniging/When_Adding_Vertegenwoordiger/CommandHandling/Given_A_NietPrimair_Vertegenwoordiger.cs +++ b/test/AssociationRegistry.Test.Admin.Api/Commands/FeitelijkeVereniging/When_Adding_Vertegenwoordiger/CommandHandling/Given_A_NietPrimair_Vertegenwoordiger.cs @@ -66,6 +66,6 @@ public async Task Then_A_EntityId_Is_Returned() var vertegenwoordigerId = _verenigingRepositoryMock.SaveInvocations[0].Vereniging.UncommittedEvents.ToArray()[0] .As().VertegenwoordigerId; - result.EntityId.Should().Be(vertegenwoordigerId.ToString()); + result.EntityId.Should().Be(vertegenwoordigerId); } } diff --git a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/CommandHandling/Given_A_Second_NietPrimair_Contactgegeven.cs b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/CommandHandling/Given_A_Second_NietPrimair_Contactgegeven.cs index a6ef73494..92f9e49c8 100644 --- a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/CommandHandling/Given_A_Second_NietPrimair_Contactgegeven.cs +++ b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/CommandHandling/Given_A_Second_NietPrimair_Contactgegeven.cs @@ -6,6 +6,7 @@ using Common.Framework; using Common.Scenarios.CommandHandling; using Events; +using FluentAssertions; using Framework; using Vereniging; using Xunit; @@ -51,4 +52,25 @@ public async Task Then_A_ContactgegevenWerdToegevoegd_Event_Is_Saved(string type command.Contactgegeven.Beschrijving, IsPrimair: false) ); } + + [Fact] + public async Task Then_A_ContactgegevenWerdToegevoegd_Event_Is_Saved() + { + var command = new VoegContactgegevenToeCommand( + _scenario.VCode, + Contactgegeven.CreateFromInitiator( + Contactgegeventype.Parse("SocialMedia"), + "https://www.example.org", + _fixture.Create(), + isPrimair: false)); + + var result = await _commandHandler.Handle( + new CommandEnvelope(command, _fixture.Create())); + + var contactgegevenId = _verenigingRepositoryMock.SaveInvocations[0].Vereniging.UncommittedEvents.ToArray()[0] + .As() + .ContactgegevenId; + + result.EntityId.Should().Be(contactgegevenId); + } } diff --git a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Invalid_ETag.cs b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Invalid_ETag.cs index c44aae900..fb11c2af0 100644 --- a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Invalid_ETag.cs +++ b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Invalid_ETag.cs @@ -6,6 +6,7 @@ using AutoFixture; using FluentAssertions; using Framework; +using Hosts.Configuration.ConfigurationBindings; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Moq; @@ -24,7 +25,13 @@ public With_Invalid_ETag() _fixture = new Fixture().CustomizeAdminApi(); var messageBusMock = new Mock(); - _controller = new VoegContactgegevenToeController(messageBusMock.Object, new VoegContactgegevenToeValidator()) + _controller = new VoegContactgegevenToeController( + messageBusMock.Object, + new VoegContactgegevenToeValidator(), + new AppSettings() + { + BaseUrl = "https://beheer.verenigingen.vlaanderen.be", + }) { ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext() } }; } diff --git a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Null_Request.cs b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Null_Request.cs index a3770fcbc..81a500fa0 100644 --- a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Null_Request.cs +++ b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Null_Request.cs @@ -3,6 +3,7 @@ using AssociationRegistry.Admin.Api.Infrastructure.ExceptionHandlers; using AssociationRegistry.Admin.Api.Verenigingen.Contactgegevens.FeitelijkeVereniging.VoegContactGegevenToe; using Framework; +using Hosts.Configuration.ConfigurationBindings; using Moq; using Wolverine; using Xunit; @@ -16,7 +17,14 @@ public class With_Null_Request public With_Null_Request() { var messageBus = Mock.Of(); - _controller = new VoegContactgegevenToeController(messageBus, new VoegContactgegevenToeValidator()); + + _controller = new VoegContactgegevenToeController( + messageBus, + new VoegContactgegevenToeValidator(), + new AppSettings() + { + BaseUrl = "https://beheer.verenigingen.vlaanderen.be", + }); } [Fact] diff --git a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Valid_ETag.cs b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Valid_ETag.cs index abfedd8cc..038f093b5 100644 --- a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Valid_ETag.cs +++ b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Valid_ETag.cs @@ -6,6 +6,7 @@ using AssociationRegistry.Framework; using AutoFixture; using Framework; +using Hosts.Configuration.ConfigurationBindings; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Moq; @@ -28,10 +29,16 @@ public With_Valid_ETag() _messageBusMock = new Mock(); _messageBusMock - .Setup(x => x.InvokeAsync(It.IsAny>(), default, null)) - .ReturnsAsync(new Fixture().CustomizeAdminApi().Create()); + .Setup(x => x.InvokeAsync(It.IsAny>(), default, null)) + .ReturnsAsync(new Fixture().CustomizeAdminApi().Create()); - _toeController = new VoegContactgegevenToeController(_messageBusMock.Object, new VoegContactgegevenToeValidator()) + _toeController = new VoegContactgegevenToeController( + _messageBusMock.Object, + new VoegContactgegevenToeValidator(), + new AppSettings() + { + BaseUrl = "https://beheer.verenigingen.vlaanderen.be", + }) { ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext() } }; } @@ -49,7 +56,7 @@ public void Then_it_invokes_with_a_correct_version_number() { _messageBusMock.Verify( expression: messageBus => - messageBus.InvokeAsync( + messageBus.InvokeAsync( It.Is>( env => env.Metadata.ExpectedVersion == ETagNumber), diff --git a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Valid_Request.cs b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Valid_Request.cs index 59c6996fa..f8035265f 100644 --- a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Valid_Request.cs +++ b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Contactgegeven/RequestHandling/With_Valid_Request.cs @@ -9,6 +9,7 @@ using FluentAssertions; using FluentAssertions.Execution; using Framework; +using Hosts.Configuration.ConfigurationBindings; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Infrastructure; @@ -25,20 +26,26 @@ public class With_Valid_Request { private readonly VoegContactgegevenToeController _controller; private readonly Fixture _fixture; - private readonly CommandResult _commandResult; + private readonly EntityCommandResult _entityCommandResult; public With_Valid_Request() { _fixture = new Fixture().CustomizeAdminApi(); var messageBusMock = new Mock(); - _commandResult = new Fixture().CustomizeAdminApi().Create(); + _entityCommandResult = new Fixture().CustomizeAdminApi().Create(); messageBusMock - .Setup(mb => mb.InvokeAsync(It.IsAny>(), default, null)) - .ReturnsAsync(_commandResult); + .Setup(mb => mb.InvokeAsync(It.IsAny>(), default, null)) + .ReturnsAsync(_entityCommandResult); - _controller = new VoegContactgegevenToeController(messageBusMock.Object, new VoegContactgegevenToeValidator()) + _controller = new VoegContactgegevenToeController( + messageBusMock.Object, + new VoegContactgegevenToeValidator(), + new AppSettings() + { + BaseUrl = "https://beheer.verenigingen.vlaanderen.be", + }) { ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext() } }; } @@ -67,7 +74,7 @@ await _controller.Post( using (new AssertionScope()) { - _controller.Response.Headers[WellknownHeaderNames.Sequence].Should().BeEquivalentTo(_commandResult.Sequence.ToString()); + _controller.Response.Headers[WellknownHeaderNames.Sequence].Should().BeEquivalentTo(_entityCommandResult.Sequence.ToString()); } } @@ -82,7 +89,23 @@ await _controller.Post( using (new AssertionScope()) { _controller.Response.GetTypedHeaders().ETag.Should() - .BeEquivalentTo(new EntityTagHeaderValue(new StringSegment($@"""{_commandResult.Version}"""), isWeak: true)); + .BeEquivalentTo(new EntityTagHeaderValue(new StringSegment($@"""{_entityCommandResult.Version}"""), isWeak: true)); + } + } + + [Fact] + public async Task Then_it_returns_a_location_header() + { + var vCode = _fixture.Create(); + await _controller.Post( + vCode, + _fixture.Create(), + _fixture.Create()); + + using (new AssertionScope()) + { + _controller.Response.GetTypedHeaders().Location.Should() + .BeEquivalentTo(new Uri($"https://beheer.verenigingen.vlaanderen.be/v1/verenigingen/{vCode}/contactgegevens/{_entityCommandResult.EntityId}")); } } } diff --git a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Locatie/CommandHandling/Given_A_Locatie.cs b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Locatie/CommandHandling/Given_A_Locatie.cs index 849b64d7d..49352b37d 100644 --- a/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Locatie/CommandHandling/Given_A_Locatie.cs +++ b/test/AssociationRegistry.Test.Admin.Api/Commands/VerenigingOfAnyKind/When_Adding_Locatie/CommandHandling/Given_A_Locatie.cs @@ -73,7 +73,7 @@ public async Task Then_An_EntityId_Is_Returned(CommandhandlerScenarioBase scenar var result = await commandHandler.Handle(new CommandEnvelope(command, _fixture.Create())); - result.EntityId.Should().Be(expectedLocatieId.ToString()); + result.EntityId.Should().Be(expectedLocatieId); } public static IEnumerable Data