-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
565 additions
and
11 deletions.
There are no files selected for viewing
70 changes: 70 additions & 0 deletions
70
src/PostalRegistry.Api.Import/PostalInformationController-UpdatePostalNames.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
namespace PostalRegistry.Api.Import | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Be.Vlaanderen.Basisregisters.AggregateSource; | ||
using Be.Vlaanderen.Basisregisters.Api.Exceptions; | ||
using Be.Vlaanderen.Basisregisters.CommandHandling.Idempotency; | ||
using Be.Vlaanderen.Basisregisters.GrAr.Legacy; | ||
using Be.Vlaanderen.Basisregisters.GrAr.Legacy.PostInfo; | ||
using FluentValidation; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Mvc; | ||
using UpdatePostalNames; | ||
|
||
public sealed partial class PostalInformationController | ||
{ | ||
[HttpPost("{postcode}/update-names")] | ||
public async Task<IActionResult> UpdatePostalNames( | ||
[FromRoute(Name = "postcode")]string? postalCode, | ||
[FromBody] UpdatePostalNamesRequest request, | ||
[FromServices] IValidator<UpdatePostalNamesRequest> validator, | ||
[FromServices] IIdempotentCommandHandler idempotentCommandHandler, | ||
CancellationToken cancellationToken = default) | ||
{ | ||
request.PostalCode = postalCode; | ||
await validator.ValidateAndThrowAsync(request, cancellationToken: cancellationToken); | ||
|
||
try | ||
{ | ||
var command = new PostalInformation.Commands.UpdatePostalNames( | ||
new PostalCode(postalCode!) | ||
, request.PostalNamesToAdd.Select(MapPostalName) | ||
, request.PostalNamesToRemove.Select(MapPostalName) | ||
, CreateProvenance(request.Reason ?? string.Empty)); | ||
|
||
await idempotentCommandHandler.Dispatch( | ||
command.CreateCommandId(), | ||
command, | ||
new Dictionary<string, object>(), | ||
cancellationToken); | ||
|
||
return Ok(); | ||
} | ||
catch (AggregateNotFoundException) | ||
{ | ||
throw new ApiException("Onbestaande postcode", StatusCodes.Status404NotFound); | ||
} | ||
} | ||
|
||
private static PostalName MapPostalName(Postnaam postnaam) | ||
{ | ||
switch (postnaam.GeografischeNaam.Taal) | ||
{ | ||
case Taal.NL: | ||
return new PostalName(postnaam.GeografischeNaam.Spelling, Language.Dutch); | ||
case Taal.FR: | ||
return new PostalName(postnaam.GeografischeNaam.Spelling, Language.French); | ||
case Taal.DE: | ||
return new PostalName(postnaam.GeografischeNaam.Spelling, Language.German); | ||
case Taal.EN: | ||
return new PostalName(postnaam.GeografischeNaam.Spelling, Language.English); | ||
default: | ||
throw new ArgumentOutOfRangeException(); | ||
} | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/PostalRegistry.Api.Import/UpdatePostalNames/UpdatePostalNamesRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
namespace PostalRegistry.Api.Import.UpdatePostalNames | ||
{ | ||
using System.Collections.Generic; | ||
using Be.Vlaanderen.Basisregisters.GrAr.Legacy.PostInfo; | ||
|
||
public sealed class UpdatePostalNamesRequest | ||
{ | ||
public string? PostalCode { get; set; } | ||
|
||
public List<Postnaam> PostalNamesToAdd { get; set; } = new List<Postnaam>(); | ||
public List<Postnaam> PostalNamesToRemove { get; set; } = new List<Postnaam>(); | ||
|
||
public string? Reason { get; set; } | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
src/PostalRegistry.Api.Import/UpdatePostalNames/UpdatePostalNamesRequestValidator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
namespace PostalRegistry.Api.Import.UpdatePostalNames | ||
{ | ||
using System.Linq; | ||
using Be.Vlaanderen.Basisregisters.GrAr.Legacy.PostInfo; | ||
using FluentValidation; | ||
|
||
public sealed class UpdatePostalNamesRequestValidator : AbstractValidator<UpdatePostalNamesRequest> | ||
{ | ||
public UpdatePostalNamesRequestValidator() | ||
{ | ||
RuleFor(request => request.PostalCode) | ||
.NotEmpty(); | ||
|
||
RuleFor(request => request.PostalNamesToAdd.Concat(request.PostalNamesToRemove)) | ||
.NotEmpty() | ||
.OverridePropertyName(nameof(UpdatePostalNamesRequest.PostalNamesToAdd)); | ||
|
||
RuleFor(request => request.PostalNamesToAdd) | ||
.Must(x => | ||
{ | ||
return x.Select(y => (y.GeografischeNaam.Spelling.ToLower(), y.GeografischeNaam.Taal)) | ||
.Distinct() | ||
.Count() == x.Count; | ||
}); | ||
|
||
RuleForEach(x => x.PostalNamesToAdd) | ||
.SetValidator(new PostnaamValidator()); | ||
|
||
RuleForEach(x => x.PostalNamesToRemove) | ||
.SetValidator(new PostnaamValidator()); | ||
} | ||
} | ||
|
||
public sealed class PostnaamValidator : AbstractValidator<Postnaam> | ||
{ | ||
public PostnaamValidator() | ||
{ | ||
RuleFor(request => request.GeografischeNaam) | ||
.NotNull(); | ||
|
||
RuleFor(request => request.GeografischeNaam.Spelling) | ||
.NotEmpty(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
src/PostalRegistry/PostalInformation/Commands/UpdatePostalNames.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
namespace PostalRegistry.PostalInformation.Commands | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Be.Vlaanderen.Basisregisters.Generators.Guid; | ||
using Be.Vlaanderen.Basisregisters.GrAr.Provenance; | ||
using Be.Vlaanderen.Basisregisters.Utilities; | ||
|
||
public sealed class UpdatePostalNames : IHasCommandProvenance | ||
{ | ||
private static readonly Guid Namespace = new Guid("6af54580-27cc-4b16-a6c9-d14eee229ed8"); | ||
|
||
public PostalCode PostalCode { get; } | ||
|
||
public IReadOnlyCollection<PostalName> PostalNamesToAdd { get; } | ||
public IReadOnlyCollection<PostalName> PostalNamesToRemove { get; } | ||
public Provenance Provenance { get; } | ||
|
||
public UpdatePostalNames( | ||
PostalCode postalCode, | ||
IEnumerable<PostalName> postalNamesToAdd, | ||
IEnumerable<PostalName> postalNamesToRemove, | ||
Provenance provenance) | ||
{ | ||
PostalCode = postalCode; | ||
PostalNamesToAdd = postalNamesToAdd.ToList(); | ||
PostalNamesToRemove = postalNamesToRemove.ToList(); | ||
Provenance = provenance; | ||
} | ||
|
||
public Guid CreateCommandId() | ||
=> Deterministic.Create(Namespace, $"UpdatePostalNames-{ToString()}"); | ||
|
||
public override string? ToString() | ||
=> ToStringBuilder.ToString(IdentityFields()); | ||
|
||
private IEnumerable<object> IdentityFields() | ||
{ | ||
yield return PostalCode; | ||
|
||
foreach (var field in Provenance.GetIdentityFields()) | ||
{ | ||
yield return field; | ||
} | ||
} | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/PostalRegistry/PostalInformation/Exceptions/PostalNameAlreadyExistsException.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace PostalRegistry.PostalInformation.Exceptions | ||
{ | ||
using System; | ||
using System.Runtime.Serialization; | ||
|
||
[Serializable] | ||
public sealed class PostalNameAlreadyExistsException : PostalRegistryException | ||
{ | ||
public PostalName PostalName { get; } | ||
|
||
public PostalNameAlreadyExistsException(PostalName postalName) | ||
{ | ||
PostalName = postalName; | ||
} | ||
|
||
private PostalNameAlreadyExistsException(SerializationInfo info, StreamingContext context) | ||
: base(info, context) | ||
{ } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
test/PostalRegistry.Tests/AggregateTests/WhenUpdatingPostalNames/GivenNoPostalInformation.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
namespace PostalRegistry.Tests.AggregateTests.WhenUpdatingPostalNames | ||
{ | ||
using AutoFixture; | ||
using Be.Vlaanderen.Basisregisters.AggregateSource; | ||
using Be.Vlaanderen.Basisregisters.AggregateSource.Testing; | ||
using global::AutoFixture; | ||
using PostalInformation; | ||
using PostalInformation.Commands; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
|
||
public class GivenNoPostalInformation : PostalRegistryTest | ||
{ | ||
private readonly Fixture _fixture; | ||
|
||
public GivenNoPostalInformation(ITestOutputHelper testOutputHelper) : base(testOutputHelper) | ||
{ | ||
_fixture = new Fixture(); | ||
_fixture.Customize(new WithFixedPostalCode()); | ||
_fixture.Customize(new WithIntegerNisCode()); | ||
} | ||
|
||
[Fact] | ||
public void ThenAggregateNotFoundExceptionIsThrown() | ||
{ | ||
var command = _fixture.Create<UpdatePostalNames>(); | ||
|
||
Assert( | ||
new Scenario() | ||
.Given() | ||
.When(command) | ||
.Throws(new AggregateNotFoundException(command.PostalCode.ToString(), typeof(PostalInformation)))); | ||
} | ||
} | ||
} |
98 changes: 98 additions & 0 deletions
98
test/PostalRegistry.Tests/AggregateTests/WhenUpdatingPostalNames/GivenPostalInformation.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
namespace PostalRegistry.Tests.AggregateTests.WhenUpdatingPostalNames | ||
{ | ||
using System.Collections.Generic; | ||
using AutoFixture; | ||
using Be.Vlaanderen.Basisregisters.AggregateSource; | ||
using Be.Vlaanderen.Basisregisters.AggregateSource.Testing; | ||
using Be.Vlaanderen.Basisregisters.GrAr.Provenance; | ||
using Builders; | ||
using FluentAssertions; | ||
using global::AutoFixture; | ||
using PostalInformation; | ||
using PostalInformation.Commands; | ||
using PostalInformation.Events; | ||
using PostalInformation.Exceptions; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
|
||
public class GivenPostalInformation : PostalRegistryTest | ||
{ | ||
private readonly Fixture _fixture; | ||
|
||
public GivenPostalInformation(ITestOutputHelper testOutputHelper) : base(testOutputHelper) | ||
{ | ||
_fixture = new Fixture(); | ||
_fixture.Customize(new WithFixedPostalCode()); | ||
_fixture.Customize(new WithIntegerNisCode()); | ||
_fixture.Customize(new InfrastructureCustomization()); | ||
} | ||
|
||
[Fact] | ||
public void GivenNameAlreadyExists_ThenPostalNameAlreadyExistsExceptionIsThrown() | ||
{ | ||
var named = _fixture.Create<PostalInformationPostalNameWasAdded>(); | ||
var postalName = new PostalName(named.Name, named.Language); | ||
var command = new UpdatePostalNames(_fixture.Create<PostalCode>(), | ||
[postalName], | ||
new List<PostalName>(), | ||
_fixture.Create<Provenance>()); | ||
|
||
Assert( | ||
new Scenario() | ||
.Given( | ||
command.PostalCode, | ||
_fixture.Create<PostalInformationWasRegistered>(), | ||
named) | ||
.When(command) | ||
.Throws(new PostalNameAlreadyExistsException(postalName))); | ||
} | ||
|
||
[Fact] | ||
public void ThenPostalNamesAreUpdated() | ||
{ | ||
var named = _fixture.Create<PostalInformationPostalNameWasAdded>(); | ||
var nameToAdd = new PostalName(_fixture.Create<string>(), Language.Dutch); | ||
var command = new UpdatePostalNames(_fixture.Create<PostalCode>(), | ||
[nameToAdd], | ||
[new PostalName(named.Name, named.Language)], | ||
_fixture.Create<Provenance>()); | ||
|
||
Assert( | ||
new Scenario() | ||
.Given( | ||
command.PostalCode, | ||
_fixture.Create<PostalInformationWasRegistered>(), | ||
named) | ||
.When(command) | ||
.Then(new Fact(command.PostalCode, | ||
new PostalInformationPostalNameWasRemoved(command.PostalCode, new PostalName(named.Name, named.Language))), | ||
new Fact(command.PostalCode, | ||
new PostalInformationPostalNameWasAdded(command.PostalCode, nameToAdd)))); | ||
} | ||
|
||
[Fact] | ||
public void StateCheck() | ||
{ | ||
// Arrange | ||
var postalInformationPostalNameWasAdded = _fixture.Create<PostalInformationPostalNameWasAdded>(); | ||
var postalInformationPostalNameWasRemoved = new PostalInformationPostalNameWasRemovedBuilder(_fixture) | ||
.WithName(postalInformationPostalNameWasAdded.Name, postalInformationPostalNameWasAdded.Language) | ||
.Build(); | ||
var postalInformationPostalNameWasAdded2 = _fixture.Create<PostalInformationPostalNameWasAdded>(); | ||
|
||
// Act | ||
var sut = PostalInformation.Factory(); | ||
sut.Initialize([ | ||
_fixture.Create<PostalInformationWasRegistered>(), | ||
_fixture.Create<MunicipalityWasAttached>(), | ||
postalInformationPostalNameWasAdded, | ||
postalInformationPostalNameWasRemoved, | ||
postalInformationPostalNameWasAdded2 | ||
]); | ||
|
||
// Assert | ||
sut.PostalNames.Count.Should().Be(1); | ||
sut.PostalNames.Should().Contain(x => x.Name == postalInformationPostalNameWasAdded2.Name && x.Language == postalInformationPostalNameWasAdded2.Language); | ||
} | ||
} | ||
} |
Oops, something went wrong.