diff --git a/wagtail/snippets/tests/test_snippets.py b/wagtail/snippets/tests/test_snippets.py index 93e51ced56..3440180c1d 100644 --- a/wagtail/snippets/tests/test_snippets.py +++ b/wagtail/snippets/tests/test_snippets.py @@ -235,21 +235,45 @@ class TestSnippetListView(WagtailTestUtils, TestCase): def test_construct_snippet_listing_buttons_hook(self): Advert.objects.create(text="My Lovely advert") - # testapp implements a construct_snippetlisting_buttons hook - # that add's an dummy button with the label 'Dummy Button' which points - # to '/dummy-button' and is placed as a top-level button instead of - # put inside the default "More" dropdown button + # testapp implements a construct_snippet_listing_buttons hook + # that adds a dummy button with the label 'Dummy Button' which points + # to '/dummy-button' and is placed inside the default "More" dropdown button response = self.get() self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "wagtailadmin/shared/buttons.html") soup = self.get_soup(response.content) - dummy_button = soup.select_one( - "tbody tr td ul.actions > li > a[href='/dummy-button']" + dropdowns = soup.select( + "tbody tr td ul.actions > li > [data-controller='w-dropdown']" ) + self.assertEqual(len(dropdowns), 1) + more_dropdown = dropdowns[0] + dummy_button = more_dropdown.find("a", attrs={"href": "/dummy-button"}) self.assertIsNotNone(dummy_button) self.assertEqual(dummy_button.text.strip(), "Dummy Button") + def test_construct_snippet_listing_buttons_hook_contains_default_buttons(self): + advert = Advert.objects.create(text="My Lovely advert") + delete_url = reverse( + "wagtailsnippets_tests_advert:delete", args=[quote(advert.pk)] + ) + + def hide_delete_button_for_lovely_advert(buttons, snippet, user): + # Edit, delete, dummy button + self.assertEqual(len(buttons), 3) + buttons[:] = [button for button in buttons if button.url != delete_url] + self.assertEqual(len(buttons), 2) + + with hooks.register_temporarily( + "construct_snippet_listing_buttons", + hide_delete_button_for_lovely_advert, + ): + response = self.get() + + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, "wagtailadmin/shared/buttons.html") + self.assertNotContains(response, delete_url) + def test_construct_snippet_listing_buttons_hook_deprecated_context(self): advert = Advert.objects.create(text="My Lovely advert") diff --git a/wagtail/snippets/views/snippets.py b/wagtail/snippets/views/snippets.py index 8134274861..406a33c47a 100644 --- a/wagtail/snippets/views/snippets.py +++ b/wagtail/snippets/views/snippets.py @@ -177,10 +177,9 @@ class IndexView(generic.IndexViewOptionalFeaturesMixin, generic.IndexView): def get_list_buttons(self, instance): more_buttons = self.get_list_more_buttons(instance) next_url = self.request.path - button_hooks = hooks.get_hooks("register_snippet_listing_buttons") list_buttons = [] - for hook in button_hooks: + for hook in hooks.get_hooks("register_snippet_listing_buttons"): hook_buttons = hook(instance, self.request.user, next_url) for button in hook_buttons: if isinstance(button, BaseDropdownMenuButton): @@ -191,6 +190,19 @@ class IndexView(generic.IndexViewOptionalFeaturesMixin, generic.IndexView): # Otherwise, add it to the default "More" dropdown more_buttons.append(button) + # Pass the more_buttons to the construct hooks, as that's what contains + # the default buttons and most buttons added via register_snippet_listing_buttons + for hook in hooks.get_hooks("construct_snippet_listing_buttons"): + try: + hook(more_buttons, instance, self.request.user) + except TypeError: + warn( + "construct_snippet_listing_buttons hook no longer accepts a context argument", + RemovedInWagtail60Warning, + stacklevel=2, + ) + hook(more_buttons, instance, self.request.user, {}) + list_buttons.append( ButtonWithDropdown( buttons=more_buttons, @@ -202,19 +214,6 @@ class IndexView(generic.IndexViewOptionalFeaturesMixin, generic.IndexView): ) ) - # Pass the top-level buttons to the hooks, so top-level non-dropdown - # buttons can still be added. - for hook in hooks.get_hooks("construct_snippet_listing_buttons"): - try: - hook(list_buttons, instance, self.request.user) - except TypeError: - warn( - "construct_snippet_listing_buttons hook no longer accepts a context argument", - RemovedInWagtail60Warning, - stacklevel=2, - ) - hook(list_buttons, instance, self.request.user, {}) - return list_buttons def get_context_data(self, **kwargs):