Skip to content

Commit

Permalink
update PlanService so GitLab orgs use the root org's plan, fold is_pr…
Browse files Browse the repository at this point in the history
…_billing_plan into PlanService
  • Loading branch information
nora-codecov committed Jan 3, 2025
1 parent 7935e52 commit 3a445a9
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 7 deletions.
5 changes: 3 additions & 2 deletions shared/billing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

class BillingPlan(Enum):
users_ghm = "users"
users_monthly = "users-inappm"
users_yearly = "users-inappy"
users_monthly = "users-inappm" # not pr_billing_plan
users_yearly = "users-inappy" # not pr_billing_plan
users_free = "users-free"
users_basic = "users-basic"
users_trial = "users-trial"
Expand Down Expand Up @@ -37,6 +37,7 @@ def is_enterprise_cloud_plan(plan: BillingPlan) -> bool:


def is_pr_billing_plan(plan: str) -> bool:
# use is_pr_billing_plan() in PlanService instead of accessing this directly
if not settings.IS_ENTERPRISE:
return plan in [
BillingPlan.pr_monthly.value,
Expand Down
4 changes: 2 additions & 2 deletions shared/plan/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class PlanName(enum.Enum):
TRIAL_PLAN_NAME = "users-trial"
CODECOV_PRO_MONTHLY = "users-pr-inappm"
CODECOV_PRO_YEARLY = "users-pr-inappy"
SENTRY_MONTHLY = "users-sentrym"
SENTRY_YEARLY = "users-sentryy"
SENTRY_MONTHLY = "users-sentrym" # not in BillingPlan
SENTRY_YEARLY = "users-sentryy" # not in BillingPlan
TEAM_MONTHLY = "users-teamm"
TEAM_YEARLY = "users-teamy"
GHM_PLAN_NAME = "users"
Expand Down
16 changes: 14 additions & 2 deletions shared/plan/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
from datetime import datetime, timedelta
from typing import List, Optional

from shared.billing import is_pr_billing_plan
from shared.config import get_config
from shared.django_apps.codecov.commands.exceptions import ValidationError
from shared.django_apps.codecov_auth.models import Owner
from shared.django_apps.codecov_auth.models import Owner, Service
from shared.plan.constants import (
BASIC_PLAN,
ENTERPRISE_CLOUD_USER_PLAN_REPRESENTATIONS,
Expand Down Expand Up @@ -46,7 +47,14 @@ def __init__(self, current_org: Owner):
Raises:
ValueError: If the organization's plan is unsupported.
"""
self.current_org = current_org
if (
current_org.service == Service.GITLAB.value
and current_org.parent_service_id
):
# for GitLab groups and subgroups, use the plan on the root org
self.current_org = current_org.root_organization
else:
self.current_org = current_org
if self.current_org.plan not in USER_PLAN_REPRESENTATIONS:
raise ValueError("Unsupported plan")
self._plan_data = None
Expand Down Expand Up @@ -340,3 +348,7 @@ def is_team_plan(self) -> bool:
@property
def is_trial_plan(self) -> bool:
return self.plan_name in TRIAL_PLAN_REPRESENTATION

@property
def is_pr_billing_plan(self) -> bool:
return is_pr_billing_plan(plan=self.plan_name)
38 changes: 37 additions & 1 deletion tests/unit/plan/test_plan.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from datetime import datetime, timedelta
from unittest.mock import patch

from django.test import TestCase
from django.test import TestCase, override_settings
from freezegun import freeze_time

from shared.django_apps.codecov.commands.exceptions import ValidationError
from shared.django_apps.codecov_auth.models import Service
from shared.django_apps.codecov_auth.tests.factories import OwnerFactory
from shared.plan.constants import (
BASIC_PLAN,
Expand Down Expand Up @@ -317,6 +318,34 @@ def test_plan_service_returns_if_owner_has_trial_dates(self):

assert plan_service.has_trial_dates == True

def test_plan_service_gitlab_with_root_org(self):
root_owner_org = OwnerFactory(
service=Service.GITLAB.value,
plan=PlanName.FREE_PLAN_NAME.value,
plan_user_count=1,
service_id="1234",
)
middle_org = OwnerFactory(
service=Service.GITLAB.value,
service_id="5678",
parent_service_id=root_owner_org.service_id,
)
child_owner_org = OwnerFactory(
service=Service.GITLAB.value,
plan=PlanName.CODECOV_PRO_MONTHLY.value,
plan_user_count=20,
parent_service_id=middle_org.service_id,
)
# root_plan and child_plan should be the same
root_plan = PlanService(current_org=root_owner_org)
child_plan = PlanService(current_org=child_owner_org)

assert root_plan.is_pro_plan == child_plan.is_pro_plan == False
assert root_plan.plan_user_count == child_plan.plan_user_count == 1
assert (
root_plan.plan_name == child_plan.plan_name == PlanName.FREE_PLAN_NAME.value
)


class AvailablePlansBeforeTrial(TestCase):
"""
Expand Down Expand Up @@ -815,6 +844,7 @@ def test_sentry_user(self, is_sentry_user):
assert self.plan_service.available_plans(owner=self.owner) == expected_result


@override_settings(IS_ENTERPRISE=False)
class PlanServiceIs___PlanTests(TestCase):
def test_is_trial_plan(self):
self.current_org = OwnerFactory(
Expand All @@ -834,6 +864,7 @@ def test_is_trial_plan(self):
assert self.plan_service.is_free_plan == False
assert self.plan_service.is_pro_plan == False
assert self.plan_service.is_enterprise_plan == False
assert self.plan_service.is_pr_billing_plan == True

def test_is_team_plan(self):
self.current_org = OwnerFactory(
Expand All @@ -849,6 +880,7 @@ def test_is_team_plan(self):
assert self.plan_service.is_free_plan == False
assert self.plan_service.is_pro_plan == False
assert self.plan_service.is_enterprise_plan == False
assert self.plan_service.is_pr_billing_plan == True

def test_is_sentry_plan(self):
self.current_org = OwnerFactory(
Expand All @@ -864,6 +896,7 @@ def test_is_sentry_plan(self):
assert self.plan_service.is_free_plan == False
assert self.plan_service.is_pro_plan == True
assert self.plan_service.is_enterprise_plan == False
assert self.plan_service.is_pr_billing_plan == False

def test_is_free_plan(self):
self.current_org = OwnerFactory(
Expand All @@ -878,6 +911,7 @@ def test_is_free_plan(self):
assert self.plan_service.is_free_plan == True
assert self.plan_service.is_pro_plan == False
assert self.plan_service.is_enterprise_plan == False
assert self.plan_service.is_pr_billing_plan == True

def test_is_pro_plan(self):
self.current_org = OwnerFactory(
Expand All @@ -892,6 +926,7 @@ def test_is_pro_plan(self):
assert self.plan_service.is_free_plan == False
assert self.plan_service.is_pro_plan == True
assert self.plan_service.is_enterprise_plan == False
assert self.plan_service.is_pr_billing_plan == True

def test_is_enterprise_plan(self):
self.current_org = OwnerFactory(
Expand All @@ -906,3 +941,4 @@ def test_is_enterprise_plan(self):
assert self.plan_service.is_free_plan == False
assert self.plan_service.is_pro_plan == False
assert self.plan_service.is_enterprise_plan == True
assert self.plan_service.is_pr_billing_plan == True

0 comments on commit 3a445a9

Please sign in to comment.