From 097cbbeaae52894e46865a25c105e44f016e382b Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Fri, 15 Dec 2017 14:28:57 -0500 Subject: [PATCH] Add new Quay pricing plans --- data/billing.py | 154 +++++++++++++++++++++++++++++++++-------- test/test_api_usage.py | 14 ++-- 2 files changed, 133 insertions(+), 35 deletions(-) diff --git a/data/billing.py b/data/billing.py index 17444a4d9..23702f67b 100644 --- a/data/billing.py +++ b/data/billing.py @@ -6,7 +6,7 @@ from calendar import timegm from util.morecollections import AttrDict PLANS = [ - # Deprecated Plans + # Deprecated Plans (2013-2014) { 'title': 'Micro', 'price': 700, @@ -16,7 +16,7 @@ PLANS = [ 'bus_features': False, 'deprecated': True, 'free_trial_days': 14, - 'superseded_by': None, + 'superseded_by': 'personal-30', 'plans_page_hidden': False, }, { @@ -28,7 +28,7 @@ PLANS = [ 'bus_features': False, 'deprecated': True, 'free_trial_days': 14, - 'superseded_by': None, + 'superseded_by': 'bus-micro-30', 'plans_page_hidden': False, }, { @@ -104,7 +104,105 @@ PLANS = [ 'plans_page_hidden': False, }, - # Active plans + # Deprecated plans (2014-2017) + { + 'title': 'Personal', + 'price': 1200, + 'privateRepos': 5, + 'stripeId': 'personal-30', + 'audience': 'Individuals', + 'bus_features': False, + 'deprecated': True, + 'free_trial_days': 30, + 'superseded_by': 'personal-2018', + 'plans_page_hidden': False, + }, + { + 'title': 'Skiff', + 'price': 2500, + 'privateRepos': 10, + 'stripeId': 'bus-micro-30', + 'audience': 'For startups', + 'bus_features': True, + 'deprecated': True, + 'free_trial_days': 30, + 'superseded_by': 'bus-micro-2018', + 'plans_page_hidden': False, + }, + { + 'title': 'Yacht', + 'price': 5000, + 'privateRepos': 20, + 'stripeId': 'bus-small-30', + 'audience': 'For small businesses', + 'bus_features': True, + 'deprecated': True, + 'free_trial_days': 30, + 'superseded_by': 'bus-small-2018', + 'plans_page_hidden': False, + }, + { + 'title': 'Freighter', + 'price': 10000, + 'privateRepos': 50, + 'stripeId': 'bus-medium-30', + 'audience': 'For normal businesses', + 'bus_features': True, + 'deprecated': True, + 'free_trial_days': 30, + 'superseded_by': 'bus-medium-2018', + 'plans_page_hidden': False, + }, + { + 'title': 'Tanker', + 'price': 20000, + 'privateRepos': 125, + 'stripeId': 'bus-large-30', + 'audience': 'For large businesses', + 'bus_features': True, + 'deprecated': True, + 'free_trial_days': 30, + 'superseded_by': 'bus-large-2018', + 'plans_page_hidden': False, + }, + { + 'title': 'Carrier', + 'price': 35000, + 'privateRepos': 250, + 'stripeId': 'bus-xlarge-30', + 'audience': 'For extra large businesses', + 'bus_features': True, + 'deprecated': True, + 'free_trial_days': 30, + 'superseded_by': 'bus-xlarge-2018', + 'plans_page_hidden': False, + }, + { + 'title': 'Huge', + 'price': 65000, + 'privateRepos': 500, + 'stripeId': 'bus-500-30', + 'audience': 'For huge business', + 'bus_features': True, + 'deprecated': True, + 'free_trial_days': 30, + 'superseded_by': 'bus-500-2018', + 'plans_page_hidden': False, + }, + { + 'title': 'Huuge', + 'price': 120000, + 'privateRepos': 1000, + 'stripeId': 'bus-1000-30', + 'audience': 'For the SaaS savvy enterprise', + 'bus_features': True, + 'deprecated': True, + 'free_trial_days': 30, + 'superseded_by': 'bus-1000-2018', + 'plans_page_hidden': False, + }, + + # Active plans (as of Dec 2017) { 'title': 'Open Source', 'price': 0, @@ -118,10 +216,10 @@ PLANS = [ 'plans_page_hidden': False, }, { - 'title': 'Personal', - 'price': 1200, + 'title': 'Developer', + 'price': 1500, 'privateRepos': 5, - 'stripeId': 'personal-30', + 'stripeId': 'personal-2018', 'audience': 'Individuals', 'bus_features': False, 'deprecated': False, @@ -130,10 +228,10 @@ PLANS = [ 'plans_page_hidden': False, }, { - 'title': 'Skiff', - 'price': 2500, + 'title': 'Micro', + 'price': 3000, 'privateRepos': 10, - 'stripeId': 'bus-micro-30', + 'stripeId': 'bus-micro-2018', 'audience': 'For startups', 'bus_features': True, 'deprecated': False, @@ -142,10 +240,10 @@ PLANS = [ 'plans_page_hidden': False, }, { - 'title': 'Yacht', - 'price': 5000, + 'title': 'Small', + 'price': 6000, 'privateRepos': 20, - 'stripeId': 'bus-small-30', + 'stripeId': 'bus-small-2018', 'audience': 'For small businesses', 'bus_features': True, 'deprecated': False, @@ -154,10 +252,10 @@ PLANS = [ 'plans_page_hidden': False, }, { - 'title': 'Freighter', - 'price': 10000, + 'title': 'Medium', + 'price': 12500, 'privateRepos': 50, - 'stripeId': 'bus-medium-30', + 'stripeId': 'bus-medium-2018', 'audience': 'For normal businesses', 'bus_features': True, 'deprecated': False, @@ -166,10 +264,10 @@ PLANS = [ 'plans_page_hidden': False, }, { - 'title': 'Tanker', - 'price': 20000, + 'title': 'Large', + 'price': 25000, 'privateRepos': 125, - 'stripeId': 'bus-large-30', + 'stripeId': 'bus-large-2018', 'audience': 'For large businesses', 'bus_features': True, 'deprecated': False, @@ -178,10 +276,10 @@ PLANS = [ 'plans_page_hidden': False, }, { - 'title': 'Carrier', - 'price': 35000, + 'title': 'Extra Large', + 'price': 45000, 'privateRepos': 250, - 'stripeId': 'bus-xlarge-30', + 'stripeId': 'bus-xlarge-2018', 'audience': 'For extra large businesses', 'bus_features': True, 'deprecated': False, @@ -190,10 +288,10 @@ PLANS = [ 'plans_page_hidden': False, }, { - 'title': 'Huge', - 'price': 65000, + 'title': 'XXL', + 'price': 85000, 'privateRepos': 500, - 'stripeId': 'bus-500-30', + 'stripeId': 'bus-500-2018', 'audience': 'For huge business', 'bus_features': True, 'deprecated': False, @@ -202,10 +300,10 @@ PLANS = [ 'plans_page_hidden': False, }, { - 'title': 'Huuge', - 'price': 120000, + 'title': 'XXXL', + 'price': 160000, 'privateRepos': 1000, - 'stripeId': 'bus-1000-30', + 'stripeId': 'bus-1000-2018', 'audience': 'For the SaaS savvy enterprise', 'bus_features': True, 'deprecated': False, diff --git a/test/test_api_usage.py b/test/test_api_usage.py index 089d36f30..434693bb7 100644 --- a/test/test_api_usage.py +++ b/test/test_api_usage.py @@ -440,14 +440,14 @@ class TestGetUserPrivateAllowed(ApiTestCase): self.login(ADMIN_ACCESS_USER) # Change the subscription of the namespace. - self.putJsonResponse(UserPlan, data=dict(plan='personal-30')) + self.putJsonResponse(UserPlan, data=dict(plan='personal-2018')) json = self.getJsonResponse(PrivateRepositories) assert json['privateCount'] >= 6 assert not json['privateAllowed'] # Change the subscription of the namespace. - self.putJsonResponse(UserPlan, data=dict(plan='bus-large-30')) + self.putJsonResponse(UserPlan, data=dict(plan='bus-large-2018')) json = self.getJsonResponse(PrivateRepositories) assert json['privateAllowed'] @@ -2019,7 +2019,7 @@ class TestChangeRepoVisibility(ApiTestCase): self.assertEquals(True, json['is_public']) # Change the subscription of the namespace. - self.putJsonResponse(UserPlan, data=dict(plan='personal-30')) + self.putJsonResponse(UserPlan, data=dict(plan='personal-2018')) # Try to make private. self.postJsonResponse(RepositoryVisibility, params=dict(repository=self.SIMPLE_REPO), @@ -3166,11 +3166,11 @@ class TestUserSubscription(ApiTestCase): self.assertEquals('free', sub['plan']) # Change the plan. - self.putJsonResponse(UserPlan, data=dict(plan='bus-large-30')) + self.putJsonResponse(UserPlan, data=dict(plan='bus-large-2018')) # Verify sub = self.getSubscription() - self.assertEquals('bus-large-30', sub['plan']) + self.assertEquals('bus-large-2018', sub['plan']) class TestOrgSubscription(ApiTestCase): @@ -3190,11 +3190,11 @@ class TestOrgSubscription(ApiTestCase): # Change the plan. self.putJsonResponse(OrganizationPlan, params=dict(orgname=ORGANIZATION), - data=dict(plan='bus-large-30')) + data=dict(plan='bus-large-2018')) # Verify sub = self.getSubscription() - self.assertEquals('bus-large-30', sub['plan']) + self.assertEquals('bus-large-2018', sub['plan']) class TestUserRobots(ApiTestCase):