1from django.contrib.auth.models import AnonymousUser
2from django.template import Context, Template
3from django.test import TestCase
4from django.test.client import RequestFactory
5from django.urls import reverse
6
7from wagtail.core.models import PAGE_TEMPLATE_VAR, Page
8from wagtail.tests.testapp.models import BusinessChild, BusinessIndex
9from wagtail.tests.utils import WagtailTestUtils
10
11
12class TestUserbarTag(TestCase, WagtailTestUtils):
13    def setUp(self):
14        self.user = self.create_superuser(
15            username='test',
16            email='test@email.com',
17            password='password'
18        )
19        self.homepage = Page.objects.get(id=2)
20
21    def dummy_request(self, user=None):
22        request = RequestFactory().get('/')
23        request.user = user or AnonymousUser()
24        return request
25
26    def test_userbar_tag(self):
27        template = Template("{% load wagtailuserbar %}{% wagtailuserbar %}")
28        content = template.render(Context({
29            PAGE_TEMPLATE_VAR: self.homepage,
30            'request': self.dummy_request(self.user),
31        }))
32
33        self.assertIn("<!-- Wagtail user bar embed code -->", content)
34
35    def test_userbar_does_not_break_without_request(self):
36        template = Template("{% load wagtailuserbar %}{% wagtailuserbar %}boom")
37        content = template.render(Context({
38        }))
39
40        self.assertEqual("boom", content)
41
42    def test_userbar_tag_self(self):
43        """
44        Ensure the userbar renders with `self` instead of `PAGE_TEMPLATE_VAR`
45        """
46        template = Template("{% load wagtailuserbar %}{% wagtailuserbar %}")
47        content = template.render(Context({
48            'self': self.homepage,
49            'request': self.dummy_request(self.user),
50        }))
51
52        self.assertIn("<!-- Wagtail user bar embed code -->", content)
53
54    def test_userbar_tag_anonymous_user(self):
55        template = Template("{% load wagtailuserbar %}{% wagtailuserbar %}")
56        content = template.render(Context({
57            PAGE_TEMPLATE_VAR: self.homepage,
58            'request': self.dummy_request(),
59        }))
60
61        # Make sure nothing was rendered
62        self.assertEqual(content, '')
63
64    def test_userbar_tag_no_page(self):
65        template = Template("{% load wagtailuserbar %}{% wagtailuserbar %}")
66        content = template.render(Context({
67            'request': self.dummy_request(self.user),
68        }))
69
70        self.assertIn("<!-- Wagtail user bar embed code -->", content)
71
72
73class TestUserbarFrontend(TestCase, WagtailTestUtils):
74    def setUp(self):
75        self.login()
76        self.homepage = Page.objects.get(id=2)
77
78    def test_userbar_frontend(self):
79        response = self.client.get(reverse('wagtailadmin_userbar_frontend', args=(self.homepage.id, )))
80
81        self.assertEqual(response.status_code, 200)
82        self.assertTemplateUsed(response, 'wagtailadmin/userbar/base.html')
83
84    def test_userbar_frontend_anonymous_user_cannot_see(self):
85        # Logout
86        self.client.logout()
87
88        response = self.client.get(reverse('wagtailadmin_userbar_frontend', args=(self.homepage.id, )))
89
90        # Check that the user received a forbidden message
91        self.assertEqual(response.status_code, 403)
92
93
94class TestUserbarAddLink(TestCase, WagtailTestUtils):
95    fixtures = ['test.json']
96
97    def setUp(self):
98        self.login()
99        self.homepage = Page.objects.get(url_path='/home/')
100        self.event_index = Page.objects.get(url_path='/home/events/')
101
102        self.business_index = BusinessIndex(title='Business', live=True)
103        self.homepage.add_child(instance=self.business_index)
104
105        self.business_child = BusinessChild(title='Business Child', live=True)
106        self.business_index.add_child(instance=self.business_child)
107
108    def test_page_allowing_subpages(self):
109        response = self.client.get(reverse('wagtailadmin_userbar_frontend', args=(self.event_index.id, )))
110
111        # page allows subpages, so the 'add page' button should show
112        expected_url = reverse('wagtailadmin_pages:add_subpage', args=(self.event_index.id, ))
113        needle = f"""
114            <a href="{expected_url}" target="_parent" role="menuitem">
115                <svg class="icon icon-plus wagtail-action-icon" aria-hidden="true" focusable="false">
116                    <use href="#icon-plus"></use>
117                </svg>
118                Add a child page
119            </a>
120            """
121        self.assertTagInHTML(needle, str(response.content))
122
123    def test_page_disallowing_subpages(self):
124        response = self.client.get(reverse('wagtailadmin_userbar_frontend', args=(self.business_child.id, )))
125
126        # page disallows subpages, so the 'add page' button shouldn't show
127        expected_url = reverse('wagtailadmin_pages:add_subpage', args=(self.business_index.id, ))
128        expected_link = '<a href="%s" target="_parent">Add a child page</a>' \
129            % expected_url
130        self.assertNotContains(response, expected_link)
131
132
133class TestUserbarModeration(TestCase, WagtailTestUtils):
134    def setUp(self):
135        self.login()
136        self.homepage = Page.objects.get(id=2)
137        self.homepage.save_revision(submitted_for_moderation=True)
138        self.revision = self.homepage.get_latest_revision()
139
140    def test_userbar_moderation(self):
141        response = self.client.get(reverse('wagtailadmin_userbar_moderation', args=(self.revision.id, )))
142
143        self.assertEqual(response.status_code, 200)
144        self.assertTemplateUsed(response, 'wagtailadmin/userbar/base.html')
145
146        expected_approve_html = """
147            <form action="/admin/pages/moderation/{}/approve/" target="_parent" method="post">
148                <input type="hidden" name="csrfmiddlewaretoken">
149                <div class="wagtail-action wagtail-icon wagtail-icon-tick">
150                    <input type="submit" value="Approve" class="button" />
151                </div>
152            </form>
153        """.format(self.revision.id)
154        self.assertTagInHTML(expected_approve_html, str(response.content))
155
156        expected_reject_html = """
157            <form action="/admin/pages/moderation/{}/reject/" target="_parent" method="post">
158                <input type="hidden" name="csrfmiddlewaretoken">
159                <div class="wagtail-action wagtail-icon wagtail-icon-cross">
160                    <input type="submit" value="Reject" class="button" />
161                </div>
162            </form>
163        """.format(self.revision.id)
164        self.assertTagInHTML(expected_reject_html, str(response.content))
165
166    def test_userbar_moderation_anonymous_user_cannot_see(self):
167        # Logout
168        self.client.logout()
169
170        response = self.client.get(reverse('wagtailadmin_userbar_moderation', args=(self.revision.id, )))
171
172        # Check that the user received a forbidden message
173        self.assertEqual(response.status_code, 403)
174