diff --git a/test/Core.Test/Auth/UserFeatures/EmergencyAccess/DeleteEmergencyAccessCommandTests.cs b/test/Core.Test/Auth/UserFeatures/EmergencyAccess/DeleteEmergencyAccessCommandTests.cs new file mode 100644 index 0000000000..ec465df1f6 --- /dev/null +++ b/test/Core.Test/Auth/UserFeatures/EmergencyAccess/DeleteEmergencyAccessCommandTests.cs @@ -0,0 +1,164 @@ +using Bit.Core.Auth.Enums; +using Bit.Core.Auth.Models.Data; +using Bit.Core.Auth.UserFeatures.EmergencyAccess.Commands; +using Bit.Core.Exceptions; +using Bit.Core.Repositories; +using Bit.Test.Common.AutoFixture; +using Bit.Test.Common.AutoFixture.Attributes; +using NSubstitute; +using Xunit; + +namespace Bit.Core.Test.Auth.UserFeatures.EmergencyAccess; + +[SutProviderCustomize] +public class DeleteEmergencyAccessCommandTests +{ + [Theory, BitAutoData] + public async Task DeleteByIdGrantorIdAsync_EmergencyAccessNotFound_ThrowsBadRequest( + SutProvider sutProvider, + Guid emergencyAccessId, + Guid grantorId) + { + sutProvider.GetDependency() + .GetDetailsByIdGrantorIdAsync(emergencyAccessId, grantorId) + .Returns((EmergencyAccessDetails)null); + + var exception = await Assert.ThrowsAsync( + () => sutProvider.Sut.DeleteByIdGrantorIdAsync(emergencyAccessId, grantorId)); + + Assert.Contains("Emergency Access not valid.", exception.Message); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .DeleteAsync(default); + } + + [Theory, BitAutoData] + public async Task DeleteByIdGrantorIdAsync_ValidRequest_DeletesAndReturnsDetails( + SutProvider sutProvider, + Guid emergencyAccessId, + Guid grantorId, + Guid granteeId) + { + var emergencyAccessDetails = new EmergencyAccessDetails + { + Id = emergencyAccessId, + GrantorId = grantorId, + GranteeId = granteeId, + Status = EmergencyAccessStatusType.Confirmed, + Type = EmergencyAccessType.View + }; + + sutProvider.GetDependency() + .GetDetailsByIdGrantorIdAsync(emergencyAccessId, grantorId) + .Returns(emergencyAccessDetails); + + var result = await sutProvider.Sut.DeleteByIdGrantorIdAsync(emergencyAccessId, grantorId); + + Assert.NotNull(result); + Assert.Equal(emergencyAccessId, result.Id); + Assert.Equal(grantorId, result.GrantorId); + await sutProvider.GetDependency() + .Received(1) + .DeleteAsync(Arg.Is(ea => ea.Id == emergencyAccessId)); + } + + [Theory, BitAutoData] + public async Task DeleteAllByGrantorIdAsync_NoEmergencyAccessRecords_ReturnsEmptyCollection( + SutProvider sutProvider, + Guid grantorId) + { + sutProvider.GetDependency() + .GetManyDetailsByGrantorIdAsync(grantorId) + .Returns(new List()); + + var result = await sutProvider.Sut.DeleteAllByGrantorIdAsync(grantorId); + + Assert.NotNull(result); + Assert.Empty(result); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .DeleteAsync(default); + } + + [Theory, BitAutoData] + public async Task DeleteAllByGrantorIdAsync_MultipleRecords_DeletesAllAndReturnsDetails( + SutProvider sutProvider, + Guid grantorId) + { + var emergencyAccessDetails1 = new EmergencyAccessDetails + { + Id = Guid.NewGuid(), + GrantorId = grantorId, + GranteeId = Guid.NewGuid(), + Status = EmergencyAccessStatusType.Confirmed, + Type = EmergencyAccessType.View + }; + + var emergencyAccessDetails2 = new EmergencyAccessDetails + { + Id = Guid.NewGuid(), + GrantorId = grantorId, + GranteeId = Guid.NewGuid(), + Status = EmergencyAccessStatusType.Invited, + Type = EmergencyAccessType.Takeover + }; + + var emergencyAccessDetails3 = new EmergencyAccessDetails + { + Id = Guid.NewGuid(), + GrantorId = grantorId, + GranteeId = Guid.NewGuid(), + Status = EmergencyAccessStatusType.RecoveryApproved, + Type = EmergencyAccessType.View + }; + + var allDetails = new List + { + emergencyAccessDetails1, + emergencyAccessDetails2, + emergencyAccessDetails3 + }; + + sutProvider.GetDependency() + .GetManyDetailsByGrantorIdAsync(grantorId) + .Returns(allDetails); + + var result = await sutProvider.Sut.DeleteAllByGrantorIdAsync(grantorId); + + Assert.NotNull(result); + Assert.Equal(3, result.Count); + await sutProvider.GetDependency() + .Received(3) + .DeleteAsync(Arg.Any()); + } + + [Theory, BitAutoData] + public async Task DeleteAllByGrantorIdAsync_SingleRecord_DeletesAndReturnsDetails( + SutProvider sutProvider, + Guid grantorId, + Guid granteeId) + { + var emergencyAccessId = Guid.NewGuid(); + var emergencyAccessDetails = new EmergencyAccessDetails + { + Id = emergencyAccessId, + GrantorId = grantorId, + GranteeId = granteeId, + Status = EmergencyAccessStatusType.Confirmed, + Type = EmergencyAccessType.Takeover + }; + + sutProvider.GetDependency() + .GetManyDetailsByGrantorIdAsync(grantorId) + .Returns(new List { emergencyAccessDetails }); + + var result = await sutProvider.Sut.DeleteAllByGrantorIdAsync(grantorId); + + Assert.NotNull(result); + Assert.Single(result); + Assert.Equal(emergencyAccessId, result.First().Id); + await sutProvider.GetDependency() + .Received(1) + .DeleteAsync(Arg.Is(ea => ea.Id == emergencyAccessId)); + } +}