django-multisite2 2.0.0__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.
Files changed (51) hide show
  1. django_multisite2-2.0.0.dist-info/LICENSE +28 -0
  2. django_multisite2-2.0.0.dist-info/METADATA +246 -0
  3. django_multisite2-2.0.0.dist-info/RECORD +51 -0
  4. django_multisite2-2.0.0.dist-info/WHEEL +5 -0
  5. django_multisite2-2.0.0.dist-info/top_level.txt +2 -0
  6. multisite/__init__.py +1 -0
  7. multisite/admin/__init__.py +3 -0
  8. multisite/admin/alias_admin.py +58 -0
  9. multisite/admin/multisite_changelist.py +64 -0
  10. multisite/admin/multisite_model_admin.py +161 -0
  11. multisite/apps.py +29 -0
  12. multisite/exceptions.py +57 -0
  13. multisite/forms.py +22 -0
  14. multisite/hacks.py +163 -0
  15. multisite/management/__init__.py +0 -0
  16. multisite/management/commands/__init__.py +0 -0
  17. multisite/management/commands/update_public_suffix_list.py +33 -0
  18. multisite/middleware/__init__.py +4 -0
  19. multisite/middleware/cookie_domain_middleware.py +72 -0
  20. multisite/middleware/dynamic_site_middleware.py +198 -0
  21. multisite/migrations/0001_initial.py +71 -0
  22. multisite/migrations/0002_alter_alias_id_alter_alias_is_canonical.py +32 -0
  23. multisite/migrations/0003_alter_alias_options_alter_alias_unique_together_and_more.py +41 -0
  24. multisite/migrations/0004_alter_alias_managers.py +22 -0
  25. multisite/migrations/__init__.py +0 -0
  26. multisite/models/__init__.py +3 -0
  27. multisite/models/alias.py +110 -0
  28. multisite/models/managers.py +196 -0
  29. multisite/models/signals.py +36 -0
  30. multisite/models/validators.py +14 -0
  31. multisite/tests/__init__.py +0 -0
  32. multisite/tests/get_test_allowed_hosts.py +14 -0
  33. multisite/tests/get_test_http_response.py +13 -0
  34. multisite/tests/hosts.py +46 -0
  35. multisite/tests/test_settings.py +23 -0
  36. multisite/tests/tests/__init__.py +0 -0
  37. multisite/tests/tests/request_factory.py +12 -0
  38. multisite/tests/tests/test_alias.py +271 -0
  39. multisite/tests/tests/test_contrib_site.py +21 -0
  40. multisite/tests/tests/test_cookie_domain_middleware.py +196 -0
  41. multisite/tests/tests/test_dynamic_site_middleware.py +262 -0
  42. multisite/tests/tests/test_site_cache.py +127 -0
  43. multisite/tests/tests/test_site_domain.py +24 -0
  44. multisite/tests/tests/test_site_id.py +76 -0
  45. multisite/tests/tests/test_template_loader.py +49 -0
  46. multisite/threadlocals.py +136 -0
  47. multisite/utils.py +172 -0
  48. multisite_app/__init__.py +0 -0
  49. multisite_app/apps.py +6 -0
  50. multisite_app/urls.py +5 -0
  51. multisite_app/views.py +8 -0
@@ -0,0 +1,271 @@
1
+ from django.contrib.sites.models import Site
2
+ from django.core.exceptions import MultipleObjectsReturned, ValidationError
3
+ from django.test import TestCase, tag
4
+
5
+ from multisite.exceptions import MultisiteInvalidHostError
6
+ from multisite.models import Alias
7
+ from multisite.utils import (
8
+ create_or_sync_alias_from_site,
9
+ create_or_sync_canonical_from_all_sites,
10
+ create_or_sync_missing_canonical_from_site_domain,
11
+ sync_blank_domain,
12
+ sync_canonical_from_site_domain,
13
+ )
14
+
15
+
16
+ class AliasTest(TestCase):
17
+ def setUp(self):
18
+ Alias.objects.all().delete()
19
+ Site.objects.all().delete()
20
+
21
+ def test_create(self):
22
+ Site.objects.create() # site0
23
+ site1 = Site.objects.create(domain="1.example")
24
+ site2 = Site.objects.create(domain="2.example")
25
+ # Missing site
26
+ self.assertRaises(ValidationError, Alias.objects.create)
27
+ self.assertRaises(ValidationError, Alias.objects.create, domain="0.example")
28
+ # Valid
29
+ self.assertTrue(Alias.objects.create(domain="1a.example", site=site1))
30
+ # Duplicate domain
31
+ self.assertRaises(
32
+ ValidationError, Alias.objects.create, domain=site1.domain, site=site1
33
+ )
34
+ self.assertRaises(
35
+ ValidationError, Alias.objects.create, domain=site2.domain, site=site1
36
+ )
37
+ self.assertRaises(
38
+ ValidationError, Alias.objects.create, domain="1a.example", site=site1
39
+ )
40
+ # Duplicate domains, case-sensitivity
41
+ self.assertRaises(
42
+ ValidationError, Alias.objects.create, domain="1A.EXAMPLE", site=site2
43
+ )
44
+ self.assertRaises(
45
+ ValidationError, Alias.objects.create, domain="2.EXAMPLE", site=site2
46
+ )
47
+ # Duplicate is_canonical
48
+ site1.domain = "1b.example"
49
+ self.assertRaises(
50
+ ValidationError,
51
+ Alias.objects.create,
52
+ domain=site1.domain,
53
+ site=site1,
54
+ is_canonical=1,
55
+ )
56
+ # Invalid is_canonical
57
+ self.assertRaises(
58
+ ValidationError,
59
+ Alias.objects.create,
60
+ domain=site1.domain,
61
+ site=site1,
62
+ is_canonical=0,
63
+ )
64
+
65
+ def test_repr(self):
66
+ site = Site.objects.create(domain="example.com")
67
+ self.assertEqual(
68
+ repr(Alias.objects.get(site=site)),
69
+ "<Alias: %(domain)s -> %(domain)s>" % site.__dict__,
70
+ )
71
+
72
+ def test_managers(self):
73
+ site = Site.objects.create(domain="example.com")
74
+ Alias.objects.create(site=site, domain="example.org")
75
+ self.assertEqual(
76
+ set(Alias.objects.values_list("domain", flat=True)),
77
+ set(["example.com", "example.org"]),
78
+ )
79
+ self.assertEqual(
80
+ set(Alias.canonical.values_list("domain", flat=True)), set(["example.com"])
81
+ )
82
+ self.assertEqual(
83
+ set(Alias.aliases.values_list("domain", flat=True)), set(["example.org"])
84
+ )
85
+
86
+ def test_sync_canonical_from_site_domain(self):
87
+ # Create Sites with Aliases
88
+ Site.objects.create()
89
+ site1 = Site.objects.create(domain="1.example.com")
90
+ site2 = Site.objects.create(domain="2.example.com")
91
+ # Create Site without triggering signals
92
+ site3 = Site(domain="3.example.com")
93
+ site3.save_base(raw=True)
94
+ self.assertEqual(
95
+ set(Alias.objects.values_list("domain", flat=True)),
96
+ set([site1.domain, site2.domain]),
97
+ )
98
+ # Sync existing
99
+ site1.domain = "1.example.org"
100
+ site1.save_base(raw=True)
101
+ site2.domain = "2.example.org"
102
+ site2.save_base(raw=True)
103
+ sync_canonical_from_site_domain()
104
+ self.assertEqual(
105
+ set(Alias.objects.values_list("domain", flat=True)),
106
+ set([site1.domain, site2.domain]),
107
+ )
108
+ # Sync with filter
109
+ site1.domain = "1.example.net"
110
+ site1.save_base(raw=True)
111
+ site2.domain = "2.example.net"
112
+ site2.save_base(raw=True)
113
+ sync_canonical_from_site_domain(site__domain=site1.domain)
114
+ self.assertEqual(
115
+ set(Alias.objects.values_list("domain", flat=True)),
116
+ set([site1.domain, "2.example.org"]),
117
+ )
118
+
119
+ def test_sync_missing(self):
120
+ Site.objects.create()
121
+ site1 = Site.objects.create(domain="1.example.com")
122
+ # Update site1 without triggering signals
123
+ site1.domain = "1.example.org"
124
+ site1.save_base(raw=True)
125
+ # Create site2 without triggering signals
126
+ site2 = Site(domain="2.example.org")
127
+ site2.save_base(raw=True)
128
+ # Only site2 should be updated
129
+ create_or_sync_missing_canonical_from_site_domain()
130
+ self.assertEqual(
131
+ set(Alias.objects.values_list("domain", flat=True)),
132
+ set(["1.example.com", site2.domain]),
133
+ )
134
+
135
+ def test_sync_all(self):
136
+ Site.objects.create()
137
+ site1 = Site.objects.create(domain="1.example.com")
138
+ # Update site1 without triggering signals
139
+ site1.domain = "1.example.org"
140
+ site1.save_base(raw=True)
141
+ # Create site2 without triggering signals
142
+ site2 = Site(domain="2.example.org")
143
+ site2.save_base(raw=True)
144
+ # Sync all
145
+ create_or_sync_canonical_from_all_sites()
146
+ self.assertEqual(
147
+ set(Alias.objects.values_list("domain", flat=True)),
148
+ set([site1.domain, site2.domain]),
149
+ )
150
+
151
+ def test_sync(self):
152
+ # Create Site without triggering signals
153
+ site = Site(domain="example.com")
154
+ site.save_base(raw=True)
155
+ # Insert Alias
156
+ self.assertFalse(Alias.objects.filter(site=site).exists())
157
+ create_or_sync_alias_from_site(site=site)
158
+ self.assertEqual(Alias.objects.get(site=site).domain, site.domain)
159
+ # Idempotent sync_alias
160
+ create_or_sync_alias_from_site(site=site)
161
+ self.assertEqual(Alias.objects.get(site=site).domain, site.domain)
162
+ # Duplicate force_insert
163
+ self.assertRaises(
164
+ ValidationError, create_or_sync_alias_from_site, site=site, force_insert=True
165
+ )
166
+ # Update Alias
167
+ site.domain = "example.org"
168
+ create_or_sync_alias_from_site(site=site)
169
+ self.assertEqual(Alias.objects.get(site=site).domain, site.domain)
170
+ # Clear domain
171
+ site.domain = ""
172
+ create_or_sync_alias_from_site(site=site)
173
+ self.assertFalse(Alias.objects.filter(site=site).exists())
174
+
175
+ def test_sync_blank_domain(self):
176
+ # Create Site
177
+ site = Site.objects.create(domain="example.com")
178
+ # Without clearing domain
179
+ self.assertRaises(ValueError, sync_blank_domain, site=site)
180
+ # With an extra Alias
181
+ site.domain = ""
182
+ alias = Alias.objects.create(site=site, domain="example.org")
183
+ self.assertRaises(MultipleObjectsReturned, sync_blank_domain, site=site)
184
+ # With a blank site
185
+ alias.delete()
186
+ sync_blank_domain(site=site)
187
+ self.assertFalse(Alias.objects.filter(site=site).exists())
188
+
189
+ def test_hooks(self):
190
+ # Create empty Site
191
+ Site.objects.create()
192
+ self.assertFalse(Alias.objects.filter(domain="").exists())
193
+ # Create Site
194
+ site = Site.objects.create(domain="example.com")
195
+ alias = Alias.objects.get(site=site)
196
+ self.assertEqual(alias.domain, site.domain)
197
+ self.assertTrue(alias.is_canonical)
198
+ # Create a non-canonical alias
199
+ Alias.objects.create(site=site, domain="example.info")
200
+ # Change Site to another domain name
201
+ site.domain = "example.org"
202
+ site.save()
203
+ self.assertEqual(Alias.canonical.get(site=site).domain, site.domain)
204
+ self.assertEqual(Alias.aliases.get(site=site).domain, "example.info")
205
+ # Change Site to an empty domain name
206
+ site.domain = ""
207
+ self.assertRaises(MultipleObjectsReturned, site.save)
208
+
209
+ Alias.aliases.all().delete()
210
+ Site.objects.get(domain="").delete() # domain is unique in Django1.9
211
+ site.save()
212
+ self.assertFalse(Alias.objects.filter(site=site).exists())
213
+
214
+ # Change Site from an empty domain name
215
+ site.domain = "example.net"
216
+ site.save()
217
+ site.refresh_from_db()
218
+ self.assertEqual(Alias.canonical.get(site=site).domain, site.domain)
219
+
220
+ # Delete Site, which deletes Alias
221
+ site.delete()
222
+ self.assertFalse(Alias.objects.filter(site__domain="example.net").exists())
223
+
224
+ def test_expand_netloc(self):
225
+ _expand_netloc = Alias.objects._expand_netloc
226
+ self.assertRaises(MultisiteInvalidHostError, _expand_netloc, "")
227
+ self.assertRaises(MultisiteInvalidHostError, _expand_netloc, "", 8000)
228
+ self.assertEqual(
229
+ _expand_netloc("testserver", 8000),
230
+ ["testserver:8000", "testserver", "*:8000", "*"],
231
+ )
232
+ self.assertEqual(_expand_netloc("testserver"), ["testserver", "*"])
233
+ self.assertEqual(
234
+ _expand_netloc("example.com", 8000),
235
+ ["example.com:8000", "example.com", "*.com:8000", "*.com", "*:8000", "*"],
236
+ )
237
+ self.assertEqual(_expand_netloc("example.com"), ["example.com", "*.com", "*"])
238
+ self.assertEqual(
239
+ _expand_netloc("www.example.com", 8000),
240
+ [
241
+ "www.example.com:8000",
242
+ "www.example.com",
243
+ "*.example.com:8000",
244
+ "*.example.com",
245
+ "*.com:8000",
246
+ "*.com",
247
+ "*:8000",
248
+ "*",
249
+ ],
250
+ )
251
+ self.assertEqual(
252
+ _expand_netloc("www.example.com"),
253
+ ["www.example.com", "*.example.com", "*.com", "*"],
254
+ )
255
+
256
+ def test_resolve(self):
257
+ site = Site.objects.create(domain="example.com")
258
+ alias = Alias.objects.get(domain="example.com")
259
+ # *.example.com
260
+ self.assertEqual(Alias.objects.resolve("www.example.com"), None)
261
+ self.assertEqual(Alias.objects.resolve("www.dev.example.com"), None)
262
+
263
+ alias = Alias.objects.create(site=site, domain="*.example.com")
264
+ self.assertEqual(Alias.objects.resolve("www.example.com"), alias)
265
+ self.assertEqual(Alias.objects.resolve("www.dev.example.com"), alias)
266
+ # *
267
+ self.assertEqual(Alias.objects.resolve("example.net"), None)
268
+
269
+ alias = Alias.objects.create(site=site, domain="*")
270
+ self.assertEqual(Alias.objects.resolve("example.net"), alias)
271
+ self.assertEqual(Alias.objects.resolve("blah"), alias)
@@ -0,0 +1,21 @@
1
+ from django.conf import settings
2
+ from django.contrib.sites.models import Site
3
+ from django.test import TestCase, override_settings
4
+
5
+ from multisite import SiteID
6
+
7
+
8
+ @override_settings(
9
+ SITE_ID=SiteID(),
10
+ CACHE_SITES_KEY_PREFIX="__test__",
11
+ )
12
+ class TestContribSite(TestCase):
13
+ def setUp(self):
14
+ Site.objects.all().delete()
15
+ self.site = Site.objects.create(domain="example.com")
16
+ settings.SITE_ID.set(self.site.id)
17
+
18
+ def test_get_current_site(self):
19
+ current_site = Site.objects.get_current()
20
+ self.assertEqual(current_site, self.site)
21
+ self.assertEqual(current_site.id, settings.SITE_ID)
@@ -0,0 +1,196 @@
1
+ import tempfile
2
+
3
+ from django.contrib.sites.models import Site
4
+ from django.http import HttpResponse, SimpleCookie
5
+ from django.test import TestCase, override_settings
6
+
7
+ from multisite.exceptions import MultisiteCookieDomainDepthError
8
+ from multisite.middleware import CookieDomainMiddleware
9
+
10
+ from ..get_test_allowed_hosts import get_test_allowed_hosts
11
+ from ..get_test_http_response import get_test_http_response
12
+ from .request_factory import RequestFactory
13
+
14
+
15
+ @override_settings(
16
+ MULTISITE_COOKIE_DOMAIN_DEPTH=0,
17
+ MULTISITE_PUBLIC_SUFFIX_LIST_CACHE_DIR=None,
18
+ ALLOWED_HOSTS=get_test_allowed_hosts(".com"),
19
+ MULTISITE_EXTRA_HOSTS=[".extrahost.com"],
20
+ )
21
+ class TestCookieDomainMiddleware(TestCase):
22
+
23
+ def setUp(self):
24
+ self.factory = RequestFactory(host="example.com")
25
+ Site.objects.all().delete()
26
+ # create sites so we populate ALLOWED_HOSTS
27
+ Site.objects.create(domain="app.test1.example.com")
28
+ Site.objects.create(domain="app.test2.example.com")
29
+ Site.objects.create(domain="example.com")
30
+ Site.objects.create(domain="new.app.test3.example.com")
31
+ Site.objects.create(domain="test.example.com")
32
+
33
+ def test_init(self):
34
+ self.assertEqual(CookieDomainMiddleware(HttpResponse).depth, 0)
35
+ self.assertEqual(
36
+ CookieDomainMiddleware(HttpResponse).psl_cache_dir, tempfile.gettempdir()
37
+ )
38
+
39
+ @override_settings(
40
+ MULTISITE_COOKIE_DOMAIN_DEPTH=1, MULTISITE_PUBLIC_SUFFIX_LIST_CACHE_DIR="/var/psl"
41
+ )
42
+ def test_init2(self):
43
+ middleware = CookieDomainMiddleware(HttpResponse)
44
+ self.assertEqual(middleware.depth, 1)
45
+ self.assertEqual(middleware.psl_cache_dir, "/var/psl")
46
+
47
+ @override_settings(
48
+ MULTISITE_COOKIE_DOMAIN_DEPTH=-1, MULTISITE_PUBLIC_SUFFIX_LIST_CACHE_DIR=None
49
+ )
50
+ def test_init3(self):
51
+ self.assertRaises(
52
+ MultisiteCookieDomainDepthError, CookieDomainMiddleware, HttpResponse
53
+ )
54
+
55
+ @override_settings(
56
+ MULTISITE_COOKIE_DOMAIN_DEPTH="invalid", MULTISITE_PUBLIC_SUFFIX_LIST_CACHE_DIR=None
57
+ )
58
+ def test_init4(self):
59
+ self.assertRaises(
60
+ MultisiteCookieDomainDepthError, CookieDomainMiddleware, HttpResponse
61
+ )
62
+
63
+ def test_no_matched_cookies(self):
64
+ # No cookies
65
+ http_response = get_test_http_response()
66
+ request = self.factory.get("/")
67
+ response = CookieDomainMiddleware(http_response)(request)
68
+ self.assertEqual(response.cookies, SimpleCookie())
69
+ response = CookieDomainMiddleware(http_response)(request)
70
+ self.assertEqual(list(response.cookies.values()), [])
71
+
72
+ # Add some cookies with their domains already set
73
+ http_response = get_test_http_response(
74
+ dict(key="a", value="a", domain=".example.org"),
75
+ dict(key="b", value="b", domain=".example.co.uk"),
76
+ )
77
+ response = CookieDomainMiddleware(http_response)(request)
78
+ self.assertCountEqual(
79
+ list(response.cookies.values()), [response.cookies["a"], response.cookies["b"]]
80
+ )
81
+ self.assertEqual(response.cookies["a"]["domain"], ".example.org")
82
+ self.assertEqual(response.cookies["b"]["domain"], ".example.co.uk")
83
+
84
+ def test_matched_cookies(self):
85
+ """Assert no new cookies introduced with multiple responses."""
86
+ http_response = get_test_http_response(dict(key="a", value="a", domain=None))
87
+ request = self.factory.get("/")
88
+ response = CookieDomainMiddleware(http_response)(request)
89
+ self.assertEqual(list(response.cookies.values()), [response.cookies["a"]])
90
+ response = CookieDomainMiddleware(http_response)(request)
91
+ self.assertEqual(list(response.cookies.values()), [response.cookies["a"]])
92
+
93
+ @override_settings(ALLOWED_HOSTS=get_test_allowed_hosts("192.0.43.10"))
94
+ def test_ip_address(self):
95
+ """Assert IP addresses not be mutated."""
96
+ http_response = get_test_http_response(dict(key="a", value="a", domain=None))
97
+ request = self.factory.get("/", host="192.0.43.10")
98
+ response = CookieDomainMiddleware(http_response)(request)
99
+ self.assertEqual(response.cookies["a"]["domain"], "")
100
+
101
+ @override_settings(
102
+ ALLOWED_HOSTS=get_test_allowed_hosts("localhost", "localhost.localdomain")
103
+ )
104
+ def test_localpath(self):
105
+ """Assert local domains not mutated."""
106
+ http_response = get_test_http_response(dict(key="a", value="a", domain=None))
107
+ request = self.factory.get("/", host="localhost")
108
+ response = CookieDomainMiddleware(http_response)(request)
109
+ self.assertEqual(response.cookies["a"]["domain"], "")
110
+ # Even local subdomains
111
+ request = self.factory.get("/", host="localhost.localdomain")
112
+ response = CookieDomainMiddleware(http_response)(request)
113
+ self.assertEqual(response.cookies["a"]["domain"], "")
114
+
115
+ @override_settings(ALLOWED_HOSTS=get_test_allowed_hosts("ai", "www.ai"))
116
+ def test_simple_tld(self):
117
+ """Assert top-level domains are not mutated."""
118
+ http_response = get_test_http_response(dict(key="a", value="a", domain=None))
119
+ request = self.factory.get("/", host="ai")
120
+ response = CookieDomainMiddleware(http_response)(request)
121
+ self.assertEqual(response.cookies["a"]["domain"], "")
122
+ # Domains inside a TLD are OK
123
+ request = self.factory.get("/", host="www.ai")
124
+ response = CookieDomainMiddleware(http_response)(request)
125
+ self.assertEqual(response.cookies["a"]["domain"], ".www.ai")
126
+
127
+ @override_settings(ALLOWED_HOSTS=get_test_allowed_hosts("com.ai", "nic.com.ai"))
128
+ def test_effective_tld(self):
129
+ """Assert effective top-level domains with a webserver are
130
+ not mutated.
131
+ """
132
+ http_response = get_test_http_response(dict(key="a", value="a", domain=None))
133
+ request = self.factory.get("/", host="com.ai")
134
+ response = CookieDomainMiddleware(http_response)(request)
135
+ self.assertEqual(response.cookies["a"]["domain"], "")
136
+ # Domains within an effective TLD are OK
137
+ request = self.factory.get("/", host="nic.com.ai")
138
+ response = CookieDomainMiddleware(http_response)(request)
139
+ self.assertEqual(response.cookies["a"]["domain"], ".nic.com.ai")
140
+
141
+ @override_settings(MULTISITE_COOKIE_DOMAIN_DEPTH=1)
142
+ def test_subdomain_depth(self):
143
+ """Assert ignores top-level domains but not subdomains."""
144
+ # At depth 1:
145
+ http_response = get_test_http_response(dict(key="a", value="a", domain=None))
146
+ middleware = CookieDomainMiddleware(http_response)
147
+ # Top-level domains are ignored
148
+ request = self.factory.get("/", host="com")
149
+ response = middleware(request)
150
+ self.assertEqual(response.cookies["a"]["domain"], "")
151
+ # As are domains within a TLD
152
+ request = self.factory.get("/", host="example.com")
153
+ response = middleware(request)
154
+ self.assertEqual(response.cookies["a"]["domain"], "")
155
+ # But subdomains will get matched
156
+ request = self.factory.get("/", host="test.example.com")
157
+ response = middleware(request)
158
+ self.assertEqual(response.cookies["a"]["domain"], ".test.example.com")
159
+ # And sub-subdomains will get matched to 1 level deep
160
+ response.cookies["a"]["domain"] = ""
161
+ request = self.factory.get("/", host="app.test1.example.com")
162
+ response = middleware(request)
163
+ self.assertEqual(response.cookies["a"]["domain"], ".test1.example.com")
164
+
165
+ @override_settings(MULTISITE_COOKIE_DOMAIN_DEPTH=2)
166
+ def test_subdomain_depth_2(self):
167
+ """Assert at MULTISITE_COOKIE_DOMAIN_DEPTH 2, subdomains are
168
+ matched two levels deep.
169
+ """
170
+ http_response = get_test_http_response(dict(key="a", value="a", domain=None))
171
+ middleware = CookieDomainMiddleware(http_response)
172
+ request = self.factory.get("/", host="app.test2.example.com")
173
+ response = middleware(request)
174
+ self.assertEqual(response.cookies["a"]["domain"], ".app.test2.example.com")
175
+ response.cookies["a"]["domain"] = ""
176
+ request = self.factory.get("/", host="new.app.test3.example.com")
177
+ response = middleware(request)
178
+ self.assertEqual(response.cookies["a"]["domain"], ".app.test3.example.com")
179
+
180
+ @override_settings(
181
+ MULTISITE_COOKIE_DOMAIN_DEPTH=2,
182
+ ALLOWED_HOSTS=get_test_allowed_hosts(".test.example.com"),
183
+ )
184
+ def test_wildcard_subdomains(self):
185
+ """Assert at MULTISITE_COOKIE_DOMAIN_DEPTH 2, subdomains are
186
+ matched to two levels deep against the wildcard.
187
+ """
188
+ http_response = get_test_http_response(dict(key="a", value="a", domain=None))
189
+ middleware = CookieDomainMiddleware(http_response)
190
+ request = self.factory.get("/", host="foo.test.example.com")
191
+ response = middleware(request)
192
+ self.assertEqual(response.cookies["a"]["domain"], ".foo.test.example.com")
193
+ response.cookies["a"]["domain"] = ""
194
+ request = self.factory.get("/", host="foo.bar.test.example.com")
195
+ response = middleware(request)
196
+ self.assertEqual(response.cookies["a"]["domain"], ".bar.test.example.com")