diff --git a/src/Core/Auth/UserFeatures/EmergencyAccess/Commands/DeleteEmergencyAccessCommand.cs b/src/Core/Auth/UserFeatures/EmergencyAccess/Commands/DeleteEmergencyAccessCommand.cs index a9996f5055..cd0bf4b7be 100644 --- a/src/Core/Auth/UserFeatures/EmergencyAccess/Commands/DeleteEmergencyAccessCommand.cs +++ b/src/Core/Auth/UserFeatures/EmergencyAccess/Commands/DeleteEmergencyAccessCommand.cs @@ -90,15 +90,18 @@ public class DeleteEmergencyAccessCommand( /// private async Task SendEmergencyAccessRemoveGranteesEmailAsync(IEnumerable grantorEmails, IEnumerable formattedGranteeIdentifiers) { - var email = new EmergencyAccessRemoveGranteesMail + foreach (var email in grantorEmails) { - ToEmails = grantorEmails, - View = new EmergencyAccessRemoveGranteesMailView + var emailViewModel = new EmergencyAccessRemoveGranteesMail { - RemovedGranteeEmails = formattedGranteeIdentifiers - } - }; + ToEmails = [email], + View = new EmergencyAccessRemoveGranteesMailView + { + RemovedGranteeEmails = formattedGranteeIdentifiers + } + }; - await mailer.SendEmail(email); + await mailer.SendEmail(emailViewModel); + } } } diff --git a/test/Core.Test/Auth/UserFeatures/EmergencyAccess/DeleteEmergencyAccessCommandTests.cs b/test/Core.Test/Auth/UserFeatures/EmergencyAccess/DeleteEmergencyAccessCommandTests.cs index 5048234dc7..5797d084cc 100644 --- a/test/Core.Test/Auth/UserFeatures/EmergencyAccess/DeleteEmergencyAccessCommandTests.cs +++ b/test/Core.Test/Auth/UserFeatures/EmergencyAccess/DeleteEmergencyAccessCommandTests.cs @@ -40,32 +40,6 @@ public class DeleteEmergencyAccessCommandTests .SendEmail(default); } - /// - /// Verifies that a valid delete request successfully deletes the emergency access record, - /// returns the deleted details, and sends a notification email to the grantor. - /// - [Theory, BitAutoData] - public async Task DeleteByIdGrantorIdAsync_ValidRequest_DeletesAndReturnsDetails( - SutProvider sutProvider, - EmergencyAccessDetails emergencyAccessDetails) - { - sutProvider.GetDependency() - .GetDetailsByIdGrantorIdAsync(emergencyAccessDetails.Id, emergencyAccessDetails.GrantorId) - .Returns(emergencyAccessDetails); - - var result = await sutProvider.Sut.DeleteByIdGrantorIdAsync(emergencyAccessDetails.Id, emergencyAccessDetails.GrantorId); - - Assert.NotNull(result); - Assert.Equal(emergencyAccessDetails.Id, result.Id); - Assert.Equal(emergencyAccessDetails.GrantorId, result.GrantorId); - await sutProvider.GetDependency() - .Received(1) - .DeleteManyAsync(Arg.Any>()); - await sutProvider.GetDependency() - .Received(1) - .SendEmail(Arg.Any()); - } - /// /// Verifies that when a grantor has no emergency access records, the method returns /// an empty collection and does not attempt to delete or send email. @@ -85,7 +59,7 @@ public class DeleteEmergencyAccessCommandTests Assert.Empty(result); await sutProvider.GetDependency() .DidNotReceiveWithAnyArgs() - .DeleteAsync(default); + .DeleteManyAsync(default); await sutProvider.GetDependency() .DidNotReceiveWithAnyArgs() .SendEmail(default); @@ -93,20 +67,21 @@ public class DeleteEmergencyAccessCommandTests /// /// Verifies that when a grantor has multiple emergency access records, all records are deleted, - /// the details are returned, and a single notification email is sent. + /// the details are returned, and a single notification email is sent to the grantor. /// [Theory, BitAutoData] - public async Task DeleteAllByGrantorIdAsync_MultipleRecords_DeletesAllAndReturnsDetails( + public async Task DeleteAllByGrantorIdAsync_MultipleRecords_DeletesAllReturnsDetailsSendsSingleEmail( SutProvider sutProvider, EmergencyAccessDetails emergencyAccessDetails1, EmergencyAccessDetails emergencyAccessDetails2, - EmergencyAccessDetails emergencyAccessDetails3, - Guid grantorId) + EmergencyAccessDetails emergencyAccessDetails3) { + // Arrange // link all details to the same grantor - emergencyAccessDetails1.GrantorId = grantorId; - emergencyAccessDetails2.GrantorId = grantorId; - emergencyAccessDetails3.GrantorId = grantorId; + emergencyAccessDetails2.GrantorId = emergencyAccessDetails1.GrantorId; + emergencyAccessDetails2.GrantorEmail = emergencyAccessDetails1.GrantorEmail; + emergencyAccessDetails3.GrantorId = emergencyAccessDetails1.GrantorId; + emergencyAccessDetails3.GrantorEmail = emergencyAccessDetails1.GrantorEmail; var allDetails = new List { @@ -116,11 +91,13 @@ public class DeleteEmergencyAccessCommandTests }; sutProvider.GetDependency() - .GetManyDetailsByGrantorIdAsync(grantorId) + .GetManyDetailsByGrantorIdAsync(emergencyAccessDetails1.GrantorId) .Returns(allDetails); - var result = await sutProvider.Sut.DeleteAllByGrantorIdAsync(grantorId); + // Act + var result = await sutProvider.Sut.DeleteAllByGrantorIdAsync(emergencyAccessDetails1.GrantorId); + // Assert Assert.NotNull(result); Assert.Equal(3, result.Count); await sutProvider.GetDependency() @@ -136,7 +113,7 @@ public class DeleteEmergencyAccessCommandTests /// the details are returned, and a notification email is sent. /// [Theory, BitAutoData] - public async Task DeleteAllByGrantorIdAsync_SingleRecord_DeletesAndReturnsDetails( + public async Task DeleteAllByGrantorIdAsync_SingleRecord_DeletesAndReturnsDetailsSendsSingleEmail( SutProvider sutProvider, EmergencyAccessDetails emergencyAccessDetails, Guid grantorId) @@ -188,7 +165,7 @@ public class DeleteEmergencyAccessCommandTests /// the details are returned, and a notification email is sent to the grantor. /// [Theory, BitAutoData] - public async Task DeleteAllByGranteeIdAsync_SingleRecord_DeletesAndReturnsDetails( + public async Task DeleteAllByGranteeIdAsync_SingleRecord_DeletesAndReturnsDetailsSendsSingleEmail( SutProvider sutProvider, EmergencyAccessDetails emergencyAccessDetails, Guid granteeId) @@ -213,20 +190,20 @@ public class DeleteEmergencyAccessCommandTests /// /// Verifies that when a grantee has multiple emergency access records from different grantors, /// all records are deleted, the details are returned, and a single notification email is sent - /// to all affected grantors. + /// to all affected grantors individually. /// [Theory, BitAutoData] - public async Task DeleteAllByGranteeIdAsync_MultipleRecords_DeletesAllAndReturnsDetails( + public async Task DeleteAllByGranteeIdAsync_MultipleRecords_DeletesAllReturnsDetailsSendsMultipleEmails( SutProvider sutProvider, EmergencyAccessDetails emergencyAccessDetails1, EmergencyAccessDetails emergencyAccessDetails2, - EmergencyAccessDetails emergencyAccessDetails3, - Guid granteeId) + EmergencyAccessDetails emergencyAccessDetails3) { // link all details to the same grantee - emergencyAccessDetails1.GranteeId = granteeId; - emergencyAccessDetails2.GranteeId = granteeId; - emergencyAccessDetails3.GranteeId = granteeId; + emergencyAccessDetails2.GranteeId = emergencyAccessDetails1.GranteeId; + emergencyAccessDetails2.GranteeEmail = emergencyAccessDetails1.GranteeEmail; + emergencyAccessDetails3.GranteeId = emergencyAccessDetails1.GranteeId; + emergencyAccessDetails3.GranteeEmail = emergencyAccessDetails1.GranteeEmail; var allDetails = new List { @@ -236,10 +213,10 @@ public class DeleteEmergencyAccessCommandTests }; sutProvider.GetDependency() - .GetManyDetailsByGranteeIdAsync(granteeId) + .GetManyDetailsByGranteeIdAsync((Guid)emergencyAccessDetails1.GranteeId) .Returns(allDetails); - var result = await sutProvider.Sut.DeleteAllByGranteeIdAsync(granteeId); + var result = await sutProvider.Sut.DeleteAllByGranteeIdAsync((Guid)emergencyAccessDetails1.GranteeId); Assert.NotNull(result); Assert.Equal(3, result.Count); @@ -247,7 +224,7 @@ public class DeleteEmergencyAccessCommandTests .Received(1) .DeleteManyAsync(Arg.Any>()); await sutProvider.GetDependency() - .Received(1) + .Received(allDetails.Count) .SendEmail(Arg.Any()); } }