Skip to content

Commit

Permalink
feat: WIP: update postalnames
Browse files Browse the repository at this point in the history
  • Loading branch information
ArneD committed Jan 6, 2025
1 parent 7c03275 commit 2f8e537
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 5 deletions.
47 changes: 47 additions & 0 deletions src/PostalRegistry/PostalInformation/Commands/UpdatePostalNames.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
namespace PostalRegistry.PostalInformation.Commands
{
using System;
using System.Collections.Generic;
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,
IReadOnlyCollection<PostalName> postalNamesToAdd,
IReadOnlyCollection<PostalName> postalNamesToRemove,
Provenance provenance)
{
PostalCode = postalCode;
PostalNamesToAdd = postalNamesToAdd;
PostalNamesToRemove = postalNamesToRemove;
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;
}
}
}
}
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)

Check warning on line 16 in src/PostalRegistry/PostalInformation/Exceptions/PostalNameAlreadyExistsException.cs

View workflow job for this annotation

GitHub Actions / Build

Non-nullable property 'PostalName' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
: base(info, context)
{ }
}
}
23 changes: 21 additions & 2 deletions src/PostalRegistry/PostalInformation/PostalInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ public void ImportPostalInformationFromBPost(
if (modification != Modification.Delete && _status != PostalInformationStatus.Retired)
ApplyChange(new PostalInformationWasRealized(PostalCode));

foreach (var postalName in postalNames.Where(x => !_postalNames.Contains(x)))
foreach (var postalName in postalNames.Where(x => !PostalNames.Contains(x)))
ApplyChange(new PostalInformationPostalNameWasAdded(PostalCode, postalName));

var namesToRemove = _postalNames.Where(x => !postalNames.Contains(x)).ToList();
var namesToRemove = PostalNames.Where(x => !postalNames.Contains(x)).ToList();
foreach (var postalName in namesToRemove)
ApplyChange(new PostalInformationPostalNameWasRemoved(PostalCode, postalName));

Expand Down Expand Up @@ -93,5 +93,24 @@ public void RelinkMunicipality(NisCode newNisCode)

ApplyChange(new MunicipalityWasRelinked(PostalCode, newNisCode, NisCode!));
}

public void UpdatePostalNames(
IReadOnlyCollection<PostalName> postalNamesToAdd,
IReadOnlyCollection<PostalName> postalNamesToRemove)
{
foreach (var postalName in postalNamesToRemove)
{
if(PostalNames.Contains(postalName))
ApplyChange(new PostalInformationPostalNameWasRemoved(PostalCode, postalName));
}

foreach (var postalName in postalNamesToAdd)
{
if(PostalNames.Contains(postalName))
throw new PostalNameAlreadyExistsException(postalName);

ApplyChange(new PostalInformationPostalNameWasAdded(PostalCode, postalName));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ public PostalInformationCommandHandlerModule(

postalInformation.RelinkMunicipality(message.Command.NewNisCode);
});

For<UpdatePostalNames>()
.AddSqlStreamStore(getStreamStore, getUnitOfWork, eventMapping, eventSerializer)
.AddProvenance(getUnitOfWork, postalInformationProvenanceFactory)
.Handle(async (message, ct) =>
{
var postalCode = new PostalCode(message.Command.PostalCode);
var postalInformation = await getPostalInformationSet().GetAsync(postalCode, ct);

postalInformation.UpdatePostalNames(message.Command.PostalNamesToAdd, message.Command.PostalNamesToRemove);
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public partial class PostalInformation
public PostalCode PostalCode { get; private set; }
private PostalInformationStatus? _status;

private readonly List<PostalName> _postalNames = new List<PostalName>();
public readonly List<PostalName> PostalNames = new List<PostalName>();

public NisCode? NisCode { get; set; }
public Modification LastModification { get; private set; }
Expand Down Expand Up @@ -46,12 +46,12 @@ private void WhenCrabEventApplied()

private void When(PostalInformationPostalNameWasRemoved @event)
{
_postalNames.Remove(new PostalName(@event.Name, @event.Language));
PostalNames.Remove(new PostalName(@event.Name, @event.Language));
}

private void When(PostalInformationPostalNameWasAdded @event)
{
_postalNames.Add(new PostalName(@event.Name, @event.Language));
PostalNames.Add(new PostalName(@event.Name, @event.Language));
}

private void When(PostalInformationWasRetired @event)
Expand Down
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))));
}
}
}
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);
}
}
}

0 comments on commit 2f8e537

Please sign in to comment.