wbmailing 1.43.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of wbmailing might be problematic. Click here for more details.

Files changed (64) hide show
  1. wbmailing/__init__.py +1 -0
  2. wbmailing/admin.py +74 -0
  3. wbmailing/apps.py +14 -0
  4. wbmailing/backend.py +131 -0
  5. wbmailing/celery.py +0 -0
  6. wbmailing/dynamic_preferences_registry.py +35 -0
  7. wbmailing/factories.py +211 -0
  8. wbmailing/filters/__init__.py +8 -0
  9. wbmailing/filters/mailing_lists.py +84 -0
  10. wbmailing/filters/mails.py +74 -0
  11. wbmailing/locale/de/LC_MESSAGES/django.po +1110 -0
  12. wbmailing/management/__init__.py +22 -0
  13. wbmailing/migrations/0001_initial_squashed_squashed_0008_alter_mail_bcc_email_alter_mail_cc_email_and_more.py +649 -0
  14. wbmailing/migrations/0002_delete_mailingsettings.py +16 -0
  15. wbmailing/migrations/0003_alter_mailinglistsubscriberchangerequest_options.py +25 -0
  16. wbmailing/migrations/__init__.py +0 -0
  17. wbmailing/models/__init__.py +6 -0
  18. wbmailing/models/mailing_lists.py +386 -0
  19. wbmailing/models/mails.py +895 -0
  20. wbmailing/serializers/__init__.py +19 -0
  21. wbmailing/serializers/mailing_lists.py +209 -0
  22. wbmailing/serializers/mails.py +251 -0
  23. wbmailing/tasks.py +37 -0
  24. wbmailing/templates/email_base_template.html +291 -0
  25. wbmailing/templates/mailing/maintain_mail_subsciptions.html +7 -0
  26. wbmailing/templates/mailing/manage_mailing_list_subscriptions.html +26 -0
  27. wbmailing/templates/template.html +295 -0
  28. wbmailing/templates/test.html +294 -0
  29. wbmailing/templates/workbench.html +24 -0
  30. wbmailing/templatetags/__init__.py +0 -0
  31. wbmailing/templatetags/mailing_tags.py +22 -0
  32. wbmailing/tests/__init__.py +0 -0
  33. wbmailing/tests/conftest.py +30 -0
  34. wbmailing/tests/models/__init__.py +0 -0
  35. wbmailing/tests/models/test_mailing_lists.py +297 -0
  36. wbmailing/tests/models/test_mails.py +205 -0
  37. wbmailing/tests/signals.py +124 -0
  38. wbmailing/tests/test_serializers.py +28 -0
  39. wbmailing/tests/test_tasks.py +49 -0
  40. wbmailing/tests/test_viewsets.py +216 -0
  41. wbmailing/tests/tests.py +142 -0
  42. wbmailing/urls.py +90 -0
  43. wbmailing/viewsets/__init__.py +32 -0
  44. wbmailing/viewsets/analytics.py +110 -0
  45. wbmailing/viewsets/buttons/__init__.py +10 -0
  46. wbmailing/viewsets/buttons/mailing_lists.py +91 -0
  47. wbmailing/viewsets/buttons/mails.py +98 -0
  48. wbmailing/viewsets/display/__init__.py +16 -0
  49. wbmailing/viewsets/display/mailing_lists.py +175 -0
  50. wbmailing/viewsets/display/mails.py +318 -0
  51. wbmailing/viewsets/endpoints/__init__.py +8 -0
  52. wbmailing/viewsets/endpoints/mailing_lists.py +86 -0
  53. wbmailing/viewsets/endpoints/mails.py +51 -0
  54. wbmailing/viewsets/mailing_lists.py +320 -0
  55. wbmailing/viewsets/mails.py +425 -0
  56. wbmailing/viewsets/menu/__init__.py +5 -0
  57. wbmailing/viewsets/menu/mailing_lists.py +37 -0
  58. wbmailing/viewsets/menu/mails.py +25 -0
  59. wbmailing/viewsets/titles/__init__.py +17 -0
  60. wbmailing/viewsets/titles/mailing_lists.py +63 -0
  61. wbmailing/viewsets/titles/mails.py +55 -0
  62. wbmailing-1.43.1.dist-info/METADATA +5 -0
  63. wbmailing-1.43.1.dist-info/RECORD +64 -0
  64. wbmailing-1.43.1.dist-info/WHEEL +5 -0
@@ -0,0 +1,205 @@
1
+ from unittest.mock import patch
2
+
3
+ import pytest
4
+ from anymail.signals import AnymailTrackingEvent, tracking
5
+ from django.core import mail
6
+ from django.test import override_settings
7
+ from rest_framework.test import APIRequestFactory
8
+ from wbcore.contrib.directory.factories import EmailContactFactory
9
+ from wbcore.contrib.documents.factories import DocumentFactory
10
+ from wbcore.test.utils import get_or_create_superuser
11
+ from wbmailing.backend import SendgridEmailBackend
12
+ from wbmailing.factories import ToEmailMailFactory
13
+ from wbmailing.models import MailEvent, MassMail
14
+ from wbmailing.models.mails import (
15
+ can_administrate_mail,
16
+ send_mail_task,
17
+ send_mass_mail_as_task,
18
+ )
19
+
20
+
21
+ @pytest.mark.django_db
22
+ class TestSpecificModels:
23
+ @patch("wbmailing.models.mails.send_mass_mail_as_task.delay")
24
+ def test_send_mail_task(self, send_mass_mail_as_task, mass_mail_factory, mailing_list_factory):
25
+ ec = EmailContactFactory()
26
+ ml = mailing_list_factory(email_contacts=(ec,))
27
+ mm = mass_mail_factory(mailing_lists=(ml,))
28
+
29
+ send_mail_task(mm.id)
30
+ send_mass_mail_as_task.assert_called()
31
+ assert send_mass_mail_as_task.call_count == 1
32
+
33
+ def test_send_mass_mail_as_task(self, mass_mail_factory, mailing_list_factory):
34
+ ec = EmailContactFactory()
35
+ ml = mailing_list_factory(email_contacts=(ec,))
36
+ mass_mail = mass_mail_factory(mailing_lists=(ml,))
37
+ assert len(mail.outbox) == 0
38
+ for subscriber in mass_mail.get_mail_addresses():
39
+ send_mass_mail_as_task(mass_mail.id, subscriber["address"])
40
+ assert len(mail.outbox) == 1
41
+
42
+ @pytest.mark.parametrize("status, expected", [("PENDING", "DENIED")])
43
+ def test_deny(self, mailing_list_subscriber_change_request_factory, status, expected):
44
+ mlscr = mailing_list_subscriber_change_request_factory()
45
+ mlscr.deny(description="SPAM")
46
+ assert mlscr.status == expected
47
+
48
+ @pytest.mark.parametrize("status, expected", [("DRAFT", "PENDING")])
49
+ def test_submit(self, mass_mail_factory, status, expected):
50
+ ml = mass_mail_factory()
51
+ ml.submit()
52
+ assert ml.status == expected
53
+
54
+ @pytest.mark.parametrize("status, expected", [("PENDING", "DENIED")])
55
+ def test_deny2(self, mass_mail_factory, status, expected):
56
+ ml = mass_mail_factory(status=MassMail.Status.PENDING)
57
+ ml.deny()
58
+ assert ml.status == expected
59
+
60
+ @pytest.mark.parametrize("status, expected", [("PENDING", "DRAFT")])
61
+ def test_revise(self, mass_mail_factory, status, expected):
62
+ ml = mass_mail_factory(status=MassMail.Status.PENDING)
63
+ ml.revise()
64
+ assert ml.status == expected
65
+
66
+ @patch("wbmailing.models.mails.send_mail_task.delay")
67
+ def test_send(self, send_mail_task, mass_mail_factory):
68
+ mm = mass_mail_factory(status=MassMail.Status.PENDING)
69
+ mm.send()
70
+ send_mail_task.assert_called()
71
+ assert send_mail_task.call_count == 1
72
+
73
+ def test_create_email(self, mass_mail_factory):
74
+ request = APIRequestFactory().get("")
75
+ request.user = get_or_create_superuser()
76
+ mm = mass_mail_factory(attachments=(DocumentFactory(),))
77
+ EmailContactFactory(address=request.user.email)
78
+ mm.template = None
79
+ mm.save()
80
+ msg = mm.create_email(request.user.email)
81
+ assert msg
82
+
83
+ @patch("wbmailing.models.mails.send_mail_as_task.delay")
84
+ def test_resend_no_massmail(self, send_mail_as_task):
85
+ request = APIRequestFactory().get("")
86
+ request.user = get_or_create_superuser()
87
+ obj = ToEmailMailFactory(attachments=(DocumentFactory(),))
88
+ obj.mass_mail = None
89
+ obj.save()
90
+ obj.resend()
91
+ send_mail_as_task.assert_called()
92
+ assert send_mail_as_task.call_count == 1
93
+
94
+ @patch("wbmailing.models.mails.send_mail_as_task.delay")
95
+ def test_resend_no_template(self, send_mail_as_task):
96
+ request = APIRequestFactory().get("")
97
+ request.user = get_or_create_superuser()
98
+ obj = ToEmailMailFactory()
99
+ obj.mass_mail.template = None
100
+ obj.mass_mail.save()
101
+ obj.resend()
102
+ send_mail_as_task.assert_called()
103
+ assert send_mail_as_task.call_count == 1
104
+
105
+ @override_settings(EMAIL_BACKEND="anymail.backends.test.EmailBackend")
106
+ @pytest.mark.parametrize(
107
+ "exits_message_id, event_type, reject_reason",
108
+ [
109
+ ("YES", MailEvent.EventType.SENT, None),
110
+ ("YES", MailEvent.EventType.SENT, MailEvent.RejectReason.SPAM),
111
+ ("YES", "Other", "Unknow"),
112
+ ("NO", "Other", None),
113
+ ],
114
+ )
115
+ def test_handle_mail_tracking(self, exits_message_id, event_type, reject_reason, mail_factory, mail_event_factory):
116
+ request = APIRequestFactory().get("")
117
+ request.user = get_or_create_superuser()
118
+ ml = ToEmailMailFactory()
119
+ nb_mail_send = len(mail.outbox)
120
+ esp_event = {}
121
+ if reject_reason:
122
+ mailevent = mail_event_factory(mail=ml, description="", reject_reason=reject_reason)
123
+ if reject_reason == MailEvent.RejectReason.SPAM:
124
+ esp_event["reason"] = "SPAM"
125
+ else:
126
+ esp_event["response"] = "Unknow"
127
+ else:
128
+ mailevent = mail_event_factory(mail=ml)
129
+
130
+ to = list(ml.to_email.values_list("address", flat=True))
131
+ msg = ml.get_mailmessage(ml.subject, ml.body, request.user.email, to, attachments=ml.documents.all())
132
+ msg.send()
133
+ assert len(mail.outbox) == nb_mail_send + 1
134
+ assert msg.anymail_status.status == {"sent"}
135
+ if exits_message_id == "YES":
136
+ message_id = mailevent.mail.message_ids[0]
137
+ else:
138
+ message_id = msg.anymail_status.message_id
139
+
140
+ esp_event["ip"] = mailevent.ip
141
+ esp_event["useragent"] = mailevent.user_agent
142
+ mevent = AnymailTrackingEvent(
143
+ event_type=event_type,
144
+ message_id=message_id,
145
+ timestamp=mailevent.timestamp,
146
+ event_id=mailevent.id,
147
+ recipient=mailevent.recipient,
148
+ reject_reason=mailevent.reject_reason,
149
+ description=mailevent.description,
150
+ user_agent=mailevent.user_agent,
151
+ click_url=mailevent.click_url,
152
+ esp_event=esp_event,
153
+ )
154
+ # sender(class) – The source of the event. (One of theanymail.webhook.*Viewclasses, but you generally won’t examine this parameter; it’s required by Django’s signalmechanism.
155
+ tracking.send(sender=msg, event=mevent, esp_name="SendGrid")
156
+
157
+ if exits_message_id == "YES":
158
+ assert MailEvent.objects.filter(mail=ml, recipient=mailevent.recipient).count() == 2
159
+ else:
160
+ assert MailEvent.objects.filter(mail=ml, recipient=mailevent.recipient).count() == 1
161
+
162
+ @override_settings(EMAIL_BACKEND="anymail.backends.test.EmailBackend", ANYMAIL_SENDGRID_API_KEY="TEST")
163
+ @patch("wbmailing.backend.SendgridEmailBackend._send")
164
+ @pytest.mark.parametrize("resend, exit_document", [(False, False), (False, True), (True, False)])
165
+ def test_SendgridEmailBackend_send_messages(self, mock_send, resend, exit_document):
166
+ request = APIRequestFactory().get("")
167
+ request.user = get_or_create_superuser()
168
+ num_sent = SendgridEmailBackend().send_messages(None)
169
+ assert num_sent == 0
170
+ doc1 = DocumentFactory()
171
+ ml = ToEmailMailFactory(cc_email=(EmailContactFactory(),), attachments=(doc1,))
172
+ to = list(ml.to_email.values_list("address", flat=True))
173
+ cc = list(ml.cc_email.values_list("address", flat=True))
174
+ bcc = ["lemissan@atonra.ch"]
175
+ if resend:
176
+ msg = ml.get_mailmessage(
177
+ ml.subject, ml.body, request.user.email, to, attachments=ml.documents.all(), mail=ml
178
+ )
179
+ else:
180
+ msg = ml.get_mailmessage(
181
+ ml.subject, ml.body, request.user.email, to, bcc=bcc, cc=cc, attachments=ml.documents.all()
182
+ )
183
+ msg.send()
184
+
185
+ if exit_document:
186
+ for name, payload, mimetype in msg.attachments:
187
+ doc1.name = name
188
+ doc1.save()
189
+
190
+ email_messages = [msg]
191
+
192
+ mock_send.return_value.status_code = 200
193
+ mock_send.return_value.json.return_value = msg
194
+
195
+ num_sent = SendgridEmailBackend().send_messages(email_messages)
196
+ mock_send.assert_called()
197
+ assert mock_send.call_count == 1
198
+ assert num_sent == 1
199
+
200
+ def test_can_administrate_mail(self, mass_mail_factory):
201
+ request = APIRequestFactory().get("")
202
+ request.user = get_or_create_superuser()
203
+ obj = mass_mail_factory()
204
+ result = can_administrate_mail(obj, request.user)
205
+ assert result
@@ -0,0 +1,124 @@
1
+ from django.dispatch import receiver
2
+ from wbcore.contrib.directory.models import EmailContact
3
+ from wbcore.test.signals import (
4
+ custom_update_data_from_factory,
5
+ custom_update_kwargs,
6
+ get_custom_factory,
7
+ )
8
+ from wbmailing.factories import (
9
+ CustomMassMailFactory,
10
+ EmailContactFactory,
11
+ MailEventFactory,
12
+ MailFactory,
13
+ MailingListFactory,
14
+ MailingListSubscriberChangeRequestFactory,
15
+ MassMailFactory,
16
+ ToEmailMailFactory,
17
+ )
18
+ from wbmailing.models import MailingListSubscriberChangeRequest
19
+ from wbmailing.viewsets import (
20
+ EmailContactMailingListModelViewSet,
21
+ MailEventMassMailMailModelViewSet,
22
+ MailingListEntryModelViewSet,
23
+ MailingListSubscriberChangeRequestModelViewSet,
24
+ MailingListSubscriberRequestEntryModelViewSet,
25
+ MailingListSubscriberRequestMailingListModelViewSet,
26
+ MailMailingListChartViewSet,
27
+ MailModelViewSet,
28
+ MailStatusMassMailModelViewSet,
29
+ MassMailModelViewSet,
30
+ )
31
+
32
+ # =================================================================================================================
33
+ # CUSTOM FACTORY
34
+ # =================================================================================================================
35
+
36
+
37
+ @receiver(get_custom_factory, sender=MassMailModelViewSet)
38
+ def receive_factory_mass_mail(sender, *args, **kwargs):
39
+ return CustomMassMailFactory
40
+
41
+
42
+ @receiver(get_custom_factory, sender=MailModelViewSet)
43
+ def receive_factory_toemail(sender, *args, **kwargs):
44
+ return ToEmailMailFactory
45
+
46
+
47
+ @receiver(get_custom_factory, sender=MailStatusMassMailModelViewSet)
48
+ def receive_factory_email(sender, *args, **kwargs):
49
+ return EmailContactFactory
50
+
51
+
52
+ # =================================================================================================================
53
+ # UPDATE DATA
54
+ # =================================================================================================================
55
+
56
+
57
+ @receiver(custom_update_data_from_factory, sender=MailingListSubscriberRequestMailingListModelViewSet)
58
+ @receiver(custom_update_data_from_factory, sender=MailingListSubscriberRequestEntryModelViewSet)
59
+ @receiver(custom_update_data_from_factory, sender=MailingListSubscriberChangeRequestModelViewSet)
60
+ def receive_data_mailinglist_subscriber(sender, *args, **kwargs):
61
+ if obj := kwargs.get("obj_factory"):
62
+ obj.status = MailingListSubscriberChangeRequest.Status.APPROVED
63
+ obj.save()
64
+ # return {"mailing_list": obj.mailing_list.id }
65
+ return {}
66
+
67
+
68
+ @receiver(custom_update_data_from_factory, sender=EmailContactMailingListModelViewSet)
69
+ def receive_data_email_contact_mailinglist(sender, *args, **kwargs):
70
+ if obj := kwargs.get("obj_factory"):
71
+ mlscr = MailingListSubscriberChangeRequestFactory(
72
+ status=MailingListSubscriberChangeRequest.Status.APPROVED, mailing_list=obj.mailing_list
73
+ )
74
+ return {"email_contact": mlscr.email_contact.id}
75
+ return {}
76
+
77
+
78
+ # =================================================================================================================
79
+ # UPDATE KWARGS
80
+ # =================================================================================================================
81
+
82
+
83
+ @receiver(custom_update_kwargs, sender=MailStatusMassMailModelViewSet)
84
+ def receive_kwargs_mass_mail_mail(sender, *args, **kwargs):
85
+ if obj := kwargs.get("obj_factory"):
86
+ ml = MailingListFactory.create(email_contacts=[obj])
87
+ mass_mail = MassMailFactory.create(mailing_lists=[ml])
88
+ MailEventFactory.create(recipient=obj.address)
89
+ MailFactory.create(mass_mail=mass_mail, to_email=[obj])
90
+ return {"mass_mail_id": mass_mail.id}
91
+ return {}
92
+
93
+
94
+ @receiver(custom_update_kwargs, sender=MailEventMassMailMailModelViewSet)
95
+ def receive_kwargs_mail_event_massmail(sender, *args, **kwargs):
96
+ if obj := kwargs.get("obj_factory"):
97
+ return {"mass_mail_id": obj.mail.mass_mail.id}
98
+ return {}
99
+
100
+
101
+ @receiver(custom_update_kwargs, sender=MailingListEntryModelViewSet)
102
+ def receive_kwargs_mailing_list_entry(sender, *args, **kwargs):
103
+ if email_id := kwargs.get("email_contact_id", None):
104
+ ec = EmailContact.objects.get(id=email_id)
105
+ return {"entry_id": ec.entry.id}
106
+ return {}
107
+
108
+
109
+ @receiver(custom_update_kwargs, sender=MailingListSubscriberRequestEntryModelViewSet)
110
+ def receive_kwargs_mailing_list_subscriber_entry(sender, *args, **kwargs):
111
+ if kwargs.get("email_contact_id"):
112
+ sec = kwargs.get("email_contact_id")
113
+ ec = EmailContact.objects.filter(id=sec).first()
114
+ return {"entry_id": ec.entry.id}
115
+ return {}
116
+
117
+
118
+ @receiver(custom_update_kwargs, sender=MailMailingListChartViewSet)
119
+ def receive_kwargs_mail_mailing_list(sender, *args, **kwargs):
120
+ if obj := kwargs.get("obj_factory"):
121
+ ml = MailingListFactory()
122
+ obj.mass_mail.mailing_lists.add(ml)
123
+ return {"mailing_list_id": ml.id}
124
+ return {}
@@ -0,0 +1,28 @@
1
+ import pytest
2
+ from django.core import mail
3
+ from rest_framework import status
4
+ from rest_framework.test import APIRequestFactory
5
+ from wbcore.contrib.directory.factories import EmailContactFactory
6
+ from wbcore.test.utils import get_kwargs
7
+ from wbmailing.factories import CustomMassMailFactory
8
+ from wbmailing.models import MassMail
9
+ from wbmailing.viewsets.mails import MassMailModelViewSet
10
+
11
+
12
+ @pytest.mark.django_db
13
+ class TestSpecificSerializers:
14
+ @pytest.mark.parametrize("mvs, factory", [(MassMailModelViewSet, CustomMassMailFactory)])
15
+ def test_serializers_mail(self, mvs, factory, user):
16
+ request = APIRequestFactory().get("")
17
+ request.user = user
18
+ obj = factory(status=MassMail.Status.SENT)
19
+ EmailContactFactory(address=request.user.email)
20
+ nb_mail_send = len(mail.outbox)
21
+ request.query_params = {}
22
+ mvs.request = request
23
+ mvs.kwargs = get_kwargs(obj, mvs, request)
24
+ mvs.kwargs["pk"] = obj.pk
25
+ response = mvs().sendtestmail(request)
26
+ assert response.status_code == status.HTTP_200_OK
27
+ assert response.data
28
+ assert len(mail.outbox) == nb_mail_send + 1
@@ -0,0 +1,49 @@
1
+ from datetime import datetime, timedelta
2
+ from unittest.mock import patch
3
+
4
+ import pytest
5
+ from django.db.models import Q
6
+ from django.utils import timezone
7
+ from faker import Faker
8
+ from wbmailing.factories import MailingListSubscriberChangeRequestFactory
9
+ from wbmailing.models import MassMail
10
+ from wbmailing.models.mailing_lists import MailingListEmailContactThroughModel
11
+ from wbmailing.tasks import (
12
+ check_and_remove_expired_mailinglist_subscription,
13
+ periodic_send_mass_mail_as_tasks,
14
+ )
15
+
16
+ fake = Faker()
17
+
18
+
19
+ @pytest.mark.django_db
20
+ class TestSpecificTasks:
21
+ @pytest.mark.parametrize("expiration_date", [fake.past_date()])
22
+ def test_check_and_remove_expired_mailinglist_subscription(self, expiration_date, mailing_list, email_contact):
23
+ request = MailingListSubscriberChangeRequestFactory(
24
+ expiration_date=expiration_date, email_contact=email_contact, mailing_list=mailing_list
25
+ )
26
+ request.approve()
27
+ request.save()
28
+ assert request.relationship.status == MailingListEmailContactThroughModel.Status.SUBSCRIBED
29
+
30
+ check_and_remove_expired_mailinglist_subscription()
31
+ request.refresh_from_db()
32
+ assert request.relationship.status == MailingListEmailContactThroughModel.Status.UNSUBSCRIBED
33
+ request.refresh_from_db()
34
+ assert request.expiration_date is None
35
+
36
+ @patch("wbmailing.models.mails.send_mail_task.delay")
37
+ def test_periodic_tasks(self, send_mail_task, mass_mail_factory):
38
+ mass_mail_factory(status=MassMail.Status.PENDING, send_at=None)
39
+ send_date = timezone.now() - timedelta(minutes=15)
40
+ mass_mail_factory(status=MassMail.Status.SEND_LATER, send_at=send_date)
41
+ assert (
42
+ MassMail.objects.filter(Q(status=MassMail.Status.SEND_LATER) & Q(send_at__lte=datetime.now())).count() == 1
43
+ )
44
+ periodic_send_mass_mail_as_tasks()
45
+ send_mail_task.assert_called()
46
+ assert send_mail_task.call_count == 1
47
+ assert (
48
+ MassMail.objects.filter(Q(status=MassMail.Status.SEND_LATER) & Q(send_at__lte=datetime.now())).count() == 0
49
+ )
@@ -0,0 +1,216 @@
1
+ from unittest.mock import patch
2
+
3
+ import pytest
4
+ from django.core import mail
5
+ from rest_framework import status
6
+ from rest_framework.test import APIRequestFactory
7
+ from wbcore.contrib.directory.factories import EmailContactFactory
8
+ from wbcore.contrib.directory.viewsets import (
9
+ CompanyModelViewSet,
10
+ EntryModelViewSet,
11
+ PersonModelViewSet,
12
+ )
13
+ from wbcore.signals.instance_buttons import add_instance_button
14
+ from wbcore.test.utils import get_kwargs, get_model_factory
15
+ from wbmailing.factories import (
16
+ CustomMassMailFactory,
17
+ MailEventFactory,
18
+ MailFactory,
19
+ MailingListEmailContactThroughModelFactory,
20
+ MailingListFactory,
21
+ MailingListSubscriberChangeRequestFactory,
22
+ MassMailFactory,
23
+ ToEmailMailFactory,
24
+ )
25
+ from wbmailing.models import (
26
+ MailEvent,
27
+ MailingListEmailContactThroughModel,
28
+ MailingListSubscriberChangeRequest,
29
+ )
30
+ from wbmailing.viewsets import (
31
+ EmailContactMailingListModelViewSet,
32
+ MailingListEntryModelViewSet,
33
+ MailingListSubscriberChangeRequestModelViewSet,
34
+ MailModelViewSet,
35
+ MailStatusMassMailModelViewSet,
36
+ ManageMailingListSubscriptions,
37
+ MassMailModelViewSet,
38
+ UnsubscribeView,
39
+ )
40
+
41
+
42
+ @pytest.mark.django_db
43
+ class TestMailStatusMassMailViewSet:
44
+ @pytest.fixture()
45
+ def mass_mail(self, user):
46
+ email = EmailContactFactory.create()
47
+ ml = MailingListFactory.create(email_contacts=[email])
48
+ mass_mail = MassMailFactory.create(mailing_lists=[ml], status="SENT")
49
+ mail = MailFactory.create(mass_mail=mass_mail)
50
+ MailEventFactory.create(mail=mail, event_type=MailEvent.EventType.BOUNCED, recipient=email.address)
51
+ return mass_mail
52
+
53
+ @patch("wbmailing.models.mails.send_mail_as_task.delay")
54
+ @pytest.mark.parametrize("mvs", [MailStatusMassMailModelViewSet])
55
+ def test_resendbouncedmails(self, send_mail_as_task, mvs, mass_mail, user):
56
+ request = APIRequestFactory().get("")
57
+ request.user = user
58
+ kwargs = {"mass_mail_id": mass_mail.id}
59
+
60
+ response = mvs(kwargs=kwargs).resendbouncedmails(request=request, mass_mail_id=mass_mail.id)
61
+ assert response.status_code == status.HTTP_200_OK
62
+ assert response.data
63
+ send_mail_as_task.assert_called()
64
+ assert send_mail_as_task.call_count == 1
65
+
66
+ @pytest.mark.parametrize("mvs", [MailStatusMassMailModelViewSet])
67
+ def test_get_custom_buttons(self, mvs, mass_mail, user):
68
+ request = APIRequestFactory().get("")
69
+ request.user = user
70
+ # obj = mail_factory()
71
+ kwargs = {"mass_mail_id": mass_mail.id}
72
+ mvs.kwargs = kwargs
73
+ response = (
74
+ mvs(kwargs=kwargs).button_config_class(view=mvs, request=request, instance=mass_mail).get_custom_buttons()
75
+ )
76
+ assert response
77
+
78
+
79
+ @pytest.mark.django_db
80
+ class TestSpecificViewsets:
81
+ @pytest.mark.parametrize(
82
+ "mvs, factory",
83
+ [
84
+ (EmailContactMailingListModelViewSet, MailingListEmailContactThroughModelFactory),
85
+ ],
86
+ )
87
+ def test_delete(self, mvs, factory, user):
88
+ request = APIRequestFactory().get("")
89
+ request.user = user
90
+ obj = factory()
91
+ kwargs = get_kwargs(obj, mvs, request)
92
+ response = mvs(kwargs=kwargs).delete(request=request, mailing_list_id=kwargs["mailing_list_id"], pk=obj.pk)
93
+ assert response.status_code == status.HTTP_200_OK
94
+ assert response.data
95
+
96
+ @pytest.mark.parametrize(
97
+ "mvs, factory", [(MailingListEntryModelViewSet, MailingListEmailContactThroughModelFactory)]
98
+ )
99
+ def test_delete_unsubscriber_email_contacts(self, mvs, factory, mailing_list_factory, user):
100
+ request = APIRequestFactory().get("")
101
+ request.user = user
102
+ mlscr = MailingListSubscriberChangeRequestFactory()
103
+ obj = factory()
104
+ kwargs = get_kwargs(obj, mvs, request)
105
+ response = mvs(kwargs=kwargs).unsubscribe(
106
+ request=request, entry_id=mlscr.email_contact.entry.id, pk=mlscr.mailing_list.pk
107
+ )
108
+ assert response.status_code == status.HTTP_200_OK
109
+ assert response.data
110
+
111
+ @pytest.mark.parametrize("myview", [PersonModelViewSet, CompanyModelViewSet, EntryModelViewSet])
112
+ def test_entry_adding_instance_buttons(self, myview, user):
113
+ remote_buttons = add_instance_button.send(myview, many=True)
114
+ custom_instance_buttons = set([button for _, button in remote_buttons])
115
+ assert custom_instance_buttons
116
+
117
+ # @pytest.mark.parametrize("mvs", [(MassMailModelViewSet)])
118
+ # def test_get_messages(self, mvs, mass_mail_factory, mail_factory, mail_event_factory, user):
119
+ # request = APIRequestFactory().get("")
120
+ # request.user = user
121
+ # obj = mass_mail_factory(status = MassMail.Status.SENT)
122
+ # qs = mvs().get_queryset()
123
+ # mail = mail_factory(mass_mail=qs[0])
124
+ # me = mail_event_factory(mail = mail, event_type=MailEvent.EventType.CLICKED)
125
+
126
+ # msg = mvs().get_messages(request, instance=qs[0])
127
+ # assert msg
128
+
129
+ @pytest.mark.parametrize("mvs, factory", [(MassMailModelViewSet, CustomMassMailFactory)])
130
+ def test_sendtestmail(self, mvs, factory, user):
131
+ request = APIRequestFactory().get("")
132
+ request.user = user
133
+ obj = factory()
134
+ EmailContactFactory(address=request.user.email)
135
+ # request.POST = request.POST.copy()
136
+ # request.POST['to_test_email'] = "lemissan@atonra.ch"
137
+ nb_mail_send = len(mail.outbox)
138
+ request.query_params = {}
139
+ mvs.request = request
140
+ mvs.kwargs = get_kwargs(obj, mvs, request)
141
+ mvs.kwargs["pk"] = obj.pk
142
+ response = mvs().sendtestmail(request)
143
+ assert response.status_code == status.HTTP_200_OK
144
+ assert response.data
145
+ assert len(mail.outbox) == nb_mail_send + 1
146
+
147
+ @pytest.mark.parametrize("mvs, factory", [(MailModelViewSet, ToEmailMailFactory)])
148
+ def test_get_queryset_mail(self, mvs, factory, user):
149
+ request = APIRequestFactory().get("")
150
+ request.user = user
151
+ request.user.is_superuser = False
152
+ request.user.save()
153
+ obj = factory()
154
+ kwargs = get_kwargs(obj, mvs, request)
155
+ vs = mvs.as_view({"get": "list"})
156
+ response = vs(request, **kwargs)
157
+ assert response.status_code == status.HTTP_403_FORBIDDEN
158
+
159
+ @patch("wbmailing.models.mails.send_mail_as_task.delay")
160
+ def test_resend(self, send_mail_as_task, user):
161
+ request = APIRequestFactory().get("")
162
+ request.user = user
163
+ obj = ToEmailMailFactory()
164
+ request.query_params = {}
165
+ MailModelViewSet.request = request
166
+ MailModelViewSet.kwargs = get_kwargs(obj, MailModelViewSet, request)
167
+ MailModelViewSet.kwargs["pk"] = obj.pk
168
+ response = MailModelViewSet().resend(request)
169
+ assert response.status_code == status.HTTP_200_OK
170
+ assert response.data
171
+ send_mail_as_task.assert_called()
172
+ assert send_mail_as_task.call_count == 1
173
+
174
+ @pytest.mark.parametrize("user__is_superuser", [True])
175
+ def test_get_custom_buttons_approveall(self, user):
176
+ request = APIRequestFactory().get("")
177
+ request.user = user
178
+ factory = get_model_factory(MailingListSubscriberChangeRequestModelViewSet().get_serializer_class().Meta.model)
179
+ for i in range(2):
180
+ obj = factory()
181
+ kwargs = get_kwargs(obj, MailingListSubscriberChangeRequestModelViewSet, request)
182
+ assert (
183
+ MailingListSubscriberChangeRequest.objects.filter(
184
+ status=MailingListSubscriberChangeRequest.Status.PENDING
185
+ ).count()
186
+ == 2
187
+ )
188
+ response = (
189
+ MailingListSubscriberChangeRequestModelViewSet(kwargs=kwargs)
190
+ .button_config_class(view=MailingListSubscriberChangeRequestModelViewSet, request=request, instance=obj)
191
+ .get_custom_buttons()
192
+ )
193
+ assert response
194
+
195
+ @pytest.mark.parametrize(
196
+ "mvs, factory", [(ManageMailingListSubscriptions, MailingListEmailContactThroughModelFactory)]
197
+ )
198
+ def test_ManageMailingListSubscriptions(self, mvs, factory, user):
199
+ request = APIRequestFactory().get("")
200
+ request.user = user
201
+ through_model = factory()
202
+ response = mvs().get(request, through_model.email_contact.id)
203
+ assert response.status_code == status.HTTP_200_OK
204
+ assert response.content
205
+
206
+ @pytest.mark.parametrize("mvs, factory", [(UnsubscribeView, MailingListEmailContactThroughModelFactory)])
207
+ def test_UnsubscribeView(self, mvs, factory, user):
208
+ request = APIRequestFactory().get("")
209
+ request.user = user
210
+ through_model = factory()
211
+ mailing_list = through_model.mailing_list
212
+ response = mvs().get(request, through_model.email_contact.id, mailing_list.id)
213
+ assert response.status_code == status.HTTP_302_FOUND
214
+ assert response.url
215
+ through_model.refresh_from_db()
216
+ assert through_model.status == MailingListEmailContactThroughModel.Status.UNSUBSCRIBED