浏览代码

Pass request to dispatcher extra context so we can retrieve the correct site based on request

master
Joey Jurjens 4 年前
父节点
当前提交
dd200b8ea3

+ 2
- 1
src/oscar/apps/checkout/mixins.py 查看文件

273
         ctx = {
273
         ctx = {
274
             'user': self.request.user,
274
             'user': self.request.user,
275
             'order': order,
275
             'order': order,
276
-            'lines': order.lines.all()
276
+            'lines': order.lines.all(),
277
+            'request': self.request,
277
         }
278
         }
278
 
279
 
279
         # Attempt to add the order status URL to the email template ctx.
280
         # Attempt to add the order status URL to the email template ctx.

+ 7
- 5
src/oscar/apps/communication/utils.py 查看文件

156
 
156
 
157
         return content_attachments, file_attachments
157
         return content_attachments, file_attachments
158
 
158
 
159
-    def get_base_context(self):
159
+    def get_base_context(self, **kwargs):
160
         """
160
         """
161
         Return context that is common to all emails
161
         Return context that is common to all emails
162
         """
162
         """
163
-        return {'site': Site.objects.get_current()}
163
+        request = kwargs.get("request")
164
+        return dict(kwargs, site=Site.objects.get_current(request))
164
 
165
 
165
     def get_messages(self, event_code, extra_context=None):
166
     def get_messages(self, event_code, extra_context=None):
166
         """
167
         """
167
         Return rendered messages
168
         Return rendered messages
168
         """
169
         """
169
-        context = self.get_base_context()
170
-        if extra_context is not None:
171
-            context.update(extra_context)
170
+        if extra_context is None:
171
+            extra_context = {}
172
+        context = self.get_base_context(**extra_context)
173
+
172
         msgs = CommunicationEventType.objects.get_and_render(event_code, context)
174
         msgs = CommunicationEventType.objects.get_and_render(event_code, context)
173
         return msgs
175
         return msgs

+ 3
- 2
src/oscar/apps/customer/forms.py 查看文件

49
         if domain_override is not None:
49
         if domain_override is not None:
50
             site.domain = site.name = domain_override
50
             site.domain = site.name = domain_override
51
         for user in self.get_users(self.cleaned_data['email']):
51
         for user in self.get_users(self.cleaned_data['email']):
52
-            self.send_password_reset_email(site, user)
52
+            self.send_password_reset_email(site, user, request)
53
 
53
 
54
-    def send_password_reset_email(self, site, user):
54
+    def send_password_reset_email(self, site, user, request=None):
55
         extra_context = {
55
         extra_context = {
56
             'user': user,
56
             'user': user,
57
             'site': site,
57
             'site': site,
58
             'reset_url': get_password_reset_url(user),
58
             'reset_url': get_password_reset_url(user),
59
+            'request': request,
59
         }
60
         }
60
         CustomerDispatcher().send_password_reset_email_for_user(user, extra_context)
61
         CustomerDispatcher().send_password_reset_email_for_user(user, extra_context)
61
 
62
 

+ 1
- 1
src/oscar/apps/customer/mixins.py 查看文件

82
         return user
82
         return user
83
 
83
 
84
     def send_registration_email(self, user):
84
     def send_registration_email(self, user):
85
-        extra_context = {'user': user}
85
+        extra_context = {'user': user, 'request': self.request}
86
         CustomerDispatcher().send_registration_email_for_user(user, extra_context)
86
         CustomerDispatcher().send_registration_email_for_user(user, extra_context)

+ 2
- 0
src/oscar/apps/customer/views.py 查看文件

340
             'user': user,
340
             'user': user,
341
             'reset_url': get_password_reset_url(old_user),
341
             'reset_url': get_password_reset_url(old_user),
342
             'new_email': new_email,
342
             'new_email': new_email,
343
+            'request': self.request,
343
         }
344
         }
344
         CustomerDispatcher().send_email_changed_email_for_user(old_user, extra_context)
345
         CustomerDispatcher().send_email_changed_email_for_user(old_user, extra_context)
345
 
346
 
390
         extra_context = {
391
         extra_context = {
391
             'user': user,
392
             'user': user,
392
             'reset_url': get_password_reset_url(self.request.user),
393
             'reset_url': get_password_reset_url(self.request.user),
394
+            'request': self.request,
393
         }
395
         }
394
         CustomerDispatcher().send_password_changed_email_for_user(user, extra_context)
396
         CustomerDispatcher().send_password_changed_email_for_user(user, extra_context)
395
 
397
 

+ 5
- 0
src/oscar/test/utils.py 查看文件

99
 
99
 
100
 
100
 
101
 class EmailsMixin:
101
 class EmailsMixin:
102
+    DJANGO_IMPROPERLY_CONFIGURED_MSG = 'You\'re using the Django "sites framework" '\
103
+        'without having set the SITE_ID setting. Create a site in your database and set '\
104
+        'the SITE_ID setting or pass a request to Site.objects.get_current() to fix this error.'
102
 
105
 
103
     def setUp(self):
106
     def setUp(self):
104
         super().setUp()
107
         super().setUp()
105
         self.user = UserFactory()
108
         self.user = UserFactory()
109
+        factory = RequestFactory(SERVER_NAME="example.com")
110
+        self.request = factory.get("/")
106
 
111
 
107
     def _test_send_plain_text_and_html(self, outboxed_email):
112
     def _test_send_plain_text_and_html(self, outboxed_email):
108
         email = outboxed_email
113
         email = outboxed_email

+ 63
- 8
tests/functional/customer/test_emails.py 查看文件

1
 from django.contrib.sites.models import Site
1
 from django.contrib.sites.models import Site
2
 from django.core import mail
2
 from django.core import mail
3
-from django.test import TestCase
3
+from django.core.exceptions import ImproperlyConfigured
4
+from django.test import TestCase, override_settings
4
 
5
 
5
 from oscar.core.loading import get_class
6
 from oscar.core.loading import get_class
6
 from oscar.test.factories import (
7
 from oscar.test.factories import (
17
         super().setUp()
18
         super().setUp()
18
         self.dispatcher = CustomerDispatcher()
19
         self.dispatcher = CustomerDispatcher()
19
 
20
 
20
-    def test_send_registration_email_for_user(self):
21
+    def test_send_registration_email_for_user(self, additional_context=None):
21
         extra_context = {'user': self.user}
22
         extra_context = {'user': self.user}
23
+
24
+        if additional_context:
25
+            extra_context.update(additional_context)
26
+
22
         self.dispatcher.send_registration_email_for_user(self.user, extra_context)
27
         self.dispatcher.send_registration_email_for_user(self.user, extra_context)
23
 
28
 
24
         self._test_common_part()
29
         self._test_common_part()
25
         self.assertEqual('Thank you for registering.', mail.outbox[0].subject)
30
         self.assertEqual('Thank you for registering.', mail.outbox[0].subject)
26
         self.assertIn('Thank you for registering.', mail.outbox[0].body)
31
         self.assertIn('Thank you for registering.', mail.outbox[0].body)
27
 
32
 
28
-    def test_send_password_reset_email_for_user(self):
33
+    @override_settings(SITE_ID=None, ALLOWED_HOSTS=["example.com"])
34
+    def test_send_registration_email_for_user_multisite(self):
35
+        with self.assertRaises(ImproperlyConfigured, msg=self.DJANGO_IMPROPERLY_CONFIGURED_MSG):
36
+            self.test_send_registration_email_for_user()
37
+
38
+        additional_context = {"request": self.request}
39
+        self.test_send_registration_email_for_user(additional_context=additional_context)
40
+
41
+    def test_send_password_reset_email_for_user(self, additional_context=None):
29
         extra_context = {
42
         extra_context = {
30
             'user': self.user,
43
             'user': self.user,
31
             'reset_url': '/django-oscar/django-oscar',
44
             'reset_url': '/django-oscar/django-oscar',
32
         }
45
         }
46
+
47
+        request = None
48
+        if additional_context:
49
+            request = additional_context.get("request")
50
+            extra_context.update(additional_context)
51
+
33
         self.dispatcher.send_password_reset_email_for_user(self.user, extra_context)
52
         self.dispatcher.send_password_reset_email_for_user(self.user, extra_context)
34
 
53
 
35
         self._test_common_part()
54
         self._test_common_part()
36
-        expected_subject = 'Resetting your password at {}.'.format(Site.objects.get_current())
55
+        expected_subject = 'Resetting your password at {}.'.format(Site.objects.get_current(request))
37
         self.assertEqual(expected_subject, mail.outbox[0].subject)
56
         self.assertEqual(expected_subject, mail.outbox[0].subject)
38
         self.assertIn('Please go to the following page and choose a new password:', mail.outbox[0].body)
57
         self.assertIn('Please go to the following page and choose a new password:', mail.outbox[0].body)
39
         self.assertIn('http://example.com/django-oscar/django-oscar', mail.outbox[0].body)
58
         self.assertIn('http://example.com/django-oscar/django-oscar', mail.outbox[0].body)
40
 
59
 
41
-    def test_send_password_changed_email_for_user(self):
60
+    @override_settings(SITE_ID=None, ALLOWED_HOSTS=["example.com"])
61
+    def test_send_password_reset_email_for_user_multisite(self):
62
+        with self.assertRaises(ImproperlyConfigured, msg=self.DJANGO_IMPROPERLY_CONFIGURED_MSG):
63
+            self.test_send_password_reset_email_for_user()
64
+
65
+        additional_context = {"request": self.request}
66
+        self.test_send_password_reset_email_for_user(additional_context=additional_context)
67
+
68
+    def test_send_password_changed_email_for_user(self, additional_context=None):
42
         extra_context = {
69
         extra_context = {
43
             'user': self.user,
70
             'user': self.user,
44
             'reset_url': '/django-oscar/django-oscar',
71
             'reset_url': '/django-oscar/django-oscar',
45
         }
72
         }
73
+
74
+        request = None
75
+        if additional_context:
76
+            request = additional_context.get("request")
77
+            extra_context.update(additional_context)
78
+
46
         self.dispatcher.send_password_changed_email_for_user(self.user, extra_context)
79
         self.dispatcher.send_password_changed_email_for_user(self.user, extra_context)
47
 
80
 
48
         self._test_common_part()
81
         self._test_common_part()
49
-        expected_subject = 'Your password changed at {}.'.format(Site.objects.get_current())
82
+        expected_subject = 'Your password changed at {}.'.format(Site.objects.get_current(request))
50
         self.assertEqual(expected_subject, mail.outbox[0].subject)
83
         self.assertEqual(expected_subject, mail.outbox[0].subject)
51
         self.assertIn('your password has been changed', mail.outbox[0].body)
84
         self.assertIn('your password has been changed', mail.outbox[0].body)
52
         self.assertIn('http://example.com/django-oscar/django-oscar', mail.outbox[0].body)
85
         self.assertIn('http://example.com/django-oscar/django-oscar', mail.outbox[0].body)
53
 
86
 
54
-    def test_send_email_changed_email_for_user(self):
87
+    @override_settings(SITE_ID=None, ALLOWED_HOSTS=["example.com"])
88
+    def test_send_password_changed_email_for_user_multisite(self):
89
+        with self.assertRaises(ImproperlyConfigured, msg=self.DJANGO_IMPROPERLY_CONFIGURED_MSG):
90
+            self.test_send_password_changed_email_for_user()
91
+
92
+        additional_context = {"request": self.request}
93
+        self.test_send_password_changed_email_for_user(additional_context=additional_context)
94
+
95
+    def test_send_email_changed_email_for_user(self, additional_context=None):
55
         extra_context = {
96
         extra_context = {
56
             'user': self.user,
97
             'user': self.user,
57
             'reset_url': '/django-oscar/django-oscar',
98
             'reset_url': '/django-oscar/django-oscar',
58
             'new_email': 'some_new@mail.com',
99
             'new_email': 'some_new@mail.com',
59
         }
100
         }
101
+
102
+        request = None
103
+        if additional_context:
104
+            request = additional_context.get("request")
105
+            extra_context.update(additional_context)
106
+
60
         self.dispatcher.send_email_changed_email_for_user(self.user, extra_context)
107
         self.dispatcher.send_email_changed_email_for_user(self.user, extra_context)
61
 
108
 
62
         self._test_common_part()
109
         self._test_common_part()
63
-        expected_subject = 'Your email address has changed at {}.'.format(Site.objects.get_current())
110
+        expected_subject = 'Your email address has changed at {}.'.format(Site.objects.get_current(request))
64
         self.assertEqual(expected_subject, mail.outbox[0].subject)
111
         self.assertEqual(expected_subject, mail.outbox[0].subject)
65
         self.assertIn('your email address has been changed', mail.outbox[0].body)
112
         self.assertIn('your email address has been changed', mail.outbox[0].body)
66
         self.assertIn('http://example.com/django-oscar/django-oscar', mail.outbox[0].body)
113
         self.assertIn('http://example.com/django-oscar/django-oscar', mail.outbox[0].body)
67
         self.assertIn('some_new@mail.com', mail.outbox[0].body)
114
         self.assertIn('some_new@mail.com', mail.outbox[0].body)
68
 
115
 
116
+    @override_settings(SITE_ID=None, ALLOWED_HOSTS=["example.com"])
117
+    def test_send_email_changed_email_for_user_multisite(self):
118
+        with self.assertRaises(ImproperlyConfigured, msg=self.DJANGO_IMPROPERLY_CONFIGURED_MSG):
119
+            self.test_send_email_changed_email_for_user()
120
+
121
+        additional_context = {"request": self.request}
122
+        self.test_send_email_changed_email_for_user(additional_context=additional_context)
123
+
69
 
124
 
70
 class TestAlertsConcreteEmailsSending(EmailsMixin, TestCase):
125
 class TestAlertsConcreteEmailsSending(EmailsMixin, TestCase):
71
 
126
 

+ 36
- 7
tests/functional/order/test_emails.py 查看文件

1
 import os
1
 import os
2
 
2
 
3
 from django.core import mail
3
 from django.core import mail
4
-from django.test import TestCase
4
+from django.core.exceptions import ImproperlyConfigured
5
+from django.test import TestCase, override_settings
5
 
6
 
6
 from oscar.core.loading import get_class
7
 from oscar.core.loading import get_class
7
 from oscar.test.factories import ProductImageFactory, create_order
8
 from oscar.test.factories import ProductImageFactory, create_order
16
         super().setUp()
17
         super().setUp()
17
         self.dispatcher = OrderDispatcher()
18
         self.dispatcher = OrderDispatcher()
18
 
19
 
19
-    def test_send_order_placed_email_for_user(self):
20
-        order_number = 'SOME-NUM00042'
21
-        order = create_order(number=order_number, user=self.user)
20
+    def test_send_order_placed_email_for_user(self, order_number=None, additional_context=None):
21
+        order_number = order_number if order_number else 'SOME-NUM00042'
22
+        order = create_order(number=order_number, user=self.user, request=self.request)
22
 
23
 
23
         extra_context = {
24
         extra_context = {
24
             'order': order,
25
             'order': order,
25
             'lines': order.lines.all()
26
             'lines': order.lines.all()
26
         }
27
         }
28
+
29
+        if additional_context:
30
+            extra_context.update(additional_context)
31
+
27
         self.dispatcher.send_order_placed_email_for_user(order, extra_context)
32
         self.dispatcher.send_order_placed_email_for_user(order, extra_context)
28
 
33
 
29
         self._test_common_part()
34
         self._test_common_part()
33
         product_title = order.lines.first().title
38
         product_title = order.lines.first().title
34
         assert product_title in mail.outbox[0].body
39
         assert product_title in mail.outbox[0].body
35
 
40
 
36
-    def test_send_order_placed_email_with_attachments_for_user(self):
41
+    @override_settings(SITE_ID=None, ALLOWED_HOSTS=["example.com"])
42
+    def test_send_order_placed_email_for_user_multisite(self):
43
+        with self.assertRaises(ImproperlyConfigured, msg=self.DJANGO_IMPROPERLY_CONFIGURED_MSG):
44
+            self.test_send_order_placed_email_for_user()
45
+
46
+        additional_context = {"request": self.request}
47
+        self.test_send_order_placed_email_for_user(
48
+            order_number="SOME-NUM00043", additional_context=additional_context
49
+        )
50
+
51
+    def test_send_order_placed_email_with_attachments_for_user(self, order_number=None, additional_context=None):
37
         remove_image_folders()
52
         remove_image_folders()
38
 
53
 
39
-        order_number = 'SOME-NUM00042'
40
-        order = create_order(number=order_number, user=self.user)
54
+        order_number = order_number if order_number else 'SOME-NUM00042'
55
+        order = create_order(number=order_number, user=self.user, request=self.request)
41
 
56
 
42
         extra_context = {
57
         extra_context = {
43
             'order': order,
58
             'order': order,
44
             'lines': order.lines.all()
59
             'lines': order.lines.all()
45
         }
60
         }
61
+
62
+        if additional_context:
63
+            extra_context.update(additional_context)
64
+
46
         line = order.lines.first()
65
         line = order.lines.first()
47
         product_image = ProductImageFactory(product=line.product)
66
         product_image = ProductImageFactory(product=line.product)
48
         attachments = [
67
         attachments = [
59
 
78
 
60
         # Remove test file
79
         # Remove test file
61
         os.remove(product_image.original.path)
80
         os.remove(product_image.original.path)
81
+
82
+    @override_settings(SITE_ID=None, ALLOWED_HOSTS=["example.com"])
83
+    def test_send_order_placed_email_with_attachments_for_user_multisite(self):
84
+        with self.assertRaises(ImproperlyConfigured, msg=self.DJANGO_IMPROPERLY_CONFIGURED_MSG):
85
+            self.test_send_order_placed_email_with_attachments_for_user()
86
+
87
+        additional_context = {"request": self.request}
88
+        self.test_send_order_placed_email_with_attachments_for_user(
89
+            order_number="SOME-NUM00043", additional_context=additional_context
90
+        )

正在加载...
取消
保存