mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-04 03:02:14 +01:00 
			
		
		
		
	Add tests for Hello Asso payments using a fake endpoint
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
		@@ -6,7 +6,7 @@ from django.contrib.contenttypes.models import ContentType
 | 
				
			|||||||
from django.contrib.sites.models import Site
 | 
					from django.contrib.sites.models import Site
 | 
				
			||||||
from django.core.files.uploadedfile import SimpleUploadedFile
 | 
					from django.core.files.uploadedfile import SimpleUploadedFile
 | 
				
			||||||
from django.core.management import call_command
 | 
					from django.core.management import call_command
 | 
				
			||||||
from django.test import TestCase
 | 
					from django.test import LiveServerTestCase, override_settings, TestCase
 | 
				
			||||||
from django.urls import reverse
 | 
					from django.urls import reverse
 | 
				
			||||||
from registration.models import CoachRegistration, Payment, StudentRegistration
 | 
					from registration.models import CoachRegistration, Payment, StudentRegistration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -875,6 +875,208 @@ class TestPayment(TestCase):
 | 
				
			|||||||
        self.assertFalse(payment.valid)
 | 
					        self.assertFalse(payment.valid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@override_settings(HELLOASSO_TEST_ENDPOINT=True, ROOT_URLCONF="tfjm.helloasso.test_urls")
 | 
				
			||||||
 | 
					class TestHelloAssoPayment(LiveServerTestCase):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Tests that are relative to a HelloAsso
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        self.superuser = User.objects.create_superuser(
 | 
				
			||||||
 | 
					            username="admin",
 | 
				
			||||||
 | 
					            email="admin@example.com",
 | 
				
			||||||
 | 
					            password="admin",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.tournament = Tournament.objects.create(
 | 
				
			||||||
 | 
					            name="France",
 | 
				
			||||||
 | 
					            place="Here",
 | 
				
			||||||
 | 
					            price=21,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.team = Team.objects.create(
 | 
				
			||||||
 | 
					            name="Super team",
 | 
				
			||||||
 | 
					            trigram="AAA",
 | 
				
			||||||
 | 
					            access_code="azerty",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.user = User.objects.create(
 | 
				
			||||||
 | 
					            first_name="Toto",
 | 
				
			||||||
 | 
					            last_name="Toto",
 | 
				
			||||||
 | 
					            email="toto@example.com",
 | 
				
			||||||
 | 
					            password="toto",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        StudentRegistration.objects.create(
 | 
				
			||||||
 | 
					            user=self.user,
 | 
				
			||||||
 | 
					            team=self.team,
 | 
				
			||||||
 | 
					            student_class=12,
 | 
				
			||||||
 | 
					            address="1 Rue de Rivoli",
 | 
				
			||||||
 | 
					            zip_code=75001,
 | 
				
			||||||
 | 
					            city="Paris",
 | 
				
			||||||
 | 
					            school="Earth",
 | 
				
			||||||
 | 
					            give_contact_to_animath=True,
 | 
				
			||||||
 | 
					            email_confirmed=True,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.coach = User.objects.create(
 | 
				
			||||||
 | 
					            first_name="Coach",
 | 
				
			||||||
 | 
					            last_name="Coach",
 | 
				
			||||||
 | 
					            email="coach@example.com",
 | 
				
			||||||
 | 
					            password="coach",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        CoachRegistration.objects.create(
 | 
				
			||||||
 | 
					            user=self.coach,
 | 
				
			||||||
 | 
					            team=self.team,
 | 
				
			||||||
 | 
					            address="1 Rue de Rivoli",
 | 
				
			||||||
 | 
					            zip_code=75001,
 | 
				
			||||||
 | 
					            city="Paris",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.team.participation.tournament = self.tournament
 | 
				
			||||||
 | 
					        self.team.participation.valid = True
 | 
				
			||||||
 | 
					        self.team.participation.save()
 | 
				
			||||||
 | 
					        self.client.force_login(self.user)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Site.objects.update(domain=self.live_server_url.replace("http://", ""))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_create_checkout_intent(self):
 | 
				
			||||||
 | 
					        with self.settings(HELLOASSO_TEST_ENDPOINT_URL=self.live_server_url):
 | 
				
			||||||
 | 
					            payment = Payment.objects.get(registrations=self.user.registration, final=False)
 | 
				
			||||||
 | 
					            checkout_intent = payment.create_checkout_intent()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self.assertIsNotNone(checkout_intent)
 | 
				
			||||||
 | 
					            self.assertEqual(checkout_intent['metadata'], {
 | 
				
			||||||
 | 
					                'payment_id': payment.pk,
 | 
				
			||||||
 | 
					                'users': [
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        'user_id': self.user.pk,
 | 
				
			||||||
 | 
					                        'first_name': self.user.first_name,
 | 
				
			||||||
 | 
					                        'last_name': self.user.last_name,
 | 
				
			||||||
 | 
					                        'email': self.user.email,
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                'final': False,
 | 
				
			||||||
 | 
					                'tournament_id': self.tournament.pk,
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            self.assertNotIn('order', checkout_intent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            checkout_intent_fetched = payment.get_checkout_intent()
 | 
				
			||||||
 | 
					            self.assertEqual(checkout_intent, checkout_intent_fetched)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Don't create a new checkout intent if one already exists
 | 
				
			||||||
 | 
					            checkout_intent_new = payment.create_checkout_intent()
 | 
				
			||||||
 | 
					            self.assertEqual(checkout_intent, checkout_intent_new)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            payment.refresh_from_db()
 | 
				
			||||||
 | 
					            self.assertEqual(payment.checkout_intent_id, checkout_intent['id'])
 | 
				
			||||||
 | 
					            self.assertFalse(payment.valid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_helloasso_payment_success(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Simulates the redirection to Hello Asso and the return for a successful payment.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        with self.settings(HELLOASSO_TEST_ENDPOINT_URL=self.live_server_url):
 | 
				
			||||||
 | 
					            payment = Payment.objects.get(registrations=self.user.registration, final=False)
 | 
				
			||||||
 | 
					            self.assertIsNone(payment.checkout_intent_id)
 | 
				
			||||||
 | 
					            self.assertFalse(payment.valid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            response = self.client.get(reverse('registration:update_payment', args=(payment.pk,)))
 | 
				
			||||||
 | 
					            self.assertEqual(response.status_code, 200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            response = self.client.get(reverse('registration:payment_hello_asso', args=(payment.pk,)),
 | 
				
			||||||
 | 
					                                       follow=True)
 | 
				
			||||||
 | 
					            self.assertEqual(response.status_code, 200)
 | 
				
			||||||
 | 
					            self.assertEqual(response.redirect_chain[-1],
 | 
				
			||||||
 | 
					                             (reverse('participation:team_detail', args=(self.team.pk,)), 302))
 | 
				
			||||||
 | 
					            self.assertIn("type=return", response.redirect_chain[1][0])
 | 
				
			||||||
 | 
					            self.assertIn("code=succeeded", response.redirect_chain[1][0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            payment.refresh_from_db()
 | 
				
			||||||
 | 
					            self.assertIsNotNone(payment.checkout_intent_id)
 | 
				
			||||||
 | 
					            self.assertTrue(payment.valid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            checkout_intent = payment.get_checkout_intent()
 | 
				
			||||||
 | 
					            self.assertIn('order', checkout_intent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_helloasso_payment_refused(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Simulates the redirection to Hello Asso and the return for a refused payment.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        with self.settings(HELLOASSO_TEST_ENDPOINT_URL=self.live_server_url):
 | 
				
			||||||
 | 
					            payment = Payment.objects.get(registrations=self.user.registration, final=False)
 | 
				
			||||||
 | 
					            checkout_intent = payment.create_checkout_intent()
 | 
				
			||||||
 | 
					            self.assertFalse(payment.valid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            response = self.client.get(reverse('registration:update_payment', args=(payment.pk,)))
 | 
				
			||||||
 | 
					            self.assertEqual(response.status_code, 200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            response = self.client.get(checkout_intent['redirectUrl'] + "?refused", follow=True)
 | 
				
			||||||
 | 
					            self.assertEqual(response.status_code, 200)
 | 
				
			||||||
 | 
					            self.assertEqual(response.redirect_chain[-1],
 | 
				
			||||||
 | 
					                             (reverse('registration:update_payment', args=(payment.pk,)), 302))
 | 
				
			||||||
 | 
					            self.assertIn("type=return", response.redirect_chain[0][0])
 | 
				
			||||||
 | 
					            self.assertIn("code=refused", response.redirect_chain[0][0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            payment.refresh_from_db()
 | 
				
			||||||
 | 
					            self.assertFalse(payment.valid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            checkout_intent = payment.get_checkout_intent()
 | 
				
			||||||
 | 
					            self.assertNotIn('order', checkout_intent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_helloasso_payment_error(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Simulates the redirection to Hello Asso and the return for an errored payment.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        with self.settings(HELLOASSO_TEST_ENDPOINT_URL=self.live_server_url):
 | 
				
			||||||
 | 
					            payment = Payment.objects.get(registrations=self.user.registration, final=False)
 | 
				
			||||||
 | 
					            checkout_intent = payment.create_checkout_intent()
 | 
				
			||||||
 | 
					            self.assertFalse(payment.valid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            response = self.client.get(reverse('registration:update_payment', args=(payment.pk,)))
 | 
				
			||||||
 | 
					            self.assertEqual(response.status_code, 200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            response = self.client.get(checkout_intent['redirectUrl'] + "?error", follow=True)
 | 
				
			||||||
 | 
					            self.assertEqual(response.status_code, 200)
 | 
				
			||||||
 | 
					            self.assertEqual(response.redirect_chain[-1],
 | 
				
			||||||
 | 
					                             (reverse('registration:update_payment', args=(payment.pk,)), 302))
 | 
				
			||||||
 | 
					            self.assertIn("type=error", response.redirect_chain[0][0])
 | 
				
			||||||
 | 
					            self.assertIn("error=", response.redirect_chain[0][0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            payment.refresh_from_db()
 | 
				
			||||||
 | 
					            self.assertFalse(payment.valid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            checkout_intent = payment.get_checkout_intent()
 | 
				
			||||||
 | 
					            self.assertNotIn('order', checkout_intent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_anonymous_payment(self):
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        Test to make a successful payment from an anonymous user, authenticated by token.
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.client.logout()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with self.settings(HELLOASSO_TEST_ENDPOINT_URL=self.live_server_url):
 | 
				
			||||||
 | 
					            payment = Payment.objects.get(registrations=self.user.registration, final=False)
 | 
				
			||||||
 | 
					            self.assertIsNone(payment.checkout_intent_id)
 | 
				
			||||||
 | 
					            self.assertFalse(payment.valid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            response = self.client.get(reverse('registration:payment_hello_asso', args=(payment.pk,)),
 | 
				
			||||||
 | 
					                                       follow=True)
 | 
				
			||||||
 | 
					            self.assertRedirects(response,
 | 
				
			||||||
 | 
					                                 f"{reverse('login')}?next="
 | 
				
			||||||
 | 
					                                 f"{reverse('registration:payment_hello_asso', args=(payment.pk,))}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            response = self.client.get(
 | 
				
			||||||
 | 
					                reverse('registration:payment_hello_asso', args=(payment.pk,)) + "?token=" + payment.token,
 | 
				
			||||||
 | 
					                follow=True)
 | 
				
			||||||
 | 
					            self.assertEqual(response.status_code, 200)
 | 
				
			||||||
 | 
					            self.assertEqual(response.redirect_chain[-1], (reverse('index'), 302))
 | 
				
			||||||
 | 
					            self.assertIn("type=return", response.redirect_chain[1][0])
 | 
				
			||||||
 | 
					            self.assertIn("code=succeeded", response.redirect_chain[1][0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            payment.refresh_from_db()
 | 
				
			||||||
 | 
					            self.assertIsNotNone(payment.checkout_intent_id)
 | 
				
			||||||
 | 
					            self.assertTrue(payment.valid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            checkout_intent = payment.get_checkout_intent()
 | 
				
			||||||
 | 
					            self.assertIn('order', checkout_intent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestAdmin(TestCase):
 | 
					class TestAdmin(TestCase):
 | 
				
			||||||
    def setUp(self) -> None:
 | 
					    def setUp(self) -> None:
 | 
				
			||||||
        self.user = User.objects.create_superuser(
 | 
					        self.user = User.objects.create_superuser(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@ _expires_at = None
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def _get_hello_asso_api_base_url():
 | 
					def _get_hello_asso_api_base_url():
 | 
				
			||||||
    if settings.HELLOASSO_TEST_ENDPOINT:
 | 
					    if settings.HELLOASSO_TEST_ENDPOINT:
 | 
				
			||||||
        return f"{settings.HELLOASSO_TEST_ENDPOINT_URL}/helloasso-test"
 | 
					        return f"{settings.HELLOASSO_TEST_ENDPOINT_URL}/helloasso-test/api"
 | 
				
			||||||
    elif not settings.DEBUG:
 | 
					    elif not settings.DEBUG:
 | 
				
			||||||
        return "https://api.helloasso.com"
 | 
					        return "https://api.helloasso.com"
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										23
									
								
								tfjm/helloasso/test_urls.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								tfjm/helloasso/test_urls.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					# Copyright (C) 2024 by Animath
 | 
				
			||||||
 | 
					# SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.urls import path
 | 
				
			||||||
 | 
					import tfjm.urls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from . import test_views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					urlpatterns = tfjm.urls.urlpatterns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					urlpatterns += [
 | 
				
			||||||
 | 
					    path('helloasso-test/api/oauth2/token', test_views.TestHelloAssoOAuth2View.as_view(),
 | 
				
			||||||
 | 
					         name='helloasso-test-oauth2-token'),
 | 
				
			||||||
 | 
					    path('helloasso-test/api/v5/organizations/animath/checkout-intents/',
 | 
				
			||||||
 | 
					         test_views.TestHelloAssoCheckoutIntentCreateView.as_view(),
 | 
				
			||||||
 | 
					         name='helloasso-test-checkout-intent-create'),
 | 
				
			||||||
 | 
					    path('helloasso-test/api/v5/organizations/animath/checkout-intents/<int:checkout_intent_id>/',
 | 
				
			||||||
 | 
					         test_views.TestHelloAssoCheckoutIntentDetailView.as_view(),
 | 
				
			||||||
 | 
					         name='helloasso-test-checkout-intent-detail'),
 | 
				
			||||||
 | 
					    path('helloasso-test/redirect-payment/<int:checkout_intent_id>/',
 | 
				
			||||||
 | 
					         test_views.TestHelloAssoRedirectPaymentView.as_view(),
 | 
				
			||||||
 | 
					         name='helloasso-test-redirect-payment'),
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
							
								
								
									
										149
									
								
								tfjm/helloasso/test_views.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								tfjm/helloasso/test_views.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
				
			|||||||
 | 
					# Copyright (C) 2024 by Animath
 | 
				
			||||||
 | 
					# SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.conf import settings
 | 
				
			||||||
 | 
					from django.http import Http404, HttpResponse, JsonResponse
 | 
				
			||||||
 | 
					from django.shortcuts import redirect
 | 
				
			||||||
 | 
					from django.urls import reverse
 | 
				
			||||||
 | 
					from django.utils import timezone
 | 
				
			||||||
 | 
					from django.utils.decorators import method_decorator
 | 
				
			||||||
 | 
					from django.views.decorators.csrf import csrf_exempt
 | 
				
			||||||
 | 
					from django.views.generic.base import View
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_CHECKOUT_INTENTS = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@method_decorator(csrf_exempt, name='dispatch')
 | 
				
			||||||
 | 
					class TestHelloAssoOAuth2View(View):
 | 
				
			||||||
 | 
					    def post(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        data = {
 | 
				
			||||||
 | 
					            'access_token': 'test_access_token',
 | 
				
			||||||
 | 
					            'refresh_token': 'test_refresh_token',
 | 
				
			||||||
 | 
					            'expires_in': 3600,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return JsonResponse(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@method_decorator(csrf_exempt, name='dispatch')
 | 
				
			||||||
 | 
					class TestHelloAssoCheckoutIntentCreateView(View):
 | 
				
			||||||
 | 
					    def post(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        checkout_intent_id = len(_CHECKOUT_INTENTS) + 1
 | 
				
			||||||
 | 
					        body = json.loads(request.body.decode())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        body['backUrl'] = body['backUrl'].replace("https", "http")
 | 
				
			||||||
 | 
					        body['returnUrl'] = body['returnUrl'].replace("https", "http")
 | 
				
			||||||
 | 
					        body['errorUrl'] = body['errorUrl'].replace("https", "http")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        output_data = {
 | 
				
			||||||
 | 
					            'id': checkout_intent_id,
 | 
				
			||||||
 | 
					            'redirectUrl': f"{settings.HELLOASSO_TEST_ENDPOINT_URL}"
 | 
				
			||||||
 | 
					                           f"{reverse('helloasso-test-redirect-payment', args=(checkout_intent_id,))}",
 | 
				
			||||||
 | 
					            'metadata': body['metadata'],
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        checkout_intent = {'input': body, 'output': output_data}
 | 
				
			||||||
 | 
					        _CHECKOUT_INTENTS[checkout_intent_id] = checkout_intent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return JsonResponse(output_data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestHelloAssoCheckoutIntentDetailView(View):
 | 
				
			||||||
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        checkout_intent_id = kwargs['checkout_intent_id']
 | 
				
			||||||
 | 
					        if checkout_intent_id not in _CHECKOUT_INTENTS:
 | 
				
			||||||
 | 
					            raise Http404
 | 
				
			||||||
 | 
					        return JsonResponse(_CHECKOUT_INTENTS[checkout_intent_id]['output'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestHelloAssoRedirectPaymentView(View):
 | 
				
			||||||
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        checkout_intent_id = kwargs['checkout_intent_id']
 | 
				
			||||||
 | 
					        if checkout_intent_id not in _CHECKOUT_INTENTS:
 | 
				
			||||||
 | 
					            raise Http404
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        checkout_intent = _CHECKOUT_INTENTS[checkout_intent_id]
 | 
				
			||||||
 | 
					        ci_input = checkout_intent['input']
 | 
				
			||||||
 | 
					        ci_output = checkout_intent['output']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if 'error' in request.GET:
 | 
				
			||||||
 | 
					            return redirect(ci_input['errorUrl'] + f"&checkoutIntentId={checkout_intent_id}&error=An error occurred.")
 | 
				
			||||||
 | 
					        elif 'refused' in request.GET:
 | 
				
			||||||
 | 
					            return redirect(ci_input['returnUrl'] + f"&checkoutIntentId={checkout_intent_id}&code=refused")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dt = timezone.now().isoformat()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ci_output['order'] = {
 | 
				
			||||||
 | 
					            'payer': {
 | 
				
			||||||
 | 
					                'email': 'payer@example.com',
 | 
				
			||||||
 | 
					                'country': 'FRA',
 | 
				
			||||||
 | 
					                'dateOfBirth': '2000-01-01T00:00:00+01:00',
 | 
				
			||||||
 | 
					                'firstName': "Payer",
 | 
				
			||||||
 | 
					                'lastName': "Payer",
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            'items': [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    'payments': [
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            'id': checkout_intent_id,
 | 
				
			||||||
 | 
					                            'shareAmount': ci_input['totalAmount'],
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    ],
 | 
				
			||||||
 | 
					                    'name': ci_input['itemName'],
 | 
				
			||||||
 | 
					                    'priceCategory': 'Fixed',
 | 
				
			||||||
 | 
					                    'qrCode': '',
 | 
				
			||||||
 | 
					                    'id': checkout_intent_id,
 | 
				
			||||||
 | 
					                    'amount': ci_input['totalAmount'],
 | 
				
			||||||
 | 
					                    'type': 'Payment',
 | 
				
			||||||
 | 
					                    'state': 'Processed'
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            'payments': [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    'items': [
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            'id': checkout_intent_id,
 | 
				
			||||||
 | 
					                            'shareAmount': ci_input['totalAmount'],
 | 
				
			||||||
 | 
					                            'shareItemAmount': ci_input['totalAmount'],
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    ],
 | 
				
			||||||
 | 
					                    'cashOutState': 'MoneyIn',
 | 
				
			||||||
 | 
					                    'paymentReceiptUrl': "https://example.com/",
 | 
				
			||||||
 | 
					                    'id': checkout_intent_id,
 | 
				
			||||||
 | 
					                    'amount': ci_input['totalAmount'],
 | 
				
			||||||
 | 
					                    'date': dt,
 | 
				
			||||||
 | 
					                    'paymentMeans': 'Card',
 | 
				
			||||||
 | 
					                    'installmentNumber': 1,
 | 
				
			||||||
 | 
					                    'state': 'Authorized',
 | 
				
			||||||
 | 
					                    'meta': {
 | 
				
			||||||
 | 
					                        'createdAt': dt,
 | 
				
			||||||
 | 
					                        'updatedAt': dt,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    'refundOperations': []
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            'amount': {
 | 
				
			||||||
 | 
					                'total': ci_input['totalAmount'],
 | 
				
			||||||
 | 
					                'vat': 0,
 | 
				
			||||||
 | 
					                'discount': 0
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            'id': 13339,
 | 
				
			||||||
 | 
					            'date': dt,
 | 
				
			||||||
 | 
					            'formSlug': 'default',
 | 
				
			||||||
 | 
					            'formType': 'Checkout',
 | 
				
			||||||
 | 
					            'organizationName': 'Animath',
 | 
				
			||||||
 | 
					            'organizationSlug': 'animath',
 | 
				
			||||||
 | 
					            'checkoutIntentId': checkout_intent_id,
 | 
				
			||||||
 | 
					            'meta': {
 | 
				
			||||||
 | 
					                'createdAt': dt,
 | 
				
			||||||
 | 
					                'updatedAt': dt,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            'isAnonymous': False,
 | 
				
			||||||
 | 
					            'isAmountHidden': False
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return redirect(ci_input['returnUrl'] + f"&checkoutIntentId={checkout_intent_id}&code=succeeded")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def head(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        return HttpResponse()
 | 
				
			||||||
@@ -244,6 +244,7 @@ PHONENUMBER_DEFAULT_REGION = 'FR'
 | 
				
			|||||||
# Hello Asso API creds
 | 
					# Hello Asso API creds
 | 
				
			||||||
HELLOASSO_CLIENT_ID = os.getenv('HELLOASSO_CLIENT_ID', 'CHANGE_ME_IN_ENV_SETTINGS')
 | 
					HELLOASSO_CLIENT_ID = os.getenv('HELLOASSO_CLIENT_ID', 'CHANGE_ME_IN_ENV_SETTINGS')
 | 
				
			||||||
HELLOASSO_CLIENT_SECRET = os.getenv('HELLOASSO_CLIENT_SECRET', 'CHANGE_ME_IN_ENV_SETTINGS')
 | 
					HELLOASSO_CLIENT_SECRET = os.getenv('HELLOASSO_CLIENT_SECRET', 'CHANGE_ME_IN_ENV_SETTINGS')
 | 
				
			||||||
 | 
					HELLOASSO_TEST_ENDPOINT = False  # Enable custom test endpoint, for unit tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Custom parameters
 | 
					# Custom parameters
 | 
				
			||||||
PROBLEMS = [
 | 
					PROBLEMS = [
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user