Repository: wagtail/wagtail

Issue:
"Edit this Page" missing from userbar
### Issue Summary

In previous versions of Wagtail, the userbar contains a link to "Edit this page" on both the live page and when viewing draft pages. The userbar shown on live pages still contains this link.

<img width="272" alt="UserbarOnLivePage" src="https://user-images.githubusercontent.com/5952/216113309-3a8e4115-8430-41c1-b39a-ac1baf44c7fd.png">

But the version displayed on "View Draft", e.g. example url: https://example.com/admin/pages/25185/view_draft/, does not.
<img width="272" alt="UserbarOnViewDraft" src="https://user-images.githubusercontent.com/5952/216113332-25cb4e7b-ab10-4d2a-8341-d10b97d7dd47.png">

### Steps to Reproduce

1. Create a site using Wagtail 4.1.1 or 4.2rc1
3. Create a page and "Save draft"
4. From the page explorer for the parent of the draft page above, choose "View Draft"
5. Click on the Wagtail icon to display the menu

I have only found this on existing projects I have upgraded. I have not confirmed that this issue can be reproduced as described on a fresh Wagtail project.

### Technical details

-   Python version:  3.8.16
-   Django version: 4.1.5
-   Wagtail version: 4.1.1 and 4.2rc1
-   Browser version: Chrome 109



Discussion:
I can confirm this on my own Wagtail 4.1.1 installation, and confirm that it previously worked on a (different) Wagtail 3.0.1 site.

I have also confirmed it on a fresh Wagtail project with no modifications (using 4.1.1).
Hi, I want to work on this issue, if possible would you please assign this issue to me?
Thanks for your interest @satvikvash! You are welcome to work on this. We do not assign issues outside of the core team - we just ask that people indicate their intention to work on an issue (as you have now done), to avoid duplicating efforts.

For further help in getting started, please see https://dev.to/lb/ten-tasty-ingredients-for-a-delicious-pull-request-hgc - you may also wish to join [our #new-contributors channel on Slack](https://github.com/wagtail/wagtail/wiki/Slack).
Hi, would it be possible to work on this issue as well?

Hello, Removing
`try:`
           `   if request.is_preview:`
                `       return ""`
        `except AttributeError:`
           `    pass`
from **EditPageItem** class of userbar.py will solve the issue.
I will be happy to create a pull request.
Hi @Aravind2203, if you do this it creates an edit button on preview page also, and this whole code is for not having an edit button on preview page userbar (this is also mentioned in the comment written above this code). I think removing this code will resolve this issue but create a new issue. I have solved this issue using a different approach and presently I am working on writing the tests for the pull request.

Resolving patch:
diff --git a/wagtail/admin/userbar.py b/wagtail/admin/userbar.py
--- a/wagtail/admin/userbar.py
+++ b/wagtail/admin/userbar.py
@@ -160,7 +160,7 @@ def render(self, request):
         # Don't render if request is a preview. This is to avoid confusion that
         # might arise when the user clicks edit on a preview.
         try:
-            if request.is_preview:
+            if request.is_preview and request.is_editing:
                 return ""
         except AttributeError:
             pass
diff --git a/wagtail/admin/views/generic/preview.py b/wagtail/admin/views/generic/preview.py
--- a/wagtail/admin/views/generic/preview.py
+++ b/wagtail/admin/views/generic/preview.py
@@ -106,7 +106,8 @@ def get(self, request, *args, **kwargs):
             raise PermissionDenied
 
         extra_attrs = {
-            "in_preview_panel": request.GET.get("in_preview_panel") == "true"
+            "in_preview_panel": request.GET.get("in_preview_panel") == "true",
+            "is_editing": True,
         }
 
         return self.object.make_preview_request(request, preview_mode, extra_attrs)


Test patch:
diff --git a/wagtail/admin/tests/pages/test_create_page.py b/wagtail/admin/tests/pages/test_create_page.py
--- a/wagtail/admin/tests/pages/test_create_page.py
+++ b/wagtail/admin/tests/pages/test_create_page.py
@@ -811,6 +811,9 @@ def test_preview_on_create(self):
         self.assertTrue(response.context["self"].path.startswith(self.root_page.path))
         self.assertEqual(response.context["self"].get_parent(), self.root_page)
 
+        # Should not show edit link in the userbar
+        self.assertNotContains(response, "Edit this page")
+
     def test_preview_with_custom_validation(self):
         post_data = {
             "title": "New page!",
diff --git a/wagtail/admin/tests/pages/test_edit_page.py b/wagtail/admin/tests/pages/test_edit_page.py
--- a/wagtail/admin/tests/pages/test_edit_page.py
+++ b/wagtail/admin/tests/pages/test_edit_page.py
@@ -1314,6 +1314,13 @@ def test_preview_on_edit(self):
         self.assertTemplateUsed(response, "tests/simple_page.html")
         self.assertContains(response, "I&#39;ve been edited!", html=True)
 
+        # Should not show edit link in the userbar
+        # https://github.com/wagtail/wagtail/issues/8765
+        self.assertNotContains(response, "Edit this page")
+        self.assertNotContains(
+            response, reverse("wagtailadmin_pages:edit", args=(self.child_page.id,))
+        )
+
     def test_preview_on_edit_no_session_key(self):
         preview_url = reverse(
             "wagtailadmin_pages:preview_on_edit", args=(self.child_page.id,)
diff --git a/wagtail/admin/tests/pages/test_revisions.py b/wagtail/admin/tests/pages/test_revisions.py
--- a/wagtail/admin/tests/pages/test_revisions.py
+++ b/wagtail/admin/tests/pages/test_revisions.py
@@ -68,6 +68,14 @@ def test_preview_revision(self):
         self.assertEqual(response.status_code, 200)
         self.assertContains(response, "Last Christmas I gave you my heart")
 
+        # Should show edit link in the userbar
+        # https://github.com/wagtail/wagtail/issues/10002
+        self.assertContains(response, "Edit this page")
+        self.assertContains(
+            response,
+            reverse("wagtailadmin_pages:edit", args=(self.christmas_event.id,)),
+        )
+
     def test_preview_revision_with_no_page_permissions_redirects_to_admin(self):
         admin_only_user = self.create_user(
             username="admin_only", email="admin_only@email.com", password="password"
diff --git a/wagtail/admin/tests/pages/test_view_draft.py b/wagtail/admin/tests/pages/test_view_draft.py
--- a/wagtail/admin/tests/pages/test_view_draft.py
+++ b/wagtail/admin/tests/pages/test_view_draft.py
@@ -100,3 +100,15 @@ def test_middleware_response_is_returned(self):
             HTTP_USER_AGENT="EvilHacker",
         )
         self.assertEqual(response.status_code, 403)
+
+    def test_show_edit_link_in_userbar(self):
+        self.login()
+        response = self.client.get(
+            reverse("wagtailadmin_pages:view_draft", args=(self.child_page.id,))
+        )
+        # Should show edit link in the userbar
+        # https://github.com/wagtail/wagtail/issues/10002
+        self.assertContains(response, "Edit this page")
+        self.assertContains(
+            response, reverse("wagtailadmin_pages:edit", args=(self.child_page.id,))
+        )
diff --git a/wagtail/admin/tests/test_userbar.py b/wagtail/admin/tests/test_userbar.py
--- a/wagtail/admin/tests/test_userbar.py
+++ b/wagtail/admin/tests/test_userbar.py
@@ -17,11 +17,18 @@ def setUp(self):
         self.homepage = Page.objects.get(id=2)
 
     def dummy_request(
-        self, user=None, *, is_preview=False, in_preview_panel=False, revision_id=None
+        self,
+        user=None,
+        *,
+        is_preview=False,
+        in_preview_panel=False,
+        revision_id=None,
+        is_editing=False,
     ):
         request = RequestFactory().get("/")
         request.user = user or AnonymousUser()
         request.is_preview = is_preview
+        request.is_editing = is_editing
         request.in_preview_panel = in_preview_panel
         if revision_id:
             request.revision_id = revision_id
@@ -117,7 +124,9 @@ def test_edit_link(self):
         self.assertIn("<!-- Wagtail user bar embed code -->", content)
         self.assertIn("Edit this page", content)
 
-    def test_userbar_edit_menu_not_in_preview(self):
+    def test_userbar_edit_menu_in_previews(self):
+        # The edit link should be visible on draft, revision, and workflow previews.
+        # https://github.com/wagtail/wagtail/issues/10002
         template = Template("{% load wagtailuserbar %}{% wagtailuserbar %}")
         content = template.render(
             Context(
@@ -128,7 +137,30 @@ def test_userbar_edit_menu_not_in_preview(self):
             )
         )
         self.assertIn("<!-- Wagtail user bar embed code -->", content)
+        self.assertIn("Edit this page", content)
+        self.assertIn(
+            reverse("wagtailadmin_pages:edit", args=(self.homepage.id,)), content
+        )
+
+    def test_userbar_edit_menu_not_in_preview(self):
+        # The edit link should not be visible on PreviewOnEdit/Create views.
+        # https://github.com/wagtail/wagtail/issues/8765
+        template = Template("{% load wagtailuserbar %}{% wagtailuserbar %}")
+        content = template.render(
+            Context(
+                {
+                    PAGE_TEMPLATE_VAR: self.homepage,
+                    "request": self.dummy_request(
+                        self.user, is_preview=True, is_editing=True
+                    ),
+                }
+            )
+        )
+        self.assertIn("<!-- Wagtail user bar embed code -->", content)
         self.assertNotIn("Edit this page", content)
+        self.assertNotIn(
+            reverse("wagtailadmin_pages:edit", args=(self.homepage.id,)), content
+        )
 
     def test_userbar_not_in_preview_panel(self):
         template = Template("{% load wagtailuserbar %}{% wagtailuserbar %}")
diff --git a/wagtail/admin/tests/test_workflows.py b/wagtail/admin/tests/test_workflows.py
--- a/wagtail/admin/tests/test_workflows.py
+++ b/wagtail/admin/tests/test_workflows.py
@@ -1,7 +1,7 @@
 import io
 import json
 import logging
-from unittest import mock
+from unittest import expectedFailure, mock
 
 from django.conf import settings
 from django.contrib.admin.utils import quote
@@ -2763,6 +2763,20 @@ def test_preview_workflow(self):
         self.assertTemplateUsed(response, self.preview_template)
         self.assertContains(response, self.preview_content)
 
+    def test_preview_workflow_show_edit_link_in_userbar(self):
+        preview_url = self.get_url(
+            "workflow_preview",
+            args=(quote(self.object.pk), self.object.current_workflow_task.id),
+        )
+        response = self.client.get(preview_url)
+
+        # Should show edit link in the userbar
+        # https://github.com/wagtail/wagtail/issues/10002
+        self.assertContains(response, "Edit this page")
+        self.assertContains(
+            response, reverse("wagtailadmin_pages:edit", args=(quote(self.object.pk),))
+        )
+
     def test_preview_workflow_by_submitter(self):
         self.login(self.submitter)
         preview_url = self.get_url(
@@ -2811,6 +2825,11 @@ def edit_object(self):
         self.object.text = self.new_content
         self.object.save_revision()
 
+    @expectedFailure
+    def test_preview_workflow_show_edit_link_in_userbar(self):
+        # TODO: Add edit link to userbar on snippet previews
+        super().test_preview_workflow_show_edit_link_in_userbar()
+
 
 class TestTaskChooserView(WagtailTestUtils, TestCase):
     def setUp(self):