From e0547d1edbb8ae49b65345774ba9c0196ecde3e5 Mon Sep 17 00:00:00 2001 From: Oleg Komarov Date: Thu, 11 Jul 2024 13:52:06 +0200 Subject: [PATCH 1/3] wip --- .../blender_fund_main/link_membership.html | 30 ++++++++--- .../tests/test_link_membership.py | 17 ++++-- blender_fund_main/urls.py | 3 ++ .../views/link_membership_or_donation.py | 9 +++- blender_fund_main/views/settings.py | 53 +++++++++++++++++++ templates/settings/membership_cancel.html | 6 ++- 6 files changed, 103 insertions(+), 15 deletions(-) diff --git a/blender_fund_main/templates/blender_fund_main/link_membership.html b/blender_fund_main/templates/blender_fund_main/link_membership.html index dcadada..5a38f2e 100644 --- a/blender_fund_main/templates/blender_fund_main/link_membership.html +++ b/blender_fund_main/templates/blender_fund_main/link_membership.html @@ -4,16 +4,31 @@ {% block admin_tools %}{# don't show any admin links here #}{% endblock admin_tools %} -{% block content_settings %} +{% block after_membership_info %} +{% if user.is_anonymous %}
-

Link Membership

+
+
+ You need a Blender ID account to manage this membership. + You can create a new Blender ID account if you don't have it yet. + Sign in +
+
+
+
+ To directly cancel your membership, please use the button below. +
+ {% csrf_token %} + +
+
+
+
+{% else %} +
+

Link Membership

-

- You are going to link this {{ membership.level.name }} membership - (created on {{ membership.created_at | date:"Y-m-d" }}, - currently {{ membership.status }}) to your account. -

{{ membership.level.badge }}
{% if membership.level.badge %} @@ -55,4 +70,5 @@
+{% endif %} {% endblock %} diff --git a/blender_fund_main/tests/test_link_membership.py b/blender_fund_main/tests/test_link_membership.py index 756604d..bae925c 100644 --- a/blender_fund_main/tests/test_link_membership.py +++ b/blender_fund_main/tests/test_link_membership.py @@ -25,14 +25,21 @@ class LinkMembershipTest(AbstractLooperTestCase): self.subscription = self.create_active_accountless_subscription() self.url = reverse('link_membership', kwargs={'token': self.link_customer_token.token}) - def test_get_redirects_if_not_logged_in(self): + def test_shows_cancelviatoken_if_not_logged_in(self): response = self.client.get(self.url) - self.assertEqual(response.status_code, 302) - self.assertEqual( - response['Location'], - f'/oauth/login?next=/link-membership/{self.link_customer_token.token}/', + self.assertEqual(response.status_code, 200) + self.assertContains(response, '
/cancel', settings.CancelMembershipView.as_view(), name='settings_membership_cancel'), + path('settings/membership/cancelviatoken/', + settings.CancelMembershipViaTokenView.as_view(), + name='settings_membership_cancel_via_token'), path( 'settings/billing/payment-methods/change/', diff --git a/blender_fund_main/views/link_membership_or_donation.py b/blender_fund_main/views/link_membership_or_donation.py index 6c2a13f..85f277b 100644 --- a/blender_fund_main/views/link_membership_or_donation.py +++ b/blender_fund_main/views/link_membership_or_donation.py @@ -4,7 +4,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.db import transaction from django.http import Http404 from django.shortcuts import get_object_or_404, redirect -from django.urls import reverse_lazy +from django.urls import reverse, reverse_lazy from django.views.generic import FormView from looper.models import ( @@ -77,7 +77,7 @@ def merge_customer_and_grant_badges(token: str, old_customer, user): campaign_order.campaign.grant_badges({campaign_order.order_id}) -class LinkMembershipView(LoginRequiredMixin, FormView): +class LinkMembershipView(FormView): template_name = 'blender_fund_main/link_membership.html' form_class = forms.LinkMembershipForm success_url = reverse_lazy('settings_home') @@ -113,6 +113,9 @@ class LinkMembershipView(LoginRequiredMixin, FormView): def get_context_data(self, **kwargs): context = super().get_context_data() + context['cancel_url'] = reverse( + 'settings_membership_cancel_via_token', kwargs={'token': self.kwargs['token']} + ) context['membership'] = self._get_membership(self.kwargs['token']) return context @@ -120,6 +123,8 @@ class LinkMembershipView(LoginRequiredMixin, FormView): token = self.kwargs['token'] membership = self._get_membership(token) user = self.request.user + if not user.is_authenticated: + return self.handle_no_permission() old_customer = membership.customer assert old_customer.user is None diff --git a/blender_fund_main/views/settings.py b/blender_fund_main/views/settings.py index 87931a3..bfe994e 100644 --- a/blender_fund_main/views/settings.py +++ b/blender_fund_main/views/settings.py @@ -209,6 +209,14 @@ class CancelMembershipView(SingleMembershipMixin, FormView): _log = log.getChild('CancelMembershipView') + def get_context_data(self, **kwargs): + return { + **super().get_context_data(**kwargs), + 'back_url': reverse( + 'settings_membership_edit', kwargs={'membership_id': self.membership_id} + ), + } + def get_success_url(self) -> str: return reverse('settings_membership_edit', kwargs={'membership_id': self.membership_id}) @@ -221,6 +229,51 @@ class CancelMembershipView(SingleMembershipMixin, FormView): return super().form_valid(form) +class CancelMembershipViaTokenView(FormView): + template_name = 'settings/membership_cancel.html' + form_class = forms.CancelMembershipForm + initial = {'confirm': False} + + _log = log.getChild('CancelMembershipViaTokenView') + + def get_membership(self, token): + linktoken = get_object_or_404(looper.models.LinkCustomerToken, token=token) + memberships = linktoken.customer.memberships + memberships_count = memberships.count() + if memberships_count != 1: + self._log.error( + 'Expected exactly one membership, found %s, customer pk=%s', + memberships_count, + linktoken.customer_id, + ) + return memberships.first() + + def get_context_data(self, **kwargs): + token = self.kwargs['token'] + membership = self.get_membership(token) + + return { + **super().get_context_data(**kwargs), + 'back_url': reverse('link_membership', kwargs={'token': token}), + 'membership': membership, + 'subscription': membership.subscription, + } + + def form_valid(self, form): + token = self.kwargs['token'] + membership = self.get_membership(token) + self._log.info('Cancelling membership pk=%d using token=%s', + membership.pk, token) + membership.cancel() + return super().form_valid(form) + + def get_success_url(self) -> str: + # land on the same page, the template will hide the form + # and confirm that cancellation has happened + return reverse('settings_membership_cancel_via_token', + kwargs={'token': self.kwargs['token']}) + + class ExtendMembershipView(SingleMembershipMixin, ExpectReadableIPAddressMixin, FormView): """Allow users to extend their membership by paying any amount.""" # TODO(Sybren): maybe move this into Looper, or at least some of the code. diff --git a/templates/settings/membership_cancel.html b/templates/settings/membership_cancel.html index 489fb14..6aea95c 100644 --- a/templates/settings/membership_cancel.html +++ b/templates/settings/membership_cancel.html @@ -4,6 +4,9 @@ {% block after_membership_info %}

Cancellation

+ {% if subscription.status == 'cancelled' or subscription.status == 'pending-cancellation' %} +

Your membership has been cancelled.

+ {% else %}

Are you sure you want to cancel your Blender Development Fund membership?

{% if subscription.status == 'active' and subscription.next_payment_in_future %}

@@ -15,7 +18,8 @@ {% csrf_token %} {% include "blender_fund_main/components/form.html" %}


- ← Keep Membership and Go Back + ← Keep Membership and Go Back + {% endif %} {% endblock after_membership_info %} -- 2.30.2 From 987df0d9375961d9d6be1e4b462d3524292a73cc Mon Sep 17 00:00:00 2001 From: Oleg Komarov Date: Thu, 11 Jul 2024 18:47:54 +0200 Subject: [PATCH 2/3] wording --- .../templates/blender_fund_main/link_membership.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blender_fund_main/templates/blender_fund_main/link_membership.html b/blender_fund_main/templates/blender_fund_main/link_membership.html index 5a38f2e..39a25b1 100644 --- a/blender_fund_main/templates/blender_fund_main/link_membership.html +++ b/blender_fund_main/templates/blender_fund_main/link_membership.html @@ -10,7 +10,7 @@
You need a Blender ID account to manage this membership. - You can create a new Blender ID account if you don't have it yet. + You can create a new Blender ID account if you don't have one yet. Sign in
-- 2.30.2 From 80c180550eda2662a5bf4410f5c5915f226a7a6a Mon Sep 17 00:00:00 2001 From: Oleg Komarov Date: Thu, 11 Jul 2024 18:50:38 +0200 Subject: [PATCH 3/3] markup --- .../templates/blender_fund_main/link_membership.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/blender_fund_main/templates/blender_fund_main/link_membership.html b/blender_fund_main/templates/blender_fund_main/link_membership.html index 39a25b1..b9a709c 100644 --- a/blender_fund_main/templates/blender_fund_main/link_membership.html +++ b/blender_fund_main/templates/blender_fund_main/link_membership.html @@ -11,7 +11,9 @@
You need a Blender ID account to manage this membership. You can create a new Blender ID account if you don't have one yet. - Sign in +
+ Sign in +
-- 2.30.2