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

Commit 310c1f7

Browse files
committed
fix account viewset tests
1 parent ec35658 commit 310c1f7

File tree

5 files changed

+142
-15
lines changed

5 files changed

+142
-15
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
interactions:
2+
- request:
3+
body: null
4+
headers:
5+
Accept:
6+
- '*/*'
7+
Accept-Encoding:
8+
- gzip, deflate
9+
Connection:
10+
- keep-alive
11+
Stripe-Version:
12+
- 2024-12-18.acacia
13+
User-Agent:
14+
- Stripe/v1 PythonBindings/11.4.1
15+
X-Stripe-Client-User-Agent:
16+
- '{"bindings_version": "11.4.1", "lang": "python", "publisher": "stripe", "httplib":
17+
"requests", "lang_version": "3.12.8", "platform": "Linux-6.10.14-linuxkit-aarch64-with-glibc2.36",
18+
"uname": "Linux f69fe8d5c257 6.10.14-linuxkit #1 SMP Fri Nov 29 17:22:03 UTC
19+
2024 aarch64 "}'
20+
method: GET
21+
uri: https://api.stripe.com/v1/subscriptions/djfos?expand%5B0%5D=latest_invoice&expand%5B1%5D=customer&expand%5B2%5D=customer.invoice_settings.default_payment_method&expand%5B3%5D=customer.tax_ids
22+
response:
23+
body:
24+
string: "{\n \"error\": {\n \"code\": \"resource_missing\",\n \"doc_url\":
25+
\"https://stripe.com/docs/error-codes/resource-missing\",\n \"message\":
26+
\"No such subscription: 'djfos'\",\n \"param\": \"id\",\n \"request_log_url\":
27+
\"https://dashboard.stripe.com/test/logs/req_fCLmExiHliLLAy?t=1738274612\",\n
28+
\ \"type\": \"invalid_request_error\"\n }\n}\n"
29+
headers:
30+
Access-Control-Allow-Credentials:
31+
- 'true'
32+
Access-Control-Allow-Methods:
33+
- GET, HEAD, PUT, PATCH, POST, DELETE
34+
Access-Control-Allow-Origin:
35+
- '*'
36+
Access-Control-Expose-Headers:
37+
- Request-Id, Stripe-Manage-Version, Stripe-Should-Retry, X-Stripe-External-Auth-Required,
38+
X-Stripe-Privileged-Session-Required
39+
Access-Control-Max-Age:
40+
- '300'
41+
Cache-Control:
42+
- no-cache, no-store
43+
Connection:
44+
- keep-alive
45+
Content-Length:
46+
- '324'
47+
Content-Security-Policy:
48+
- base-uri 'none'; default-src 'none'; form-action 'none'; frame-ancestors 'none';
49+
img-src 'self'; script-src 'self' 'report-sample'; style-src 'self'; upgrade-insecure-requests;
50+
report-uri https://q.stripe.com/csp-violation?q=JU_aZLssk7a3_VZEeiDM3UWQN0mgWJiEG8zz5aFpDfoiI4Itt-XeW-vHYyCYd8ZJIklaArUO0YdslYml
51+
Content-Type:
52+
- application/json
53+
Cross-Origin-Opener-Policy-Report-Only:
54+
- same-origin; report-to="coop"
55+
Date:
56+
- Thu, 30 Jan 2025 22:03:32 GMT
57+
Report-To:
58+
- '{"group":"coop","max_age":8640,"endpoints":[{"url":"https://q.stripe.com/coop-report"}],"include_subdomains":true}'
59+
Reporting-Endpoints:
60+
- coop="https://q.stripe.com/coop-report"
61+
Request-Id:
62+
- req_fCLmExiHliLLAy
63+
Server:
64+
- nginx
65+
Strict-Transport-Security:
66+
- max-age=63072000; includeSubDomains; preload
67+
Stripe-Version:
68+
- 2024-12-18.acacia
69+
Vary:
70+
- Origin
71+
X-Content-Type-Options:
72+
- nosniff
73+
X-Stripe-Priority-Routing-Enabled:
74+
- 'true'
75+
X-Stripe-Routing-Context-Priority-Tier:
76+
- api-testmode
77+
X-Wc:
78+
- AB
79+
status:
80+
code: 404
81+
message: Not Found
82+
version: 1

api/internal/tests/views/test_account_viewset.py

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,42 @@
2626

2727

2828
class MockSubscription(object):
29-
def __init__(self, subscription_params):
29+
def __init__(self, subscription_params: dict):
3030
self.items = {"data": [{"id": "abc"}]}
3131
self.cancel_at_period_end = False
3232
self.current_period_end = 1633512445
33-
self.latest_invoice = subscription_params["latest_invoice"]
33+
self.latest_invoice = subscription_params.get(
34+
"latest_invoice",
35+
{
36+
"id": "in_123",
37+
"status": "complete",
38+
},
39+
)
40+
41+
default_payment_method = {
42+
"id": "pm_123",
43+
"card": {
44+
"brand": "visa",
45+
"exp_month": 12,
46+
"exp_year": 2024,
47+
"last4": "abcd",
48+
},
49+
}
3450
self.customer = {
3551
"invoice_settings": {
36-
"default_payment_method": subscription_params["default_payment_method"]
52+
"default_payment_method": subscription_params.get(
53+
"default_payment_method", default_payment_method
54+
)
3755
},
3856
"id": "cus_LK&*Hli8YLIO",
3957
"discount": None,
4058
"email": None,
4159
}
42-
self.schedule = subscription_params["schedule_id"]
43-
self.collection_method = subscription_params["collection_method"]
60+
self.schedule = subscription_params.get("schedule_id")
61+
self.status = subscription_params.get("status", "active")
62+
self.collection_method = subscription_params.get(
63+
"collection_method", "charge_automatically"
64+
)
4465
self.trial_end = subscription_params.get("trial_end")
4566

4667
customer_coupon = subscription_params.get("customer_coupon")
@@ -1104,6 +1125,7 @@ def test_update_payment_method_without_body(self):
11041125
response = self.client.patch(url, format="json")
11051126
assert response.status_code == status.HTTP_400_BAD_REQUEST
11061127

1128+
@patch("services.billing.StripeService._is_unverified_payment_method")
11071129
@patch("services.billing.stripe.Subscription.retrieve")
11081130
@patch("services.billing.stripe.PaymentMethod.attach")
11091131
@patch("services.billing.stripe.Customer.modify")
@@ -1114,12 +1136,15 @@ def test_update_payment_method(
11141136
modify_customer_mock,
11151137
attach_payment_mock,
11161138
retrieve_subscription_mock,
1139+
is_unverified_payment_method_mock,
11171140
):
11181141
self.current_owner.stripe_customer_id = "flsoe"
11191142
self.current_owner.stripe_subscription_id = "djfos"
11201143
self.current_owner.save()
11211144
f = open("./services/tests/samples/stripe_invoice.json")
11221145

1146+
is_unverified_payment_method_mock.return_value = False
1147+
11231148
default_payment_method = {
11241149
"card": {
11251150
"brand": "visa",
@@ -1435,14 +1460,15 @@ def test_update_can_change_name_and_email(self):
14351460
assert self.current_owner.name == expected_name
14361461
assert self.current_owner.email == expected_email
14371462

1463+
@patch("services.billing.stripe.Subscription.retrieve")
14381464
@patch("services.billing.StripeService.modify_subscription")
1439-
def test_update_handles_stripe_error(self, modify_sub_mock):
1465+
def test_update_handles_stripe_error(self, retrieve_sub_mock, modify_sub_mock):
14401466
code, message = 402, "Not right, wrong in fact"
14411467
desired_plan = {"value": PlanName.CODECOV_PRO_MONTHLY.value, "quantity": 12}
14421468
self.current_owner.stripe_customer_id = "flsoe"
14431469
self.current_owner.stripe_subscription_id = "djfos"
14441470
self.current_owner.save()
1445-
1471+
retrieve_sub_mock.return_value = MockSubscription({})
14461472
modify_sub_mock.side_effect = StripeError(message=message, http_status=code)
14471473

14481474
response = self._update(
@@ -1456,9 +1482,12 @@ def test_update_handles_stripe_error(self, modify_sub_mock):
14561482
assert response.status_code == code
14571483
assert response.data["detail"] == message
14581484

1485+
@patch("services.billing.stripe.Subscription.retrieve")
14591486
@patch("api.internal.owner.serializers.send_sentry_webhook")
14601487
@patch("services.billing.StripeService.modify_subscription")
1461-
def test_update_sentry_plan_monthly(self, modify_sub_mock, send_sentry_webhook):
1488+
def test_update_sentry_plan_monthly(
1489+
self, modify_sub_mock, send_sentry_webhook, retrieve_sub_mock
1490+
):
14621491
desired_plan = {"value": PlanName.SENTRY_MONTHLY.value, "quantity": 12}
14631492
self.current_owner.stripe_customer_id = "flsoe"
14641493
self.current_owner.stripe_subscription_id = "djfos"
@@ -1499,9 +1528,15 @@ def test_update_sentry_plan_monthly_with_users_org(
14991528
)
15001529
send_sentry_webhook.assert_called_once_with(self.current_owner, org)
15011530

1531+
@patch("services.billing.stripe.Subscription.retrieve")
15021532
@patch("api.internal.owner.serializers.send_sentry_webhook")
15031533
@patch("services.billing.StripeService.modify_subscription")
1504-
def test_update_sentry_plan_annual(self, modify_sub_mock, send_sentry_webhook):
1534+
def test_update_sentry_plan_annual(
1535+
self,
1536+
modify_sub_mock,
1537+
send_sentry_webhook,
1538+
retrieve_sub_mock,
1539+
):
15051540
desired_plan = {"value": PlanName.SENTRY_YEARLY.value, "quantity": 12}
15061541
self.current_owner.stripe_customer_id = "flsoe"
15071542
self.current_owner.stripe_subscription_id = "djfos"

billing/views.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
from billing.helpers import get_all_admins_for_owners
1616
from codecov_auth.models import Owner
17-
from services.billing import BillingService
1817
from services.task.task import TaskService
1918

2019
from .constants import StripeHTTPHeaders, StripeWebhookEvents

services/billing.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,9 @@ def create_setup_intent(self, owner: Owner):
911911
"""
912912
return self.payment_service.create_setup_intent(owner)
913913

914-
def _cleanup_incomplete_subscription(self, subscription, owner):
914+
def _cleanup_incomplete_subscription(
915+
self, subscription: stripe.Subscription, owner: Owner
916+
):
915917
latest_invoice = subscription.get("latest_invoice")
916918
if not latest_invoice:
917919
return None
@@ -932,7 +934,7 @@ def _cleanup_incomplete_subscription(self, subscription, owner):
932934
try:
933935
# Delete the subscription, which also removes the
934936
# pending payment method and unverified payment intent
935-
stripe.Subscription.delete(subscription.id)
937+
stripe.Subscription.delete(subscription)
936938
log.info(
937939
"Deleted incomplete subscription",
938940
extra=dict(

services/tests/samples/stripe_invoice.json

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,10 @@
9797
"next_payment_attempt": null,
9898
"number": "EF0A41E-0001",
9999
"paid": true,
100-
"payment_intent": null,
100+
"payment_intent": {
101+
"id": "pi_3P4567890123456789012345",
102+
"status": "completed"
103+
},
101104
"period_end": 1489789420,
102105
"period_start": 1487370220,
103106
"post_payment_credit_notes_amount": 0,
@@ -214,7 +217,10 @@
214217
"next_payment_attempt": null,
215218
"number": "EF0A41E-0001",
216219
"paid": true,
217-
"payment_intent": null,
220+
"payment_intent": {
221+
"id": "pi_3P4567890123456789012345",
222+
"status": "completed"
223+
},
218224
"period_end": 1489789420,
219225
"period_start": 1487370220,
220226
"post_payment_credit_notes_amount": 0,
@@ -351,7 +357,10 @@
351357
"on_behalf_of": null,
352358
"paid": false,
353359
"paid_out_of_band": false,
354-
"payment_intent": null,
360+
"payment_intent": {
361+
"id": "pi_3P4567890123456789012345",
362+
"status": "completed"
363+
},
355364
"payment_settings": {
356365
"default_mandate": null,
357366
"payment_method_options": null,

0 commit comments

Comments
 (0)