mirror of
https://github.com/bitwarden/server.git
synced 2025-07-02 08:32:50 -05:00
[AC-1923] Add endpoint to create client organization (#3977)
* Add new endpoint for creating client organizations in consolidated billing * Create empty org and then assign seats for code re-use * Fixes made from debugging client side * few more small fixes * Vincent's feedback
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
using Bit.Api.Billing.Controllers;
|
||||
using Bit.Api.Billing.Models;
|
||||
using Bit.Api.Billing.Models.Responses;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Billing.Models;
|
||||
using Bit.Core.Billing.Queries;
|
||||
@ -61,7 +61,7 @@ public class ProviderBillingControllerTests
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IProviderBillingQueries>().GetSubscriptionData(providerId).ReturnsNull();
|
||||
sutProvider.GetDependency<IProviderBillingQueries>().GetSubscriptionDTO(providerId).ReturnsNull();
|
||||
|
||||
var result = await sutProvider.Sut.GetSubscriptionAsync(providerId);
|
||||
|
||||
@ -79,7 +79,7 @@ public class ProviderBillingControllerTests
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(true);
|
||||
|
||||
var configuredPlans = new List<ConfiguredProviderPlan>
|
||||
var configuredProviderPlanDTOList = new List<ConfiguredProviderPlanDTO>
|
||||
{
|
||||
new (Guid.NewGuid(), providerId, PlanType.TeamsMonthly, 50, 10, 30),
|
||||
new (Guid.NewGuid(), providerId, PlanType.EnterpriseMonthly, 100, 0, 90)
|
||||
@ -92,25 +92,25 @@ public class ProviderBillingControllerTests
|
||||
Customer = new Customer { Discount = new Discount { Coupon = new Coupon { PercentOff = 10 } } }
|
||||
};
|
||||
|
||||
var providerSubscriptionData = new ProviderSubscriptionData(
|
||||
configuredPlans,
|
||||
var providerSubscriptionDTO = new ProviderSubscriptionDTO(
|
||||
configuredProviderPlanDTOList,
|
||||
subscription);
|
||||
|
||||
sutProvider.GetDependency<IProviderBillingQueries>().GetSubscriptionData(providerId)
|
||||
.Returns(providerSubscriptionData);
|
||||
sutProvider.GetDependency<IProviderBillingQueries>().GetSubscriptionDTO(providerId)
|
||||
.Returns(providerSubscriptionDTO);
|
||||
|
||||
var result = await sutProvider.Sut.GetSubscriptionAsync(providerId);
|
||||
|
||||
Assert.IsType<Ok<ProviderSubscriptionDTO>>(result);
|
||||
Assert.IsType<Ok<ProviderSubscriptionResponse>>(result);
|
||||
|
||||
var providerSubscriptionDTO = ((Ok<ProviderSubscriptionDTO>)result).Value;
|
||||
var providerSubscriptionResponse = ((Ok<ProviderSubscriptionResponse>)result).Value;
|
||||
|
||||
Assert.Equal(providerSubscriptionDTO.Status, subscription.Status);
|
||||
Assert.Equal(providerSubscriptionDTO.CurrentPeriodEndDate, subscription.CurrentPeriodEnd);
|
||||
Assert.Equal(providerSubscriptionDTO.DiscountPercentage, subscription.Customer!.Discount!.Coupon!.PercentOff);
|
||||
Assert.Equal(providerSubscriptionResponse.Status, subscription.Status);
|
||||
Assert.Equal(providerSubscriptionResponse.CurrentPeriodEndDate, subscription.CurrentPeriodEnd);
|
||||
Assert.Equal(providerSubscriptionResponse.DiscountPercentage, subscription.Customer!.Discount!.Coupon!.PercentOff);
|
||||
|
||||
var teamsPlan = StaticStore.GetPlan(PlanType.TeamsMonthly);
|
||||
var providerTeamsPlan = providerSubscriptionDTO.Plans.FirstOrDefault(plan => plan.PlanName == teamsPlan.Name);
|
||||
var providerTeamsPlan = providerSubscriptionResponse.Plans.FirstOrDefault(plan => plan.PlanName == teamsPlan.Name);
|
||||
Assert.NotNull(providerTeamsPlan);
|
||||
Assert.Equal(50, providerTeamsPlan.SeatMinimum);
|
||||
Assert.Equal(10, providerTeamsPlan.PurchasedSeats);
|
||||
@ -119,7 +119,7 @@ public class ProviderBillingControllerTests
|
||||
Assert.Equal("Monthly", providerTeamsPlan.Cadence);
|
||||
|
||||
var enterprisePlan = StaticStore.GetPlan(PlanType.EnterpriseMonthly);
|
||||
var providerEnterprisePlan = providerSubscriptionDTO.Plans.FirstOrDefault(plan => plan.PlanName == enterprisePlan.Name);
|
||||
var providerEnterprisePlan = providerSubscriptionResponse.Plans.FirstOrDefault(plan => plan.PlanName == enterprisePlan.Name);
|
||||
Assert.NotNull(providerEnterprisePlan);
|
||||
Assert.Equal(100, providerEnterprisePlan.SeatMinimum);
|
||||
Assert.Equal(0, providerEnterprisePlan.PurchasedSeats);
|
||||
|
@ -0,0 +1,339 @@
|
||||
using System.Security.Claims;
|
||||
using Bit.Api.Billing.Controllers;
|
||||
using Bit.Api.Billing.Models.Requests;
|
||||
using Bit.Core;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Entities.Provider;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.AdminConsole.Services;
|
||||
using Bit.Core.Billing.Commands;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using NSubstitute;
|
||||
using NSubstitute.ReturnsExtensions;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Api.Test.Billing.Controllers;
|
||||
|
||||
[ControllerCustomize(typeof(ProviderClientsController))]
|
||||
[SutProviderCustomize]
|
||||
public class ProviderClientsControllerTests
|
||||
{
|
||||
#region CreateAsync
|
||||
[Theory, BitAutoData]
|
||||
public async Task CreateAsync_FFDisabled_NotFound(
|
||||
Guid providerId,
|
||||
CreateClientOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(false);
|
||||
|
||||
var result = await sutProvider.Sut.CreateAsync(providerId, requestBody);
|
||||
|
||||
Assert.IsType<NotFound>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task CreateAsync_NoPrincipalUser_Unauthorized(
|
||||
Guid providerId,
|
||||
CreateClientOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).ReturnsNull();
|
||||
|
||||
var result = await sutProvider.Sut.CreateAsync(providerId, requestBody);
|
||||
|
||||
Assert.IsType<UnauthorizedHttpResult>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task CreateAsync_NotProviderAdmin_Unauthorized(
|
||||
Guid providerId,
|
||||
CreateClientOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(new User());
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ManageProviderOrganizations(providerId)
|
||||
.Returns(false);
|
||||
|
||||
var result = await sutProvider.Sut.CreateAsync(providerId, requestBody);
|
||||
|
||||
Assert.IsType<UnauthorizedHttpResult>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task CreateAsync_NoProvider_NotFound(
|
||||
Guid providerId,
|
||||
CreateClientOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(new User());
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ManageProviderOrganizations(providerId)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId)
|
||||
.ReturnsNull();
|
||||
|
||||
var result = await sutProvider.Sut.CreateAsync(providerId, requestBody);
|
||||
|
||||
Assert.IsType<NotFound>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task CreateAsync_MissingClientOrganization_ServerError(
|
||||
Guid providerId,
|
||||
CreateClientOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
var user = new User();
|
||||
|
||||
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(user);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ManageProviderOrganizations(providerId)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId)
|
||||
.Returns(new Provider());
|
||||
|
||||
var clientOrganizationId = Guid.NewGuid();
|
||||
|
||||
sutProvider.GetDependency<IProviderService>().CreateOrganizationAsync(
|
||||
providerId,
|
||||
Arg.Any<OrganizationSignup>(),
|
||||
requestBody.OwnerEmail,
|
||||
user)
|
||||
.Returns(new ProviderOrganization
|
||||
{
|
||||
OrganizationId = clientOrganizationId
|
||||
});
|
||||
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(clientOrganizationId).ReturnsNull();
|
||||
|
||||
var result = await sutProvider.Sut.CreateAsync(providerId, requestBody);
|
||||
|
||||
Assert.IsType<ProblemHttpResult>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task CreateAsync_OK(
|
||||
Guid providerId,
|
||||
CreateClientOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
var user = new User();
|
||||
|
||||
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>())
|
||||
.Returns(user);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ManageProviderOrganizations(providerId)
|
||||
.Returns(true);
|
||||
|
||||
var provider = new Provider();
|
||||
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId)
|
||||
.Returns(provider);
|
||||
|
||||
var clientOrganizationId = Guid.NewGuid();
|
||||
|
||||
sutProvider.GetDependency<IProviderService>().CreateOrganizationAsync(
|
||||
providerId,
|
||||
Arg.Is<OrganizationSignup>(signup =>
|
||||
signup.Name == requestBody.Name &&
|
||||
signup.Plan == requestBody.PlanType &&
|
||||
signup.AdditionalSeats == requestBody.Seats &&
|
||||
signup.OwnerKey == requestBody.Key &&
|
||||
signup.PublicKey == requestBody.KeyPair.PublicKey &&
|
||||
signup.PrivateKey == requestBody.KeyPair.EncryptedPrivateKey &&
|
||||
signup.CollectionName == requestBody.CollectionName),
|
||||
requestBody.OwnerEmail,
|
||||
user)
|
||||
.Returns(new ProviderOrganization
|
||||
{
|
||||
OrganizationId = clientOrganizationId
|
||||
});
|
||||
|
||||
var clientOrganization = new Organization { Id = clientOrganizationId };
|
||||
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(clientOrganizationId)
|
||||
.Returns(clientOrganization);
|
||||
|
||||
var result = await sutProvider.Sut.CreateAsync(providerId, requestBody);
|
||||
|
||||
Assert.IsType<Ok>(result);
|
||||
|
||||
await sutProvider.GetDependency<ICreateCustomerCommand>().Received(1).CreateCustomer(
|
||||
provider,
|
||||
clientOrganization);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UpdateAsync
|
||||
[Theory, BitAutoData]
|
||||
public async Task UpdateAsync_FFDisabled_NotFound(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateClientOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(false);
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
Assert.IsType<NotFound>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task UpdateAsync_NotProviderAdmin_Unauthorized(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateClientOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(false);
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
Assert.IsType<UnauthorizedHttpResult>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task UpdateAsync_NoProvider_NotFound(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateClientOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId)
|
||||
.ReturnsNull();
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
Assert.IsType<NotFound>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task UpdateAsync_NoProviderOrganization_NotFound(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateClientOrganizationRequestBody requestBody,
|
||||
Provider provider,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId)
|
||||
.Returns(provider);
|
||||
|
||||
sutProvider.GetDependency<IProviderOrganizationRepository>().GetByIdAsync(providerOrganizationId)
|
||||
.ReturnsNull();
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
Assert.IsType<NotFound>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task UpdateAsync_NoOrganization_ServerError(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateClientOrganizationRequestBody requestBody,
|
||||
Provider provider,
|
||||
ProviderOrganization providerOrganization,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId)
|
||||
.Returns(provider);
|
||||
|
||||
sutProvider.GetDependency<IProviderOrganizationRepository>().GetByIdAsync(providerOrganizationId)
|
||||
.Returns(providerOrganization);
|
||||
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(providerOrganization.OrganizationId)
|
||||
.ReturnsNull();
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
Assert.IsType<ProblemHttpResult>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task UpdateAsync_NoContent(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateClientOrganizationRequestBody requestBody,
|
||||
Provider provider,
|
||||
ProviderOrganization providerOrganization,
|
||||
Organization organization,
|
||||
SutProvider<ProviderClientsController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId)
|
||||
.Returns(provider);
|
||||
|
||||
sutProvider.GetDependency<IProviderOrganizationRepository>().GetByIdAsync(providerOrganizationId)
|
||||
.Returns(providerOrganization);
|
||||
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(providerOrganization.OrganizationId)
|
||||
.Returns(organization);
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
await sutProvider.GetDependency<IAssignSeatsToClientOrganizationCommand>().Received(1)
|
||||
.AssignSeatsToClientOrganization(
|
||||
provider,
|
||||
organization,
|
||||
requestBody.AssignedSeats);
|
||||
|
||||
Assert.IsType<Ok>(result);
|
||||
}
|
||||
#endregion
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
using Bit.Api.Billing.Controllers;
|
||||
using Bit.Api.Billing.Models;
|
||||
using Bit.Core;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.Billing.Commands;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Infrastructure.EntityFramework.AdminConsole.Models.Provider;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using NSubstitute;
|
||||
using NSubstitute.ReturnsExtensions;
|
||||
using Xunit;
|
||||
using ProviderOrganization = Bit.Core.AdminConsole.Entities.Provider.ProviderOrganization;
|
||||
|
||||
namespace Bit.Api.Test.Billing.Controllers;
|
||||
|
||||
[ControllerCustomize(typeof(ProviderOrganizationController))]
|
||||
[SutProviderCustomize]
|
||||
public class ProviderOrganizationControllerTests
|
||||
{
|
||||
[Theory, BitAutoData]
|
||||
public async Task UpdateAsync_FFDisabled_NotFound(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateProviderOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderOrganizationController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(false);
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
Assert.IsType<NotFound>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionAsync_NotProviderAdmin_Unauthorized(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateProviderOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderOrganizationController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(false);
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
Assert.IsType<UnauthorizedHttpResult>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionAsync_NoProvider_NotFound(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateProviderOrganizationRequestBody requestBody,
|
||||
SutProvider<ProviderOrganizationController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId)
|
||||
.ReturnsNull();
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
Assert.IsType<NotFound>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionAsync_NoProviderOrganization_NotFound(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateProviderOrganizationRequestBody requestBody,
|
||||
Provider provider,
|
||||
SutProvider<ProviderOrganizationController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId)
|
||||
.Returns(provider);
|
||||
|
||||
sutProvider.GetDependency<IProviderOrganizationRepository>().GetByIdAsync(providerOrganizationId)
|
||||
.ReturnsNull();
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
Assert.IsType<NotFound>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionAsync_NoOrganization_ServerError(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateProviderOrganizationRequestBody requestBody,
|
||||
Provider provider,
|
||||
ProviderOrganization providerOrganization,
|
||||
SutProvider<ProviderOrganizationController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId)
|
||||
.Returns(provider);
|
||||
|
||||
sutProvider.GetDependency<IProviderOrganizationRepository>().GetByIdAsync(providerOrganizationId)
|
||||
.Returns(providerOrganization);
|
||||
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(providerOrganization.OrganizationId)
|
||||
.ReturnsNull();
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
Assert.IsType<ProblemHttpResult>(result);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionAsync_NoContent(
|
||||
Guid providerId,
|
||||
Guid providerOrganizationId,
|
||||
UpdateProviderOrganizationRequestBody requestBody,
|
||||
Provider provider,
|
||||
ProviderOrganization providerOrganization,
|
||||
Organization organization,
|
||||
SutProvider<ProviderOrganizationController> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<ICurrentContext>().ProviderProviderAdmin(providerId)
|
||||
.Returns(true);
|
||||
|
||||
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(providerId)
|
||||
.Returns(provider);
|
||||
|
||||
sutProvider.GetDependency<IProviderOrganizationRepository>().GetByIdAsync(providerOrganizationId)
|
||||
.Returns(providerOrganization);
|
||||
|
||||
sutProvider.GetDependency<IOrganizationRepository>().GetByIdAsync(providerOrganization.OrganizationId)
|
||||
.Returns(organization);
|
||||
|
||||
var result = await sutProvider.Sut.UpdateAsync(providerId, providerOrganizationId, requestBody);
|
||||
|
||||
await sutProvider.GetDependency<IAssignSeatsToClientOrganizationCommand>().Received(1)
|
||||
.AssignSeatsToClientOrganization(
|
||||
provider,
|
||||
organization,
|
||||
requestBody.AssignedSeats);
|
||||
|
||||
Assert.IsType<Ok>(result);
|
||||
}
|
||||
}
|
63
test/Api.Test/Utilities/EnumMatchesAttributeTests.cs
Normal file
63
test/Api.Test/Utilities/EnumMatchesAttributeTests.cs
Normal file
@ -0,0 +1,63 @@
|
||||
using Bit.Api.Utilities;
|
||||
using Bit.Core.Enums;
|
||||
using Xunit;
|
||||
|
||||
namespace Bit.Api.Test.Utilities;
|
||||
|
||||
public class EnumMatchesAttributeTests
|
||||
{
|
||||
[Fact]
|
||||
public void IsValid_NullInput_False()
|
||||
{
|
||||
var enumMatchesAttribute =
|
||||
new EnumMatchesAttribute<PlanType>(PlanType.TeamsMonthly, PlanType.EnterpriseMonthly);
|
||||
|
||||
var result = enumMatchesAttribute.IsValid(null);
|
||||
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValid_NullAccepted_False()
|
||||
{
|
||||
var enumMatchesAttribute =
|
||||
new EnumMatchesAttribute<PlanType>();
|
||||
|
||||
var result = enumMatchesAttribute.IsValid(PlanType.TeamsMonthly);
|
||||
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValid_EmptyAccepted_False()
|
||||
{
|
||||
var enumMatchesAttribute =
|
||||
new EnumMatchesAttribute<PlanType>([]);
|
||||
|
||||
var result = enumMatchesAttribute.IsValid(PlanType.TeamsMonthly);
|
||||
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValid_ParseFails_False()
|
||||
{
|
||||
var enumMatchesAttribute =
|
||||
new EnumMatchesAttribute<PlanType>(PlanType.TeamsMonthly, PlanType.EnterpriseMonthly);
|
||||
|
||||
var result = enumMatchesAttribute.IsValid(GatewayType.Stripe);
|
||||
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsValid_Matches_True()
|
||||
{
|
||||
var enumMatchesAttribute =
|
||||
new EnumMatchesAttribute<PlanType>(PlanType.TeamsMonthly, PlanType.EnterpriseMonthly);
|
||||
|
||||
var result = enumMatchesAttribute.IsValid(PlanType.TeamsMonthly);
|
||||
|
||||
Assert.True(result);
|
||||
}
|
||||
}
|
@ -447,6 +447,47 @@ public class OrganizationServiceTests
|
||||
Assert.Contains("You can't subtract Machine Accounts!", exception.Message);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task SignupClientAsync_Succeeds(
|
||||
OrganizationSignup signup,
|
||||
SutProvider<OrganizationService> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.EnableConsolidatedBilling).Returns(true);
|
||||
|
||||
signup.Plan = PlanType.TeamsMonthly;
|
||||
|
||||
var (organization, _, _) = await sutProvider.Sut.SignupClientAsync(signup);
|
||||
|
||||
var plan = StaticStore.GetPlan(signup.Plan);
|
||||
|
||||
await sutProvider.GetDependency<IOrganizationRepository>().Received(1).CreateAsync(Arg.Is<Organization>(org =>
|
||||
org.Id == organization.Id &&
|
||||
org.Name == signup.Name &&
|
||||
org.Plan == plan.Name &&
|
||||
org.PlanType == plan.Type &&
|
||||
org.UsePolicies == plan.HasPolicies &&
|
||||
org.PublicKey == signup.PublicKey &&
|
||||
org.PrivateKey == signup.PrivateKey &&
|
||||
org.UseSecretsManager == false));
|
||||
|
||||
await sutProvider.GetDependency<IOrganizationApiKeyRepository>().Received(1)
|
||||
.CreateAsync(Arg.Is<OrganizationApiKey>(orgApiKey =>
|
||||
orgApiKey.OrganizationId == organization.Id));
|
||||
|
||||
await sutProvider.GetDependency<IApplicationCacheService>().Received(1)
|
||||
.UpsertOrganizationAbilityAsync(organization);
|
||||
|
||||
await sutProvider.GetDependency<IOrganizationUserRepository>().DidNotReceiveWithAnyArgs().CreateAsync(default);
|
||||
|
||||
await sutProvider.GetDependency<ICollectionRepository>().Received(1)
|
||||
.CreateAsync(Arg.Is<Collection>(c => c.Name == signup.CollectionName && c.OrganizationId == organization.Id), null, null);
|
||||
|
||||
await sutProvider.GetDependency<IReferenceEventService>().Received(1).RaiseEventAsync(Arg.Is<ReferenceEvent>(
|
||||
re =>
|
||||
re.Type == ReferenceEventType.Signup &&
|
||||
re.PlanType == plan.Type));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[OrganizationInviteCustomize(InviteeUserType = OrganizationUserType.User,
|
||||
InvitorUserType = OrganizationUserType.Owner), OrganizationCustomize(FlexibleCollections = false), BitAutoData]
|
||||
|
129
test/Core.Test/Billing/Commands/CreateCustomerCommandTests.cs
Normal file
129
test/Core.Test/Billing/Commands/CreateCustomerCommandTests.cs
Normal file
@ -0,0 +1,129 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Entities.Provider;
|
||||
using Bit.Core.Billing.Commands.Implementations;
|
||||
using Bit.Core.Billing.Queries;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using NSubstitute;
|
||||
using Stripe;
|
||||
using Xunit;
|
||||
using GlobalSettings = Bit.Core.Settings.GlobalSettings;
|
||||
|
||||
namespace Bit.Core.Test.Billing.Commands;
|
||||
|
||||
[SutProviderCustomize]
|
||||
public class CreateCustomerCommandTests
|
||||
{
|
||||
private const string _customerId = "customer_id";
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task CreateCustomer_ForClientOrg_ProviderNull_ThrowsArgumentNullException(
|
||||
Organization organization,
|
||||
SutProvider<CreateCustomerCommand> sutProvider) =>
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(() => sutProvider.Sut.CreateCustomer(null, organization));
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task CreateCustomer_ForClientOrg_OrganizationNull_ThrowsArgumentNullException(
|
||||
Provider provider,
|
||||
SutProvider<CreateCustomerCommand> sutProvider) =>
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(() => sutProvider.Sut.CreateCustomer(provider, null));
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task CreateCustomer_ForClientOrg_HasGatewayCustomerId_NoOp(
|
||||
Provider provider,
|
||||
Organization organization,
|
||||
SutProvider<CreateCustomerCommand> sutProvider)
|
||||
{
|
||||
organization.GatewayCustomerId = _customerId;
|
||||
|
||||
await sutProvider.Sut.CreateCustomer(provider, organization);
|
||||
|
||||
await sutProvider.GetDependency<ISubscriberQueries>().DidNotReceiveWithAnyArgs()
|
||||
.GetCustomerOrThrow(Arg.Any<ISubscriber>(), Arg.Any<CustomerGetOptions>());
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task CreateCustomer_ForClientOrg_Succeeds(
|
||||
Provider provider,
|
||||
Organization organization,
|
||||
SutProvider<CreateCustomerCommand> sutProvider)
|
||||
{
|
||||
organization.GatewayCustomerId = null;
|
||||
organization.Name = "Name";
|
||||
organization.BusinessName = "BusinessName";
|
||||
|
||||
var providerCustomer = new Customer
|
||||
{
|
||||
Address = new Address
|
||||
{
|
||||
Country = "USA",
|
||||
PostalCode = "12345",
|
||||
Line1 = "123 Main St.",
|
||||
Line2 = "Unit 4",
|
||||
City = "Fake Town",
|
||||
State = "Fake State"
|
||||
},
|
||||
TaxIds = new StripeList<TaxId>
|
||||
{
|
||||
Data =
|
||||
[
|
||||
new TaxId { Type = "TYPE", Value = "VALUE" }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
sutProvider.GetDependency<ISubscriberQueries>().GetCustomerOrThrow(provider, Arg.Is<CustomerGetOptions>(
|
||||
options => options.Expand.FirstOrDefault() == "tax_ids"))
|
||||
.Returns(providerCustomer);
|
||||
|
||||
sutProvider.GetDependency<IGlobalSettings>().BaseServiceUri
|
||||
.Returns(new GlobalSettings.BaseServiceUriSettings(new GlobalSettings()) { CloudRegion = "US" });
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(
|
||||
options =>
|
||||
options.Address.Country == providerCustomer.Address.Country &&
|
||||
options.Address.PostalCode == providerCustomer.Address.PostalCode &&
|
||||
options.Address.Line1 == providerCustomer.Address.Line1 &&
|
||||
options.Address.Line2 == providerCustomer.Address.Line2 &&
|
||||
options.Address.City == providerCustomer.Address.City &&
|
||||
options.Address.State == providerCustomer.Address.State &&
|
||||
options.Name == organization.DisplayName() &&
|
||||
options.Description == $"{provider.Name} Client Organization" &&
|
||||
options.Email == provider.BillingEmail &&
|
||||
options.InvoiceSettings.CustomFields.FirstOrDefault().Name == "Organization" &&
|
||||
options.InvoiceSettings.CustomFields.FirstOrDefault().Value == "Name" &&
|
||||
options.Metadata["region"] == "US" &&
|
||||
options.TaxIdData.FirstOrDefault().Type == providerCustomer.TaxIds.FirstOrDefault().Type &&
|
||||
options.TaxIdData.FirstOrDefault().Value == providerCustomer.TaxIds.FirstOrDefault().Value))
|
||||
.Returns(new Customer
|
||||
{
|
||||
Id = "customer_id"
|
||||
});
|
||||
|
||||
await sutProvider.Sut.CreateCustomer(provider, organization);
|
||||
|
||||
await sutProvider.GetDependency<IStripeAdapter>().Received(1).CustomerCreateAsync(Arg.Is<CustomerCreateOptions>(
|
||||
options =>
|
||||
options.Address.Country == providerCustomer.Address.Country &&
|
||||
options.Address.PostalCode == providerCustomer.Address.PostalCode &&
|
||||
options.Address.Line1 == providerCustomer.Address.Line1 &&
|
||||
options.Address.Line2 == providerCustomer.Address.Line2 &&
|
||||
options.Address.City == providerCustomer.Address.City &&
|
||||
options.Address.State == providerCustomer.Address.State &&
|
||||
options.Name == organization.DisplayName() &&
|
||||
options.Description == $"{provider.Name} Client Organization" &&
|
||||
options.Email == provider.BillingEmail &&
|
||||
options.InvoiceSettings.CustomFields.FirstOrDefault().Name == "Organization" &&
|
||||
options.InvoiceSettings.CustomFields.FirstOrDefault().Value == "Name" &&
|
||||
options.Metadata["region"] == "US" &&
|
||||
options.TaxIdData.FirstOrDefault().Type == providerCustomer.TaxIds.FirstOrDefault().Type &&
|
||||
options.TaxIdData.FirstOrDefault().Value == providerCustomer.TaxIds.FirstOrDefault().Value));
|
||||
|
||||
await sutProvider.GetDependency<IOrganizationRepository>().Received(1).ReplaceAsync(Arg.Is<Organization>(
|
||||
org => org.GatewayCustomerId == "customer_id"));
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@ public class ProviderBillingQueriesTests
|
||||
|
||||
providerRepository.GetByIdAsync(providerId).ReturnsNull();
|
||||
|
||||
var subscriptionData = await sutProvider.Sut.GetSubscriptionData(providerId);
|
||||
var subscriptionData = await sutProvider.Sut.GetSubscriptionDTO(providerId);
|
||||
|
||||
Assert.Null(subscriptionData);
|
||||
|
||||
@ -50,7 +50,7 @@ public class ProviderBillingQueriesTests
|
||||
|
||||
subscriberQueries.GetSubscription(provider).ReturnsNull();
|
||||
|
||||
var subscriptionData = await sutProvider.Sut.GetSubscriptionData(providerId);
|
||||
var subscriptionData = await sutProvider.Sut.GetSubscriptionDTO(providerId);
|
||||
|
||||
Assert.Null(subscriptionData);
|
||||
|
||||
@ -109,7 +109,7 @@ public class ProviderBillingQueriesTests
|
||||
|
||||
providerPlanRepository.GetByProviderId(providerId).Returns(providerPlans);
|
||||
|
||||
var subscriptionData = await sutProvider.Sut.GetSubscriptionData(providerId);
|
||||
var subscriptionData = await sutProvider.Sut.GetSubscriptionDTO(providerId);
|
||||
|
||||
Assert.NotNull(subscriptionData);
|
||||
|
||||
@ -140,7 +140,7 @@ public class ProviderBillingQueriesTests
|
||||
|
||||
return;
|
||||
|
||||
void Compare(ProviderPlan providerPlan, ConfiguredProviderPlan configuredProviderPlan)
|
||||
void Compare(ProviderPlan providerPlan, ConfiguredProviderPlanDTO configuredProviderPlan)
|
||||
{
|
||||
Assert.NotNull(configuredProviderPlan);
|
||||
Assert.Equal(providerPlan.Id, configuredProviderPlan.Id);
|
||||
|
@ -1,7 +1,5 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Entities.Provider;
|
||||
using Bit.Core.Billing.Queries.Implementations;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Test.Common.AutoFixture;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@ -17,6 +15,56 @@ namespace Bit.Core.Test.Billing.Queries;
|
||||
[SutProviderCustomize]
|
||||
public class SubscriberQueriesTests
|
||||
{
|
||||
#region GetCustomer
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetCustomer_NullSubscriber_ThrowsArgumentNullException(
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
=> await Assert.ThrowsAsync<ArgumentNullException>(
|
||||
async () => await sutProvider.Sut.GetCustomer(null));
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetCustomer_NoGatewayCustomerId_ReturnsNull(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
organization.GatewayCustomerId = null;
|
||||
|
||||
var customer = await sutProvider.Sut.GetCustomer(organization);
|
||||
|
||||
Assert.Null(customer);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetCustomer_NoCustomer_ReturnsNull(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId)
|
||||
.ReturnsNull();
|
||||
|
||||
var customer = await sutProvider.Sut.GetCustomer(organization);
|
||||
|
||||
Assert.Null(customer);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetCustomer_Succeeds(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
var customer = new Customer();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId)
|
||||
.Returns(customer);
|
||||
|
||||
var gotCustomer = await sutProvider.Sut.GetCustomer(organization);
|
||||
|
||||
Assert.Equivalent(customer, gotCustomer);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetSubscription
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscription_NullSubscriber_ThrowsArgumentNullException(
|
||||
@ -25,123 +73,91 @@ public class SubscriberQueriesTests
|
||||
async () => await sutProvider.Sut.GetSubscription(null));
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscription_Organization_NoGatewaySubscriptionId_ReturnsNull(
|
||||
public async Task GetSubscription_NoGatewaySubscriptionId_ReturnsNull(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
organization.GatewaySubscriptionId = null;
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscription(organization);
|
||||
var subscription = await sutProvider.Sut.GetSubscription(organization);
|
||||
|
||||
Assert.Null(gotSubscription);
|
||||
Assert.Null(subscription);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscription_Organization_NoSubscription_ReturnsNull(
|
||||
public async Task GetSubscription_NoSubscription_ReturnsNull(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.ReturnsNull();
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscription(organization);
|
||||
var subscription = await sutProvider.Sut.GetSubscription(organization);
|
||||
|
||||
Assert.Null(gotSubscription);
|
||||
Assert.Null(subscription);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscription_Organization_Succeeds(
|
||||
public async Task GetSubscription_Succeeds(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
var subscription = new Subscription();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscription(organization);
|
||||
|
||||
Assert.Equivalent(subscription, gotSubscription);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetCustomerOrThrow
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetCustomerOrThrow_NullSubscriber_ThrowsArgumentNullException(
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
=> await Assert.ThrowsAsync<ArgumentNullException>(
|
||||
async () => await sutProvider.Sut.GetCustomerOrThrow(null));
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscription_User_NoGatewaySubscriptionId_ReturnsNull(
|
||||
User user,
|
||||
public async Task GetCustomerOrThrow_NoGatewaySubscriptionId_ThrowsGatewayException(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
user.GatewaySubscriptionId = null;
|
||||
organization.GatewayCustomerId = null;
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscription(user);
|
||||
|
||||
Assert.Null(gotSubscription);
|
||||
await ThrowsContactSupportAsync(async () => await sutProvider.Sut.GetCustomerOrThrow(organization));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscription_User_NoSubscription_ReturnsNull(
|
||||
User user,
|
||||
public async Task GetSubscriptionOrThrow_NoCustomer_ThrowsGatewayException(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(user.GatewaySubscriptionId)
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId)
|
||||
.ReturnsNull();
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscription(user);
|
||||
|
||||
Assert.Null(gotSubscription);
|
||||
await ThrowsContactSupportAsync(async () => await sutProvider.Sut.GetCustomerOrThrow(organization));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscription_User_Succeeds(
|
||||
User user,
|
||||
public async Task GetCustomerOrThrow_Succeeds(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
var subscription = new Subscription();
|
||||
var customer = new Customer();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(user.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.CustomerGetAsync(organization.GatewayCustomerId)
|
||||
.Returns(customer);
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscription(user);
|
||||
var gotCustomer = await sutProvider.Sut.GetCustomerOrThrow(organization);
|
||||
|
||||
Assert.Equivalent(subscription, gotSubscription);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscription_Provider_NoGatewaySubscriptionId_ReturnsNull(
|
||||
Provider provider,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
provider.GatewaySubscriptionId = null;
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscription(provider);
|
||||
|
||||
Assert.Null(gotSubscription);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscription_Provider_NoSubscription_ReturnsNull(
|
||||
Provider provider,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(provider.GatewaySubscriptionId)
|
||||
.ReturnsNull();
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscription(provider);
|
||||
|
||||
Assert.Null(gotSubscription);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscription_Provider_Succeeds(
|
||||
Provider provider,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
var subscription = new Subscription();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(provider.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscription(provider);
|
||||
|
||||
Assert.Equivalent(subscription, gotSubscription);
|
||||
Assert.Equivalent(customer, gotCustomer);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -153,7 +169,7 @@ public class SubscriberQueriesTests
|
||||
async () => await sutProvider.Sut.GetSubscriptionOrThrow(null));
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionOrThrow_Organization_NoGatewaySubscriptionId_ThrowsGatewayException(
|
||||
public async Task GetSubscriptionOrThrow_NoGatewaySubscriptionId_ThrowsGatewayException(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
@ -163,101 +179,31 @@ public class SubscriberQueriesTests
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionOrThrow_Organization_NoSubscription_ThrowsGatewayException(
|
||||
public async Task GetSubscriptionOrThrow_NoSubscription_ThrowsGatewayException(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.ReturnsNull();
|
||||
|
||||
await ThrowsContactSupportAsync(async () => await sutProvider.Sut.GetSubscriptionOrThrow(organization));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionOrThrow_Organization_Succeeds(
|
||||
public async Task GetSubscriptionOrThrow_Succeeds(
|
||||
Organization organization,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
var subscription = new Subscription();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
sutProvider.GetDependency<IStripeAdapter>()
|
||||
.SubscriptionGetAsync(organization.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscriptionOrThrow(organization);
|
||||
|
||||
Assert.Equivalent(subscription, gotSubscription);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionOrThrow_User_NoGatewaySubscriptionId_ThrowsGatewayException(
|
||||
User user,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
user.GatewaySubscriptionId = null;
|
||||
|
||||
await ThrowsContactSupportAsync(async () => await sutProvider.Sut.GetSubscriptionOrThrow(user));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionOrThrow_User_NoSubscription_ThrowsGatewayException(
|
||||
User user,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(user.GatewaySubscriptionId)
|
||||
.ReturnsNull();
|
||||
|
||||
await ThrowsContactSupportAsync(async () => await sutProvider.Sut.GetSubscriptionOrThrow(user));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionOrThrow_User_Succeeds(
|
||||
User user,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
var subscription = new Subscription();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(user.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscriptionOrThrow(user);
|
||||
|
||||
Assert.Equivalent(subscription, gotSubscription);
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionOrThrow_Provider_NoGatewaySubscriptionId_ThrowsGatewayException(
|
||||
Provider provider,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
provider.GatewaySubscriptionId = null;
|
||||
|
||||
await ThrowsContactSupportAsync(async () => await sutProvider.Sut.GetSubscriptionOrThrow(provider));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionOrThrow_Provider_NoSubscription_ThrowsGatewayException(
|
||||
Provider provider,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(provider.GatewaySubscriptionId)
|
||||
.ReturnsNull();
|
||||
|
||||
await ThrowsContactSupportAsync(async () => await sutProvider.Sut.GetSubscriptionOrThrow(provider));
|
||||
}
|
||||
|
||||
[Theory, BitAutoData]
|
||||
public async Task GetSubscriptionOrThrow_Provider_Succeeds(
|
||||
Provider provider,
|
||||
SutProvider<SubscriberQueries> sutProvider)
|
||||
{
|
||||
var subscription = new Subscription();
|
||||
|
||||
sutProvider.GetDependency<IStripeAdapter>().SubscriptionGetAsync(provider.GatewaySubscriptionId)
|
||||
.Returns(subscription);
|
||||
|
||||
var gotSubscription = await sutProvider.Sut.GetSubscriptionOrThrow(provider);
|
||||
|
||||
Assert.Equivalent(subscription, gotSubscription);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
Reference in New Issue
Block a user