|
| 1 | +using Bit.Core.AdminConsole.Entities; |
| 2 | +using Bit.Core.Entities; |
| 3 | +using Bit.Core.Enums; |
| 4 | +using Bit.Core.Repositories; |
| 5 | +using Xunit; |
| 6 | + |
| 7 | +namespace Bit.Infrastructure.IntegrationTest.AdminConsole.Repositories.CollectionRepository; |
| 8 | + |
| 9 | +/// <summary> |
| 10 | +/// Shared tests for CreateDefaultCollections methods - both bulk and non-bulk implementations, |
| 11 | +/// as they share the same behavior. Both test suites call the tests in this class. |
| 12 | +/// </summary> |
| 13 | +public static class CreateDefaultCollectionsSharedTests |
| 14 | +{ |
| 15 | + public static async Task CreatesDefaultCollections_Success( |
| 16 | + Func<Guid, IEnumerable<Guid>, string, Task> createDefaultCollectionsFunc, |
| 17 | + IOrganizationRepository organizationRepository, |
| 18 | + IUserRepository userRepository, |
| 19 | + IOrganizationUserRepository organizationUserRepository, |
| 20 | + ICollectionRepository collectionRepository) |
| 21 | + { |
| 22 | + // Arrange |
| 23 | + var organization = await organizationRepository.CreateTestOrganizationAsync(); |
| 24 | + |
| 25 | + var resultOrganizationUsers = await Task.WhenAll( |
| 26 | + CreateUserForOrgAsync(userRepository, organizationUserRepository, organization), |
| 27 | + CreateUserForOrgAsync(userRepository, organizationUserRepository, organization) |
| 28 | + ); |
| 29 | + |
| 30 | + var affectedOrgUserIds = resultOrganizationUsers.Select(organizationUser => organizationUser.Id).ToList(); |
| 31 | + var defaultCollectionName = $"default-name-{organization.Id}"; |
| 32 | + |
| 33 | + // Act |
| 34 | + await createDefaultCollectionsFunc(organization.Id, affectedOrgUserIds, defaultCollectionName); |
| 35 | + |
| 36 | + // Assert |
| 37 | + await AssertAllUsersHaveOneDefaultCollectionAsync(collectionRepository, resultOrganizationUsers, organization.Id); |
| 38 | + |
| 39 | + await CleanupAsync(organizationRepository, userRepository, organization, resultOrganizationUsers); |
| 40 | + } |
| 41 | + |
| 42 | + public static async Task CreatesForNewUsersOnly_AndIgnoresExistingUsers( |
| 43 | + Func<Guid, IEnumerable<Guid>, string, Task> createDefaultCollectionsFunc, |
| 44 | + IOrganizationRepository organizationRepository, |
| 45 | + IUserRepository userRepository, |
| 46 | + IOrganizationUserRepository organizationUserRepository, |
| 47 | + ICollectionRepository collectionRepository) |
| 48 | + { |
| 49 | + // Arrange |
| 50 | + var organization = await organizationRepository.CreateTestOrganizationAsync(); |
| 51 | + |
| 52 | + var arrangedOrganizationUsers = await Task.WhenAll( |
| 53 | + CreateUserForOrgAsync(userRepository, organizationUserRepository, organization), |
| 54 | + CreateUserForOrgAsync(userRepository, organizationUserRepository, organization) |
| 55 | + ); |
| 56 | + |
| 57 | + var arrangedOrgUserIds = arrangedOrganizationUsers.Select(organizationUser => organizationUser.Id).ToList(); |
| 58 | + var defaultCollectionName = $"default-name-{organization.Id}"; |
| 59 | + |
| 60 | + await CreateUsersWithExistingDefaultCollectionsAsync(createDefaultCollectionsFunc, collectionRepository, organization.Id, arrangedOrgUserIds, defaultCollectionName, arrangedOrganizationUsers); |
| 61 | + |
| 62 | + var newOrganizationUsers = new List<OrganizationUser> |
| 63 | + { |
| 64 | + await CreateUserForOrgAsync(userRepository, organizationUserRepository, organization) |
| 65 | + }; |
| 66 | + |
| 67 | + var affectedOrgUsers = newOrganizationUsers.Concat(arrangedOrganizationUsers).ToList(); |
| 68 | + var affectedOrgUserIds = affectedOrgUsers.Select(organizationUser => organizationUser.Id).ToList(); |
| 69 | + |
| 70 | + // Act |
| 71 | + await createDefaultCollectionsFunc(organization.Id, affectedOrgUserIds, defaultCollectionName); |
| 72 | + |
| 73 | + // Assert |
| 74 | + await AssertAllUsersHaveOneDefaultCollectionAsync(collectionRepository, affectedOrgUsers, organization.Id); |
| 75 | + |
| 76 | + await CleanupAsync(organizationRepository, userRepository, organization, affectedOrgUsers); |
| 77 | + } |
| 78 | + |
| 79 | + public static async Task IgnoresAllExistingUsers( |
| 80 | + Func<Guid, IEnumerable<Guid>, string, Task> createDefaultCollectionsFunc, |
| 81 | + IOrganizationRepository organizationRepository, |
| 82 | + IUserRepository userRepository, |
| 83 | + IOrganizationUserRepository organizationUserRepository, |
| 84 | + ICollectionRepository collectionRepository) |
| 85 | + { |
| 86 | + // Arrange |
| 87 | + var organization = await organizationRepository.CreateTestOrganizationAsync(); |
| 88 | + |
| 89 | + var resultOrganizationUsers = await Task.WhenAll( |
| 90 | + CreateUserForOrgAsync(userRepository, organizationUserRepository, organization), |
| 91 | + CreateUserForOrgAsync(userRepository, organizationUserRepository, organization) |
| 92 | + ); |
| 93 | + |
| 94 | + var affectedOrgUserIds = resultOrganizationUsers.Select(organizationUser => organizationUser.Id).ToList(); |
| 95 | + var defaultCollectionName = $"default-name-{organization.Id}"; |
| 96 | + |
| 97 | + await CreateUsersWithExistingDefaultCollectionsAsync(createDefaultCollectionsFunc, collectionRepository, organization.Id, affectedOrgUserIds, defaultCollectionName, resultOrganizationUsers); |
| 98 | + |
| 99 | + // Act - Try to create again, should silently filter and not create duplicates |
| 100 | + await createDefaultCollectionsFunc(organization.Id, affectedOrgUserIds, defaultCollectionName); |
| 101 | + |
| 102 | + // Assert - Original collections should remain unchanged, still only one per user |
| 103 | + await AssertAllUsersHaveOneDefaultCollectionAsync(collectionRepository, resultOrganizationUsers, organization.Id); |
| 104 | + |
| 105 | + await CleanupAsync(organizationRepository, userRepository, organization, resultOrganizationUsers); |
| 106 | + } |
| 107 | + |
| 108 | + private static async Task CreateUsersWithExistingDefaultCollectionsAsync( |
| 109 | + Func<Guid, IEnumerable<Guid>, string, Task> createDefaultCollectionsFunc, |
| 110 | + ICollectionRepository collectionRepository, |
| 111 | + Guid organizationId, |
| 112 | + IEnumerable<Guid> affectedOrgUserIds, |
| 113 | + string defaultCollectionName, |
| 114 | + OrganizationUser[] resultOrganizationUsers) |
| 115 | + { |
| 116 | + await createDefaultCollectionsFunc(organizationId, affectedOrgUserIds, defaultCollectionName); |
| 117 | + |
| 118 | + await AssertAllUsersHaveOneDefaultCollectionAsync(collectionRepository, resultOrganizationUsers, organizationId); |
| 119 | + } |
| 120 | + |
| 121 | + private static async Task AssertAllUsersHaveOneDefaultCollectionAsync(ICollectionRepository collectionRepository, |
| 122 | + IEnumerable<OrganizationUser> organizationUsers, Guid organizationId) |
| 123 | + { |
| 124 | + foreach (var organizationUser in organizationUsers) |
| 125 | + { |
| 126 | + var collectionDetails = await collectionRepository.GetManyByUserIdAsync(organizationUser!.UserId.Value); |
| 127 | + var defaultCollection = collectionDetails |
| 128 | + .SingleOrDefault(collectionDetail => |
| 129 | + collectionDetail.OrganizationId == organizationId |
| 130 | + && collectionDetail.Type == CollectionType.DefaultUserCollection); |
| 131 | + |
| 132 | + Assert.NotNull(defaultCollection); |
| 133 | + } |
| 134 | + } |
| 135 | + |
| 136 | + private static async Task<OrganizationUser> CreateUserForOrgAsync(IUserRepository userRepository, |
| 137 | + IOrganizationUserRepository organizationUserRepository, Organization organization) |
| 138 | + { |
| 139 | + var user = await userRepository.CreateTestUserAsync(); |
| 140 | + var orgUser = await organizationUserRepository.CreateTestOrganizationUserAsync(organization, user); |
| 141 | + |
| 142 | + return orgUser; |
| 143 | + } |
| 144 | + |
| 145 | + private static async Task CleanupAsync(IOrganizationRepository organizationRepository, |
| 146 | + IUserRepository userRepository, |
| 147 | + Organization organization, |
| 148 | + IEnumerable<OrganizationUser> organizationUsers) |
| 149 | + { |
| 150 | + await organizationRepository.DeleteAsync(organization); |
| 151 | + |
| 152 | + await userRepository.DeleteManyAsync( |
| 153 | + organizationUsers |
| 154 | + .Where(organizationUser => organizationUser.UserId != null) |
| 155 | + .Select(organizationUser => new User() { Id = organizationUser.UserId.Value }) |
| 156 | + ); |
| 157 | + } |
| 158 | +} |
0 commit comments