From f1832e899f0e2653ff19992769f7bcbbfc978b77 Mon Sep 17 00:00:00 2001 From: Matt Gibson Date: Fri, 12 Nov 2021 11:37:13 -0500 Subject: [PATCH] Test org sponsorship service --- .../OrganizationSponsorshipService.cs | 18 +- .../Helpers/BitAutoDataAttributeHelpers.cs | 8 +- .../OrganizationSponsorshipServiceTests.cs | 260 +++++++++++++++++- 3 files changed, 273 insertions(+), 13 deletions(-) diff --git a/src/Core/Services/Implementations/OrganizationSponsorshipService.cs b/src/Core/Services/Implementations/OrganizationSponsorshipService.cs index 8dde09d9e..b3ddc7a40 100644 --- a/src/Core/Services/Implementations/OrganizationSponsorshipService.cs +++ b/src/Core/Services/Implementations/OrganizationSponsorshipService.cs @@ -128,6 +128,11 @@ namespace Bit.Core.Services public async Task ValidateSponsorshipAsync(Guid sponsoredOrganizationId) { var sponsoredOrganization = await _organizationRepository.GetByIdAsync(sponsoredOrganizationId); + if (sponsoredOrganization == null) + { + return false; + } + var existingSponsorship = await _organizationSponsorshipRepository .GetBySponsoredOrganizationIdAsync(sponsoredOrganizationId); @@ -164,12 +169,15 @@ namespace Bit.Core.Services public async Task RemoveSponsorshipAsync(Organization sponsoredOrganization, OrganizationSponsorship sponsorship = null) { - await _paymentService.RemoveOrganizationSponsorshipAsync(sponsoredOrganization, sponsorship); - await _organizationRepository.UpsertAsync(sponsoredOrganization); + if (sponsoredOrganization != null) + { + await _paymentService.RemoveOrganizationSponsorshipAsync(sponsoredOrganization, sponsorship); + await _organizationRepository.UpsertAsync(sponsoredOrganization); - await _mailService.SendFamiliesForEnterpriseSponsorshipRevertingEmailAsync( - sponsoredOrganization.BillingEmailAddress(), - sponsoredOrganization.Name); + await _mailService.SendFamiliesForEnterpriseSponsorshipRevertingEmailAsync( + sponsoredOrganization.BillingEmailAddress(), + sponsoredOrganization.Name); + } if (sponsorship == null) { diff --git a/test/Common/Helpers/BitAutoDataAttributeHelpers.cs b/test/Common/Helpers/BitAutoDataAttributeHelpers.cs index 394a03ed8..635d99671 100644 --- a/test/Common/Helpers/BitAutoDataAttributeHelpers.cs +++ b/test/Common/Helpers/BitAutoDataAttributeHelpers.cs @@ -11,18 +11,18 @@ namespace Bit.Test.Common.Helpers { public static class BitAutoDataAttributeHelpers { - public static IEnumerable GetData(MethodInfo testMethod, IFixture fixture, object[] fixedTestParamters) + public static IEnumerable GetData(MethodInfo testMethod, IFixture fixture, object[] fixedTestParameters) { var methodParameters = testMethod.GetParameters(); var classCustomizations = testMethod.DeclaringType.GetCustomAttributes().Select(attr => attr.GetCustomization()); var methodCustomizations = testMethod.GetCustomAttributes().Select(attr => attr.GetCustomization()); - fixedTestParamters = fixedTestParamters ?? Array.Empty(); + fixedTestParameters = fixedTestParameters ?? Array.Empty(); fixture = ApplyCustomizations(ApplyCustomizations(fixture, classCustomizations), methodCustomizations); - var missingParameters = methodParameters.Skip(fixedTestParamters.Length).Select(p => CustomizeAndCreate(p, fixture)); + var missingParameters = methodParameters.Skip(fixedTestParameters.Length).Select(p => CustomizeAndCreate(p, fixture)); - return new object[1][] { fixedTestParamters.Concat(missingParameters).ToArray() }; + return new object[1][] { fixedTestParameters.Concat(missingParameters).ToArray() }; } public static object CustomizeAndCreate(ParameterInfo p, IFixture fixture) diff --git a/test/Core.Test/Services/OrganizationSponsorshipServiceTests.cs b/test/Core.Test/Services/OrganizationSponsorshipServiceTests.cs index 9e595d312..162cb2a6e 100644 --- a/test/Core.Test/Services/OrganizationSponsorshipServiceTests.cs +++ b/test/Core.Test/Services/OrganizationSponsorshipServiceTests.cs @@ -1,18 +1,18 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Bit.Core.Enums; using Bit.Core.Models.Table; using Bit.Core.Repositories; using Bit.Core.Services; +using Bit.Core.Utilities; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.Helpers; using Microsoft.AspNetCore.DataProtection; -using Microsoft.IdentityModel.Tokens; using NSubstitute; using NSubstitute.ExceptionExtensions; -using NSubstitute.Extensions; using Xunit; namespace Bit.Core.Test.Services @@ -33,6 +33,12 @@ namespace Bit.Core.Test.Services } } + public static IEnumerable EnterprisePlanTypes => + Enum.GetValues().Where(p => StaticStore.GetPlan(p).Product == ProductType.Enterprise).Select(p => new object[] { p }); + + public static IEnumerable NonEnterprisePlanTypes => + Enum.GetValues().Where(p => StaticStore.GetPlan(p).Product != ProductType.Enterprise).Select(p => new object[] { p }); + [Theory] [BitAutoData] public async Task OfferSponsorship_CreatesSponsorship(Organization sponsoringOrg, OrganizationUser sponsoringOrgUser, @@ -104,8 +110,254 @@ namespace Bit.Core.Test.Services .SendFamiliesForEnterpriseOfferEmailAsync(sponsorship.OfferedToEmail, org.Name, Arg.Any()); } - // TODO: test validateSponsorshipAsync + private async Task AssertRemovedSponsoredPaymentAsync(Organization sponsoredOrg, + OrganizationSponsorship sponsorship, SutProvider sutProvider) + { + await sutProvider.GetDependency().Received(1) + .RemoveOrganizationSponsorshipAsync(sponsoredOrg, sponsorship); + await sutProvider.GetDependency().Received(1).UpsertAsync(sponsoredOrg); + await sutProvider.GetDependency().Received(1) + .SendFamiliesForEnterpriseSponsorshipRevertingEmailAsync(sponsoredOrg.BillingEmailAddress(), sponsoredOrg.Name); + } - // TODO: test RemoveSponsorshipAsync + private async Task AssertRemovedSponsorshipAsync(OrganizationSponsorship sponsorship, + SutProvider sutProvider) + { + if (sponsorship.CloudSponsor || sponsorship.SponsorshipLapsedDate.HasValue) + { + await sutProvider.GetDependency().Received(1) + .DeleteAsync(sponsorship); + } + else + { + await sutProvider.GetDependency().Received(1) + .UpsertAsync(sponsorship); + } + } + + private static async Task AssertDidNotRemoveSponsoredPaymentAsync(SutProvider sutProvider) + { + await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() + .RemoveOrganizationSponsorshipAsync(default, default); + await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() + .UpsertAsync(default); + await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() + .SendFamiliesForEnterpriseSponsorshipRevertingEmailAsync(default, default); + } + + private static async Task AssertDidNotRemoveSponsorshipAsync(SutProvider sutProvider) + { + await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() + .DeleteAsync(default); + await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() + .UpsertAsync(default); + } + + [Theory] + [BitAutoData] + public async Task ValidateSponsorshipAsync_NoSponsoredOrg_EarlyReturn(Guid sponsoredOrgId, + SutProvider sutProvider) + { + sutProvider.GetDependency().GetByIdAsync(sponsoredOrgId).Returns((Organization)null); + + var result = await sutProvider.Sut.ValidateSponsorshipAsync(sponsoredOrgId); + + Assert.False(result); + await AssertDidNotRemoveSponsoredPaymentAsync(sutProvider); + await AssertDidNotRemoveSponsorshipAsync(sutProvider); + } + + [Theory] + [BitAutoData] + public async Task ValidateSponsorshipAsync_NoExistingSponsorship_UpdatesStripePlan(Organization sponsoredOrg, + SutProvider sutProvider) + { + sutProvider.GetDependency().GetByIdAsync(sponsoredOrg.Id).Returns(sponsoredOrg); + + var result = await sutProvider.Sut.ValidateSponsorshipAsync(sponsoredOrg.Id); + + Assert.False(result); + await AssertRemovedSponsoredPaymentAsync(sponsoredOrg, null, sutProvider); + } + + [Theory] + [BitAutoData] + public async Task ValidateSponsorshipAsync_SponsoringOrgNull_UpdatesStripePlan(Organization sponsoredOrg, + OrganizationSponsorship existingSponsorship, SutProvider sutProvider) + { + existingSponsorship.SponsoringOrganizationId = null; + + sutProvider.GetDependency() + .GetBySponsoredOrganizationIdAsync(sponsoredOrg.Id).Returns(existingSponsorship); + sutProvider.GetDependency().GetByIdAsync(sponsoredOrg.Id).Returns(sponsoredOrg); + + var result = await sutProvider.Sut.ValidateSponsorshipAsync(sponsoredOrg.Id); + + Assert.False(result); + await AssertRemovedSponsoredPaymentAsync(sponsoredOrg, existingSponsorship, sutProvider); + await AssertRemovedSponsorshipAsync(existingSponsorship, sutProvider); + } + + [Theory] + [BitAutoData] + public async Task ValidateSponsorshipAsync_SponsoringOrgUserNull_UpdatesStripePlan(Organization sponsoredOrg, + OrganizationSponsorship existingSponsorship, SutProvider sutProvider) + { + existingSponsorship.SponsoringOrganizationUserId = null; + + sutProvider.GetDependency() + .GetBySponsoredOrganizationIdAsync(sponsoredOrg.Id).Returns(existingSponsorship); + sutProvider.GetDependency().GetByIdAsync(sponsoredOrg.Id).Returns(sponsoredOrg); + + var result = await sutProvider.Sut.ValidateSponsorshipAsync(sponsoredOrg.Id); + + Assert.False(result); + await AssertRemovedSponsoredPaymentAsync(sponsoredOrg, existingSponsorship, sutProvider); + await AssertRemovedSponsorshipAsync(existingSponsorship, sutProvider); + } + + [Theory] + [BitAutoData] + public async Task ValidateSponsorshipAsync_SponsorshipTypeNull_UpdatesStripePlan(Organization sponsoredOrg, + OrganizationSponsorship existingSponsorship, SutProvider sutProvider) + { + existingSponsorship.PlanSponsorshipType = null; + + sutProvider.GetDependency() + .GetBySponsoredOrganizationIdAsync(sponsoredOrg.Id).Returns(existingSponsorship); + sutProvider.GetDependency().GetByIdAsync(sponsoredOrg.Id).Returns(sponsoredOrg); + + var result = await sutProvider.Sut.ValidateSponsorshipAsync(sponsoredOrg.Id); + + Assert.False(result); + await AssertRemovedSponsoredPaymentAsync(sponsoredOrg, existingSponsorship, sutProvider); + await AssertRemovedSponsorshipAsync(existingSponsorship, sutProvider); + } + + [Theory] + [BitAutoData] + public async Task ValidateSponsorshipAsync_SponsoringOrgNotFound_UpdatesStripePlan(Organization sponsoredOrg, + OrganizationSponsorship existingSponsorship, SutProvider sutProvider) + { + sutProvider.GetDependency() + .GetBySponsoredOrganizationIdAsync(sponsoredOrg.Id).Returns(existingSponsorship); + sutProvider.GetDependency().GetByIdAsync(sponsoredOrg.Id).Returns(sponsoredOrg); + + var result = await sutProvider.Sut.ValidateSponsorshipAsync(sponsoredOrg.Id); + + Assert.False(result); + await AssertRemovedSponsoredPaymentAsync(sponsoredOrg, existingSponsorship, sutProvider); + await AssertRemovedSponsorshipAsync(existingSponsorship, sutProvider); + } + + [Theory] + [BitMemberAutoData(nameof(NonEnterprisePlanTypes))] + public async Task ValidateSponsorshipAsync_SponsoringOrgNotEnterprise_UpdatesStripePlan(PlanType planType, + Organization sponsoredOrg, OrganizationSponsorship existingSponsorship, Organization sponsoringOrg, + SutProvider sutProvider) + { + sponsoringOrg.PlanType = planType; + existingSponsorship.SponsoringOrganizationId = sponsoringOrg.Id; + + sutProvider.GetDependency() + .GetBySponsoredOrganizationIdAsync(sponsoredOrg.Id).Returns(existingSponsorship); + sutProvider.GetDependency().GetByIdAsync(sponsoredOrg.Id).Returns(sponsoredOrg); + sutProvider.GetDependency().GetByIdAsync(sponsoringOrg.Id).Returns(sponsoringOrg); + + var result = await sutProvider.Sut.ValidateSponsorshipAsync(sponsoredOrg.Id); + + Assert.False(result); + await AssertRemovedSponsoredPaymentAsync(sponsoredOrg, existingSponsorship, sutProvider); + await AssertRemovedSponsorshipAsync(existingSponsorship, sutProvider); + } + + [Theory] + [BitMemberAutoData(nameof(EnterprisePlanTypes))] + public async Task ValidateSponsorshipAsync_SponsoringOrgDisabled_UpdatesStripePlan(PlanType planType, + Organization sponsoredOrg, OrganizationSponsorship existingSponsorship, Organization sponsoringOrg, + SutProvider sutProvider) + { + sponsoringOrg.PlanType = planType; + sponsoringOrg.Enabled = false; + existingSponsorship.SponsoringOrganizationId = sponsoringOrg.Id; + + sutProvider.GetDependency() + .GetBySponsoredOrganizationIdAsync(sponsoredOrg.Id).Returns(existingSponsorship); + sutProvider.GetDependency().GetByIdAsync(sponsoredOrg.Id).Returns(sponsoredOrg); + sutProvider.GetDependency().GetByIdAsync(sponsoringOrg.Id).Returns(sponsoringOrg); + + var result = await sutProvider.Sut.ValidateSponsorshipAsync(sponsoredOrg.Id); + + Assert.False(result); + await AssertRemovedSponsoredPaymentAsync(sponsoredOrg, existingSponsorship, sutProvider); + await AssertRemovedSponsorshipAsync(existingSponsorship, sutProvider); + } + + [Theory] + [BitMemberAutoData(nameof(EnterprisePlanTypes))] + public async Task ValidateSponsorshipAsync_Valid(PlanType planType, + Organization sponsoredOrg, OrganizationSponsorship existingSponsorship, Organization sponsoringOrg, + SutProvider sutProvider) + { + sponsoringOrg.PlanType = planType; + sponsoringOrg.Enabled = true; + existingSponsorship.SponsoringOrganizationId = sponsoringOrg.Id; + + sutProvider.GetDependency() + .GetBySponsoredOrganizationIdAsync(sponsoredOrg.Id).Returns(existingSponsorship); + sutProvider.GetDependency().GetByIdAsync(sponsoredOrg.Id).Returns(sponsoredOrg); + sutProvider.GetDependency().GetByIdAsync(sponsoringOrg.Id).Returns(sponsoringOrg); + + var result = await sutProvider.Sut.ValidateSponsorshipAsync(sponsoredOrg.Id); + + Assert.True(result); + + await AssertDidNotRemoveSponsoredPaymentAsync(sutProvider); + await AssertDidNotRemoveSponsorshipAsync(sutProvider); + } + + + [Theory] + [BitAutoData] + public async Task RemoveSponsorshipAsync_NullDoNothing(SutProvider sutProvider) + { + await sutProvider.Sut.RemoveSponsorshipAsync(null, null); + + await AssertDidNotRemoveSponsoredPaymentAsync(sutProvider); + await AssertDidNotRemoveSponsorshipAsync(sutProvider); + } + + [Theory] + [BitAutoData] + public async Task RemoveSponsorshipAsync_NullSponsoredOrg(OrganizationSponsorship sponsorship, + SutProvider sutProvider) + { + await sutProvider.Sut.RemoveSponsorshipAsync(null, sponsorship); + + await AssertDidNotRemoveSponsoredPaymentAsync(sutProvider); + await AssertRemovedSponsorshipAsync(sponsorship, sutProvider); + } + + [Theory] + [BitAutoData] + public async Task RemoveSponsorshipAsync_NullSponsorship(Organization sponsoredOrg, + SutProvider sutProvider) + { + await sutProvider.Sut.RemoveSponsorshipAsync(sponsoredOrg, null); + + await AssertRemovedSponsoredPaymentAsync(sponsoredOrg, null, sutProvider); + await AssertDidNotRemoveSponsorshipAsync(sutProvider); + } + + [Theory] + [BitAutoData] + public async Task RemoveSponsorshipAsync_RemoveBoth(Organization sponsoredOrg, + OrganizationSponsorship sponsorship, SutProvider sutProvider) + { + await sutProvider.Sut.RemoveSponsorshipAsync(sponsoredOrg, sponsorship); + + await AssertRemovedSponsoredPaymentAsync(sponsoredOrg, sponsorship, sutProvider); + await AssertRemovedSponsorshipAsync(sponsorship, sutProvider); + } } }