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

Commit 392c975

Browse files
ref: Update shared + Add missing fields for plan representation (#1068)
Co-authored-by: Ajay Singh <[email protected]>
1 parent 9958e78 commit 392c975

File tree

7 files changed

+132
-14
lines changed

7 files changed

+132
-14
lines changed

api/internal/owner/serializers.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import logging
2-
from dataclasses import asdict
32
from datetime import datetime
43

54
from dateutil.relativedelta import relativedelta
@@ -127,10 +126,9 @@ def validate_value(self, value):
127126
current_owner = self.context["request"].current_owner
128127

129128
plan_service = PlanService(current_org=current_org)
130-
available_plans = [
131-
asdict(plan) for plan in plan_service.available_plans(current_owner)
129+
plan_values = [
130+
plan["value"] for plan in plan_service.available_plans(current_owner)
132131
]
133-
plan_values = [plan["value"] for plan in available_plans]
134132
if value not in plan_values:
135133
if value in SENTRY_PAID_USER_PLAN_REPRESENTATIONS:
136134
log.warning(

graphql_api/tests/test_owner.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,3 +1078,86 @@ def test_fetch_activated_user_count_when_not_in_org_but_has_shared_account(self)
10781078
""" % (other_owner.username)
10791079
data = self.gql_request(query, owner=owner)
10801080
assert data["owner"]["activatedUserCount"] == 2
1081+
1082+
def test_fetch_available_plans_is_enterprise_plan(self):
1083+
current_org = OwnerFactory(
1084+
username="random-plan-user",
1085+
service="github",
1086+
plan=PlanName.FREE_PLAN_NAME.value,
1087+
)
1088+
1089+
query = """{
1090+
owner(username: "%s") {
1091+
availablePlans {
1092+
value
1093+
isEnterprisePlan
1094+
isProPlan
1095+
isTeamPlan
1096+
isSentryPlan
1097+
isFreePlan
1098+
isTrialPlan
1099+
}
1100+
}
1101+
}
1102+
""" % (current_org.username)
1103+
data = self.gql_request(query, owner=current_org)
1104+
assert data == {
1105+
"owner": {
1106+
"availablePlans": [
1107+
{
1108+
"value": "users-basic",
1109+
"isEnterprisePlan": False,
1110+
"isProPlan": False,
1111+
"isTeamPlan": False,
1112+
"isSentryPlan": False,
1113+
"isFreePlan": True,
1114+
"isTrialPlan": False,
1115+
},
1116+
{
1117+
"value": "users-free",
1118+
"isEnterprisePlan": False,
1119+
"isProPlan": False,
1120+
"isTeamPlan": False,
1121+
"isSentryPlan": False,
1122+
"isFreePlan": True,
1123+
"isTrialPlan": False,
1124+
},
1125+
{
1126+
"value": "users-pr-inappm",
1127+
"isEnterprisePlan": False,
1128+
"isProPlan": True,
1129+
"isTeamPlan": False,
1130+
"isSentryPlan": False,
1131+
"isFreePlan": False,
1132+
"isTrialPlan": False,
1133+
},
1134+
{
1135+
"value": "users-pr-inappy",
1136+
"isEnterprisePlan": False,
1137+
"isProPlan": True,
1138+
"isTeamPlan": False,
1139+
"isSentryPlan": False,
1140+
"isFreePlan": False,
1141+
"isTrialPlan": False,
1142+
},
1143+
{
1144+
"value": "users-teamm",
1145+
"isEnterprisePlan": False,
1146+
"isProPlan": False,
1147+
"isTeamPlan": True,
1148+
"isSentryPlan": False,
1149+
"isFreePlan": False,
1150+
"isTrialPlan": False,
1151+
},
1152+
{
1153+
"value": "users-teamy",
1154+
"isEnterprisePlan": False,
1155+
"isProPlan": False,
1156+
"isTeamPlan": True,
1157+
"isSentryPlan": False,
1158+
"isFreePlan": False,
1159+
"isTrialPlan": False,
1160+
},
1161+
]
1162+
}
1163+
}

graphql_api/types/owner/owner.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ def resolve_plan(owner: Owner, info: GraphQLResolveInfo) -> PlanService:
112112
@require_part_of_org
113113
def resolve_plan_representation(owner: Owner, info: GraphQLResolveInfo) -> PlanData:
114114
info.context["plan_service"] = PlanService(current_org=owner)
115-
return FREE_PLAN_REPRESENTATIONS[PlanName.BASIC_PLAN_NAME.value]
115+
free_plan = FREE_PLAN_REPRESENTATIONS[PlanName.BASIC_PLAN_NAME.value]
116+
return free_plan.convert_to_DTO()
116117

117118

118119
@owner_bindable.field("availablePlans")

graphql_api/types/plan_representation/plan_representation.graphql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ type PlanRepresentation {
22
baseUnitPrice: Int!
33
benefits: [String!]!
44
billingRate: String
5+
isEnterprisePlan: Boolean!
6+
isFreePlan: Boolean!
7+
isProPlan: Boolean!
8+
isTeamPlan: Boolean!
9+
isSentryPlan: Boolean!
10+
isTrialPlan: Boolean!
511
marketingName: String!
612
monthlyUploadLimit: Int
713
value: String!

graphql_api/types/plan_representation/plan_representation.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,22 @@
1414

1515
@plan_representation_bindable.field("marketingName")
1616
def resolve_marketing_name(plan_data: PlanData, info) -> str:
17-
return plan_data.marketing_name
17+
return plan_data["marketing_name"]
1818

1919

2020
@plan_representation_bindable.field("value")
2121
def resolve_plan_value(plan_data: PlanData, info) -> str:
22-
return plan_data.value
22+
return plan_data["value"]
2323

2424

2525
@plan_representation_bindable.field("billingRate")
2626
def resolve_billing_rate(plan_data: PlanData, info) -> Optional[str]:
27-
return plan_data.billing_rate
27+
return plan_data["billing_rate"]
2828

2929

3030
@plan_representation_bindable.field("baseUnitPrice")
3131
def resolve_base_unit_price(plan_data: PlanData, info) -> int:
32-
return plan_data.base_unit_price
32+
return plan_data["base_unit_price"]
3333

3434

3535
@plan_representation_bindable.field("benefits")
@@ -41,13 +41,43 @@ def resolve_benefits(plan_data: PlanData, info) -> List[str]:
4141
lambda benefit: benefit.replace(
4242
"Up to 1 user", f"Up to {plan_service.pretrial_users_count} users"
4343
),
44-
plan_data.benefits,
44+
plan_data["benefits"],
4545
)
4646
)
4747
return benefits_with_pretrial_users
48-
return plan_data.benefits
48+
return plan_data["benefits"]
4949

5050

5151
@plan_representation_bindable.field("monthlyUploadLimit")
5252
def resolve_monthly_uploads_limit(plan_data: PlanData, info) -> Optional[int]:
53-
return plan_data.monthly_uploads_limit
53+
return plan_data["monthly_uploads_limit"]
54+
55+
56+
@plan_representation_bindable.field("isEnterprisePlan")
57+
def resolve_is_enterprise(plan_data: PlanData, info) -> bool:
58+
return plan_data["is_enterprise_plan"]
59+
60+
61+
@plan_representation_bindable.field("isFreePlan")
62+
def resolve_is_free(plan_data: PlanData, info) -> bool:
63+
return plan_data["is_free_plan"]
64+
65+
66+
@plan_representation_bindable.field("isProPlan")
67+
def resolve_is_pro(plan_data: PlanData, info) -> bool:
68+
return plan_data["is_pro_plan"]
69+
70+
71+
@plan_representation_bindable.field("isTeamPlan")
72+
def resolve_is_team(plan_data: PlanData, info) -> bool:
73+
return plan_data["is_team_plan"]
74+
75+
76+
@plan_representation_bindable.field("isSentryPlan")
77+
def resolve_is_sentry(plan_data: PlanData, info) -> bool:
78+
return plan_data["is_sentry_plan"]
79+
80+
81+
@plan_representation_bindable.field("isTrialPlan")
82+
def resolve_is_trial(plan_data: PlanData, info) -> bool:
83+
return plan_data["is_trial_plan"]

requirements.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ freezegun
2626
google-cloud-pubsub
2727
gunicorn>=22.0.0
2828
https://github.com/codecov/opentelem-python/archive/refs/tags/v0.0.4a1.tar.gz#egg=codecovopentelem
29-
https://github.com/codecov/shared/archive/1c4ca00e35d95d1281e0415ce1897f6dbbc6368a.tar.gz#egg=shared
29+
https://github.com/codecov/shared/archive/abc6b36feceb05c3b754050061436574111058f9.tar.gz#egg=shared
3030
https://github.com/photocrowd/django-cursor-pagination/archive/f560902696b0c8509e4d95c10ba0d62700181d84.tar.gz
3131
idna>=3.7
3232
minio

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ sentry-sdk[celery]==2.13.0
414414
# shared
415415
setproctitle==1.1.10
416416
# via -r requirements.in
417-
shared @ https://github.com/codecov/shared/archive/1c4ca00e35d95d1281e0415ce1897f6dbbc6368a.tar.gz
417+
shared @ https://github.com/codecov/shared/archive/abc6b36feceb05c3b754050061436574111058f9.tar.gz
418418
# via -r requirements.in
419419
simplejson==3.17.2
420420
# via -r requirements.in

0 commit comments

Comments
 (0)