diff --git a/src/StreetNameRegistry.Api.BackOffice.Abstractions/Validation/RenameStreetName.cs b/src/StreetNameRegistry.Api.BackOffice.Abstractions/Validation/RenameStreetName.cs
index a93172c2f..2916452e9 100644
--- a/src/StreetNameRegistry.Api.BackOffice.Abstractions/Validation/RenameStreetName.cs
+++ b/src/StreetNameRegistry.Api.BackOffice.Abstractions/Validation/RenameStreetName.cs
@@ -29,6 +29,14 @@ public static class SourceAndDestinationStreetNameAreNotInSameMunicipality
public static TicketError ToTicketError() => new TicketError(Message, Code);
}
+
+ public static class SourceAndDestinationStreetNameAreTheSame
+ {
+ public const string Code = "BronStraatnaamIdHetzelfdeAlsDoelStraatnaam";
+ public static string Message(string straatNaamId) => $"Het doelStraatnaamId is hetzelfde als de bron straatnaam: {straatNaamId}.";
+
+ public static TicketError ToTicketError(string straatNaamId) => new TicketError(Message(straatNaamId), Code);
+ }
}
}
}
diff --git a/src/StreetNameRegistry.Api.BackOffice/Validators/RenameStreetNameRequestValidator.cs b/src/StreetNameRegistry.Api.BackOffice/Validators/RenameStreetNameRequestValidator.cs
index 86a0936d8..e9bc206f1 100644
--- a/src/StreetNameRegistry.Api.BackOffice/Validators/RenameStreetNameRequestValidator.cs
+++ b/src/StreetNameRegistry.Api.BackOffice/Validators/RenameStreetNameRequestValidator.cs
@@ -3,7 +3,9 @@ namespace StreetNameRegistry.Api.BackOffice.Validators
using Abstractions;
using Abstractions.Requests;
using Abstractions.Validation;
+ using Azure.Core;
using Be.Vlaanderen.Basisregisters.GrAr.Edit.Validators;
+ using Be.Vlaanderen.Basisregisters.GrAr.Legacy;
using Be.Vlaanderen.Basisregisters.GrAr.Legacy.Straatnaam;
using FluentValidation;
@@ -15,6 +17,18 @@ public RenameStreetNameRequestValidator(BackOfficeContext backOfficeContext)
.Must(straatNaamId =>
OsloPuriValidator.TryParseIdentifier(straatNaamId, out var persistentLocalId) && int.TryParse(persistentLocalId, out _))
.DependentRules(() =>
+ {
+ RuleFor(x => x.DoelStraatnaamId)
+ .MustAsync(async (request, straatNaamId, ct) =>
+ {
+ OsloPuriValidator.TryParseIdentifier(straatNaamId, out var persistentLocalIdAsString);
+
+ var persistentLocalId = int.Parse(persistentLocalIdAsString);
+ return persistentLocalId != request.StreetNamePersistentLocalId;
+ })
+ .WithMessage((_, straatNaamId) => ValidationErrors.RenameStreetName.SourceAndDestinationStreetNameAreTheSame.Message(straatNaamId))
+ .WithErrorCode(ValidationErrors.RenameStreetName.SourceAndDestinationStreetNameAreTheSame.Code);
+
RuleFor(x => x.DoelStraatnaamId)
.MustAsync(async (straatNaamId, ct) =>
{
@@ -49,13 +63,15 @@ public RenameStreetNameRequestValidator(BackOfficeContext backOfficeContext)
return
municipalityIdBySourcePersistentLocalId is null
|| municipalityIdByDestinationPersistentLocalId is null
- || municipalityIdByDestinationPersistentLocalId.MunicipalityId == municipalityIdBySourcePersistentLocalId.MunicipalityId;
+ || municipalityIdByDestinationPersistentLocalId.MunicipalityId ==
+ municipalityIdBySourcePersistentLocalId.MunicipalityId;
})
.WithMessage(ValidationErrors.RenameStreetName.SourceAndDestinationStreetNameAreNotInSameMunicipality.Message)
.WithErrorCode(ValidationErrors.RenameStreetName.SourceAndDestinationStreetNameAreNotInSameMunicipality.Code)
)
.WithMessage((_, straatNaamId) => ValidationErrors.Common.StreetNameInvalid.Message(straatNaamId))
- .WithErrorCode(ValidationErrors.Common.StreetNameInvalid.Code))
+ .WithErrorCode(ValidationErrors.Common.StreetNameInvalid.Code);
+ })
.WithMessage(ValidationErrors.Common.StreetNameNotFound.Message)
.WithErrorCode(ValidationErrors.Common.StreetNameNotFound.Code);
}
diff --git a/src/StreetNameRegistry/Municipality/Exceptions/SourceAndDestinationStreetNameAreTheSameException.cs b/src/StreetNameRegistry/Municipality/Exceptions/SourceAndDestinationStreetNameAreTheSameException.cs
new file mode 100644
index 000000000..0e4c1212d
--- /dev/null
+++ b/src/StreetNameRegistry/Municipality/Exceptions/SourceAndDestinationStreetNameAreTheSameException.cs
@@ -0,0 +1,30 @@
+namespace StreetNameRegistry.Municipality.Exceptions
+{
+ using System;
+ using System.Runtime.Serialization;
+
+ [Serializable]
+ public sealed class SourceAndDestinationStreetNameAreTheSameException : StreetNameRegistryException
+ {
+ ///
+ /// The streetname id which already exists
+ ///
+ public string StreetNameId { get; }
+
+ public SourceAndDestinationStreetNameAreTheSameException()
+ {
+ StreetNameId = string.Empty;
+ }
+
+ public SourceAndDestinationStreetNameAreTheSameException(string streetNameId)
+ {
+ StreetNameId = streetNameId;
+ }
+
+ private SourceAndDestinationStreetNameAreTheSameException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ StreetNameId = string.Empty;
+ }
+ }
+}
diff --git a/src/StreetNameRegistry/Municipality/Municipality_StreetName.cs b/src/StreetNameRegistry/Municipality/Municipality_StreetName.cs
index 7086a1ea6..ad2090dd9 100644
--- a/src/StreetNameRegistry/Municipality/Municipality_StreetName.cs
+++ b/src/StreetNameRegistry/Municipality/Municipality_StreetName.cs
@@ -219,6 +219,9 @@ public void RemoveStreetName(PersistentLocalId persistentLocalId)
public void RenameStreetName(PersistentLocalId sourcePersistentLocalId, PersistentLocalId destinationPersistentLocalId)
{
+ if(sourcePersistentLocalId == destinationPersistentLocalId)
+ throw new SourceAndDestinationStreetNameAreTheSameException(sourcePersistentLocalId);
+
var streetName = StreetNames.GetNotRemovedByPersistentLocalId(sourcePersistentLocalId);
var destinationStreetName = StreetNames.GetNotRemovedByPersistentLocalId(destinationPersistentLocalId);
diff --git a/test/StreetNameRegistry.Tests/AggregateTests/WhenRenamingStreetName/GivenMunicipality.cs b/test/StreetNameRegistry.Tests/AggregateTests/WhenRenamingStreetName/GivenMunicipality.cs
index 8faeca20e..7c97997b3 100644
--- a/test/StreetNameRegistry.Tests/AggregateTests/WhenRenamingStreetName/GivenMunicipality.cs
+++ b/test/StreetNameRegistry.Tests/AggregateTests/WhenRenamingStreetName/GivenMunicipality.cs
@@ -5,6 +5,7 @@ namespace StreetNameRegistry.Tests.AggregateTests.WhenRenamingStreetName
using Be.Vlaanderen.Basisregisters.AggregateSource;
using Be.Vlaanderen.Basisregisters.AggregateSource.Snapshotting;
using Be.Vlaanderen.Basisregisters.AggregateSource.Testing;
+ using Be.Vlaanderen.Basisregisters.GrAr.Provenance;
using Builders;
using FluentAssertions;
using global::AutoFixture;
@@ -61,6 +62,34 @@ public void ThenSourceStreetNameWasRenamedAndDestinationStreetNameWasApproved()
new Fact(_streamId, new StreetNameWasRenamed(_municipalityId, command.PersistentLocalId, command.DestinationPersistentLocalId))));
}
+ [Fact]
+ public void WithDestinationSameAsSource_ThenThrowsSourceAndDestinationStreetNameAreTheSameException()
+ {
+ var command = new RenameStreetName(
+ Fixture.Create(),
+ new PersistentLocalId(1),
+ new PersistentLocalId(1),
+ Fixture.Create());
+
+ var sourceStreetNameWasProposed = new StreetNameWasProposedV2Builder(Fixture)
+ .WithPersistentLocalId(command.PersistentLocalId)
+ .Build();
+
+ var sourceStreetNameWasApproved = new StreetNameWasApprovedBuilder(Fixture)
+ .WithPersistentLocalId(sourceStreetNameWasProposed.PersistentLocalId)
+ .Build();
+
+ // Act, assert
+ Assert(new Scenario()
+ .Given(_streamId,
+ Fixture.Create(),
+ Fixture.Create(),
+ sourceStreetNameWasProposed,
+ sourceStreetNameWasApproved)
+ .When(command)
+ .Throws(new SourceAndDestinationStreetNameAreTheSameException(command.PersistentLocalId)));
+ }
+
[Fact]
public void WithApprovedDestinationStreetName_ThenSourceStreetNameWasRenamed()
{
diff --git a/test/StreetNameRegistry.Tests/BackOffice/Validators/RenameStreetNameRequestValidatorTests.cs b/test/StreetNameRegistry.Tests/BackOffice/Validators/RenameStreetNameRequestValidatorTests.cs
index 749097037..6ad40e9eb 100644
--- a/test/StreetNameRegistry.Tests/BackOffice/Validators/RenameStreetNameRequestValidatorTests.cs
+++ b/test/StreetNameRegistry.Tests/BackOffice/Validators/RenameStreetNameRequestValidatorTests.cs
@@ -101,5 +101,28 @@ public async Task GivenStreetNamesInDifferentMunicipalities_ReturnsExpectedError
.WithErrorMessage("De meegegeven straatnamen liggen in verschillende gemeenten.")
.WithErrorCode("StraatnamenAndereGemeenten");
}
+
+ [Fact]
+ public async Task GivenSourceAndDestinationStreetNameAreTheSame_ReturnsExpectedError()
+ {
+ var municipalityId = Guid.NewGuid();
+ var persistentLocalId = 10000;
+ _backOfficeContext.MunicipalityIdByPersistentLocalId.Add(new MunicipalityIdByPersistentLocalId(
+ persistentLocalId,
+ municipalityId,
+ "NISCODE"));
+ await _backOfficeContext.SaveChangesAsync();
+
+ var doelStraatnaamId = $"https://data.vlaanderen.be/id/straatnaam/{persistentLocalId}";
+ var result = await _validator.TestValidateAsync(new RenameStreetNameRequest
+ {
+ DoelStraatnaamId = doelStraatnaamId,
+ StreetNamePersistentLocalId = persistentLocalId
+ });
+
+ result.ShouldHaveValidationErrorFor(nameof(RenameStreetNameRequest.DoelStraatnaamId))
+ .WithErrorMessage($"Het doelStraatnaamId is hetzelfde als de bron straatnaam: {doelStraatnaamId}.")
+ .WithErrorCode("BronStraatnaamIdHetzelfdeAlsDoelStraatnaam");
+ }
}
}