1from django.test import TestCase
2from django.urls import reverse
3from django.utils.http import urlencode
4
5from wagtail.admin import widgets as wagtailadmin_widgets
6from wagtail.admin.wagtail_hooks import page_listing_more_buttons
7from wagtail.core import hooks
8from wagtail.core.models import Page
9from wagtail.tests.utils import WagtailTestUtils
10
11
12class PagePerms:
13    def can_move(self):
14        return False
15
16    def can_copy(self):
17        return False
18
19    def can_delete(self):
20        return True
21
22    def can_unpublish(self):
23        return False
24
25    def can_view_revisions(self):
26        return False
27
28
29class TestButtonsHooks(TestCase, WagtailTestUtils):
30    def setUp(self):
31        self.root_page = Page.objects.get(id=2)
32        self.login()
33
34    def test_register_page_listing_buttons(self):
35        def page_listing_buttons(page, page_perms, is_parent=False, next_url=None):
36            yield wagtailadmin_widgets.PageListingButton(
37                'Another useless page listing button',
38                '/custom-url',
39                priority=10
40            )
41
42        with hooks.register_temporarily('register_page_listing_buttons', page_listing_buttons):
43            response = self.client.get(
44                reverse('wagtailadmin_explore', args=(self.root_page.id, ))
45            )
46
47        self.assertEqual(response.status_code, 200)
48        self.assertTemplateUsed(response, 'wagtailadmin/pages/listing/_button_with_dropdown.html')
49        self.assertTemplateUsed(response, 'wagtailadmin/pages/listing/_buttons.html')
50
51        self.assertContains(response, 'Another useless page listing button')
52
53    def test_register_page_listing_more_buttons(self):
54        def page_listing_more_buttons(page, page_perms, is_parent=False, next_url=None):
55            yield wagtailadmin_widgets.Button(
56                'Another useless button in default "More" dropdown',
57                '/custom-url',
58                priority=10
59            )
60
61        with hooks.register_temporarily('register_page_listing_more_buttons', page_listing_more_buttons):
62            response = self.client.get(
63                reverse('wagtailadmin_explore', args=(self.root_page.id, ))
64            )
65
66        self.assertEqual(response.status_code, 200)
67        self.assertTemplateUsed(response, 'wagtailadmin/pages/listing/_button_with_dropdown.html')
68        self.assertTemplateUsed(response, 'wagtailadmin/pages/listing/_buttons.html')
69
70        self.assertContains(response, 'Another useless button in default "More" dropdown')
71
72    def test_custom_button_with_dropdown(self):
73        def page_custom_listing_buttons(page, page_perms, is_parent=False, next_url=None):
74            yield wagtailadmin_widgets.ButtonWithDropdownFromHook(
75                'One more more button',
76                hook_name='register_page_listing_one_more_more_buttons',
77                page=page,
78                page_perms=page_perms,
79                is_parent=is_parent,
80                next_url=next_url,
81                attrs={'target': '_blank', 'rel': 'noopener noreferrer'},
82                priority=50
83            )
84
85        def page_custom_listing_more_buttons(page, page_perms, is_parent=False, next_url=None):
86            yield wagtailadmin_widgets.Button(
87                'Another useless dropdown button in "One more more button" dropdown',
88                '/custom-url',
89                priority=10
90            )
91
92        with hooks.register_temporarily('register_page_listing_buttons', page_custom_listing_buttons), hooks.register_temporarily('register_page_listing_one_more_more_buttons', page_custom_listing_more_buttons):
93            response = self.client.get(
94                reverse('wagtailadmin_explore', args=(self.root_page.id, ))
95            )
96
97        self.assertEqual(response.status_code, 200)
98        self.assertTemplateUsed(response, 'wagtailadmin/pages/listing/_button_with_dropdown.html')
99        self.assertTemplateUsed(response, 'wagtailadmin/pages/listing/_buttons.html')
100
101        self.assertContains(response, 'One more more button')
102        self.assertContains(response, 'Another useless dropdown button in "One more more button" dropdown')
103
104    def test_delete_button_next_url(self):
105        page_perms = PagePerms()
106        page = self.root_page
107        base_url = reverse('wagtailadmin_pages:delete', args=[page.id])
108
109        next_url = "a/random/url/"
110        full_url = base_url + '?' + urlencode({'next': next_url})
111
112        # page_listing_more_button generator yields only `Delete button`
113        delete_button = next(page_listing_more_buttons(
114            page,
115            page_perms,
116            is_parent=False,
117            next_url=next_url
118        ))
119
120        self.assertEqual(delete_button.url, full_url)
121
122        next_url = reverse('wagtailadmin_explore', args=[page.id])
123        delete_button = next(page_listing_more_buttons(
124            page,
125            page_perms,
126            is_parent=False,
127            next_url=next_url
128        ))
129
130        self.assertEqual(delete_button.url, base_url)
131