mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 15:42:48 -05:00
[PM-17154] Limit item deletion feature flag logic removal (#5925)
* Refactor CiphersController and related tests by removing unused IFeatureService dependency and associated feature flag checks. Cleaned up tests to reflect these changes, ensuring they focus on manage permissions without reliance on feature flags. * Refactor CipherService and related tests by removing feature flag checks for item deletion permissions. Updated tests to focus on user manage permissions without reliance on feature flags, ensuring cleaner and more maintainable code. * Enhance CiphersControllerTests by adding user retrieval and organization ability checks. Updated test cases to ensure proper handling of item deletion permissions based on user roles and organization settings, improving test coverage and reliability.
This commit is contained in:
@ -673,13 +673,21 @@ public class CipherServiceTests
|
||||
[BitAutoData]
|
||||
public async Task RestoreAsync_UpdatesUserCipher(Guid restoringUserId, CipherDetails cipher, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<ICipherRepository>().GetCanEditByIdAsync(restoringUserId, cipher.Id).Returns(true);
|
||||
cipher.UserId = restoringUserId;
|
||||
cipher.OrganizationId = null;
|
||||
|
||||
var initialRevisionDate = new DateTime(1970, 1, 1, 0, 0, 0);
|
||||
cipher.DeletedDate = initialRevisionDate;
|
||||
cipher.RevisionDate = initialRevisionDate;
|
||||
|
||||
await sutProvider.Sut.RestoreAsync(cipher, restoringUserId, cipher.OrganizationId.HasValue);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(restoringUserId)
|
||||
.Returns(new User
|
||||
{
|
||||
Id = restoringUserId,
|
||||
});
|
||||
|
||||
await sutProvider.Sut.RestoreAsync(cipher, restoringUserId);
|
||||
|
||||
Assert.Null(cipher.DeletedDate);
|
||||
Assert.NotEqual(initialRevisionDate, cipher.RevisionDate);
|
||||
@ -688,15 +696,28 @@ public class CipherServiceTests
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task RestoreAsync_UpdatesOrganizationCipher(Guid restoringUserId, CipherDetails cipher, SutProvider<CipherService> sutProvider)
|
||||
public async Task RestoreAsync_UpdatesOrganizationCipher(Guid restoringUserId, CipherDetails cipher, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<ICipherRepository>().GetCanEditByIdAsync(restoringUserId, cipher.Id).Returns(true);
|
||||
cipher.OrganizationId = Guid.NewGuid();
|
||||
cipher.Edit = false;
|
||||
cipher.Manage = true;
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(restoringUserId)
|
||||
.Returns(user);
|
||||
sutProvider.GetDependency<IApplicationCacheService>()
|
||||
.GetOrganizationAbilityAsync(cipher.OrganizationId.Value)
|
||||
.Returns(new OrganizationAbility
|
||||
{
|
||||
Id = cipher.OrganizationId.Value,
|
||||
LimitItemDeletion = true
|
||||
});
|
||||
|
||||
var initialRevisionDate = new DateTime(1970, 1, 1, 0, 0, 0);
|
||||
cipher.DeletedDate = initialRevisionDate;
|
||||
cipher.RevisionDate = initialRevisionDate;
|
||||
|
||||
await sutProvider.Sut.RestoreAsync(cipher, restoringUserId, cipher.OrganizationId.HasValue);
|
||||
await sutProvider.Sut.RestoreAsync(cipher, restoringUserId);
|
||||
|
||||
Assert.Null(cipher.DeletedDate);
|
||||
Assert.NotEqual(initialRevisionDate, cipher.RevisionDate);
|
||||
@ -724,24 +745,12 @@ public class CipherServiceTests
|
||||
cipherDetails.UserId = Guid.NewGuid();
|
||||
cipherDetails.OrganizationId = null;
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||
() => sutProvider.Sut.RestoreAsync(cipherDetails, restoringUserId));
|
||||
|
||||
Assert.Contains("do not have permissions", exception.Message);
|
||||
await sutProvider.GetDependency<ICipherRepository>().DidNotReceiveWithAnyArgs().UpsertAsync(default);
|
||||
await sutProvider.GetDependency<IEventService>().DidNotReceiveWithAnyArgs().LogCipherEventAsync(default, default);
|
||||
await sutProvider.GetDependency<IPushNotificationService>().DidNotReceiveWithAnyArgs().PushSyncCipherUpdateAsync(default, default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task RestoreAsync_WithOrgCipherLackingEditPermission_ThrowsBadRequestException(
|
||||
Guid restoringUserId, CipherDetails cipherDetails, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetCanEditByIdAsync(restoringUserId, cipherDetails.Id)
|
||||
.Returns(false);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(restoringUserId)
|
||||
.Returns(new User
|
||||
{
|
||||
Id = restoringUserId,
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||
() => sutProvider.Sut.RestoreAsync(cipherDetails, restoringUserId));
|
||||
@ -752,28 +761,6 @@ public class CipherServiceTests
|
||||
await sutProvider.GetDependency<IPushNotificationService>().DidNotReceiveWithAnyArgs().PushSyncCipherUpdateAsync(default, default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task RestoreAsync_WithEditPermission_RestoresCipherDetails(
|
||||
Guid restoringUserId, CipherDetails cipherDetails, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetCanEditByIdAsync(restoringUserId, cipherDetails.Id)
|
||||
.Returns(true);
|
||||
|
||||
var initialRevisionDate = new DateTime(1970, 1, 1, 0, 0, 0);
|
||||
cipherDetails.DeletedDate = initialRevisionDate;
|
||||
cipherDetails.RevisionDate = initialRevisionDate;
|
||||
|
||||
await sutProvider.Sut.RestoreAsync(cipherDetails, restoringUserId);
|
||||
|
||||
Assert.Null(cipherDetails.DeletedDate);
|
||||
Assert.NotEqual(initialRevisionDate, cipherDetails.RevisionDate);
|
||||
await sutProvider.GetDependency<ICipherRepository>().Received(1).UpsertAsync(cipherDetails);
|
||||
await sutProvider.GetDependency<IEventService>().Received(1).LogCipherEventAsync(cipherDetails, EventType.Cipher_Restored);
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(1).PushSyncCipherUpdateAsync(cipherDetails, null);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
@ -794,7 +781,7 @@ public class CipherServiceTests
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task RestoreAsync_WithLimitItemDeletionEnabled_WithManagePermission_RestoresCipher(
|
||||
public async Task RestoreAsync_WithManagePermission_RestoresCipher(
|
||||
Guid restoringUserId, CipherDetails cipherDetails, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
cipherDetails.OrganizationId = Guid.NewGuid();
|
||||
@ -802,9 +789,6 @@ public class CipherServiceTests
|
||||
cipherDetails.Edit = false;
|
||||
cipherDetails.Manage = true;
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(restoringUserId)
|
||||
.Returns(user);
|
||||
@ -828,7 +812,7 @@ public class CipherServiceTests
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task RestoreAsync_WithLimitItemDeletionEnabled_WithoutManagePermission_ThrowsBadRequestException(
|
||||
public async Task RestoreAsync_WithoutManagePermission_ThrowsBadRequestException(
|
||||
Guid restoringUserId, CipherDetails cipherDetails, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
cipherDetails.OrganizationId = Guid.NewGuid();
|
||||
@ -836,9 +820,6 @@ public class CipherServiceTests
|
||||
cipherDetails.Edit = true;
|
||||
cipherDetails.Manage = false;
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(restoringUserId)
|
||||
.Returns(user);
|
||||
@ -859,32 +840,7 @@ public class CipherServiceTests
|
||||
await sutProvider.GetDependency<IPushNotificationService>().DidNotReceiveWithAnyArgs().PushSyncCipherUpdateAsync(default, default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task RestoreManyAsync_UpdatesCiphers(ICollection<CipherDetails> ciphers,
|
||||
SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var cipherIds = ciphers.Select(c => c.Id).ToArray();
|
||||
var restoringUserId = ciphers.First().UserId.Value;
|
||||
var previousRevisionDate = DateTime.UtcNow;
|
||||
foreach (var cipher in ciphers)
|
||||
{
|
||||
cipher.Edit = true;
|
||||
cipher.RevisionDate = previousRevisionDate;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<ICipherRepository>().GetManyByUserIdAsync(restoringUserId).Returns(ciphers);
|
||||
var revisionDate = previousRevisionDate + TimeSpan.FromMinutes(1);
|
||||
sutProvider.GetDependency<ICipherRepository>().RestoreAsync(Arg.Any<IEnumerable<Guid>>(), restoringUserId).Returns(revisionDate);
|
||||
|
||||
await sutProvider.Sut.RestoreManyAsync(cipherIds, restoringUserId);
|
||||
|
||||
foreach (var cipher in ciphers)
|
||||
{
|
||||
Assert.Null(cipher.DeletedDate);
|
||||
Assert.Equal(revisionDate, cipher.RevisionDate);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
@ -971,90 +927,14 @@ public class CipherServiceTests
|
||||
.PushSyncCiphersAsync(restoringUserId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task RestoreManyAsync_WithOrgCipherAndEditPermission_RestoresCiphers(
|
||||
Guid restoringUserId, List<CipherDetails> ciphers, Guid organizationId, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var cipherIds = ciphers.Select(c => c.Id).ToArray();
|
||||
var previousRevisionDate = DateTime.UtcNow;
|
||||
|
||||
foreach (var cipher in ciphers)
|
||||
{
|
||||
cipher.OrganizationId = organizationId;
|
||||
cipher.Edit = true;
|
||||
cipher.DeletedDate = DateTime.UtcNow;
|
||||
cipher.RevisionDate = previousRevisionDate;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(restoringUserId)
|
||||
.Returns(ciphers);
|
||||
|
||||
var revisionDate = previousRevisionDate + TimeSpan.FromMinutes(1);
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.RestoreAsync(Arg.Any<IEnumerable<Guid>>(), restoringUserId)
|
||||
.Returns(revisionDate);
|
||||
|
||||
var result = await sutProvider.Sut.RestoreManyAsync(cipherIds, restoringUserId);
|
||||
|
||||
Assert.Equal(ciphers.Count, result.Count);
|
||||
foreach (var cipher in result)
|
||||
{
|
||||
Assert.Null(cipher.DeletedDate);
|
||||
Assert.Equal(revisionDate, cipher.RevisionDate);
|
||||
}
|
||||
|
||||
await sutProvider.GetDependency<ICipherRepository>()
|
||||
.Received(1)
|
||||
.RestoreAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Count() == cipherIds.Count() &&
|
||||
ids.All(id => cipherIds.Contains(id))), restoringUserId);
|
||||
await sutProvider.GetDependency<IEventService>()
|
||||
.Received(1)
|
||||
.LogCipherEventsAsync(Arg.Any<IEnumerable<Tuple<Cipher, EventType, DateTime?>>>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushSyncCiphersAsync(restoringUserId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task RestoreManyAsync_WithOrgCipherLackingEditPermission_DoesNotRestoreCiphers(
|
||||
Guid restoringUserId, List<Cipher> ciphers, Guid organizationId, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var cipherIds = ciphers.Select(c => c.Id).ToArray();
|
||||
var cipherDetailsList = ciphers.Select(c => new CipherDetails
|
||||
{
|
||||
Id = c.Id,
|
||||
OrganizationId = organizationId,
|
||||
Edit = false,
|
||||
DeletedDate = DateTime.UtcNow
|
||||
}).ToList();
|
||||
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(restoringUserId)
|
||||
.Returns(cipherDetailsList);
|
||||
|
||||
var result = await sutProvider.Sut.RestoreManyAsync(cipherIds, restoringUserId);
|
||||
|
||||
Assert.Empty(result);
|
||||
await sutProvider.GetDependency<ICipherRepository>()
|
||||
.Received(1)
|
||||
.RestoreAsync(Arg.Is<IEnumerable<Guid>>(ids => !ids.Any()), restoringUserId);
|
||||
await sutProvider.GetDependency<IEventService>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.LogCipherEventsAsync(Arg.Any<IEnumerable<Tuple<Cipher, EventType, DateTime?>>>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushSyncCiphersAsync(restoringUserId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task RestoreManyAsync_WithLimitItemDeletionEnabled_WithManagePermission_RestoresCiphers(
|
||||
public async Task RestoreManyAsync_WithManagePermission_RestoresCiphers(
|
||||
Guid restoringUserId, List<CipherDetails> ciphers, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var organizationId = Guid.NewGuid();
|
||||
@ -1070,9 +950,6 @@ public class CipherServiceTests
|
||||
cipher.RevisionDate = previousRevisionDate;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(restoringUserId)
|
||||
.Returns(ciphers);
|
||||
@ -1121,7 +998,7 @@ public class CipherServiceTests
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task RestoreManyAsync_WithLimitItemDeletionEnabled_WithoutManagePermission_DoesNotRestoreCiphers(
|
||||
public async Task RestoreManyAsync_WithoutManagePermission_DoesNotRestoreCiphers(
|
||||
Guid restoringUserId, List<CipherDetails> ciphers, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var organizationId = Guid.NewGuid();
|
||||
@ -1135,9 +1012,6 @@ public class CipherServiceTests
|
||||
cipher.DeletedDate = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(restoringUserId)
|
||||
.Returns(ciphers);
|
||||
@ -1502,23 +1376,12 @@ public class CipherServiceTests
|
||||
cipherDetails.UserId = deletingUserId;
|
||||
cipherDetails.OrganizationId = null;
|
||||
|
||||
await sutProvider.Sut.DeleteAsync(cipherDetails, deletingUserId);
|
||||
|
||||
await sutProvider.GetDependency<ICipherRepository>().Received(1).DeleteAsync(cipherDetails);
|
||||
await sutProvider.GetDependency<IAttachmentStorageService>().Received(1).DeleteAttachmentsForCipherAsync(cipherDetails.Id);
|
||||
await sutProvider.GetDependency<IEventService>().Received(1).LogCipherEventAsync(cipherDetails, EventType.Cipher_Deleted);
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(1).PushSyncCipherDeleteAsync(cipherDetails);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task DeleteAsync_WithOrgCipherAndEditPermission_DeletesCipher(
|
||||
Guid deletingUserId, CipherDetails cipherDetails, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetCanEditByIdAsync(deletingUserId, cipherDetails.Id)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(deletingUserId)
|
||||
.Returns(new User
|
||||
{
|
||||
Id = deletingUserId,
|
||||
});
|
||||
|
||||
await sutProvider.Sut.DeleteAsync(cipherDetails, deletingUserId);
|
||||
|
||||
@ -1528,6 +1391,8 @@ public class CipherServiceTests
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(1).PushSyncCipherDeleteAsync(cipherDetails);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task DeleteAsync_WithPersonalCipherBelongingToDifferentUser_ThrowsBadRequestException(
|
||||
@ -1536,25 +1401,12 @@ public class CipherServiceTests
|
||||
cipherDetails.UserId = Guid.NewGuid();
|
||||
cipherDetails.OrganizationId = null;
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||
() => sutProvider.Sut.DeleteAsync(cipherDetails, deletingUserId));
|
||||
|
||||
Assert.Contains("do not have permissions", exception.Message);
|
||||
await sutProvider.GetDependency<ICipherRepository>().DidNotReceiveWithAnyArgs().DeleteAsync(default);
|
||||
await sutProvider.GetDependency<IAttachmentStorageService>().DidNotReceiveWithAnyArgs().DeleteAttachmentsForCipherAsync(default);
|
||||
await sutProvider.GetDependency<IEventService>().DidNotReceiveWithAnyArgs().LogCipherEventAsync(default, default);
|
||||
await sutProvider.GetDependency<IPushNotificationService>().DidNotReceiveWithAnyArgs().PushSyncCipherDeleteAsync(default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task DeleteAsync_WithOrgCipherLackingEditPermission_ThrowsBadRequestException(
|
||||
Guid deletingUserId, CipherDetails cipherDetails, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetCanEditByIdAsync(deletingUserId, cipherDetails.Id)
|
||||
.Returns(false);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(deletingUserId)
|
||||
.Returns(new User
|
||||
{
|
||||
Id = deletingUserId,
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||
() => sutProvider.Sut.DeleteAsync(cipherDetails, deletingUserId));
|
||||
@ -1583,16 +1435,13 @@ public class CipherServiceTests
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task DeleteAsync_WithLimitItemDeletionEnabled_WithManagePermission_DeletesCipher(
|
||||
public async Task DeleteAsync_WithManagePermission_DeletesCipher(
|
||||
Guid deletingUserId, CipherDetails cipherDetails, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
cipherDetails.OrganizationId = Guid.NewGuid();
|
||||
cipherDetails.Edit = false;
|
||||
cipherDetails.Manage = true;
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(deletingUserId)
|
||||
.Returns(user);
|
||||
@ -1615,16 +1464,13 @@ public class CipherServiceTests
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task DeleteAsync_WithLimitItemDeletionEnabled_WithoutManagePermission_ThrowsBadRequestException(
|
||||
public async Task DeleteAsync_WithoutManagePermission_ThrowsBadRequestException(
|
||||
Guid deletingUserId, CipherDetails cipherDetails, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
cipherDetails.OrganizationId = Guid.NewGuid();
|
||||
cipherDetails.Edit = true;
|
||||
cipherDetails.Manage = false;
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(deletingUserId)
|
||||
.Returns(user);
|
||||
@ -1691,6 +1537,12 @@ public class CipherServiceTests
|
||||
cipher.Edit = true;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(deletingUserId)
|
||||
.Returns(new User
|
||||
{
|
||||
Id = deletingUserId,
|
||||
});
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(deletingUserId)
|
||||
.Returns(ciphers);
|
||||
@ -1740,71 +1592,14 @@ public class CipherServiceTests
|
||||
.PushSyncCiphersAsync(deletingUserId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task DeleteManyAsync_WithOrgCipherAndEditPermission_DeletesCiphers(
|
||||
Guid deletingUserId, List<CipherDetails> ciphers, Guid organizationId, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var cipherIds = ciphers.Select(c => c.Id).ToArray();
|
||||
foreach (var cipher in ciphers)
|
||||
{
|
||||
cipher.OrganizationId = organizationId;
|
||||
cipher.Edit = true;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(deletingUserId)
|
||||
.Returns(ciphers);
|
||||
|
||||
await sutProvider.Sut.DeleteManyAsync(cipherIds, deletingUserId, organizationId);
|
||||
|
||||
await sutProvider.GetDependency<ICipherRepository>()
|
||||
.Received(1)
|
||||
.DeleteAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Count() == cipherIds.Count() && ids.All(id => cipherIds.Contains(id))), deletingUserId);
|
||||
await sutProvider.GetDependency<IEventService>()
|
||||
.Received(1)
|
||||
.LogCipherEventsAsync(Arg.Any<IEnumerable<Tuple<Cipher, EventType, DateTime?>>>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushSyncCiphersAsync(deletingUserId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task DeleteManyAsync_WithOrgCipherLackingEditPermission_DoesNotDeleteCiphers(
|
||||
Guid deletingUserId, List<Cipher> ciphers, Guid organizationId, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var cipherIds = ciphers.Select(c => c.Id).ToArray();
|
||||
var cipherDetailsList = ciphers.Select(c => new CipherDetails
|
||||
{
|
||||
Id = c.Id,
|
||||
OrganizationId = organizationId,
|
||||
Edit = false
|
||||
}).ToList();
|
||||
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(deletingUserId)
|
||||
.Returns(cipherDetailsList);
|
||||
|
||||
await sutProvider.Sut.DeleteManyAsync(cipherIds, deletingUserId, organizationId);
|
||||
|
||||
await sutProvider.GetDependency<ICipherRepository>()
|
||||
.Received(1)
|
||||
.DeleteAsync(Arg.Is<IEnumerable<Guid>>(ids => !ids.Any()), deletingUserId);
|
||||
await sutProvider.GetDependency<IEventService>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.LogCipherEventsAsync(Arg.Any<IEnumerable<Tuple<Cipher, EventType, DateTime?>>>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushSyncCiphersAsync(deletingUserId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task DeleteManyAsync_WithLimitItemDeletionEnabled_WithoutManagePermission_DoesNotDeleteCiphers(
|
||||
public async Task DeleteManyAsync_WithoutManagePermission_DoesNotDeleteCiphers(
|
||||
Guid deletingUserId, List<CipherDetails> ciphers, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var organizationId = Guid.NewGuid();
|
||||
@ -1817,9 +1612,6 @@ public class CipherServiceTests
|
||||
cipher.Manage = false;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(deletingUserId)
|
||||
.Returns(ciphers);
|
||||
@ -1855,7 +1647,7 @@ public class CipherServiceTests
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task DeleteManyAsync_WithLimitItemDeletionEnabled_WithManagePermission_DeletesCiphers(
|
||||
public async Task DeleteManyAsync_WithManagePermission_DeletesCiphers(
|
||||
Guid deletingUserId, List<CipherDetails> ciphers, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var organizationId = Guid.NewGuid();
|
||||
@ -1868,9 +1660,6 @@ public class CipherServiceTests
|
||||
cipher.Manage = true;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(deletingUserId)
|
||||
.Returns(ciphers);
|
||||
@ -1913,9 +1702,12 @@ public class CipherServiceTests
|
||||
cipherDetails.OrganizationId = null;
|
||||
cipherDetails.DeletedDate = null;
|
||||
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetCanEditByIdAsync(deletingUserId, cipherDetails.Id)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(deletingUserId)
|
||||
.Returns(new User
|
||||
{
|
||||
Id = deletingUserId,
|
||||
});
|
||||
|
||||
await sutProvider.Sut.SoftDeleteAsync(cipherDetails, deletingUserId);
|
||||
|
||||
@ -1926,26 +1718,7 @@ public class CipherServiceTests
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(1).PushSyncCipherUpdateAsync(cipherDetails, null);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task SoftDeleteAsync_WithOrgCipherAndEditPermission_SoftDeletesCipher(
|
||||
Guid deletingUserId, CipherDetails cipherDetails, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
cipherDetails.DeletedDate = null;
|
||||
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetCanEditByIdAsync(deletingUserId, cipherDetails.Id)
|
||||
.Returns(true);
|
||||
|
||||
await sutProvider.Sut.SoftDeleteAsync(cipherDetails, deletingUserId);
|
||||
|
||||
Assert.NotNull(cipherDetails.DeletedDate);
|
||||
Assert.Equal(cipherDetails.RevisionDate, cipherDetails.DeletedDate);
|
||||
await sutProvider.GetDependency<ICipherRepository>().Received(1).UpsertAsync(cipherDetails);
|
||||
await sutProvider.GetDependency<IEventService>().Received(1).LogCipherEventAsync(cipherDetails, EventType.Cipher_SoftDeleted);
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(1).PushSyncCipherUpdateAsync(cipherDetails, null);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
@ -1955,9 +1728,12 @@ public class CipherServiceTests
|
||||
cipherDetails.UserId = Guid.NewGuid();
|
||||
cipherDetails.OrganizationId = null;
|
||||
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetCanEditByIdAsync(deletingUserId, cipherDetails.Id)
|
||||
.Returns(false);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(deletingUserId)
|
||||
.Returns(new User
|
||||
{
|
||||
Id = deletingUserId,
|
||||
});
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||
() => sutProvider.Sut.SoftDeleteAsync(cipherDetails, deletingUserId));
|
||||
@ -1965,48 +1741,23 @@ public class CipherServiceTests
|
||||
Assert.Contains("do not have permissions", exception.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task SoftDeleteAsync_WithOrgCipherLackingEditPermission_ThrowsBadRequestException(
|
||||
Guid deletingUserId, CipherDetails cipherDetails, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetCanEditByIdAsync(deletingUserId, cipherDetails.Id)
|
||||
.Returns(false);
|
||||
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(
|
||||
() => sutProvider.Sut.SoftDeleteAsync(cipherDetails, deletingUserId));
|
||||
|
||||
Assert.Contains("do not have permissions", exception.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SoftDeleteAsync_WithEditPermission_SoftDeletesCipherDetails(
|
||||
Guid deletingUserId, CipherDetails cipherDetails, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
cipherDetails.DeletedDate = null;
|
||||
|
||||
await sutProvider.Sut.SoftDeleteAsync(cipherDetails, deletingUserId, true);
|
||||
|
||||
Assert.NotNull(cipherDetails.DeletedDate);
|
||||
Assert.Equal(cipherDetails.RevisionDate, cipherDetails.DeletedDate);
|
||||
await sutProvider.GetDependency<ICipherRepository>().Received(1).UpsertAsync(cipherDetails);
|
||||
await sutProvider.GetDependency<IEventService>().Received(1).LogCipherEventAsync(cipherDetails, EventType.Cipher_SoftDeleted);
|
||||
await sutProvider.GetDependency<IPushNotificationService>().Received(1).PushSyncCipherUpdateAsync(cipherDetails, null);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task SoftDeleteAsync_WithAlreadySoftDeletedCipher_SkipsOperation(
|
||||
Guid deletingUserId, CipherDetails cipherDetails, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetCanEditByIdAsync(deletingUserId, cipherDetails.Id)
|
||||
.Returns(true);
|
||||
// Set up as personal cipher owned by the deleting user
|
||||
cipherDetails.UserId = deletingUserId;
|
||||
cipherDetails.OrganizationId = null;
|
||||
cipherDetails.DeletedDate = DateTime.UtcNow.AddDays(-1);
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(deletingUserId)
|
||||
.Returns(new User
|
||||
{
|
||||
Id = deletingUserId,
|
||||
});
|
||||
|
||||
await sutProvider.Sut.SoftDeleteAsync(cipherDetails, deletingUserId);
|
||||
|
||||
await sutProvider.GetDependency<ICipherRepository>().DidNotReceive().UpsertAsync(Arg.Any<Cipher>());
|
||||
@ -2032,7 +1783,7 @@ public class CipherServiceTests
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task SoftDeleteAsync_WithLimitItemDeletionEnabled_WithManagePermission_SoftDeletesCipher(
|
||||
public async Task SoftDeleteAsync_WithManagePermission_SoftDeletesCipher(
|
||||
Guid deletingUserId, CipherDetails cipherDetails, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
cipherDetails.OrganizationId = Guid.NewGuid();
|
||||
@ -2040,9 +1791,6 @@ public class CipherServiceTests
|
||||
cipherDetails.Edit = false;
|
||||
cipherDetails.Manage = true;
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(deletingUserId)
|
||||
.Returns(user);
|
||||
@ -2066,7 +1814,7 @@ public class CipherServiceTests
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task SoftDeleteAsync_WithLimitItemDeletionEnabled_WithoutManagePermission_ThrowsBadRequestException(
|
||||
public async Task SoftDeleteAsync_WithoutManagePermission_ThrowsBadRequestException(
|
||||
Guid deletingUserId, CipherDetails cipherDetails, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
cipherDetails.OrganizationId = Guid.NewGuid();
|
||||
@ -2074,9 +1822,6 @@ public class CipherServiceTests
|
||||
cipherDetails.Edit = true;
|
||||
cipherDetails.Manage = false;
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(deletingUserId)
|
||||
.Returns(user);
|
||||
@ -2143,6 +1888,12 @@ public class CipherServiceTests
|
||||
cipher.DeletedDate = null;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<IUserService>()
|
||||
.GetUserByIdAsync(deletingUserId)
|
||||
.Returns(new User
|
||||
{
|
||||
Id = deletingUserId,
|
||||
});
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(deletingUserId)
|
||||
.Returns(ciphers);
|
||||
@ -2192,72 +1943,14 @@ public class CipherServiceTests
|
||||
.PushSyncCiphersAsync(deletingUserId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task SoftDeleteManyAsync_WithOrgCipherAndEditPermission_SoftDeletesCiphers(
|
||||
Guid deletingUserId, List<CipherDetails> ciphers, Guid organizationId, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var cipherIds = ciphers.Select(c => c.Id).ToArray();
|
||||
foreach (var cipher in ciphers)
|
||||
{
|
||||
cipher.OrganizationId = organizationId;
|
||||
cipher.Edit = true;
|
||||
cipher.DeletedDate = null;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(deletingUserId)
|
||||
.Returns(ciphers);
|
||||
|
||||
await sutProvider.Sut.SoftDeleteManyAsync(cipherIds, deletingUserId, organizationId, false);
|
||||
|
||||
await sutProvider.GetDependency<ICipherRepository>()
|
||||
.Received(1)
|
||||
.SoftDeleteAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Count() == cipherIds.Count() && ids.All(id => cipherIds.Contains(id))), deletingUserId);
|
||||
await sutProvider.GetDependency<IEventService>()
|
||||
.Received(1)
|
||||
.LogCipherEventsAsync(Arg.Any<IEnumerable<Tuple<Cipher, EventType, DateTime?>>>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushSyncCiphersAsync(deletingUserId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task SoftDeleteManyAsync_WithOrgCipherLackingEditPermission_DoesNotDeleteCiphers(
|
||||
Guid deletingUserId, List<Cipher> ciphers, Guid organizationId, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var cipherIds = ciphers.Select(c => c.Id).ToArray();
|
||||
var cipherDetailsList = ciphers.Select(c => new CipherDetails
|
||||
{
|
||||
Id = c.Id,
|
||||
OrganizationId = organizationId,
|
||||
Edit = false
|
||||
}).ToList();
|
||||
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(deletingUserId)
|
||||
.Returns(cipherDetailsList);
|
||||
|
||||
await sutProvider.Sut.SoftDeleteManyAsync(cipherIds, deletingUserId, organizationId, false);
|
||||
|
||||
await sutProvider.GetDependency<ICipherRepository>()
|
||||
.Received(1)
|
||||
.SoftDeleteAsync(Arg.Is<IEnumerable<Guid>>(ids => !ids.Any()), deletingUserId);
|
||||
await sutProvider.GetDependency<IEventService>()
|
||||
.DidNotReceiveWithAnyArgs()
|
||||
.LogCipherEventsAsync(Arg.Any<IEnumerable<Tuple<Cipher, EventType, DateTime?>>>());
|
||||
await sutProvider.GetDependency<IPushNotificationService>()
|
||||
.Received(1)
|
||||
.PushSyncCiphersAsync(deletingUserId);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task SoftDeleteManyAsync_WithLimitItemDeletionEnabled_WithoutManagePermission_DoesNotDeleteCiphers(
|
||||
public async Task SoftDeleteManyAsync_WithoutManagePermission_DoesNotDeleteCiphers(
|
||||
Guid deletingUserId, List<CipherDetails> ciphers, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var organizationId = Guid.NewGuid();
|
||||
@ -2270,9 +1963,6 @@ public class CipherServiceTests
|
||||
cipher.Manage = false;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(deletingUserId)
|
||||
.Returns(ciphers);
|
||||
@ -2308,7 +1998,7 @@ public class CipherServiceTests
|
||||
[Theory]
|
||||
[OrganizationCipherCustomize]
|
||||
[BitAutoData]
|
||||
public async Task SoftDeleteManyAsync_WithLimitItemDeletionEnabled_WithManagePermission_SoftDeletesCiphers(
|
||||
public async Task SoftDeleteManyAsync_WithManagePermission_SoftDeletesCiphers(
|
||||
Guid deletingUserId, List<CipherDetails> ciphers, User user, SutProvider<CipherService> sutProvider)
|
||||
{
|
||||
var organizationId = Guid.NewGuid();
|
||||
@ -2322,9 +2012,6 @@ public class CipherServiceTests
|
||||
cipher.DeletedDate = null;
|
||||
}
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>()
|
||||
.IsEnabled(FeatureFlagKeys.LimitItemDeletion)
|
||||
.Returns(true);
|
||||
sutProvider.GetDependency<ICipherRepository>()
|
||||
.GetManyByUserIdAsync(deletingUserId)
|
||||
.Returns(ciphers);
|
||||
|
Reference in New Issue
Block a user