From eae9a5d579fa4a61ffcfece21cb76017c7512be5 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Fri, 10 May 2019 15:41:01 +0200 Subject: [PATCH] Reset plan. --- .../Apps/AppGrain.cs | 5 +++ .../Implementations/ConfigAppLimitsPlan.cs | 2 ++ .../NoopAppPlanBillingManager.cs | 2 +- .../Apps/Services/PlanChangedResult.cs | 2 +- .../Apps/Services/PlanResetResult.cs | 13 ++++++++ .../Apps/AppGrainTests.cs | 31 +++++++++++++------ .../Apps/Guards/GuardAppTests.cs | 17 ++++++---- 7 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 src/Squidex.Domain.Apps.Entities/Apps/Services/PlanResetResult.cs diff --git a/src/Squidex.Domain.Apps.Entities/Apps/AppGrain.cs b/src/Squidex.Domain.Apps.Entities/Apps/AppGrain.cs index 194711a93..019171ac7 100644 --- a/src/Squidex.Domain.Apps.Entities/Apps/AppGrain.cs +++ b/src/Squidex.Domain.Apps.Entities/Apps/AppGrain.cs @@ -198,6 +198,11 @@ namespace Squidex.Domain.Apps.Entities.Apps if (result is PlanChangedResult) { + if (result is PlanResetResult) + { + c.PlanId = null; + } + ChangePlan(c); } diff --git a/src/Squidex.Domain.Apps.Entities/Apps/Services/Implementations/ConfigAppLimitsPlan.cs b/src/Squidex.Domain.Apps.Entities/Apps/Services/Implementations/ConfigAppLimitsPlan.cs index 3d568c928..0766a5a45 100644 --- a/src/Squidex.Domain.Apps.Entities/Apps/Services/Implementations/ConfigAppLimitsPlan.cs +++ b/src/Squidex.Domain.Apps.Entities/Apps/Services/Implementations/ConfigAppLimitsPlan.cs @@ -19,6 +19,8 @@ namespace Squidex.Domain.Apps.Entities.Apps.Services.Implementations public string YearlyId { get; set; } + public bool ShouldReset { get; set; } + public long MaxApiCalls { get; set; } public long MaxAssetSize { get; set; } diff --git a/src/Squidex.Domain.Apps.Entities/Apps/Services/Implementations/NoopAppPlanBillingManager.cs b/src/Squidex.Domain.Apps.Entities/Apps/Services/Implementations/NoopAppPlanBillingManager.cs index 2d82d145b..8e968ccc7 100644 --- a/src/Squidex.Domain.Apps.Entities/Apps/Services/Implementations/NoopAppPlanBillingManager.cs +++ b/src/Squidex.Domain.Apps.Entities/Apps/Services/Implementations/NoopAppPlanBillingManager.cs @@ -19,7 +19,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Services.Implementations public Task ChangePlanAsync(string userId, Guid appId, string appName, string planId) { - return Task.FromResult(new PlanChangedResult()); + return Task.FromResult(new PlanResetResult()); } public Task GetPortalLinkAsync(string userId) diff --git a/src/Squidex.Domain.Apps.Entities/Apps/Services/PlanChangedResult.cs b/src/Squidex.Domain.Apps.Entities/Apps/Services/PlanChangedResult.cs index 5361af735..757832981 100644 --- a/src/Squidex.Domain.Apps.Entities/Apps/Services/PlanChangedResult.cs +++ b/src/Squidex.Domain.Apps.Entities/Apps/Services/PlanChangedResult.cs @@ -7,7 +7,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Services { - public sealed class PlanChangedResult : IChangePlanResult + public class PlanChangedResult : IChangePlanResult { } } diff --git a/src/Squidex.Domain.Apps.Entities/Apps/Services/PlanResetResult.cs b/src/Squidex.Domain.Apps.Entities/Apps/Services/PlanResetResult.cs new file mode 100644 index 000000000..f8fd1a57c --- /dev/null +++ b/src/Squidex.Domain.Apps.Entities/Apps/Services/PlanResetResult.cs @@ -0,0 +1,13 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +namespace Squidex.Domain.Apps.Entities.Apps.Services +{ + public class PlanResetResult : PlanChangedResult + { + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppGrainTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppGrainTests.cs index f0cb36d3b..4113ef4cd 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppGrainTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppGrainTests.cs @@ -98,9 +98,6 @@ namespace Squidex.Domain.Apps.Entities.Apps { var command = new ChangePlan { PlanId = planId }; - A.CallTo(() => appPlansProvider.IsConfiguredPlan(planId)) - .Returns(true); - A.CallTo(() => appPlansBillingManager.ChangePlanAsync(User.Identifier, AppId, AppName, planId)) .Returns(new PlanChangedResult()); @@ -119,12 +116,31 @@ namespace Squidex.Domain.Apps.Entities.Apps } [Fact] - public async Task ChangePlan_should_not_make_update_for_redirect_result() + public async Task ChangePlan_should_reset_plan_for_reset_plan() { var command = new ChangePlan { PlanId = planId }; - A.CallTo(() => appPlansProvider.IsConfiguredPlan(planId)) - .Returns(true); + A.CallTo(() => appPlansBillingManager.ChangePlanAsync(User.Identifier, AppId, AppName, planId)) + .Returns(new PlanResetResult()); + + await ExecuteCreateAsync(); + + var result = await sut.ExecuteAsync(CreateCommand(command)); + + Assert.True(result.Value is PlanResetResult); + + Assert.Null(sut.Snapshot.Plan); + + LastEvents + .ShouldHaveSameEvents( + CreateEvent(new AppPlanChanged { PlanId = null }) + ); + } + + [Fact] + public async Task ChangePlan_should_not_make_update_for_redirect_result() + { + var command = new ChangePlan { PlanId = planId }; A.CallTo(() => appPlansBillingManager.ChangePlanAsync(User.Identifier, AppId, AppName, planId)) .Returns(new RedirectToCheckoutResult(new Uri("http://squidex.io"))); @@ -143,9 +159,6 @@ namespace Squidex.Domain.Apps.Entities.Apps { var command = new ChangePlan { PlanId = planId, FromCallback = true }; - A.CallTo(() => appPlansProvider.IsConfiguredPlan(planId)) - .Returns(true); - await ExecuteCreateAsync(); var result = await sut.ExecuteAsync(CreateCommand(command)); diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/Guards/GuardAppTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/Guards/GuardAppTests.cs index b6e750a28..b199c203f 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/Guards/GuardAppTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/Guards/GuardAppTests.cs @@ -20,6 +20,8 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards { private readonly IUserResolver users = A.Fake(); private readonly IAppPlansProvider appPlans = A.Fake(); + private readonly IAppLimitsPlan basicPlan = A.Fake(); + private readonly IAppLimitsPlan freePlan = A.Fake(); public GuardAppTests() { @@ -29,8 +31,11 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards A.CallTo(() => appPlans.GetPlan("notfound")) .Returns(null); + A.CallTo(() => appPlans.GetPlan("basic")) + .Returns(basicPlan); + A.CallTo(() => appPlans.GetPlan("free")) - .Returns(A.Dummy()); + .Returns(freePlan); } [Fact] @@ -75,7 +80,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards [Fact] public void CanChangePlan_should_throw_exception_if_plan_was_configured_from_another_user() { - var command = new ChangePlan { PlanId = "free", Actor = new RefToken("user", "me") }; + var command = new ChangePlan { PlanId = "basic", Actor = new RefToken("user", "me") }; var plan = new AppPlan(new RefToken("user", "other"), "premium"); @@ -86,9 +91,9 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards [Fact] public void CanChangePlan_should_throw_exception_if_plan_is_the_same() { - var command = new ChangePlan { PlanId = "free", Actor = new RefToken("user", "me") }; + var command = new ChangePlan { PlanId = "basic", Actor = new RefToken("user", "me") }; - var plan = new AppPlan(new RefToken("user", "me"), "free"); + var plan = new AppPlan(command.Actor, "basic"); ValidationAssert.Throws(() => GuardApp.CanChangePlan(command, plan, appPlans), new ValidationError("App has already this plan.")); @@ -97,9 +102,9 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards [Fact] public void CanChangePlan_should_not_throw_exception_if_same_user_but_other_plan() { - var command = new ChangePlan { PlanId = "free", Actor = new RefToken("user", "me") }; + var command = new ChangePlan { PlanId = "basic", Actor = new RefToken("user", "me") }; - var plan = new AppPlan(new RefToken("user", "me"), "premium"); + var plan = new AppPlan(command.Actor, "premium"); GuardApp.CanChangePlan(command, plan, appPlans); }