From 6b16de6c7b1cb251acc61fd2d7a0e8ad885f0356 Mon Sep 17 00:00:00 2001
From: PaarthAgarwal <paarth.agarwal.mec20@itbhu.ac.in>
Date: Wed, 1 Jun 2022 17:03:56 +0530
Subject: [PATCH] Ensure TabbedInterface will not show a tab if no panels are
 shown

- If no panels show (due to permissions) the tab was still showing
- instead it is expected that the tabs should not show at all if empty
- fixes #8593

# Conflicts:
#	CHANGELOG.txt
#	docs/releases/4.0.md
---
 .../wagtailadmin/panels/tabbed_interface.html |  4 +-
 wagtail/admin/tests/test_edit_handlers.py     | 66 +++++++++++++++++--
 wagtail/test/testapp/models.py                |  7 +-
 3 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html b/wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html
index 7f3d8297a2..c197755e47 100644
--- a/wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html
+++ b/wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html
@@ -3,7 +3,7 @@
 <div class="w-tabs" data-tabs>
     <div class="w-tabs__wrapper">
         <div role="tablist" class="w-tabs__list">
-            {% for child in self.children %}
+            {% for child in self.visible_children %}
                 {% include 'wagtailadmin/shared/tabs/tab_nav_link.html' with tab_id=child.heading title=child.heading classes=child.classes|join:" " %}
             {% endfor %}
         </div>
@@ -21,7 +21,7 @@
     </div>
 
     <div class="tab-content">
-        {% for child in self.children %}
+        {% for child in self.visible_children %}
             <section
                 id="tab-{{ child.heading|cautious_slugify }}"
                 class="w-tabs__panel {{ child.classes|join:" " }}"
diff --git a/wagtail/admin/tests/test_edit_handlers.py b/wagtail/admin/tests/test_edit_handlers.py
index 63a7b79b86..38c8fcbef3 100644
--- a/wagtail/admin/tests/test_edit_handlers.py
+++ b/wagtail/admin/tests/test_edit_handlers.py
@@ -367,12 +367,12 @@ class TestExtractPanelDefinitionsFromModelClass(TestCase):
         )
 
 
-class TestTabbedInterface(TestCase):
+class TestTabbedInterface(TestCase, WagtailTestUtils):
     def setUp(self):
         self.request = RequestFactory().get("/")
-        user = AnonymousUser()  # technically, Anonymous users cannot access the admin
+        user = self.create_superuser(username="admin")
         self.request.user = user
-
+        self.user = self.login()
         # a custom tabbed interface for EventPage
         self.event_page_tabbed_interface = TabbedInterface(
             [
@@ -391,6 +391,12 @@ class TestTabbedInterface(TestCase):
                     ],
                     heading="Speakers",
                 ),
+                ObjectList(
+                    [
+                        FieldPanel("cost", permission="superuser"),
+                    ],
+                    heading="Secret",
+                ),
             ]
         ).bind_to_model(EventPage)
 
@@ -440,7 +446,7 @@ class TestTabbedInterface(TestCase):
     def test_required_fields(self):
         # get_form_options should report the set of form fields to be rendered recursively by children of TabbedInterface
         result = set(self.event_page_tabbed_interface.get_form_options()["fields"])
-        self.assertEqual(result, {"title", "date_from", "date_to"})
+        self.assertEqual(result, {"title", "date_from", "date_to", "cost"})
 
     def test_render_form_content(self):
         EventPageForm = self.event_page_tabbed_interface.get_form_class()
@@ -460,6 +466,58 @@ class TestTabbedInterface(TestCase):
         # in the panel definition
         self.assertNotIn("signup_link", result)
 
+    def test_tabs_permissions(self):
+        """
+        test that three tabs show when the current user has permission to see all three
+        test that two tabs show when the current user does not have permission to see all three
+        """
+
+        EventPageForm = self.event_page_tabbed_interface.get_form_class()
+        event = EventPage(title="Abergavenny sheepdog trials")
+        form = EventPageForm(instance=event)
+
+        # when signed in as a superuser all three tabs should be visible
+        tabbed_interface = self.event_page_tabbed_interface.get_bound_panel(
+            instance=event,
+            form=form,
+            request=self.request,
+        )
+        result = tabbed_interface.render_html()
+        self.assertIn(
+            '<a id="tab-label-event-details" href="#tab-event-details" class="w-tabs__tab shiny" role="tab" aria-selected="false" tabindex="-1">',
+            result,
+        )
+        self.assertIn(
+            '<a id="tab-label-speakers" href="#tab-speakers" class="w-tabs__tab " role="tab" aria-selected="false" tabindex="-1">',
+            result,
+        )
+        self.assertIn(
+            '<a id="tab-label-secret" href="#tab-secret" ',
+            result,
+        )
+
+        # Login as non superuser to check that the third tab does not show
+        user = AnonymousUser()  # technically, Anonymous users cannot access the admin
+        self.request.user = user
+        tabbed_interface = self.event_page_tabbed_interface.get_bound_panel(
+            instance=event,
+            form=form,
+            request=self.request,
+        )
+        result = tabbed_interface.render_html()
+        self.assertIn(
+            '<a id="tab-label-event-details" href="#tab-event-details" class="w-tabs__tab shiny" role="tab" aria-selected="false" tabindex="-1">',
+            result,
+        )
+        self.assertIn(
+            '<a id="tab-label-speakers" href="#tab-speakers" class="w-tabs__tab " role="tab" aria-selected="false" tabindex="-1">',
+            result,
+        )
+        self.assertNotIn(
+            '<a id="tab-label-secret" href="#tab-secret" ',
+            result,
+        )
+
 
 class TestObjectList(TestCase):
     def setUp(self):
diff --git a/wagtail/test/testapp/models.py b/wagtail/test/testapp/models.py
index 17834bd218..20450738db 100644
--- a/wagtail/test/testapp/models.py
+++ b/wagtail/test/testapp/models.py
@@ -951,7 +951,12 @@ StandardChild.edit_handler = TabbedInterface(
         ObjectList(
             StandardChild.settings_panels, heading="Settings", classname="settings"
         ),
-        ObjectList([], heading="Dinosaurs"),
+        ObjectList(
+            [
+                HelpPanel("remember to check for asteroids"),
+            ],
+            heading="Dinosaurs",
+        ),
     ],
     base_form_class=WagtailAdminPageForm,
 )