1from django.contrib.auth.models import Group
2from django.test import TestCase
3from django.urls import reverse
4
5from wagtail.core.models import Page, PageViewRestriction
6from wagtail.tests.testapp.models import SimplePage
7from wagtail.tests.utils import WagtailTestUtils
8
9
10class TestSetPrivacyView(TestCase, WagtailTestUtils):
11    def setUp(self):
12        self.login()
13
14        # Create some pages
15        self.homepage = Page.objects.get(id=2)
16
17        self.public_page = self.homepage.add_child(instance=SimplePage(
18            title="Public page",
19            content="hello",
20            live=True,
21        ))
22
23        self.private_page = self.homepage.add_child(instance=SimplePage(
24            title="Private page",
25            content="hello",
26            live=True,
27        ))
28        PageViewRestriction.objects.create(
29            page=self.private_page, restriction_type='password', password='password123'
30        )
31
32        self.private_child_page = self.private_page.add_child(instance=SimplePage(
33            title="Private child page",
34            content="hello",
35            live=True,
36        ))
37
38        self.private_groups_page = self.homepage.add_child(instance=SimplePage(
39            title="Private groups page",
40            content="hello",
41            live=True,
42        ))
43        restriction = PageViewRestriction.objects.create(page=self.private_groups_page, restriction_type='groups')
44        self.group = Group.objects.create(name='Private page group')
45        self.group2 = Group.objects.create(name='Private page group2')
46        restriction.groups.add(self.group)
47        restriction.groups.add(self.group2)
48
49        self.private_groups_child_page = self.private_groups_page.add_child(instance=SimplePage(
50            title="Private groups child page",
51            content="hello",
52            live=True,
53        ))
54
55    def test_get_public(self):
56        """
57        This tests that a blank form is returned when a user opens the set_privacy view on a public page
58        """
59        response = self.client.get(reverse('wagtailadmin_pages:set_privacy', args=(self.public_page.id, )))
60
61        # Check response
62        self.assertEqual(response.status_code, 200)
63        self.assertTemplateUsed(response, 'wagtailadmin/page_privacy/set_privacy.html')
64        self.assertEqual(response.context['page'].specific, self.public_page)
65
66        # Check form attributes
67        self.assertEqual(response.context['form']['restriction_type'].value(), 'none')
68
69    def test_get_private(self):
70        """
71        This tests that the restriction type and password fields as set correctly
72        when a user opens the set_privacy view on a public page
73        """
74        response = self.client.get(reverse('wagtailadmin_pages:set_privacy', args=(self.private_page.id, )))
75
76        # Check response
77        self.assertEqual(response.status_code, 200)
78        self.assertTemplateUsed(response, 'wagtailadmin/page_privacy/set_privacy.html')
79        self.assertEqual(response.context['page'].specific, self.private_page)
80
81        # Check form attributes
82        self.assertEqual(response.context['form']['restriction_type'].value(), 'password')
83        self.assertEqual(response.context['form']['password'].value(), 'password123')
84        self.assertEqual(response.context['form']['groups'].value(), [])
85
86    def test_get_private_child(self):
87        """
88        This tests that the set_privacy view tells the user
89        that the password restriction has been applied to an ancestor
90        """
91        response = self.client.get(reverse('wagtailadmin_pages:set_privacy', args=(self.private_child_page.id, )))
92
93        # Check response
94        self.assertEqual(response.status_code, 200)
95        self.assertTemplateUsed(response, 'wagtailadmin/page_privacy/ancestor_privacy.html')
96        self.assertEqual(response.context['page_with_restriction'].specific, self.private_page)
97
98    def test_set_password_restriction(self):
99        """
100        This tests that setting a password restriction using the set_privacy view works
101        """
102        post_data = {
103            'restriction_type': 'password',
104            'password': 'helloworld',
105            'groups': [],
106        }
107        response = self.client.post(reverse('wagtailadmin_pages:set_privacy', args=(self.public_page.id, )), post_data)
108
109        # Check response
110        self.assertEqual(response.status_code, 200)
111        self.assertContains(response, '"is_public": false')
112
113        # Check that a page restriction has been created
114        self.assertTrue(PageViewRestriction.objects.filter(page=self.public_page).exists())
115        restriction = PageViewRestriction.objects.get(page=self.public_page)
116
117        # Check that the password is set correctly
118        self.assertEqual(restriction.password, 'helloworld')
119
120        # Check that the restriction_type is set correctly
121        self.assertEqual(restriction.restriction_type, 'password')
122
123        # Be sure there are no groups set
124        self.assertEqual(restriction.groups.count(), 0)
125
126    def test_set_password_restriction_password_unset(self):
127        """
128        This tests that the password field on the form is validated correctly
129        """
130        post_data = {
131            'restriction_type': 'password',
132            'password': '',
133            'groups': [],
134        }
135        response = self.client.post(reverse('wagtailadmin_pages:set_privacy', args=(self.public_page.id, )), post_data)
136
137        # Check response
138        self.assertEqual(response.status_code, 200)
139
140        # Check that a form error was raised
141        self.assertFormError(response, 'form', 'password', "This field is required.")
142
143    def test_unset_password_restriction(self):
144        """
145        This tests that removing a password restriction using the set_privacy view works
146        """
147        post_data = {
148            'restriction_type': 'none',
149            'password': '',
150            'groups': [],
151        }
152        response = self.client.post(
153            reverse('wagtailadmin_pages:set_privacy', args=(self.private_page.id, )), post_data)
154
155        # Check response
156        self.assertEqual(response.status_code, 200)
157        self.assertContains(response, '"is_public": true')
158
159        # Check that the page restriction has been deleted
160        self.assertFalse(PageViewRestriction.objects.filter(page=self.private_page).exists())
161
162    def test_get_private_groups(self):
163        """
164        This tests that the restriction type and group fields as set correctly when a user opens the set_privacy view on a public page
165        """
166        response = self.client.get(reverse('wagtailadmin_pages:set_privacy', args=(self.private_groups_page.id, )))
167
168        # Check response
169        self.assertEqual(response.status_code, 200)
170        self.assertTemplateUsed(response, 'wagtailadmin/page_privacy/set_privacy.html')
171        self.assertEqual(response.context['page'].specific, self.private_groups_page)
172
173        # Check form attributes
174        self.assertEqual(response.context['form']['restriction_type'].value(), 'groups')
175        self.assertEqual(response.context['form']['password'].value(), '')
176        self.assertEqual(response.context['form']['groups'].value(), [self.group.id, self.group2.id])
177
178    def test_set_group_restriction(self):
179        """
180        This tests that setting a group restriction using the set_privacy view works
181        """
182        post_data = {
183            'restriction_type': 'groups',
184            'password': '',
185            'groups': [self.group.id, self.group2.id],
186        }
187        response = self.client.post(reverse('wagtailadmin_pages:set_privacy', args=(self.public_page.id, )), post_data)
188
189        # Check response
190        self.assertEqual(response.status_code, 200)
191        self.assertContains(response, '"is_public": false')
192
193        # Check that a page restriction has been created
194        self.assertTrue(PageViewRestriction.objects.filter(page=self.public_page).exists())
195
196        restriction = PageViewRestriction.objects.get(page=self.public_page)
197
198        # restriction_type should be 'groups'
199        self.assertEqual(restriction.restriction_type, 'groups')
200
201        # Be sure there is no password set
202        self.assertEqual(restriction.password, '')
203
204        # Check that the groups are set correctly
205        self.assertEqual(
206            set(PageViewRestriction.objects.get(page=self.public_page).groups.all()),
207            set([self.group, self.group2])
208        )
209
210    def test_set_group_restriction_password_unset(self):
211        """
212        This tests that the group fields on the form are validated correctly
213        """
214        post_data = {
215            'restriction_type': 'groups',
216            'password': '',
217            'groups': [],
218        }
219        response = self.client.post(reverse('wagtailadmin_pages:set_privacy', args=(self.public_page.id, )), post_data)
220
221        # Check response
222        self.assertEqual(response.status_code, 200)
223
224        # Check that a form error was raised
225        self.assertFormError(response, 'form', 'groups', "Please select at least one group.")
226
227    def test_unset_group_restriction(self):
228        """
229        This tests that removing a groups restriction using the set_privacy view works
230        """
231        post_data = {
232            'restriction_type': 'none',
233            'password': '',
234            'groups': [],
235        }
236        response = self.client.post(reverse('wagtailadmin_pages:set_privacy', args=(self.private_page.id, )), post_data)
237
238        # Check response
239        self.assertEqual(response.status_code, 200)
240        self.assertContains(response, '"is_public": true')
241
242        # Check that the page restriction has been deleted
243        self.assertFalse(PageViewRestriction.objects.filter(page=self.private_page).exists())
244
245
246class TestPrivacyIndicators(TestCase, WagtailTestUtils):
247    def setUp(self):
248        self.login()
249
250        # Create some pages
251        self.homepage = Page.objects.get(id=2)
252
253        self.public_page = self.homepage.add_child(instance=SimplePage(
254            title="Public page",
255            content="hello",
256            live=True,
257        ))
258
259        self.private_page = self.homepage.add_child(instance=SimplePage(
260            title="Private page",
261            content="hello",
262            live=True,
263        ))
264        PageViewRestriction.objects.create(
265            page=self.private_page, restriction_type='password', password='password123'
266        )
267
268        self.private_child_page = self.private_page.add_child(instance=SimplePage(
269            title="Private child page",
270            content="hello",
271            live=True,
272        ))
273
274    def test_explorer_public(self):
275        """
276        This tests that the privacy indicator on the public pages explore view is set to "PUBLIC"
277        """
278        response = self.client.get(reverse('wagtailadmin_explore', args=(self.public_page.id, )))
279
280        # Check the response
281        self.assertEqual(response.status_code, 200)
282
283        # Check the privacy indicator is public
284        self.assertTemplateUsed(response, 'wagtailadmin/pages/_privacy_switch.html')
285        self.assertContains(response, '<div class="privacy-indicator public">')
286        self.assertNotContains(response, '<div class="privacy-indicator private">')
287
288    def test_explorer_private(self):
289        """
290        This tests that the privacy indicator on the private pages explore view is set to "PRIVATE"
291        """
292        response = self.client.get(reverse('wagtailadmin_explore', args=(self.private_page.id, )))
293
294        # Check the response
295        self.assertEqual(response.status_code, 200)
296
297        # Check the privacy indicator is public
298        self.assertTemplateUsed(response, 'wagtailadmin/pages/_privacy_switch.html')
299        self.assertContains(response, '<div class="privacy-indicator private">')
300        self.assertNotContains(response, '<div class="privacy-indicator public">')
301
302    def test_explorer_private_child(self):
303        """
304        This tests that the privacy indicator on the private child pages explore view is set to "PRIVATE"
305        """
306        response = self.client.get(reverse('wagtailadmin_explore', args=(self.private_child_page.id, )))
307
308        # Check the response
309        self.assertEqual(response.status_code, 200)
310
311        # Check the privacy indicator is public
312        self.assertTemplateUsed(response, 'wagtailadmin/pages/_privacy_switch.html')
313        self.assertContains(response, '<div class="privacy-indicator private">')
314        self.assertNotContains(response, '<div class="privacy-indicator public">')
315
316    def test_explorer_list_homepage(self):
317        """
318        This tests that there is a padlock displayed next to the private page in the homepages explorer listing
319        """
320        response = self.client.get(reverse('wagtailadmin_explore', args=(self.homepage.id, )))
321
322        # Check the response
323        self.assertEqual(response.status_code, 200)
324
325        # Must have one privacy icon (next to the private page)
326        self.assertContains(response, "<span class=\"indicator privacy-indicator icon icon-no-view\"", count=1)
327
328    def test_explorer_list_private(self):
329        """
330        This tests that there is a padlock displayed
331        next to the private child page in the private pages explorer listing
332        """
333        response = self.client.get(reverse('wagtailadmin_explore', args=(self.private_page.id, )))
334
335        # Check the response
336        self.assertEqual(response.status_code, 200)
337
338        # Must have one privacy icon (next to the private child page)
339        self.assertContains(response, "<span class=\"indicator privacy-indicator icon icon-no-view\"", count=1)
340
341    def test_edit_public(self):
342        """
343        This tests that the privacy indicator on the public pages edit view is set to "PUBLIC"
344        """
345        response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.public_page.id, )))
346
347        # Check the response
348        self.assertEqual(response.status_code, 200)
349
350        # Check the privacy indicator is public
351        self.assertTemplateUsed(response, 'wagtailadmin/pages/privacy_switch_panel.html')
352        self.assertContains(response, '<div class="privacy-indicator public">')
353        self.assertNotContains(response, '<div class="privacy-indicator private">')
354
355    def test_edit_private(self):
356        """
357        This tests that the privacy indicator on the private pages edit view is set to "PRIVATE"
358        """
359        response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.private_page.id, )))
360
361        # Check the response
362        self.assertEqual(response.status_code, 200)
363
364        # Check the privacy indicator is public
365        self.assertTemplateUsed(response, 'wagtailadmin/pages/privacy_switch_panel.html')
366        self.assertContains(response, '<div class="privacy-indicator private">')
367        self.assertNotContains(response, '<div class="privacy-indicator public">')
368
369    def test_edit_private_child(self):
370        """
371        This tests that the privacy indicator on the private child pages edit view is set to "PRIVATE"
372        """
373        response = self.client.get(reverse('wagtailadmin_pages:edit', args=(self.private_child_page.id, )))
374
375        # Check the response
376        self.assertEqual(response.status_code, 200)
377
378        # Check the privacy indicator is public
379        self.assertTemplateUsed(response, 'wagtailadmin/pages/privacy_switch_panel.html')
380        self.assertContains(response, '<div class="privacy-indicator private">')
381        self.assertNotContains(response, '<div class="privacy-indicator public">')
382