Stripe checkout #104411
59
stripe_create_checkout_session.yaml
Normal file
59
stripe_create_checkout_session.yaml
Normal file
@ -0,0 +1,59 @@
|
||||
responses:
|
||||
- response:
|
||||
auto_calculate_content_length: false
|
||||
body: "{\n \"id\": \"cus_QFaxRrT6ZbD9NN\",\n \"object\": \"customer\",\n \"\
|
||||
address\": null,\n \"balance\": 0,\n \"created\": 1717778124,\n \"currency\"\
|
||||
: null,\n \"default_source\": null,\n \"delinquent\": false,\n \"description\"\
|
||||
: null,\n \"discount\": null,\n \"email\": \"my.billing.email@example.com\"\
|
||||
,\n \"invoice_prefix\": \"046F772E\",\n \"invoice_settings\": {\n \"custom_fields\"\
|
||||
: null,\n \"default_payment_method\": null,\n \"footer\": null,\n \"\
|
||||
rendering_options\": null\n },\n \"livemode\": false,\n \"metadata\": {},\n\
|
||||
\ \"name\": \"New Full Name\",\n \"phone\": null,\n \"preferred_locales\"\
|
||||
: [],\n \"shipping\": null,\n \"tax_exempt\": \"none\",\n \"test_clock\"\
|
||||
: null\n}"
|
||||
content_type: text/plain
|
||||
method: POST
|
||||
status: 200
|
||||
url: https://api.stripe.com/v1/customers
|
||||
- response:
|
||||
auto_calculate_content_length: false
|
||||
body: "{\n \"id\": \"cs_test_a1hoP4Yj4ZmfghAwGoUtWJngVt1XreEVLGAj2n7U5o9BlvqhnDimuA07zh\"\
|
||||
,\n \"object\": \"checkout.session\",\n \"after_expiration\": null,\n \"\
|
||||
allow_promotion_codes\": null,\n \"amount_subtotal\": 990,\n \"amount_total\"\
|
||||
: 990,\n \"automatic_tax\": {\n \"enabled\": false,\n \"liability\":\
|
||||
\ null,\n \"status\": null\n },\n \"billing_address_collection\": null,\n\
|
||||
\ \"cancel_url\": \"http://testserver/join/plan-variation/2/billing/\",\n \
|
||||
\ \"client_reference_id\": null,\n \"client_secret\": null,\n \"consent\"\
|
||||
: null,\n \"consent_collection\": null,\n \"created\": 1717778125,\n \"currency\"\
|
||||
: \"eur\",\n \"currency_conversion\": null,\n \"custom_fields\": [],\n \"\
|
||||
custom_text\": {\n \"after_submit\": null,\n \"shipping_address\": null,\n\
|
||||
\ \"submit\": null,\n \"terms_of_service_acceptance\": null\n },\n \"\
|
||||
customer\": \"cus_QFaxRrT6ZbD9NN\",\n \"customer_creation\": null,\n \"customer_details\"\
|
||||
: {\n \"address\": null,\n \"email\": \"my.billing.email@example.com\"\
|
||||
,\n \"name\": null,\n \"phone\": null,\n \"tax_exempt\": \"none\",\n\
|
||||
\ \"tax_ids\": null\n },\n \"customer_email\": null,\n \"expires_at\"\
|
||||
: 1717864524,\n \"invoice\": null,\n \"invoice_creation\": {\n \"enabled\"\
|
||||
: false,\n \"invoice_data\": {\n \"account_tax_ids\": null,\n \"\
|
||||
custom_fields\": null,\n \"description\": null,\n \"footer\": null,\n\
|
||||
\ \"issuer\": null,\n \"metadata\": {},\n \"rendering_options\"\
|
||||
: null\n }\n },\n \"livemode\": false,\n \"locale\": null,\n \"metadata\"\
|
||||
: {},\n \"mode\": \"payment\",\n \"payment_intent\": null,\n \"payment_link\"\
|
||||
: null,\n \"payment_method_collection\": \"if_required\",\n \"payment_method_configuration_details\"\
|
||||
: null,\n \"payment_method_options\": {\n \"card\": {\n \"request_three_d_secure\"\
|
||||
: \"automatic\"\n }\n },\n \"payment_method_types\": [\n \"card\",\n\
|
||||
\ \"link\",\n \"paypal\"\n ],\n \"payment_status\": \"unpaid\",\n \"\
|
||||
phone_number_collection\": {\n \"enabled\": false\n },\n \"recovered_from\"\
|
||||
: null,\n \"saved_payment_method_options\": {\n \"allow_redisplay_filters\"\
|
||||
: [\n \"always\"\n ],\n \"payment_method_remove\": null,\n \"\
|
||||
payment_method_save\": null\n },\n \"setup_intent\": null,\n \"shipping_address_collection\"\
|
||||
: null,\n \"shipping_cost\": null,\n \"shipping_details\": null,\n \"shipping_options\"\
|
||||
: [],\n \"status\": \"open\",\n \"submit_type\": \"pay\",\n \"subscription\"\
|
||||
: null,\n \"success_url\": \"http://testserver/looper/stripe_success/1/{CHECKOUT_SESSION_ID}\"\
|
||||
,\n \"total_details\": {\n \"amount_discount\": 0,\n \"amount_shipping\"\
|
||||
: 0,\n \"amount_tax\": 0\n },\n \"ui_mode\": \"hosted\",\n \"url\": \"\
|
||||
https://checkout.stripe.com/c/pay/cs_test_a1hoP4Yj4ZmfghAwGoUtWJngVt1XreEVLGAj2n7U5o9BlvqhnDimuA07zh#fidkdWxOYHwnPyd1blpxYHZxWjA0VUpnNzNAMU5EUEcwYW92dWIwclxRMzQ8ZkxsUDRET2dPbTVidnBCNEJTdlBJQTRJYFF2c09BMEFBdlxVT19USGpWSXRSXFJwdm5UQXRpdVw2Rmp%2FZ11NNTU3fHdHUl1JTCcpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl\"\
|
||||
\n}"
|
||||
content_type: text/plain
|
||||
method: POST
|
||||
status: 200
|
||||
url: https://api.stripe.com/v1/checkout/sessions
|
@ -1,5 +1,4 @@
|
||||
"""Views handling subscription management."""
|
||||
from decimal import Decimal
|
||||
import logging
|
||||
|
||||
from django.contrib import messages
|
||||
@ -43,6 +42,24 @@ class JoinView(LoginRequiredMixin, FormView):
|
||||
)
|
||||
return existing_subscriptions.first()
|
||||
|
||||
def _set_preferred_currency_and_redirect(self):
|
||||
# If no country is set in the existing address, use GeoIP's
|
||||
geoip_country = self.request.session.get(looper.middleware.COUNTRY_CODE_SESSION_KEY)
|
||||
if geoip_country and (not self.customer or not self.customer.billing_address.country):
|
||||
country = geoip_country
|
||||
else:
|
||||
country = self.customer.billing_address.country
|
||||
currency = preferred_currency_for_country_code(country)
|
||||
if self.plan_variation.currency != currency:
|
||||
# If variation's currency doesn't match, redirect to another plan variation
|
||||
plan_variation = self.plan_variation.in_other_currency(currency)
|
||||
self.request.session[looper.middleware.PREFERRED_CURRENCY_SESSION_KEY] = currency
|
||||
self.request.session.modified = True
|
||||
return redirect(
|
||||
'subscriptions:join-billing-details', plan_variation_id=plan_variation.pk
|
||||
)
|
||||
return None # nothing to do, no need to redirect
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
"""Redirect to login or to billing, or prepare plan variation."""
|
||||
if not request.user.is_authenticated:
|
||||
@ -62,6 +79,10 @@ class JoinView(LoginRequiredMixin, FormView):
|
||||
self.user = request.user
|
||||
self.customer = self.user.customer
|
||||
self.subscription = self._get_existing_subscription()
|
||||
|
||||
response_redirect = self._set_preferred_currency_and_redirect()
|
||||
if response_redirect:
|
||||
return response_redirect
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_form_kwargs(self, *args, **kwargs):
|
||||
@ -164,27 +185,21 @@ class JoinView(LoginRequiredMixin, FormView):
|
||||
form.save()
|
||||
|
||||
msg = 'Pricing has been updated to reflect changes to your billing details'
|
||||
new_country = self.customer.billing_address.country
|
||||
new_currency = preferred_currency_for_country_code(new_country)
|
||||
# Compare currency before and after the billing address is updated
|
||||
if self.plan_variation.currency != new_currency:
|
||||
# If currency has changed, find a matching plan variation for this new currency
|
||||
plan_variation = self.plan_variation.in_other_currency(new_currency)
|
||||
self.request.session[looper.middleware.PREFERRED_CURRENCY_SESSION_KEY] = new_currency
|
||||
response_redirect = self._set_preferred_currency_and_redirect()
|
||||
if response_redirect:
|
||||
messages.add_message(self.request, messages.INFO, msg)
|
||||
return redirect(
|
||||
'subscriptions:join-billing-details', plan_variation_id=plan_variation.pk
|
||||
)
|
||||
return response_redirect
|
||||
|
||||
# Compare tax before and after the billing address is updated
|
||||
new_tax = self.customer.get_tax(product_type=product_type)
|
||||
new_taxable = looper.taxes.Taxable(self.plan_variation.price, *new_tax)
|
||||
if old_taxable != new_taxable:
|
||||
# If price has changed, stay on the same page and display a notification
|
||||
messages.add_message(self.request, messages.INFO, msg)
|
||||
return self.form_invalid(form)
|
||||
|
||||
gateway = self.gateway_from_form(form)
|
||||
price_cents = int(Decimal(form.cleaned_data['price']) * 100)
|
||||
price_cents = new_taxable.price.cents
|
||||
subscription = self._get_or_create_subscription(gateway)
|
||||
# Update the tax info stored on the subscription
|
||||
subscription.update_tax()
|
||||
|
@ -1,13 +1,15 @@
|
||||
from typing import Tuple
|
||||
from unittest.mock import patch
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from django.conf import settings
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from freezegun import freeze_time
|
||||
import responses
|
||||
|
||||
# from responses import _recorder
|
||||
|
||||
from looper.tests.test_preferred_currency import EURO_IPV4, USA_IPV4, SINGAPORE_IPV4
|
||||
from looper.money import Money
|
||||
import looper.models
|
||||
@ -41,7 +43,7 @@ def _get_default_variation(currency='USD'):
|
||||
|
||||
|
||||
@freeze_time('2023-05-19 11:41:11')
|
||||
class TestGETBillingDetailsView(BaseSubscriptionTestCase):
|
||||
class TestGETJoinView(BaseSubscriptionTestCase):
|
||||
url_usd = reverse('subscriptions:join-billing-details', kwargs={'plan_variation_id': 1})
|
||||
url = reverse('subscriptions:join-billing-details', kwargs={'plan_variation_id': 2})
|
||||
|
||||
@ -65,7 +67,8 @@ class TestGETBillingDetailsView(BaseSubscriptionTestCase):
|
||||
)
|
||||
|
||||
def test_get_displays_total_and_billing_details_to_logged_in_nl(self):
|
||||
user = create_customer_with_billing_address(vat_number='', country='NL')
|
||||
customer = create_customer_with_billing_address(vat_number='', country='NL')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
response = self.client.get(self.url, REMOTE_ADDR=EURO_IPV4)
|
||||
@ -76,7 +79,8 @@ class TestGETBillingDetailsView(BaseSubscriptionTestCase):
|
||||
self._assert_total_default_variation_selected_tax_21_eur(response)
|
||||
|
||||
def test_get_displays_total_and_billing_details_to_logged_in_de(self):
|
||||
user = create_customer_with_billing_address(vat_number='', country='DE')
|
||||
customer = create_customer_with_billing_address(vat_number='', country='DE')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
response = self.client.get(self.url, REMOTE_ADDR=EURO_IPV4)
|
||||
@ -86,9 +90,10 @@ class TestGETBillingDetailsView(BaseSubscriptionTestCase):
|
||||
self._assert_total_default_variation_selected_tax_19_eur(response)
|
||||
|
||||
def test_get_displays_total_and_billing_details_to_logged_in_us(self):
|
||||
user = create_customer_with_billing_address(
|
||||
customer = create_customer_with_billing_address(
|
||||
vat_number='', country='US', region='NY', postal_code='12001'
|
||||
)
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
response = self.client.get(self.url_usd)
|
||||
@ -99,16 +104,23 @@ class TestGETBillingDetailsView(BaseSubscriptionTestCase):
|
||||
self._assert_total_default_variation_selected_usd(response)
|
||||
|
||||
@unittest.skipUnless(os.path.exists(settings.GEOIP2_DB), 'GeoIP database file is required')
|
||||
def test_get_detects_country_us_sets_preferred_currency_usd_invalid_variation(self):
|
||||
user = create_customer_with_billing_address()
|
||||
def test_get_detects_country_us_sets_preferred_currency_usd_and_redirects(self):
|
||||
customer = create_customer_with_billing_address()
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
self.assertTrue(looper.middleware.PREFERRED_CURRENCY_SESSION_KEY not in self.client.session)
|
||||
|
||||
response = self.client.get(self.url, REMOTE_ADDR=USA_IPV4)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response['Location'], self.url_usd)
|
||||
self.assertEqual(
|
||||
self.client.session[looper.middleware.PREFERRED_CURRENCY_SESSION_KEY], 'USD'
|
||||
)
|
||||
|
||||
@unittest.skipUnless(os.path.exists(settings.GEOIP2_DB), 'GeoIP database file is required')
|
||||
def test_get_detects_country_us_sets_preferred_currency_usd(self):
|
||||
user = create_customer_with_billing_address()
|
||||
customer = create_customer_with_billing_address()
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
response = self.client.get(self.url_usd, REMOTE_ADDR=USA_IPV4)
|
||||
@ -125,7 +137,8 @@ class TestGETBillingDetailsView(BaseSubscriptionTestCase):
|
||||
|
||||
@unittest.skipUnless(os.path.exists(settings.GEOIP2_DB), 'GeoIP database file is required')
|
||||
def test_get_detects_country_sg_sets_preferred_currency_eur(self):
|
||||
user = create_customer_with_billing_address()
|
||||
customer = create_customer_with_billing_address()
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
response = self.client.get(self.url, REMOTE_ADDR=SINGAPORE_IPV4)
|
||||
@ -142,7 +155,8 @@ class TestGETBillingDetailsView(BaseSubscriptionTestCase):
|
||||
|
||||
@unittest.skipUnless(os.path.exists(settings.GEOIP2_DB), 'GeoIP database file is required')
|
||||
def test_get_detects_country_nl_sets_preferred_currency_eur_displays_correct_vat(self):
|
||||
user = create_customer_with_billing_address()
|
||||
customer = create_customer_with_billing_address()
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
response = self.client.get(self.url, REMOTE_ADDR=EURO_IPV4)
|
||||
@ -158,12 +172,15 @@ class TestGETBillingDetailsView(BaseSubscriptionTestCase):
|
||||
|
||||
|
||||
@freeze_time('2023-05-19 11:41:11')
|
||||
class TestPOSTBillingDetailsView(BaseSubscriptionTestCase):
|
||||
@responses.activate
|
||||
class TestPOSTJoinView(BaseSubscriptionTestCase):
|
||||
url_usd = reverse('subscriptions:join-billing-details', kwargs={'plan_variation_id': 1})
|
||||
url = reverse('subscriptions:join-billing-details', kwargs={'plan_variation_id': 2})
|
||||
responses._add_from_file('stripe_create_checkout_session.yaml')
|
||||
|
||||
def test_post_updates_billing_address_and_customer_renders_next_form_de(self):
|
||||
user = create_customer_with_billing_address(vat_number='', country='DE')
|
||||
customer = create_customer_with_billing_address(vat_number='', country='DE')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
selected_variation = (
|
||||
@ -197,33 +214,21 @@ class TestPOSTBillingDetailsView(BaseSubscriptionTestCase):
|
||||
self.assertContains(response, 'Manual ')
|
||||
self.assertContains(response, '/ <span class="x-price-period">1 year</span>', html=True)
|
||||
|
||||
# @_recorder.record(file_path='stripe_create_checkout_session.yaml')
|
||||
def test_post_has_correct_price_field_value(self):
|
||||
self.client.force_login(self.user)
|
||||
|
||||
default_variation = _get_default_variation('EUR')
|
||||
data = required_address_data
|
||||
response = self.client.post(self.url, data, REMOTE_ADDR=EURO_IPV4)
|
||||
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(
|
||||
response['Location'],
|
||||
reverse(
|
||||
'subscriptions:join-confirm-and-pay',
|
||||
kwargs={'plan_variation_id': default_variation.pk},
|
||||
),
|
||||
)
|
||||
|
||||
# Follow the redirect to avoid "Couldn't retrieve content: Response code was 302 (expected 200)"
|
||||
response = self.client.get(response['Location'])
|
||||
# Check that we are no longer on the billing details page
|
||||
self._assert_payment_form_displayed(response)
|
||||
|
||||
self._assert_total_default_variation_selected_tax_21_eur(response)
|
||||
# The hidden price field must also be set to a matching amount
|
||||
self.assertContains(
|
||||
response,
|
||||
'<input type="hidden" name="price" value="9.90" class="form-control" id="id_price">',
|
||||
html=True,
|
||||
'https://checkout.stripe.com/c/pay/cs_test_a1hoP4Yj4ZmfghAwGoUtWJngVt1XreEVLGAj2'
|
||||
'n7U5o9BlvqhnDimuA07zh#fidkdWxOYHwnPyd1blpxYHZxWjA0VUpnNzNAMU5EUEcwYW92dWIwclxRMzQ8Zkx'
|
||||
'sUDRET2dPbTVidnBCNEJTdlBJQTRJYFF2c09BMEFBdlxVT19USGpWSXRSXFJwdm5UQXRpdVw2Rmp'
|
||||
'%2FZ11NNTU3fHdHUl1JTCcpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabH'
|
||||
'FgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl',
|
||||
)
|
||||
|
||||
def test_post_updates_billing_address_and_customer_applies_reverse_charged_tax(self):
|
||||
@ -240,8 +245,8 @@ class TestPOSTBillingDetailsView(BaseSubscriptionTestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.user.refresh_from_db()
|
||||
self.assertEqual(self.user.customer.vat_number, 'DE260543043')
|
||||
address = self.user.customer.billing_address
|
||||
self.assertEqual(address.vat_number, 'DE260543043')
|
||||
self.assertEqual(address.full_name, 'New Full Name')
|
||||
self.assertEqual(address.postal_code, '11111')
|
||||
self.assertEqual(address.country, 'DE')
|
||||
@ -269,9 +274,10 @@ class TestPOSTBillingDetailsView(BaseSubscriptionTestCase):
|
||||
)
|
||||
|
||||
def test_post_changing_address_from_with_region_to_without_region_clears_region(self):
|
||||
user = create_customer_with_billing_address(
|
||||
customer = create_customer_with_billing_address(
|
||||
vat_number='', country='US', region='NY', postal_code='12001'
|
||||
)
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
response = self.client.get(self.url_usd)
|
||||
@ -304,22 +310,10 @@ class TestPOSTBillingDetailsView(BaseSubscriptionTestCase):
|
||||
self.assertEqual(user.customer.billing_address.country, 'DE')
|
||||
self.assertEqual(user.customer.billing_address.postal_code, '11111')
|
||||
|
||||
|
||||
@freeze_time('2023-05-19 11:41:11')
|
||||
class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
def _get_url_for(self, **filter_params) -> Tuple[str, looper.models.PlanVariation]:
|
||||
plan_variation = looper.models.PlanVariation.objects.active().get(**filter_params)
|
||||
return (
|
||||
reverse(
|
||||
'subscriptions:join-confirm-and-pay',
|
||||
kwargs={'plan_variation_id': plan_variation.pk},
|
||||
),
|
||||
plan_variation,
|
||||
)
|
||||
|
||||
def test_plan_variation_does_not_match_detected_currency_usd_euro_ip(self):
|
||||
url, _ = self._get_url_for(currency='USD', price=11900)
|
||||
user = create_customer_with_billing_address(country='NL')
|
||||
customer = create_customer_with_billing_address(country='NL')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
data = required_address_data
|
||||
@ -329,7 +323,8 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
|
||||
def test_plan_variation_matches_detected_currency_eur_non_eea_ip(self):
|
||||
url, _ = self._get_url_for(currency='EUR', price=990)
|
||||
user = create_customer_with_billing_address()
|
||||
customer = create_customer_with_billing_address()
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
data = required_address_data
|
||||
@ -341,7 +336,8 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
|
||||
def test_billing_address_country_takes_precedence_over_geo_ip(self):
|
||||
url, _ = self._get_url_for(currency='EUR', price=990)
|
||||
user = create_customer_with_billing_address(country='NL')
|
||||
customer = create_customer_with_billing_address(country='NL')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
data = required_address_data
|
||||
@ -352,7 +348,8 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
|
||||
def test_invalid_missing_required_fields(self):
|
||||
url, _ = self._get_url_for(currency='EUR', price=990)
|
||||
user = create_customer_with_billing_address(country='NL')
|
||||
customer = create_customer_with_billing_address(country='NL')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
data = required_address_data
|
||||
@ -371,7 +368,8 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
|
||||
def test_invalid_price_does_not_match_selected_plan_variation(self):
|
||||
url, selected_variation = self._get_url_for(currency='EUR', price=990)
|
||||
user = create_customer_with_billing_address(country='NL')
|
||||
customer = create_customer_with_billing_address(country='NL')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
data = {
|
||||
@ -391,7 +389,8 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
|
||||
def test_invalid_bank_transfer_cannot_be_selected_for_automatic_payments(self):
|
||||
url, selected_variation = self._get_url_for(currency='EUR', price=990)
|
||||
user = create_customer_with_billing_address(country='NL')
|
||||
customer = create_customer_with_billing_address(country='NL')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
data = {
|
||||
@ -423,7 +422,8 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
)
|
||||
@responses.activate
|
||||
def test_pay_with_bank_transfer_creates_order_subscription_on_hold(self):
|
||||
user = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
customer = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
util.mock_blender_id_badger_badger_response(
|
||||
'grant', 'cloud_has_subscription', user.oauth_info.oauth_user_id
|
||||
@ -500,9 +500,10 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
def test_pay_with_bank_transfer_creates_order_subscription_on_hold_shows_reverse_charged_price(
|
||||
self,
|
||||
):
|
||||
user = create_customer_with_billing_address(
|
||||
customer = create_customer_with_billing_address(
|
||||
country='ES', full_name='Jane Doe', vat_number='DE260543043'
|
||||
)
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
util.mock_blender_id_badger_badger_response(
|
||||
'grant', 'cloud_has_subscription', user.oauth_info.oauth_user_id
|
||||
@ -584,7 +585,8 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
@responses.activate
|
||||
def test_pay_with_credit_card_creates_order_subscription_active(self):
|
||||
url, selected_variation = self._get_url_for(currency='EUR', price=990)
|
||||
user = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
customer = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
util.mock_blender_id_badger_badger_response(
|
||||
'grant', 'cloud_has_subscription', user.oauth_info.oauth_user_id
|
||||
@ -636,7 +638,8 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
price=9000,
|
||||
plan__name='Automatic renewal, 15 seats',
|
||||
)
|
||||
user = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
customer = create_customer_with_billing_address(country='NL', full_name='Jane Doe')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
util.mock_blender_id_badger_badger_response(
|
||||
'grant', 'cloud_has_subscription', user.oauth_info.oauth_user_id
|
||||
@ -655,7 +658,7 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
|
||||
self._assert_done_page_displayed(response)
|
||||
|
||||
subscription = user.customer.subscription_set.first()
|
||||
subscription = customer.subscription_set.first()
|
||||
order = subscription.latest_order()
|
||||
self.assertEqual(subscription.status, 'active')
|
||||
self.assertEqual(subscription.price, Money('EUR', 9000))
|
||||
@ -670,7 +673,8 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
self._assert_team_subscription_activated_email_is_sent(subscription)
|
||||
|
||||
def test_pay_with_credit_card_creates_order_subscription_active_business_de(self):
|
||||
user = create_customer_with_billing_address(country='DE', vat_number='DE260543043')
|
||||
customer = create_customer_with_billing_address(country='DE', vat_number='DE260543043')
|
||||
user = customer.user
|
||||
self.client.force_login(user)
|
||||
|
||||
url, selected_variation = self._get_url_for(
|
||||
@ -716,15 +720,17 @@ class TestPOSTConfirmAndPayView(BaseSubscriptionTestCase):
|
||||
self.assertIsNotNone(order.number)
|
||||
|
||||
|
||||
class TestJoinConfirmAndPayLoggedInUserOnlyView(BaseSubscriptionTestCase):
|
||||
url = reverse('subscriptions:join-confirm-and-pay', kwargs={'plan_variation_id': 8})
|
||||
class TestJoinViewLoggedInUserOnly(TestCase):
|
||||
url = reverse('subscriptions:join-billing-details', kwargs={'plan_variation_id': 2})
|
||||
|
||||
def test_get_anonymous_403(self):
|
||||
def test_get_anonymous_redirects_to_login_with_next(self):
|
||||
response = self.client.get(self.url)
|
||||
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response['Location'], '/oauth/login?next=/join/plan-variation/2/billing/')
|
||||
|
||||
def test_join_post_anonymous_403(self):
|
||||
def test_post_anonymous_redirects_to_login_with_next(self):
|
||||
response = self.client.post(self.url)
|
||||
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response['Location'], '/oauth/login?next=/join/plan-variation/2/billing/')
|
||||
|
Loading…
Reference in New Issue
Block a user