From b0db7482a63a1d28668a3d9be6b456ff56189bd1 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <theskumar@users.noreply.github.com> Date: Tue, 26 Jul 2022 15:46:17 +0530 Subject: [PATCH] Relax the testing for Mailchimp library --- hypha/public/mailchimp/tests/test_views.py | 50 ++++------------- hypha/public/mailchimp/views.py | 65 +++++++++++++--------- 2 files changed, 48 insertions(+), 67 deletions(-) diff --git a/hypha/public/mailchimp/tests/test_views.py b/hypha/public/mailchimp/tests/test_views.py index 772cc990d..e3c7795b9 100644 --- a/hypha/public/mailchimp/tests/test_views.py +++ b/hypha/public/mailchimp/tests/test_views.py @@ -2,7 +2,6 @@ import re from unittest import mock from urllib import parse -import responses from django.test import TestCase, override_settings from django.urls import reverse @@ -14,15 +13,12 @@ class TestNewsletterView(TestCase): def setUp(self): self.origin = 'https://testserver/' - self.client.defaults = {'HTTP_ORIGIN': self.origin} def assertNewsletterRedirects(self, response, target_url, *args, **kwargs): url = response.redirect_chain[0][0] parts = parse.urlsplit(url) self.assertTrue(parts.query.startswith('newsletter-')) - target_url = target_url + '?' + parts.query - return self.assertRedirects(response, target_url, *args, **kwargs) def test_redirected_home_if_get(self): @@ -34,45 +30,19 @@ class TestNewsletterView(TestCase): MAILCHIMP_API_KEY='a' * 32, MAILCHIMP_LIST_ID='12345' ) - @responses.activate def test_can_subscribe(self): - responses.add(responses.POST, any_url, json={'id': '1234'}, status=200) + with mock.patch("hypha.public.mailchimp.views.subscribe_to_mailchimp") as mc_mock: + mc_mock.return_value = None + response = self.client.post(self.url, data={'email': 'email@email.com'}, secure=True, follow=True) - response = self.client.post(self.url, data={'email': 'email@email.com'}, secure=True, follow=True) - self.assertNewsletterRedirects(response, self.origin) + self.assertNewsletterRedirects(response, self.origin) - messages = list(response.context['messages']) - self.assertEqual(len(messages), 1) - self.assertIn('Thank you', str(messages[0])) + mc_mock.assert_called_once_with(email='email@email.com', data={'fname': '', 'lname': ''}) def test_error_in_form(self): - response = self.client.post(self.url, data={'email': 'email_is_bad.com'}, secure=True, follow=True) - self.assertNewsletterRedirects(response, self.origin) - - messages = list(response.context['messages']) - self.assertEqual(len(messages), 1) - self.assertIn('errors with', str(messages[0])) - - @override_settings( - MAILCHIMP_API_KEY='a' * 32, - MAILCHIMP_LIST_ID='12345' - ) - @responses.activate - @mock.patch('hypha.public.mailchimp.views.logger') - def test_error_with_mailchimp(self, logger): - # Copied from the mailchimp playground - response_data = { - "title": "Invalid Resource", - "status": 400, - "detail": "Please provide a valid email address.", - } - responses.add(responses.POST, any_url, json=response_data, status=400) - response = self.client.post(self.url, data={'email': 'email@email.com'}, secure=True, follow=True) - - self.assertNewsletterRedirects(response, self.origin) + with mock.patch("hypha.public.mailchimp.views.subscribe_to_mailchimp") as mc_mock: + mc_mock.return_value = None + response = self.client.post(self.url, data={'email': 'email_is_bad.com'}, secure=True, follow=True) + self.assertNewsletterRedirects(response, self.origin) - messages = list(response.context['messages']) - self.assertEqual(len(messages), 1) - self.assertIn('problem', str(messages[0])) - # See hypha/public/mailchimp/views.py warning() - # logger.error.assert_called_once_with(response_data) + assert not mc_mock.called, 'method should not have been called' diff --git a/hypha/public/mailchimp/views.py b/hypha/public/mailchimp/views.py index 7960122f0..c7967c0fa 100644 --- a/hypha/public/mailchimp/views.py +++ b/hypha/public/mailchimp/views.py @@ -16,6 +16,34 @@ from .forms import NewsletterForm logger = logging.getLogger(__name__) +def subscribe_to_mailchimp(email: str, data) -> None: + mailchimp_enabled = settings.MAILCHIMP_API_KEY and settings.MAILCHIMP_LIST_ID + + dummy_key = 'a' * 32 + + if not mailchimp_enabled: + raise Exception( + f'Incorrect Mailchimp configuration: ' + f'API_KEY: {settings.MAILCHIMP_API_KEY}, LIST_ID: {settings.MAILCHIMP_LIST_ID}' + ) + + client = MailChimp( + mc_api=settings.MAILCHIMP_API_KEY or dummy_key, + timeout=5.0, + enabled=mailchimp_enabled, + ) + data = {k.upper(): v for k, v in data.items()} + + client.lists.members.create( + settings.MAILCHIMP_LIST_ID, + { + 'email_address': email, + 'status': 'pending', + 'merge_fields': data, + }, + ) + + @method_decorator(csrf_exempt, name='dispatch') class MailchimpSubscribeView(FormMixin, RedirectView): form_class = NewsletterForm @@ -32,44 +60,27 @@ class MailchimpSubscribeView(FormMixin, RedirectView): return HttpResponseRedirect(self.get_success_url()) def form_valid(self, form): - mailchimp_enabled = settings.MAILCHIMP_API_KEY and settings.MAILCHIMP_LIST_ID - - dummy_key = 'a' * 32 - - client = MailChimp(mc_api=settings.MAILCHIMP_API_KEY or dummy_key, timeout=5.0, enabled=mailchimp_enabled) - data = form.cleaned_data.copy() email = data.pop('email') - data = { - k.upper(): v - for k, v in data.items() - } + try: - client.lists.members.create(settings.MAILCHIMP_LIST_ID, { - 'email_address': email, - 'status': 'pending', - 'merge_fields': data, - }) + subscribe_to_mailchimp(email=email, data=data) + self.success() except Exception as e: self.warning(e) - else: - if mailchimp_enabled: - self.success() - else: - self.warning(Exception( - 'Incorrect Mailchimp configuration: API_KEY: {}, LIST_ID: {}'.format( - str(settings.MAILCHIMP_API_KEY), - str(settings.MAILCHIMP_LIST_ID), - ) - )) return super().form_valid(form) def error(self, form): - messages.error(self.request, _('Sorry, there were errors with your form.') + str(form.errors)) + messages.error( + self.request, + _('Sorry, there were errors with your form.') + str(form.errors), + ) def warning(self, e): - messages.warning(self.request, _('Sorry, there has been an problem. Please try again later.')) + messages.warning( + self.request, _('Sorry, there has been an problem. Please try again later.') + ) # If there is a problem with subscribing uncomment this to get notifications. # When things work warnings is only about spam scipts. # logger.error(e.args[0]) -- GitLab