From 8e7fa98bcf183fad20016b44e9e892fee2caf221 Mon Sep 17 00:00:00 2001 From: Thomas Rittson Date: Fri, 9 May 2025 15:11:10 +1000 Subject: [PATCH] Rewrite using latest utils, add Create test --- .../AdminConsole/OrganizationTestHelpers.cs | 11 +- .../CollectionRepositoryCreateTests.cs | 72 ++++++++++ .../CollectionRepositoryReplaceTests.cs | 124 +++++------------- 3 files changed, 114 insertions(+), 93 deletions(-) create mode 100644 test/Infrastructure.IntegrationTest/AdminConsole/Repositories/CollectionRepository/CollectionRepositoryCreateTests.cs diff --git a/test/Infrastructure.IntegrationTest/AdminConsole/OrganizationTestHelpers.cs b/test/Infrastructure.IntegrationTest/AdminConsole/OrganizationTestHelpers.cs index e631280bb3..144bff9dcb 100644 --- a/test/Infrastructure.IntegrationTest/AdminConsole/OrganizationTestHelpers.cs +++ b/test/Infrastructure.IntegrationTest/AdminConsole/OrganizationTestHelpers.cs @@ -1,5 +1,6 @@ using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Repositories; +using Bit.Core.Billing.Enums; using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Repositories; @@ -26,15 +27,23 @@ public static class OrganizationTestHelpers }); } + /// + /// Creates an Enterprise organization. + /// public static Task CreateTestOrganizationAsync(this IOrganizationRepository organizationRepository, string identifier = "test") => organizationRepository.CreateAsync(new Organization { Name = $"{identifier}-{Guid.NewGuid()}", BillingEmail = "billing@example.com", // TODO: EF does not enforce this being NOT NULL - Plan = "Test", // TODO: EF does not enforce this being NOT NULl + Plan = "Enterprise (Annually)", // TODO: EF does not enforce this being NOT NULl + PlanType = PlanType.EnterpriseAnnually }); + /// + /// Creates a confirmed Owner for the specified organization and user. + /// Does not include any cryptographic material. + /// public static Task CreateTestOrganizationUserAsync( this IOrganizationUserRepository organizationUserRepository, Organization organization, diff --git a/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/CollectionRepository/CollectionRepositoryCreateTests.cs b/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/CollectionRepository/CollectionRepositoryCreateTests.cs new file mode 100644 index 0000000000..1558cd4ed6 --- /dev/null +++ b/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/CollectionRepository/CollectionRepositoryCreateTests.cs @@ -0,0 +1,72 @@ +using Bit.Core.AdminConsole.Repositories; +using Bit.Core.Entities; +using Bit.Core.Models.Data; +using Bit.Core.Repositories; +using Xunit; + +namespace Bit.Infrastructure.IntegrationTest.AdminConsole.Repositories.CollectionRepository; + +public class CollectionRepositoryCreateTests +{ + [DatabaseTheory, DatabaseData] + public async Task CreateAsync_Works( + IUserRepository userRepository, + IOrganizationRepository organizationRepository, + IOrganizationUserRepository organizationUserRepository, + IGroupRepository groupRepository, + ICollectionRepository collectionRepository) + { + // Arrange + var organization = await organizationRepository.CreateTestOrganizationAsync(); + + var user1 = await userRepository.CreateTestUserAsync(); + var orgUser1 = await organizationUserRepository.CreateTestOrganizationUserAsync(organization, user1); + + var user2 = await userRepository.CreateTestUserAsync(); + var orgUser2 = await organizationUserRepository.CreateTestOrganizationUserAsync(organization, user2); + + var group1 = await groupRepository.CreateTestGroupAsync(organization); + var group2 = await groupRepository.CreateTestGroupAsync(organization); + + var collection = new Collection + { + Name = "Test Collection Name", + OrganizationId = organization.Id, + }; + + // Act + await collectionRepository.CreateAsync(collection, + [ + new CollectionAccessSelection { Id = group1.Id, Manage = true, HidePasswords = true, ReadOnly = false, }, + new CollectionAccessSelection { Id = group2.Id, Manage = false, HidePasswords = false, ReadOnly = true, }, + ], + [ + new CollectionAccessSelection { Id = orgUser1.Id, Manage = true, HidePasswords = false, ReadOnly = true }, + new CollectionAccessSelection { Id = orgUser2.Id, Manage = false, HidePasswords = true, ReadOnly = false }, + ] + ); + + // Assert + var (actualCollection, actualAccess) = await collectionRepository.GetByIdWithAccessAsync(collection.Id); + + Assert.NotNull(actualCollection); + Assert.Equal("Test Collection Name", actualCollection.Name); + + var groups = actualAccess.Groups.ToArray(); + Assert.Equal(2, groups.Length); + Assert.Single(groups, g => g.Id == group1.Id && g.Manage && g.HidePasswords && !g.ReadOnly); + Assert.Single(groups, g => g.Id == group2.Id && !g.Manage && !g.HidePasswords && g.ReadOnly); + + var users = actualAccess.Users.ToArray(); + Assert.Equal(2, users.Length); + Assert.Single(users, u => u.Id == orgUser1.Id && u.Manage && !u.HidePasswords && u.ReadOnly); + Assert.Single(users, u => u.Id == orgUser2.Id && !u.Manage && u.HidePasswords && !u.ReadOnly); + + // Clean up data + await userRepository.DeleteAsync(user1); + await userRepository.DeleteAsync(user2); + await organizationRepository.DeleteAsync(organization); + await groupRepository.DeleteManyAsync([group1.Id, group2.Id]); + await organizationUserRepository.DeleteManyAsync([orgUser1.Id, orgUser2.Id]); + } +} diff --git a/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/CollectionRepository/CollectionRepositoryReplaceTests.cs b/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/CollectionRepository/CollectionRepositoryReplaceTests.cs index 20244a3b0a..7512795124 100644 --- a/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/CollectionRepository/CollectionRepositoryReplaceTests.cs +++ b/test/Infrastructure.IntegrationTest/AdminConsole/Repositories/CollectionRepository/CollectionRepositoryReplaceTests.cs @@ -1,8 +1,5 @@ -using Bit.Core.AdminConsole.Entities; -using Bit.Core.AdminConsole.Repositories; -using Bit.Core.Billing.Enums; +using Bit.Core.AdminConsole.Repositories; using Bit.Core.Entities; -using Bit.Core.Enums; using Bit.Core.Models.Data; using Bit.Core.Repositories; using Xunit; @@ -19,60 +16,21 @@ public class CollectionRepositoryReplaceTests IGroupRepository groupRepository, ICollectionRepository collectionRepository) { - var user = await userRepository.CreateAsync(new User - { - Name = "Test User", - Email = $"test+{Guid.NewGuid()}@email.com", - ApiKey = "TEST", - SecurityStamp = "stamp", - }); + // Arrange + var organization = await organizationRepository.CreateTestOrganizationAsync(); - var organization = await organizationRepository.CreateAsync(new Organization - { - Name = "Test Org", - PlanType = PlanType.EnterpriseAnnually, - Plan = "Test Plan", - BillingEmail = "billing@email.com" - }); + var user1 = await userRepository.CreateTestUserAsync(); + var orgUser1 = await organizationUserRepository.CreateTestOrganizationUserAsync(organization, user1); - var orgUser1 = await organizationUserRepository.CreateAsync(new OrganizationUser - { - OrganizationId = organization.Id, - UserId = user.Id, - Status = OrganizationUserStatusType.Confirmed, - }); + var user2 = await userRepository.CreateTestUserAsync(); + var orgUser2 = await organizationUserRepository.CreateTestOrganizationUserAsync(organization, user2); - var orgUser2 = await organizationUserRepository.CreateAsync(new OrganizationUser - { - OrganizationId = organization.Id, - UserId = user.Id, - Status = OrganizationUserStatusType.Confirmed, - }); + var user3 = await userRepository.CreateTestUserAsync(); + var orgUser3 = await organizationUserRepository.CreateTestOrganizationUserAsync(organization, user3); - var orgUser3 = await organizationUserRepository.CreateAsync(new OrganizationUser - { - OrganizationId = organization.Id, - UserId = user.Id, - Status = OrganizationUserStatusType.Confirmed, - }); - - var group1 = await groupRepository.CreateAsync(new Group - { - Name = "Test Group #1", - OrganizationId = organization.Id, - }); - - var group2 = await groupRepository.CreateAsync(new Group - { - Name = "Test Group #2", - OrganizationId = organization.Id, - }); - - var group3 = await groupRepository.CreateAsync(new Group - { - Name = "Test Group #3", - OrganizationId = organization.Id, - }); + var group1 = await groupRepository.CreateTestGroupAsync(organization); + var group2 = await groupRepository.CreateTestGroupAsync(organization); + var group3 = await groupRepository.CreateTestGroupAsync(organization); var collection = new Collection { @@ -91,67 +49,49 @@ public class CollectionRepositoryReplaceTests ] ); + // Act collection.Name = "Updated Collection Name"; await collectionRepository.ReplaceAsync(collection, [ - // Should delete group1 + // Delete group1 + // Update group2: new CollectionAccessSelection { Id = group2.Id, Manage = true, HidePasswords = true, ReadOnly = false, }, - // Should add group3 + // Add group3: new CollectionAccessSelection { Id = group3.Id, Manage = false, HidePasswords = false, ReadOnly = true, }, ], [ - // Should delete orgUser1 + // Delete orgUser1 + // Update orgUser2: new CollectionAccessSelection { Id = orgUser2.Id, Manage = false, HidePasswords = false, ReadOnly = true }, - // Should add orgUser3 + // Add orgUser3: new CollectionAccessSelection { Id = orgUser3.Id, Manage = true, HidePasswords = false, ReadOnly = true }, ] ); - // Assert it - var info = await collectionRepository.GetByIdWithPermissionsAsync(collection.Id, user.Id, true); + // Assert + var (actualCollection, actualAccess) = await collectionRepository.GetByIdWithAccessAsync(collection.Id); - Assert.NotNull(info); - - Assert.Equal("Updated Collection Name", info.Name); - - var groups = info.Groups.ToArray(); + Assert.NotNull(actualCollection); + Assert.Equal("Updated Collection Name", actualCollection.Name); + var groups = actualAccess.Groups.ToArray(); Assert.Equal(2, groups.Length); + Assert.Single(groups, g => g.Id == group2.Id && g.Manage && g.HidePasswords && !g.ReadOnly); + Assert.Single(groups, g => g.Id == group3.Id && !g.Manage && !g.HidePasswords && g.ReadOnly); - var actualGroup2 = Assert.Single(groups.Where(g => g.Id == group2.Id)); - - Assert.True(actualGroup2.Manage); - Assert.True(actualGroup2.HidePasswords); - Assert.False(actualGroup2.ReadOnly); - - var actualGroup3 = Assert.Single(groups.Where(g => g.Id == group3.Id)); - - Assert.False(actualGroup3.Manage); - Assert.False(actualGroup3.HidePasswords); - Assert.True(actualGroup3.ReadOnly); - - var users = info.Users.ToArray(); + var users = actualAccess.Users.ToArray(); Assert.Equal(2, users.Length); - - var actualOrgUser2 = Assert.Single(users.Where(u => u.Id == orgUser2.Id)); - - Assert.False(actualOrgUser2.Manage); - Assert.False(actualOrgUser2.HidePasswords); - Assert.True(actualOrgUser2.ReadOnly); - - var actualOrgUser3 = Assert.Single(users.Where(u => u.Id == orgUser3.Id)); - - Assert.True(actualOrgUser3.Manage); - Assert.False(actualOrgUser3.HidePasswords); - Assert.True(actualOrgUser3.ReadOnly); + Assert.Single(users, u => u.Id == orgUser2.Id && !u.Manage && !u.HidePasswords && u.ReadOnly); + Assert.Single(users, u => u.Id == orgUser3.Id && u.Manage && !u.HidePasswords && u.ReadOnly); // Clean up data - await userRepository.DeleteAsync(user); + await userRepository.DeleteAsync(user1); + await userRepository.DeleteAsync(user2); + await userRepository.DeleteAsync(user3); await organizationRepository.DeleteAsync(organization); await groupRepository.DeleteManyAsync([group1.Id, group2.Id, group3.Id]); await organizationUserRepository.DeleteManyAsync([orgUser1.Id, orgUser2.Id, orgUser3.Id]); } - }