using Bit.Core.Auth.Enums; using Bit.Core.Auth.Models.Data; using Bit.Core.Auth.UserFeatures.EmergencyAccess.Commands; using Bit.Core.Auth.UserFeatures.EmergencyAccess.Mail; using Bit.Core.Exceptions; using Bit.Core.Platform.Mail.Mailer; 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); await sutProvider.GetDependency() .DidNotReceiveWithAnyArgs() .SendEmail(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)); await sutProvider.GetDependency() .Received(1) .SendEmail(Arg.Any()); } [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); await sutProvider.GetDependency() .DidNotReceiveWithAnyArgs() .SendEmail(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(), 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()); await sutProvider.GetDependency() .Received(1) .SendEmail(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([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)); await sutProvider.GetDependency() .Received(1) .SendEmail(Arg.Any()); } }