Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.

Commit dfb161f

Browse files
feat: Default api to new free plan (#1118)
Co-authored-by: Ajay Singh <[email protected]>
1 parent 5ee4fc7 commit dfb161f

File tree

16 files changed

+110
-116
lines changed

16 files changed

+110
-116
lines changed

api/internal/owner/views.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from rest_framework.exceptions import PermissionDenied, ValidationError
88
from rest_framework.response import Response
99
from shared.django_apps.codecov_auth.models import Owner
10+
from shared.plan.constants import DEFAULT_FREE_PLAN
1011

1112
from api.shared.mixins import OwnerPropertyMixin
1213
from api.shared.owner.mixins import OwnerViewSetMixin, UserViewSetMixin
@@ -45,8 +46,13 @@ def retrieve(self, *args, **kwargs):
4546
return res
4647

4748
@stripe_safe
48-
def update(self, *args, **kwargs):
49-
return super().update(*args, **kwargs)
49+
def update(self, request, *args, **kwargs):
50+
# Temporary fix. Remove once Gazebo uses the new free plan
51+
plan_value = request.data.get("plan", {}).get("value")
52+
if plan_value == "users-basic":
53+
request.data["plan"]["value"] = DEFAULT_FREE_PLAN
54+
55+
return super().update(request, *args, **kwargs)
5056

5157
def destroy(self, request, *args, **kwargs):
5258
if self.owner.ownerid != request.current_owner.ownerid:

api/internal/tests/views/test_account_viewset.py

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
OwnerFactory,
1515
UserFactory,
1616
)
17-
from shared.plan.constants import PlanName, TrialStatus
17+
from shared.plan.constants import DEFAULT_FREE_PLAN, PlanName, TrialStatus
1818
from stripe import StripeError
1919

2020
from api.internal.tests.test_utils import GetAdminProviderAdapter
@@ -185,7 +185,7 @@ def test_retrieve_account_gets_account_fields(self):
185185
"inactive_user_count": 1,
186186
"plan": {
187187
"marketing_name": "Developer",
188-
"value": PlanName.BASIC_PLAN_NAME.value,
188+
"value": DEFAULT_FREE_PLAN,
189189
"billing_rate": None,
190190
"base_unit_price": 0,
191191
"benefits": [
@@ -270,7 +270,7 @@ def test_retrieve_account_gets_account_fields_when_there_are_scheduled_details(
270270
"plan_provider": owner.plan_provider,
271271
"plan": {
272272
"marketing_name": "Developer",
273-
"value": PlanName.BASIC_PLAN_NAME.value,
273+
"value": DEFAULT_FREE_PLAN,
274274
"billing_rate": None,
275275
"base_unit_price": 0,
276276
"benefits": [
@@ -367,7 +367,7 @@ def test_retrieve_account_returns_last_phase_when_more_than_one_scheduled_phases
367367
"inactive_user_count": 1,
368368
"plan": {
369369
"marketing_name": "Developer",
370-
"value": PlanName.BASIC_PLAN_NAME.value,
370+
"value": DEFAULT_FREE_PLAN,
371371
"billing_rate": None,
372372
"base_unit_price": 0,
373373
"benefits": [
@@ -441,7 +441,7 @@ def test_retrieve_account_gets_none_for_schedule_details_when_schedule_is_nonexi
441441
"inactive_user_count": 1,
442442
"plan": {
443443
"marketing_name": "Developer",
444-
"value": PlanName.BASIC_PLAN_NAME.value,
444+
"value": DEFAULT_FREE_PLAN,
445445
"billing_rate": None,
446446
"base_unit_price": 0,
447447
"benefits": [
@@ -509,13 +509,13 @@ def test_retrieve_account_gets_account_students(self):
509509
}
510510

511511
def test_account_with_free_user_plan(self):
512-
self.current_owner.plan = PlanName.BASIC_PLAN_NAME.value
512+
self.current_owner.plan = DEFAULT_FREE_PLAN
513513
self.current_owner.save()
514514
response = self._retrieve()
515515
assert response.status_code == status.HTTP_200_OK
516516
assert response.data["plan"] == {
517517
"marketing_name": "Developer",
518-
"value": PlanName.BASIC_PLAN_NAME.value,
518+
"value": DEFAULT_FREE_PLAN,
519519
"billing_rate": None,
520520
"base_unit_price": 0,
521521
"benefits": [
@@ -711,7 +711,7 @@ def test_update_can_set_plan_auto_activate_on_org_with_account(self):
711711
assert self.current_owner.plan_auto_activate is False
712712
assert response.data["plan_auto_activate"] is False
713713

714-
def test_update_can_set_plan_to_users_basic(self):
714+
def test_update_can_set_plan_to_users_developer_should_set_to_developer(self):
715715
self.current_owner.plan = PlanName.CODECOV_PRO_YEARLY.value
716716
self.current_owner.save()
717717

@@ -720,14 +720,14 @@ def test_update_can_set_plan_to_users_basic(self):
720720
"service": self.current_owner.service,
721721
"owner_username": self.current_owner.username,
722722
},
723-
data={"plan": {"value": PlanName.BASIC_PLAN_NAME.value}},
723+
data={"plan": {"value": DEFAULT_FREE_PLAN}},
724724
)
725725

726726
assert response.status_code == status.HTTP_200_OK
727727

728728
self.current_owner.refresh_from_db()
729729

730-
assert self.current_owner.plan == PlanName.BASIC_PLAN_NAME.value
730+
assert self.current_owner.plan == DEFAULT_FREE_PLAN
731731
assert self.current_owner.plan_activated_users is None
732732
assert self.current_owner.plan_user_count == 1
733733
assert response.data["plan_auto_activate"] is True
@@ -984,7 +984,7 @@ def test_update_must_fail_if_quantity_and_plan_are_equal_to_the_owners_current_o
984984
)
985985

986986
def test_update_team_plan_must_fail_if_too_many_activated_users_during_trial(self):
987-
self.current_owner.plan = PlanName.BASIC_PLAN_NAME.value
987+
self.current_owner.plan = DEFAULT_FREE_PLAN
988988
self.current_owner.plan_user_count = 1
989989
self.current_owner.trial_status = TrialStatus.ONGOING.value
990990
self.current_owner.plan_activated_users = list(range(11))
@@ -1005,13 +1005,7 @@ def test_update_team_plan_must_fail_if_too_many_activated_users_during_trial(sel
10051005
)
10061006

10071007
assert response.status_code == status.HTTP_400_BAD_REQUEST
1008-
assert response.json() == {
1009-
"plan": {
1010-
"value": [
1011-
f"Invalid value for plan: {desired_plan['value']}; must be one of ['users-basic', 'users-pr-inappm', 'users-pr-inappy']"
1012-
]
1013-
}
1014-
}
1008+
assert "Invalid value for plan:" in response.json()["plan"]["value"][0]
10151009

10161010
def test_update_team_plan_must_fail_if_currently_team_plan_add_too_many_users(self):
10171011
self.current_owner.plan = PlanName.TEAM_MONTHLY.value
@@ -1602,7 +1596,7 @@ def test_update_sentry_plan_non_sentry_user(
16021596
assert res.json() == {
16031597
"plan": {
16041598
"value": [
1605-
"Invalid value for plan: users-sentrym; must be one of ['users-basic', 'users-pr-inappm', 'users-pr-inappy', 'users-teamm', 'users-teamy']"
1599+
f"Invalid value for plan: users-sentrym; must be one of ['users-pr-inappm', 'users-pr-inappy', 'users-teamm', 'users-teamy', '{DEFAULT_FREE_PLAN}']"
16061600
]
16071601
}
16081602
}

billing/helpers.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from django.db.models import QuerySet
33
from shared.django_apps.codecov_auth.models import BillingRate
44
from shared.django_apps.codecov_auth.tests.factories import PlanFactory, TierFactory
5-
from shared.plan.constants import PlanName, PlanPrice, TierName
5+
from shared.plan.constants import DEFAULT_FREE_PLAN, PlanName, PlanPrice, TierName
66

77
from codecov_auth.models import Owner, Plan
88

@@ -42,17 +42,6 @@ def mock_all_plans_and_tiers():
4242
)
4343

4444
basic_tier = TierFactory(tier_name=TierName.BASIC.value)
45-
PlanFactory(
46-
name=PlanName.BASIC_PLAN_NAME.value,
47-
tier=basic_tier,
48-
marketing_name="Developer",
49-
benefits=[
50-
"Up to 1 user",
51-
"Unlimited public repositories",
52-
"Unlimited private repositories",
53-
],
54-
monthly_uploads_limit=250,
55-
)
5645
PlanFactory(
5746
name=PlanName.FREE_PLAN_NAME.value,
5847
tier=basic_tier,
@@ -187,3 +176,18 @@ def mock_all_plans_and_tiers():
187176
"Priority Support",
188177
],
189178
)
179+
180+
PlanFactory(
181+
name=DEFAULT_FREE_PLAN,
182+
tier=team_tier,
183+
marketing_name="Developer",
184+
billing_rate=None,
185+
base_unit_price=0,
186+
paid_plan=False,
187+
monthly_uploads_limit=250,
188+
benefits=[
189+
"Up to 1 user",
190+
"Unlimited public repositories",
191+
"Unlimited private repositories",
192+
],
193+
)

billing/tests/test_views.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from rest_framework.reverse import reverse
1010
from rest_framework.test import APIRequestFactory, APITestCase
1111
from shared.django_apps.core.tests.factories import OwnerFactory, RepositoryFactory
12-
from shared.plan.constants import PlanName
12+
from shared.plan.constants import DEFAULT_FREE_PLAN, PlanName
1313

1414
from billing.helpers import mock_all_plans_and_tiers
1515
from billing.views import StripeWebhookHandler
@@ -554,7 +554,7 @@ def test_customer_subscription_deleted_sets_plan_to_free(self):
554554
)
555555
self.owner.refresh_from_db()
556556

557-
assert self.owner.plan == PlanName.BASIC_PLAN_NAME.value
557+
assert self.owner.plan == DEFAULT_FREE_PLAN
558558
assert self.owner.plan_user_count == 1
559559
assert self.owner.plan_activated_users is None
560560
assert self.owner.stripe_subscription_id is None
@@ -584,12 +584,12 @@ def test_customer_subscription_deleted_sets_plan_to_free_mutliple_owner(self):
584584
self.owner.refresh_from_db()
585585
self.other_owner.refresh_from_db()
586586

587-
assert self.owner.plan == PlanName.BASIC_PLAN_NAME.value
587+
assert self.owner.plan == DEFAULT_FREE_PLAN
588588
assert self.owner.plan_user_count == 1
589589
assert self.owner.plan_activated_users is None
590590
assert self.owner.stripe_subscription_id is None
591591

592-
assert self.other_owner.plan == PlanName.BASIC_PLAN_NAME.value
592+
assert self.other_owner.plan == DEFAULT_FREE_PLAN
593593
assert self.other_owner.plan_user_count == 1
594594
assert self.other_owner.plan_activated_users is None
595595
assert self.other_owner.stripe_subscription_id is None
@@ -998,7 +998,7 @@ def test_customer_subscription_updated_sets_free_and_deactivates_all_repos_if_in
998998
)
999999
self.owner.refresh_from_db()
10001000

1001-
assert self.owner.plan == PlanName.BASIC_PLAN_NAME.value
1001+
assert self.owner.plan == DEFAULT_FREE_PLAN
10021002
assert self.owner.plan_user_count == 1
10031003
assert self.owner.plan_auto_activate == False
10041004
assert self.owner.stripe_subscription_id is None
@@ -1102,14 +1102,14 @@ def test_customer_subscription_updated_sets_free_and_deactivates_all_repos_if_in
11021102
self.owner.refresh_from_db()
11031103
self.other_owner.refresh_from_db()
11041104

1105-
assert self.owner.plan == PlanName.BASIC_PLAN_NAME.value
1105+
assert self.owner.plan == DEFAULT_FREE_PLAN
11061106
assert self.owner.plan_user_count == 1
11071107
assert self.owner.plan_auto_activate == False
11081108
assert self.owner.stripe_subscription_id is None
11091109
assert (
11101110
self.owner.repository_set.filter(active=True, activated=True).count() == 0
11111111
)
1112-
assert self.other_owner.plan == PlanName.BASIC_PLAN_NAME.value
1112+
assert self.other_owner.plan == DEFAULT_FREE_PLAN
11131113
assert self.other_owner.plan_user_count == 1
11141114
assert self.other_owner.plan_auto_activate == False
11151115
assert self.other_owner.stripe_subscription_id is None

codecov_auth/commands/owner/interactors/tests/test_cancel_trial.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from shared.django_apps.codecov.commands.exceptions import ValidationError
88
from shared.django_apps.codecov_auth.tests.factories import PlanFactory, TierFactory
99
from shared.django_apps.core.tests.factories import OwnerFactory
10-
from shared.plan.constants import PlanName, TierName, TrialStatus
10+
from shared.plan.constants import DEFAULT_FREE_PLAN, PlanName, TierName, TrialStatus
1111

1212
from codecov.commands.exceptions import Unauthorized
1313
from codecov.commands.exceptions import ValidationError as CodecovValidationError
@@ -18,7 +18,7 @@
1818

1919
class CancelTrialInteractorTest(TransactionTestCase):
2020
def setUp(self):
21-
self.tier = TierFactory(tier_name=TierName.BASIC.value)
21+
self.tier = TierFactory(tier_name=DEFAULT_FREE_PLAN)
2222
self.plan = PlanFactory(tier=self.tier)
2323

2424
@async_to_sync
@@ -103,7 +103,7 @@ def test_cancel_trial_starts_trial_for_org_that_has_trial_ongoing(self):
103103
now = datetime.now()
104104
assert current_user.trial_end_date == now
105105
assert current_user.trial_status == TrialStatus.EXPIRED.value
106-
assert current_user.plan == PlanName.BASIC_PLAN_NAME.value
106+
assert current_user.plan == DEFAULT_FREE_PLAN
107107
assert current_user.plan_activated_users is None
108108
assert current_user.plan_user_count == 1
109109
assert current_user.stripe_subscription_id is None

0 commit comments

Comments
 (0)