Changeset View
Changeset View
Standalone View
Standalone View
tests/test_checkout.py
| import datetime | |||||
| from typing import Callable, Dict, Iterable, Optional, TypeVar, cast | from typing import Callable, Dict, Iterable, Optional, TypeVar, cast | ||||
| from unittest import mock | from unittest import mock | ||||
| import responses | import responses | ||||
| from django.contrib.auth.models import User | |||||
| from django.dispatch import receiver | from django.dispatch import receiver | ||||
| from django.http import HttpResponse | from django.http import HttpResponse | ||||
| from django.test import override_settings | from django.test import override_settings | ||||
| from django.urls import reverse | from django.urls import reverse | ||||
| from looper import gateways, models, permissions, signals | from looper import gateways, models, permissions, signals | ||||
| from looper.exceptions import GatewayError | from looper.exceptions import GatewayError | ||||
| from looper.models import PlanVariation | from looper.models import PlanVariation | ||||
| Show All 19 Lines | class AbstractCheckoutTestCase(AbstractLooperTestCase): | ||||
| @property | @property | ||||
| def checkout_url(self) -> str: | def checkout_url(self) -> str: | ||||
| return reverse( | return reverse( | ||||
| 'looper:checkout_new_subscription', | 'looper:checkout_new_subscription', | ||||
| kwargs={'customer_id': self.customer.pk, 'currency': 'usd', 'plan_id': 2}, | kwargs={'customer_id': self.customer.pk, 'currency': 'usd', 'plan_id': 2}, | ||||
| ) | ) | ||||
| def setUp(self): | |||||
| super().setUp() | |||||
| self.user = User.objects.get(email='harry@blender.org') | |||||
| # The signed-cookies session engine doesn't play nice with the test client. | |||||
| @override_settings(SESSION_ENGINE='django.contrib.sessions.backends.file') | |||||
| class BraintreeClientTokenTestCase(AbstractCheckoutTestCase): | |||||
| def set_session(self, token: str, expire: str): | |||||
| session = self.client.session | |||||
| if token: | |||||
| session['PAYMENT_GATEWAY_CLIENT_TOKEN__braintree_USD'] = token | |||||
| if expire: | |||||
| session['PAYMENT_GATEWAY_CLIENT_TOKEN__braintree_USD_expire'] = expire | |||||
| session.save() | |||||
| return session | |||||
| @mock.patch('braintree.client_token_gateway.ClientTokenGateway.generate') | |||||
| def test_client_token_happy(self, mock_generate): | |||||
sybren: Rename `test_client_token_happy` to `test_fresh_session` | |||||
| mock_generate.side_effect = ['mock-client-token'] | |||||
| self.client.force_login(self.user) | |||||
| r = self.client.get(self.checkout_url) | |||||
| self.assertEqual(r.status_code, 200) | |||||
| mock_generate.assert_called_once() | |||||
| @mock.patch('braintree.client_token_gateway.ClientTokenGateway.generate') | |||||
| def test_token_in_session__no_expiry_in_session(self, mock_generate): | |||||
sybrenUnsubmitted Done Inline ActionsRename to test_token_in_session__missing_expiry sybren: Rename to `test_token_in_session__missing_expiry` | |||||
| mock_generate.side_effect = ['mock-client-token'] | |||||
| self.client.force_login(self.user) | |||||
| self.set_session('token-in-session', '') | |||||
| r = self.client.get(self.checkout_url) | |||||
| self.assertEqual(r.status_code, 200) | |||||
| # Without expiry in the session, the cached token should not be reused. | |||||
| mock_generate.assert_called_once() | |||||
| @mock.patch('braintree.client_token_gateway.ClientTokenGateway.generate') | |||||
| def test_token_in_session__expired_in_session(self, mock_generate): | |||||
sybrenUnsubmitted Done Inline ActionsRename to test_token_in_session__expired sybren: Rename to `test_token_in_session__expired` | |||||
| mock_generate.side_effect = ['mock-client-token'] | |||||
| self.client.force_login(self.user) | |||||
| self.set_session('token-in-session', '2020-04-07 12:31:14') | |||||
| r = self.client.get(self.checkout_url) | |||||
| self.assertEqual(r.status_code, 200) | |||||
| # Expired in the session, the cached token should not be reused. | |||||
| mock_generate.assert_called_once() | |||||
| @mock.patch('braintree.client_token_gateway.ClientTokenGateway.generate') | |||||
| def test_token_in_session__expiry_just_right(self, mock_generate): | |||||
sybrenUnsubmitted Done Inline ActionsRename to test_token_in_session__not_expired. sybren: Rename to `test_token_in_session__not_expired`.
| |||||
| mock_generate.side_effect = ['mock-client-token'] | |||||
| expiry = datetime.datetime.now() + datetime.timedelta(minutes=5) | |||||
sybrenUnsubmitted Done Inline ActionsSee comment above about the constant: here datetime.timedelta(minutes=5) should then be replaced with something like GATEWAY_TOKEN_EXPIRY / 2. sybren: See comment above about the constant: here `datetime.timedelta(minutes=5)` should then be… | |||||
| self.client.force_login(self.user) | |||||
| self.set_session('token-in-session', expiry.isoformat()) | |||||
| r = self.client.get(self.checkout_url) | |||||
| self.assertEqual(r.status_code, 200) | |||||
| # Not trustworthy in the session, the cached token should not be reused. | |||||
sybrenUnsubmitted Done Inline ActionsThis comment is nonsense, it is trustworthy so the cached token should be used. sybren: This comment is nonsense, it is trustworthy so the cached token should be used. | |||||
| mock_generate.assert_not_called() | |||||
| class CheckoutTestCase(AbstractCheckoutTestCase): | class CheckoutTestCase(AbstractCheckoutTestCase): | ||||
| def setUp(self) -> None: | def setUp(self) -> None: | ||||
| super().setUp() | super().setUp() | ||||
| # Do a GET first to mimick the normal request flow. | # Do a GET first to mimic the normal request flow. | ||||
| self.client.force_login(self.user) | self.client.force_login(self.user) | ||||
| r = self.client.get(self.checkout_url) | r = self.client.get(self.checkout_url) | ||||
| self.assertEqual(r.status_code, 200) | self.assertEqual(r.status_code, 200) | ||||
| @override_settings( | @override_settings( | ||||
| LOOPER_IS_AUTHORIZED_FOR_CUSTOMER_FUNCTION='tests.settings.is_never_authorized_for_customer' | LOOPER_IS_AUTHORIZED_FOR_CUSTOMER_FUNCTION='tests.settings.is_never_authorized_for_customer' | ||||
| ) | ) | ||||
| def test_checkout_can_change_customer_fail(self) -> None: | def test_checkout_can_change_customer_fail(self) -> None: | ||||
| ▲ Show 20 Lines • Show All 405 Lines • Show Last 20 Lines | |||||
Rename test_client_token_happy to test_fresh_session