Skip to content

Commit 443557e

Browse files
committed
Add missing tests
1 parent 8057ff5 commit 443557e

File tree

4 files changed

+370
-0
lines changed

4 files changed

+370
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
using Bit.Core.AdminConsole.Entities;
2+
using Bit.Core.AdminConsole.Enums;
3+
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
4+
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.AutoConfirmUser;
5+
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
6+
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
7+
using Bit.Core.Billing.Enums;
8+
using Bit.Core.Entities;
9+
using Bit.Core.Enums;
10+
using Bit.Core.Repositories;
11+
using Bit.Core.Test.AdminConsole.AutoFixture;
12+
using Bit.Core.Test.AutoFixture.OrganizationUserFixtures;
13+
using Bit.Test.Common.AutoFixture;
14+
using Bit.Test.Common.AutoFixture.Attributes;
15+
using NSubstitute;
16+
using Xunit;
17+
using static Bit.Core.AdminConsole.Utilities.v2.Validation.ValidationResultHelpers;
18+
19+
namespace Bit.Core.Test.AdminConsole.OrganizationFeatures.OrganizationUsers.AutoConfirmUser;
20+
21+
[SutProviderCustomize]
22+
public class AutomaticallyConfirmOrganizationUserCommandTests
23+
{
24+
[Theory, BitAutoData]
25+
public async Task AutomaticallyConfirmOrganizationUserAsync_UseMyItemsDisabled_DoesNotCreateCollection(
26+
Organization organization,
27+
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser orgUser,
28+
string key,
29+
string collectionName,
30+
SutProvider<AutomaticallyConfirmOrganizationUserCommand> sutProvider)
31+
{
32+
// Arrange
33+
organization.PlanType = PlanType.EnterpriseAnnually;
34+
organization.UseMyItems = false;
35+
orgUser.OrganizationId = organization.Id;
36+
37+
var request = new AutomaticallyConfirmOrganizationUserRequest
38+
{
39+
OrganizationUserId = orgUser.Id,
40+
OrganizationId = organization.Id,
41+
Key = key,
42+
DefaultUserCollectionName = collectionName,
43+
PerformedBy = null
44+
};
45+
46+
var validationRequest = new AutomaticallyConfirmOrganizationUserValidationRequest
47+
{
48+
OrganizationUserId = orgUser.Id,
49+
OrganizationId = organization.Id,
50+
Key = key,
51+
DefaultUserCollectionName = collectionName,
52+
PerformedBy = null,
53+
OrganizationUser = orgUser,
54+
Organization = organization
55+
};
56+
57+
sutProvider.GetDependency<IOrganizationUserRepository>()
58+
.GetByIdAsync(orgUser.Id)
59+
.Returns(orgUser);
60+
sutProvider.GetDependency<IOrganizationRepository>()
61+
.GetByIdAsync(organization.Id)
62+
.Returns(organization);
63+
sutProvider.GetDependency<IOrganizationUserRepository>()
64+
.ConfirmOrganizationUserAsync(Arg.Any<Bit.Core.AdminConsole.Models.Data.OrganizationUsers.AcceptedOrganizationUserToConfirm>())
65+
.Returns(true);
66+
67+
var policyDetails = new PolicyDetails
68+
{
69+
OrganizationId = organization.Id,
70+
OrganizationUserId = orgUser.Id,
71+
IsProvider = false,
72+
OrganizationUserStatus = orgUser.Status,
73+
OrganizationUserType = orgUser.Type,
74+
PolicyType = PolicyType.OrganizationDataOwnership
75+
};
76+
sutProvider.GetDependency<IPolicyRequirementQuery>()
77+
.GetAsync<OrganizationDataOwnershipPolicyRequirement>(orgUser.UserId!.Value)
78+
.Returns(new OrganizationDataOwnershipPolicyRequirement(OrganizationDataOwnershipState.Enabled, [policyDetails]));
79+
80+
sutProvider.GetDependency<IAutomaticallyConfirmOrganizationUsersValidator>()
81+
.ValidateAsync(Arg.Any<AutomaticallyConfirmOrganizationUserValidationRequest>())
82+
.Returns(Valid(validationRequest));
83+
84+
// Act
85+
await sutProvider.Sut.AutomaticallyConfirmOrganizationUserAsync(request);
86+
87+
// Assert - Collection repository should NOT be called
88+
await sutProvider.GetDependency<ICollectionRepository>()
89+
.DidNotReceive()
90+
.CreateDefaultCollectionsAsync(Arg.Any<Guid>(), Arg.Any<IEnumerable<Guid>>(), Arg.Any<string>());
91+
}
92+
93+
[Theory, BitAutoData]
94+
public async Task AutomaticallyConfirmOrganizationUserAsync_UseMyItemsEnabled_CreatesCollection(
95+
Organization organization,
96+
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser orgUser,
97+
string key,
98+
string collectionName,
99+
SutProvider<AutomaticallyConfirmOrganizationUserCommand> sutProvider)
100+
{
101+
// Arrange
102+
organization.PlanType = PlanType.EnterpriseAnnually;
103+
organization.UseMyItems = true;
104+
orgUser.OrganizationId = organization.Id;
105+
106+
var request = new AutomaticallyConfirmOrganizationUserRequest
107+
{
108+
OrganizationUserId = orgUser.Id,
109+
OrganizationId = organization.Id,
110+
Key = key,
111+
DefaultUserCollectionName = collectionName,
112+
PerformedBy = null
113+
};
114+
115+
var validationRequest = new AutomaticallyConfirmOrganizationUserValidationRequest
116+
{
117+
OrganizationUserId = orgUser.Id,
118+
OrganizationId = organization.Id,
119+
Key = key,
120+
DefaultUserCollectionName = collectionName,
121+
PerformedBy = null,
122+
OrganizationUser = orgUser,
123+
Organization = organization
124+
};
125+
126+
sutProvider.GetDependency<IOrganizationUserRepository>()
127+
.GetByIdAsync(orgUser.Id)
128+
.Returns(orgUser);
129+
sutProvider.GetDependency<IOrganizationRepository>()
130+
.GetByIdAsync(organization.Id)
131+
.Returns(organization);
132+
sutProvider.GetDependency<IOrganizationUserRepository>()
133+
.ConfirmOrganizationUserAsync(Arg.Any<Bit.Core.AdminConsole.Models.Data.OrganizationUsers.AcceptedOrganizationUserToConfirm>())
134+
.Returns(true);
135+
136+
var policyDetails = new PolicyDetails
137+
{
138+
OrganizationId = organization.Id,
139+
OrganizationUserId = orgUser.Id,
140+
IsProvider = false,
141+
OrganizationUserStatus = orgUser.Status,
142+
OrganizationUserType = orgUser.Type,
143+
PolicyType = PolicyType.OrganizationDataOwnership
144+
};
145+
sutProvider.GetDependency<IPolicyRequirementQuery>()
146+
.GetAsync<OrganizationDataOwnershipPolicyRequirement>(orgUser.UserId!.Value)
147+
.Returns(new OrganizationDataOwnershipPolicyRequirement(OrganizationDataOwnershipState.Enabled, [policyDetails]));
148+
149+
sutProvider.GetDependency<IAutomaticallyConfirmOrganizationUsersValidator>()
150+
.ValidateAsync(Arg.Any<AutomaticallyConfirmOrganizationUserValidationRequest>())
151+
.Returns(Valid(validationRequest));
152+
153+
// Act
154+
await sutProvider.Sut.AutomaticallyConfirmOrganizationUserAsync(request);
155+
156+
// Assert - Collection repository should be called
157+
await sutProvider.GetDependency<ICollectionRepository>()
158+
.Received(1)
159+
.CreateDefaultCollectionsAsync(
160+
organization.Id,
161+
Arg.Is<IEnumerable<Guid>>(ids => ids.Single() == orgUser.Id),
162+
collectionName);
163+
}
164+
165+
[Theory, BitAutoData]
166+
public async Task AutomaticallyConfirmOrganizationUserAsync_UseMyItemsEnabled_PolicyDisabled_DoesNotCreateCollection(
167+
Organization organization,
168+
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser orgUser,
169+
string key,
170+
string collectionName,
171+
SutProvider<AutomaticallyConfirmOrganizationUserCommand> sutProvider)
172+
{
173+
// Arrange
174+
organization.PlanType = PlanType.EnterpriseAnnually;
175+
organization.UseMyItems = true;
176+
orgUser.OrganizationId = organization.Id;
177+
178+
var request = new AutomaticallyConfirmOrganizationUserRequest
179+
{
180+
OrganizationUserId = orgUser.Id,
181+
OrganizationId = organization.Id,
182+
Key = key,
183+
DefaultUserCollectionName = collectionName,
184+
PerformedBy = null
185+
};
186+
187+
var validationRequest = new AutomaticallyConfirmOrganizationUserValidationRequest
188+
{
189+
OrganizationUserId = orgUser.Id,
190+
OrganizationId = organization.Id,
191+
Key = key,
192+
DefaultUserCollectionName = collectionName,
193+
PerformedBy = null,
194+
OrganizationUser = orgUser,
195+
Organization = organization
196+
};
197+
198+
sutProvider.GetDependency<IOrganizationUserRepository>()
199+
.GetByIdAsync(orgUser.Id)
200+
.Returns(orgUser);
201+
sutProvider.GetDependency<IOrganizationRepository>()
202+
.GetByIdAsync(organization.Id)
203+
.Returns(organization);
204+
sutProvider.GetDependency<IOrganizationUserRepository>()
205+
.ConfirmOrganizationUserAsync(Arg.Any<Bit.Core.AdminConsole.Models.Data.OrganizationUsers.AcceptedOrganizationUserToConfirm>())
206+
.Returns(true);
207+
208+
// Policy is disabled
209+
sutProvider.GetDependency<IPolicyRequirementQuery>()
210+
.GetAsync<OrganizationDataOwnershipPolicyRequirement>(orgUser.UserId!.Value)
211+
.Returns(new OrganizationDataOwnershipPolicyRequirement(OrganizationDataOwnershipState.Disabled, []));
212+
213+
sutProvider.GetDependency<IAutomaticallyConfirmOrganizationUsersValidator>()
214+
.ValidateAsync(Arg.Any<AutomaticallyConfirmOrganizationUserValidationRequest>())
215+
.Returns(Valid(validationRequest));
216+
217+
// Act
218+
await sutProvider.Sut.AutomaticallyConfirmOrganizationUserAsync(request);
219+
220+
// Assert - Collection repository should NOT be called when policy is disabled
221+
await sutProvider.GetDependency<ICollectionRepository>()
222+
.DidNotReceive()
223+
.CreateDefaultCollectionsAsync(Arg.Any<Guid>(), Arg.Any<IEnumerable<Guid>>(), Arg.Any<string>());
224+
}
225+
}

test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/ConfirmOrganizationUserCommandTests.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,4 +961,46 @@ await sutProvider.GetDependency<ICollectionRepository>()
961961
.DidNotReceive()
962962
.CreateDefaultCollectionsAsync(Arg.Any<Guid>(), Arg.Any<IEnumerable<Guid>>(), Arg.Any<string>());
963963
}
964+
965+
[Theory, BitAutoData]
966+
public async Task ConfirmUsersAsync_UseMyItemsEnabled_CreatesDefaultCollections(
967+
Organization organization, OrganizationUser confirmingUser,
968+
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser orgUser1,
969+
[OrganizationUser(OrganizationUserStatusType.Accepted)] OrganizationUser orgUser2,
970+
User user1, User user2, string key1, string key2, string collectionName,
971+
SutProvider<ConfirmOrganizationUserCommand> sutProvider)
972+
{
973+
// Arrange
974+
organization.PlanType = PlanType.EnterpriseAnnually;
975+
organization.UseMyItems = true;
976+
orgUser1.OrganizationId = confirmingUser.OrganizationId = organization.Id;
977+
orgUser2.OrganizationId = organization.Id;
978+
orgUser1.UserId = user1.Id;
979+
orgUser2.UserId = user2.Id;
980+
981+
var keys = new Dictionary<Guid, string>
982+
{
983+
{ orgUser1.Id, key1 },
984+
{ orgUser2.Id, key2 }
985+
};
986+
987+
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(organization.Id).Returns(organization);
988+
sutProvider.GetDependency<IOrganizationUserRepository>().GetManyAsync(default).ReturnsForAnyArgs(new[] { orgUser1, orgUser2 });
989+
sutProvider.GetDependency<IUserRepository>().GetManyAsync(default).ReturnsForAnyArgs(new[] { user1, user2 });
990+
991+
sutProvider.GetDependency<IPolicyRequirementQuery>()
992+
.GetManyByOrganizationIdAsync<OrganizationDataOwnershipPolicyRequirement>(organization.Id)
993+
.Returns([orgUser1.Id, orgUser2.Id]);
994+
995+
// Act
996+
await sutProvider.Sut.ConfirmUsersAsync(organization.Id, keys, confirmingUser.Id, collectionName);
997+
998+
// Assert - Collection repository should be called with correct parameters
999+
await sutProvider.GetDependency<ICollectionRepository>()
1000+
.Received(1)
1001+
.CreateDefaultCollectionsAsync(
1002+
organization.Id,
1003+
Arg.Is<IEnumerable<Guid>>(ids => ids.Count() == 2 && ids.Contains(orgUser1.Id) && ids.Contains(orgUser2.Id)),
1004+
collectionName);
1005+
}
9641006
}

test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/RestoreUser/RestoreOrganizationUserCommandTests.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1671,5 +1671,65 @@ await sutProvider.GetDependency<ICollectionRepository>()
16711671
.CreateDefaultCollectionsAsync(Arg.Any<Guid>(), Arg.Any<IEnumerable<Guid>>(), Arg.Any<string>());
16721672
}
16731673

1674+
[Theory, BitAutoData]
1675+
public async Task RestoreUsersAsync_UseMyItemsEnabled_CreatesCollections(
1676+
Organization organization,
1677+
[OrganizationUser(type: OrganizationUserType.Owner)] OrganizationUser owner,
1678+
[OrganizationUser(status: OrganizationUserStatusType.Revoked)] OrganizationUser orgUser1,
1679+
[OrganizationUser(status: OrganizationUserStatusType.Revoked)] OrganizationUser orgUser2,
1680+
string collectionName,
1681+
SutProvider<RestoreOrganizationUserCommand> sutProvider)
1682+
{
1683+
// Arrange
1684+
RestoreUser_Setup(organization, owner, orgUser1, sutProvider);
1685+
organization.UseMyItems = true;
1686+
1687+
var organizationUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
1688+
var userService = Substitute.For<IUserService>();
1689+
1690+
sutProvider.GetDependency<IFeatureService>()
1691+
.IsEnabled(FeatureFlagKeys.DefaultUserCollectionRestore)
1692+
.Returns(true);
1693+
1694+
// Both users will restore to Confirmed
1695+
orgUser1.Email = null;
1696+
orgUser1.OrganizationId = organization.Id;
1697+
orgUser2.Email = null;
1698+
orgUser2.OrganizationId = organization.Id;
1699+
1700+
organizationUserRepository
1701+
.GetManyAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(orgUser1.Id) && ids.Contains(orgUser2.Id)))
1702+
.Returns([orgUser1, orgUser2]);
1703+
1704+
// Setup bulk policy query - both users have policy enabled
1705+
sutProvider.GetDependency<IPolicyRequirementQuery>()
1706+
.GetManyByOrganizationIdAsync<OrganizationDataOwnershipPolicyRequirement>(organization.Id)
1707+
.Returns([orgUser1.Id, orgUser2.Id]);
1708+
1709+
sutProvider.GetDependency<ITwoFactorIsEnabledQuery>()
1710+
.TwoFactorIsEnabledAsync(Arg.Any<IEnumerable<Guid>>())
1711+
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>
1712+
{
1713+
(orgUser1.UserId!.Value, true),
1714+
(orgUser2.UserId!.Value, true)
1715+
});
1716+
1717+
// Act
1718+
var result = await sutProvider.Sut.RestoreUsersAsync(
1719+
organization.Id,
1720+
[orgUser1.Id, orgUser2.Id],
1721+
owner.Id,
1722+
userService,
1723+
collectionName);
1724+
1725+
// Assert - Collections should be created for both confirmed users
1726+
await sutProvider.GetDependency<ICollectionRepository>()
1727+
.Received(1)
1728+
.CreateDefaultCollectionsAsync(
1729+
organization.Id,
1730+
Arg.Is<IEnumerable<Guid>>(ids => ids.Count() == 2 && ids.Contains(orgUser1.Id) && ids.Contains(orgUser2.Id)),
1731+
collectionName);
1732+
}
1733+
16741734
#endregion
16751735
}

test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyValidators/OrganizationDataOwnershipPolicyValidatorTests.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,4 +379,47 @@ await sutProvider.GetDependency<ICollectionRepository>()
379379
.DidNotReceiveWithAnyArgs()
380380
.CreateDefaultCollectionsBulkAsync(default, default, default);
381381
}
382+
383+
[Theory]
384+
[BitMemberAutoData(nameof(ShouldUpsertDefaultCollectionsTestCases))]
385+
public async Task ExecuteSideEffectsAsync_UseMyItemsDisabled_DoesNotCreateCollections(
386+
Policy postUpdatedPolicy,
387+
Policy? previousPolicyState,
388+
[PolicyUpdate(PolicyType.OrganizationDataOwnership)] PolicyUpdate policyUpdate,
389+
[OrganizationPolicyDetails(PolicyType.OrganizationDataOwnership)] IEnumerable<OrganizationPolicyDetails> orgPolicyDetails,
390+
OrganizationDataOwnershipPolicyRequirementFactory factory)
391+
{
392+
// Arrange
393+
var orgPolicyDetailsList = orgPolicyDetails.ToList();
394+
foreach (var policyDetail in orgPolicyDetailsList)
395+
{
396+
policyDetail.OrganizationId = policyUpdate.OrganizationId;
397+
}
398+
399+
var policyRepository = ArrangePolicyRepository(orgPolicyDetailsList);
400+
var collectionRepository = Substitute.For<ICollectionRepository>();
401+
402+
// Create a custom application cache service with UseMyItems = false
403+
var applicationCacheService = Substitute.For<IApplicationCacheService>();
404+
applicationCacheService.GetOrganizationAbilityAsync(Arg.Any<Guid>())
405+
.Returns(callInfo => new OrganizationAbility
406+
{
407+
Id = callInfo.Arg<Guid>(),
408+
UseMyItems = false
409+
});
410+
411+
var sut = new OrganizationDataOwnershipPolicyValidator(policyRepository, collectionRepository, applicationCacheService, [factory]);
412+
var policyRequest = new SavePolicyModel(policyUpdate, new OrganizationModelOwnershipPolicyModel(_defaultUserCollectionName));
413+
414+
// Act
415+
await sut.ExecuteSideEffectsAsync(policyRequest, postUpdatedPolicy, previousPolicyState);
416+
417+
// Assert - Should NOT create collections when UseMyItems is disabled
418+
await collectionRepository
419+
.DidNotReceive()
420+
.CreateDefaultCollectionsBulkAsync(
421+
Arg.Any<Guid>(),
422+
Arg.Any<IEnumerable<Guid>>(),
423+
Arg.Any<string>());
424+
}
382425
}

0 commit comments

Comments
 (0)