-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add new users-developer plan #494
Changes from all commits
8f71e4b
d4193dd
7fa9dd4
8f62e53
c04d773
59674dc
8bb5d10
b7bb750
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# Generated by Django 4.2.16 on 2025-01-30 13:24 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
""" | ||
BEGIN; | ||
-- | ||
-- Alter field plan on account | ||
-- | ||
-- (no-op) | ||
-- | ||
-- Raw SQL operation | ||
-- | ||
ALTER TYPE plans ADD VALUE IF NOT EXISTS 'users-developer'; | ||
-- | ||
-- Alter field plan on owner | ||
-- | ||
-- (no-op) | ||
COMMIT; | ||
""" | ||
|
||
dependencies = [ | ||
("codecov_auth", "0064_plan_stripe_id"), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterField( | ||
model_name="account", | ||
name="plan", | ||
field=models.CharField( | ||
choices=[ | ||
("users-basic", "BASIC_PLAN_NAME"), | ||
("users-trial", "TRIAL_PLAN_NAME"), | ||
("users-pr-inappm", "CODECOV_PRO_MONTHLY"), | ||
("users-pr-inappy", "CODECOV_PRO_YEARLY"), | ||
("users-sentrym", "SENTRY_MONTHLY"), | ||
("users-sentryy", "SENTRY_YEARLY"), | ||
("users-teamm", "TEAM_MONTHLY"), | ||
("users-teamy", "TEAM_YEARLY"), | ||
("users", "GHM_PLAN_NAME"), | ||
("users-free", "FREE_PLAN_NAME"), | ||
("users-inappm", "CODECOV_PRO_MONTHLY_LEGACY"), | ||
("users-inappy", "CODECOV_PRO_YEARLY_LEGACY"), | ||
("users-enterprisem", "ENTERPRISE_CLOUD_MONTHLY"), | ||
("users-enterprisey", "ENTERPRISE_CLOUD_YEARLY"), | ||
("users-developer", "USERS_DEVELOPER"), | ||
], | ||
default="users-developer", | ||
max_length=50, | ||
), | ||
), | ||
migrations.RunSQL( | ||
"ALTER TYPE plans ADD VALUE IF NOT EXISTS 'users-developer';" | ||
), | ||
migrations.AlterField( | ||
model_name="owner", | ||
name="plan", | ||
field=models.TextField(blank=True, default="users-developer", null=True), | ||
), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
|
||
|
||
class MonthlyUploadLimits(enum.Enum): | ||
CODECOV_BASIC_PLAN = 250 | ||
CODECOV_FREE_PLAN = 250 | ||
CODECOV_TEAM_PLAN = 2500 | ||
|
||
|
||
|
@@ -23,6 +23,9 @@ class PlanMarketingName(enum.Enum): | |
TEAM = "Team" | ||
|
||
|
||
DEFAULT_FREE_PLAN = "users-developer" | ||
|
||
|
||
class PlanName(enum.Enum): | ||
# If you add or remove, make a migration for Account table | ||
BASIC_PLAN_NAME = "users-basic" | ||
|
@@ -39,6 +42,7 @@ class PlanName(enum.Enum): | |
CODECOV_PRO_YEARLY_LEGACY = "users-inappy" | ||
ENTERPRISE_CLOUD_MONTHLY = "users-enterprisem" | ||
ENTERPRISE_CLOUD_YEARLY = "users-enterprisey" | ||
USERS_DEVELOPER = "users-developer" | ||
|
||
@classmethod | ||
def choices(cls): | ||
|
@@ -292,7 +296,7 @@ def convert_to_DTO(self) -> dict: | |
"Unlimited private repositories", | ||
], | ||
tier_name=TierName.BASIC.value, | ||
monthly_uploads_limit=MonthlyUploadLimits.CODECOV_BASIC_PLAN.value, | ||
monthly_uploads_limit=MonthlyUploadLimits.CODECOV_FREE_PLAN.value, | ||
trial_days=None, | ||
) | ||
|
||
|
@@ -311,9 +315,25 @@ def convert_to_DTO(self) -> dict: | |
monthly_uploads_limit=None, | ||
) | ||
|
||
DEVELOPER_PLAN = PlanData( | ||
marketing_name=PlanMarketingName.FREE.value, | ||
value=DEFAULT_FREE_PLAN, | ||
billing_rate=None, | ||
base_unit_price=PlanPrice.CODECOV_FREE.value, | ||
benefits=[ | ||
"Up to 1 user", | ||
"Unlimited public repositories", | ||
"Unlimited private repositories", | ||
], | ||
tier_name=TierName.TEAM.value, | ||
trial_days=None, | ||
monthly_uploads_limit=250, | ||
) | ||
|
||
FREE_PLAN_REPRESENTATIONS = { | ||
PlanName.FREE_PLAN_NAME.value: FREE_PLAN, | ||
PlanName.BASIC_PLAN_NAME.value: BASIC_PLAN, | ||
DEFAULT_FREE_PLAN: DEVELOPER_PLAN, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't need this anymore right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same thing here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same response, we can double confirm with @adrian-codecov but that's what he told me originally |
||
} | ||
|
||
TEAM_PLAN_REPRESENTATIONS = { | ||
|
@@ -389,6 +409,7 @@ def convert_to_DTO(self) -> dict: | |
} | ||
|
||
PLANS_THAT_CAN_TRIAL = [ | ||
DEFAULT_FREE_PLAN, | ||
PlanName.FREE_PLAN_NAME.value, | ||
PlanName.BASIC_PLAN_NAME.value, | ||
PlanName.CODECOV_PRO_MONTHLY.value, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,7 +36,8 @@ | |
) | ||
from shared.django_apps.core.tests.factories import RepositoryFactory | ||
from shared.plan.constants import ( | ||
BASIC_PLAN, | ||
DEFAULT_FREE_PLAN, | ||
DEVELOPER_PLAN, | ||
ENTERPRISE_CLOUD_USER_PLAN_REPRESENTATIONS, | ||
PlanName, | ||
) | ||
|
@@ -380,11 +381,11 @@ def test_can_activate_user_cannot_activate_account(self): | |
def test_fields_that_account_overrides(self): | ||
mock_all_plans_and_tiers() | ||
to_activate = OwnerFactory() | ||
self.owner.plan = PlanName.BASIC_PLAN_NAME.value | ||
self.owner.plan = DEFAULT_FREE_PLAN | ||
self.owner.plan_user_count = 1 | ||
self.owner.save() | ||
self.assertTrue(self.owner.can_activate_user(to_activate)) | ||
org_pretty_plan = asdict(BASIC_PLAN) | ||
org_pretty_plan = asdict(DEVELOPER_PLAN) | ||
org_pretty_plan.update({"quantity": 1}) | ||
self.assertEqual(self.owner.pretty_plan, org_pretty_plan) | ||
|
||
|
@@ -527,7 +528,7 @@ def test_has_yaml(self): | |
|
||
class TestOrganizationLevelTokenModel(TestCase): | ||
def test_can_save_org_token_for_org_basic_plan(self): | ||
owner = OwnerFactory(plan="users-basic") | ||
owner = OwnerFactory(plan=DEFAULT_FREE_PLAN) | ||
owner.save() | ||
token = OrganizationLevelToken(owner=owner) | ||
token.save() | ||
|
@@ -545,7 +546,7 @@ def test_token_is_deleted_when_changing_user_plan( | |
owner.save() | ||
org_token.save() | ||
assert OrganizationLevelToken.objects.filter(owner=owner).count() == 1 | ||
owner.plan = "users-basic" | ||
owner.plan = DEFAULT_FREE_PLAN | ||
owner.save() | ||
assert OrganizationLevelToken.objects.filter(owner=owner).count() == 0 | ||
|
||
|
@@ -759,7 +760,7 @@ def test_account_with_users(self): | |
self.assertEqual(account.activated_student_count, 0) | ||
self.assertEqual(account.total_seat_count, 1) | ||
self.assertEqual(account.available_seat_count, 0) | ||
pretty_plan = asdict(BASIC_PLAN) | ||
pretty_plan = asdict(DEVELOPER_PLAN) | ||
pretty_plan.update({"quantity": 1}) | ||
self.assertEqual(account.pretty_plan, pretty_plan) | ||
|
||
|
@@ -772,21 +773,21 @@ def test_create_account_for_enterprise_experience(self): | |
user_for_owner_1 = UserFactory(email="[email protected]", name="Luigi") | ||
owner_1 = OwnerFactory( | ||
username="codecov-1", | ||
plan=PlanName.BASIC_PLAN_NAME.value, | ||
plan=DEFAULT_FREE_PLAN, | ||
plan_user_count=1, | ||
organizations=[], | ||
user_id=user_for_owner_1.id, # has user | ||
) | ||
owner_2 = OwnerFactory( | ||
username="codecov-sentry", | ||
plan=PlanName.BASIC_PLAN_NAME.value, | ||
plan=DEFAULT_FREE_PLAN, | ||
plan_user_count=1, | ||
organizations=[], | ||
user_id=None, # no user | ||
) | ||
owner_3 = OwnerFactory( | ||
username="sentry-1", | ||
plan=PlanName.BASIC_PLAN_NAME.value, | ||
plan=DEFAULT_FREE_PLAN, | ||
plan_user_count=1, | ||
organizations=[], | ||
user_id=None, # no user | ||
|
@@ -810,7 +811,7 @@ def test_create_account_for_enterprise_experience(self): | |
username="codecov-org", | ||
stripe_customer_id=stripe_customer_id, | ||
stripe_subscription_id=stripe_subscription_id, | ||
plan=PlanName.BASIC_PLAN_NAME.value, | ||
plan=DEFAULT_FREE_PLAN, | ||
plan_user_count=50, | ||
plan_activated_users=[owner_1.ownerid, owner_2.ownerid], | ||
free=10, | ||
|
@@ -930,7 +931,7 @@ def test_create_account_for_enterprise_experience(self): | |
self.assertEqual(enterprise_account.activated_student_count, 0) | ||
self.assertEqual(enterprise_account.total_seat_count, 60) | ||
self.assertEqual(enterprise_account.available_seat_count, 57) | ||
pretty_plan = asdict(BASIC_PLAN) | ||
pretty_plan = asdict(DEVELOPER_PLAN) | ||
pretty_plan.update({"quantity": 50}) | ||
self.assertEqual(enterprise_account.pretty_plan, pretty_plan) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't need these anymore right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unfortunately we do because API is still using
FREE_PLAN_REPRESENTATIONS
once we clean up API we can go back and remove all plans representations.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just double checked that reference and it's for a django command script that is "dead" :) I think we're good to not add it for that reason