diff --git a/test/Core.Test/OrganizationFeatures/OrganizationSponsorships/FamiliesForEnterprise/SponsorshipCreation/CreateAdminInitiatedSponsorshipHandlerTests.cs b/test/Core.Test/OrganizationFeatures/OrganizationSponsorships/FamiliesForEnterprise/SponsorshipCreation/CreateAdminInitiatedSponsorshipHandlerTests.cs new file mode 100644 index 0000000000..ee6e64535a --- /dev/null +++ b/test/Core.Test/OrganizationFeatures/OrganizationSponsorships/FamiliesForEnterprise/SponsorshipCreation/CreateAdminInitiatedSponsorshipHandlerTests.cs @@ -0,0 +1,168 @@ +using Bit.Core.AdminConsole.Entities; +using Bit.Core.Billing.Enums; +using Bit.Core.Context; +using Bit.Core.Entities; +using Bit.Core.Enums; +using Bit.Core.Exceptions; +using Bit.Core.Models.Data; +using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.SponsorshipCreation; +using Bit.Core.Services; +using Bit.Test.Common.AutoFixture; +using Bit.Test.Common.AutoFixture.Attributes; +using Bit.Test.Common.Helpers; +using NSubstitute; +using Xunit; + +namespace Bit.Core.Test.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.SponsorshipCreation; + +[SutProviderCustomize] +public class CreateAdminInitiatedSponsorshipHandlerTests : FamiliesForEnterpriseTestsBase +{ + [Theory] + [BitAutoData] + public async Task HandleAsync_MissingManageUsersPermission_ThrowsUnauthorizedException( + Organization sponsoringOrg, OrganizationUser sponsoringOrgUser, string sponsoredEmail, string friendlyName, + Guid currentUserId, SutProvider sutProvider) + { + sponsoringOrg.PlanType = PlanType.EnterpriseAnnually; + sponsoringOrgUser.Status = OrganizationUserStatusType.Confirmed; + + sutProvider.GetDependency() + .IsEnabled(Arg.Is(p => p == FeatureFlagKeys.PM17772_AdminInitiatedSponsorships)) + .Returns(true); + + sutProvider.GetDependency().UserId.Returns(currentUserId); + sutProvider.GetDependency().Organizations.Returns([ + new() + { + Id = sponsoringOrg.Id, + Permissions = new Permissions(), + Type = OrganizationUserType.Admin + } + ]); + + var request = new CreateSponsorshipRequest(sponsoringOrg, sponsoringOrgUser, + PlanSponsorshipType.FamiliesForEnterprise, sponsoredEmail, friendlyName, null); + + var actual = await Assert.ThrowsAsync(async () => + await sutProvider.Sut.HandleAsync(request)); + + Assert.Equal("You do not have permissions to send sponsorships on behalf of the organization.", actual.Message); + } + + [Theory] + [BitAutoData(OrganizationUserType.User)] + public async Task HandleAsync_InvalidUserType_ThrowsUnauthorizedException( + OrganizationUserType organizationUserType, + Organization sponsoringOrg, OrganizationUser sponsoringOrgUser, string sponsoredEmail, + string friendlyName, Guid currentUserId, + SutProvider sutProvider) + { + sponsoringOrg.PlanType = PlanType.EnterpriseAnnually; + sponsoringOrgUser.Status = OrganizationUserStatusType.Confirmed; + + sutProvider.GetDependency() + .IsEnabled(Arg.Is(p => p == FeatureFlagKeys.PM17772_AdminInitiatedSponsorships)) + .Returns(true); + + sutProvider.GetDependency().UserId.Returns(currentUserId); + sutProvider.GetDependency().Organizations.Returns([ + new() + { + Id = sponsoringOrg.Id, + Permissions = new Permissions + { + ManageUsers = true, + }, + Type = organizationUserType + } + ]); + + var request = new CreateSponsorshipRequest(sponsoringOrg, sponsoringOrgUser, + PlanSponsorshipType.FamiliesForEnterprise, sponsoredEmail, friendlyName, null); + + var actual = await Assert.ThrowsAsync(async () => + await sutProvider.Sut.HandleAsync(request)); + + Assert.Equal("You do not have permissions to send sponsorships on behalf of the organization.", actual.Message); + } + + [Theory] + [BitAutoData(OrganizationUserType.Admin)] + [BitAutoData(OrganizationUserType.Custom)] + [BitAutoData(OrganizationUserType.Owner)] + public async Task HandleAsync_CreatesAdminInitiatedSponsorship( + OrganizationUserType organizationUserType, Organization sponsoringOrg, OrganizationUser sponsoringOrgUser, + string sponsoredEmail, string friendlyName, Guid currentUserId, string notes, + SutProvider sutProvider) + { + sponsoringOrg.PlanType = PlanType.EnterpriseAnnually; + sponsoringOrgUser.Status = OrganizationUserStatusType.Confirmed; + + sutProvider.GetDependency() + .IsEnabled(Arg.Is(p => p == FeatureFlagKeys.PM17772_AdminInitiatedSponsorships)) + .Returns(true); + + sutProvider.GetDependency().UserId.Returns(currentUserId); + sutProvider.GetDependency().Organizations.Returns([ + new() + { + Id = sponsoringOrg.Id, + Permissions = new Permissions + { + ManageUsers = true, + }, + Type = organizationUserType + } + ]); + + var request = new CreateSponsorshipRequest(sponsoringOrg, sponsoringOrgUser, + PlanSponsorshipType.FamiliesForEnterprise, sponsoredEmail, friendlyName, notes); + + var actual = await sutProvider.Sut.HandleAsync(request); + + var expectedSponsorship = new OrganizationSponsorship + { + IsAdminInitiated = true, + Notes = notes + }; + + AssertHelper.AssertPropertyEqual(expectedSponsorship, actual); + } + + [Theory] + [BitAutoData] + public async Task HandleAsync_ThrowsBadRequestException_WhenFeatureFlagIsDisabled( + OrganizationUserType organizationUserType, Organization sponsoringOrg, OrganizationUser sponsoringOrgUser, + string sponsoredEmail, string friendlyName, Guid currentUserId, string notes, + SutProvider sutProvider) + { + sponsoringOrg.PlanType = PlanType.EnterpriseAnnually; + sponsoringOrgUser.Status = OrganizationUserStatusType.Confirmed; + + sutProvider.GetDependency() + .IsEnabled(Arg.Is(p => p == FeatureFlagKeys.PM17772_AdminInitiatedSponsorships)) + .Returns(false); + + sutProvider.GetDependency().UserId.Returns(currentUserId); + sutProvider.GetDependency().Organizations.Returns([ + new() + { + Id = sponsoringOrg.Id, + Permissions = new Permissions + { + ManageUsers = true, + }, + Type = organizationUserType + } + ]); + + var request = new CreateSponsorshipRequest(sponsoringOrg, sponsoringOrgUser, + PlanSponsorshipType.FamiliesForEnterprise, sponsoredEmail, friendlyName, notes); + + var actual = await Assert.ThrowsAsync(async () => + await sutProvider.Sut.HandleAsync(request)); + + Assert.Equal("Feature 'pm-17772-admin-initiated-sponsorships' is not enabled.", actual.Message); + } +} diff --git a/test/Core.Test/OrganizationFeatures/OrganizationSponsorships/FamiliesForEnterprise/SponsorshipCreation/CreateSponsorshipHandlerTests.cs b/test/Core.Test/OrganizationFeatures/OrganizationSponsorships/FamiliesForEnterprise/SponsorshipCreation/CreateSponsorshipHandlerTests.cs index a2d8369d35..25dbfbc37d 100644 --- a/test/Core.Test/OrganizationFeatures/OrganizationSponsorships/FamiliesForEnterprise/SponsorshipCreation/CreateSponsorshipHandlerTests.cs +++ b/test/Core.Test/OrganizationFeatures/OrganizationSponsorships/FamiliesForEnterprise/SponsorshipCreation/CreateSponsorshipHandlerTests.cs @@ -46,11 +46,11 @@ public class CreateSponsorshipHandlerTests : FamiliesForEnterpriseTestsBase .CreateAsync(null!); } - public static readonly OrganizationUserStatusType[] _unconfirmedOrganizationUserStatusTypes = Enum + public static readonly OrganizationUserStatusType[] UnconfirmedOrganizationUserStatusTypes = Enum .GetValues() .Where(x => x != OrganizationUserStatusType.Confirmed).ToArray(); - [Theory, BitMemberAutoData(nameof(_unconfirmedOrganizationUserStatusTypes))] + [Theory, BitMemberAutoData(nameof(UnconfirmedOrganizationUserStatusTypes))] public async Task HandleAsync_UnconfirmedSponsoringMember_ThrowsBadRequest( OrganizationUserStatusType sponsoringMemberStatus, Organization sponsoringOrg, OrganizationUser sponsoringOrgUser, string sponsoredEmail, User user, string friendlyName,