From b1d06b740ceca0dec333e357f193fb9e16ff59b8 Mon Sep 17 00:00:00 2001 From: Timo Notheisen <65653426+tnotheis@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:12:34 +0100 Subject: [PATCH] It is possible to cancel deletion processes with expired grace periods (#989) * fix: throw if deletion grace period is expired * test: write a test for it --- .../Devices/src/Devices.Domain/DomainErrors.cs | 6 ++++++ .../Identities/IdentityDeletionProcess.cs | 3 +++ .../CancelDeletionProcessAsOwnerTests.cs | 15 +++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/Modules/Devices/src/Devices.Domain/DomainErrors.cs b/Modules/Devices/src/Devices.Domain/DomainErrors.cs index d63efbd4f7..2bb535e1ce 100644 --- a/Modules/Devices/src/Devices.Domain/DomainErrors.cs +++ b/Modules/Devices/src/Devices.Domain/DomainErrors.cs @@ -64,6 +64,12 @@ public static DomainError GracePeriodHasNotYetExpired() "The deletion via this deletion process cannot be started because the grace period has not yet expired."); } + public static DomainError GracePeriodHasAlreadyExpired() + { + return new DomainError("error.platform.validation.device.gracePeriodHasAlreadyExpired", + "You cannot perform this action, because the grace period of this deletion process has already expired."); + } + public static DomainError DeletionProcessMustBePastDueApproval() { return new DomainError("error.platform.validation.device.noDeletionProcessIsPastDueApproval", "No deletion process is past due approval."); diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs index 94a5fa7dfe..7a23d1c242 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs @@ -181,6 +181,9 @@ public void CancelAsOwner(IdentityAddress address, DeviceId cancelledByDevice) if (Status != DeletionProcessStatus.Approved) throw new DomainException(DomainErrors.DeletionProcessMustBeInStatus(DeletionProcessStatus.Approved)); + if (GracePeriodEndsAt < SystemTime.UtcNow) + throw new DomainException(DomainErrors.GracePeriodHasAlreadyExpired()); + ChangeStatus(DeletionProcessStatus.Cancelled, address, address); CancelledAt = SystemTime.UtcNow; CancelledByDevice = cancelledByDevice; diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessAsOwnerTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessAsOwnerTests.cs index 45f64dfe44..0acef26620 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessAsOwnerTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessAsOwnerTests.cs @@ -58,6 +58,21 @@ public void Throws_when_deletion_process_is_in_wrong_status() acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.deletionProcessIsNotInRequiredStatus"); } + [Fact] + public void Throws_when_grace_period_has_expired() + { + // Arrange + var identity = TestDataGenerator.CreateIdentityWithApprovedDeletionProcess(); + + SystemTime.Set(DateTime.UtcNow.AddDays(IdentityDeletionConfiguration.Instance.LengthOfGracePeriodInDays)); + + // Act + var acting = () => identity.CancelDeletionProcessAsOwner(identity.DeletionProcesses[0].Id, identity.Devices[0].Id); + + // Assert + acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.gracePeriodHasAlreadyExpired"); + } + [Fact] public void Raises_domain_events() {