Repository: wagtail/wagtail
File: wagtail/admin/tests/test_editing_sessions.py (Python)

Code before:
        self.user.save()
        editors = Group.objects.get(name="Editors")
        self.user.groups.add(editors)

        session = EditingSession.objects.create(
            user=self.user,
            content_type=ContentType.objects.get_for_model(Advert),
            object_id=snippet.pk,
            last_seen_at=TIMESTAMP_1,
        )
        response = self.client.post(
            reverse(
                "wagtailadmin_editing_sessions:ping",
                args=("tests", "advert", str(snippet.pk), session.id),
            )
        )
        self.assertEqual(response.status_code, 404)

    def test_moderator_without_explicit_edit_permission_on_snippet(self):
        snippet = FullFeaturedSnippet.objects.create(text="Test snippet")
        snippet.save_revision(user=self.other_user)

        # Assign default workflow to the snippet model
        snippet_content_type = ContentType.objects.get_for_model(FullFeaturedSnippet)
        workflow = Workflow.objects.get()
        WorkflowContentType.objects.create(
            content_type=snippet_content_type,
            workflow=workflow,
        )

        # submit snippet for moderation
        workflow = snippet.get_workflow()
        workflow.start(snippet, self.other_user)

        # make user a moderator. The Moderators group has no explicit permission over the
        # FullFeaturedSnippet model, and is only granted access to it via the workflow
        moderators = Group.objects.get(name="Moderators")
        self.user.is_superuser = False
        self.user.save()
        self.user.groups.add(moderators)

        session = EditingSession.objects.create(
            user=self.user,
            content_type=ContentType.objects.get_for_model(FullFeaturedSnippet),
            object_id=snippet.pk,
            last_seen_at=TIMESTAMP_1,
        )

        # access to the ping endpoint should be granted
        response = self.client.post(
            reverse(

Review comment (suggestion):
I noticed we don't have assertions for the messaging when the conflict is caused by the same user (in a different session). We have assertions in other test methods where the conflict is caused by a different user.

Just adding this for completeness sake.

Code after:
        self.assertEqual(
            response_json["other_sessions"],
            [
                # The 'other' session of the same user is still shown
                # as it has the latest revision, even though there are no
                # other sessions to attach the revision to. The last_seen_at
                # is set to the time of the revision's creation.
                {
                    "session_id": None,
                    "user": "Bob Testuser",
                    "last_seen_at": TIMESTAMP_4.isoformat(),
                    "is_editing": False,
                    "revision_id": new_revision.id,
                },
                {
                    "session_id": self.other_session.id,
                    "user": "Vic Otheruser",
                    "last_seen_at": TIMESTAMP_2.isoformat(),
                    "is_editing": False,
                    "revision_id": None,
                },
            ],
        )

        # The rendered HTML should use special messaging if the newer revision
        # is made by the same user ("in another window").
        soup = self.get_soup(response_json["html"])
        rendered_sessions = soup.select("ol.w-editing-sessions__list li")
        self.assertEqual(len(rendered_sessions), 2)
        session_text = rendered_sessions[0].text
        self.assertIn("You saved a new version in another window", session_text)
        self.assertNotIn("Currently viewing", session_text)
        dialog_title = soup.select_one(
            'template[data-w-teleport-target-value="#title-text-w-overwrite-changes-dialog"]'
        )
        self.assertIsNotNone(dialog_title)
        self.assertIn(
            "You saved a new version in another window", dialog_title.text.strip()
        )
        dialog_subtitle = soup.select_one(
            'template[data-w-teleport-target-value="#subtitle-w-overwrite-changes-dialog"]'
        )
        self.assertIsNotNone(dialog_subtitle)
        self.assertIn(
            "Proceeding will overwrite the changes you made in that window. "
            "Refreshing the page will show you the new changes, but you will "
            "lose any of your unsaved changes in the current window.",
            dialog_subtitle.text.strip(),
        )

    @freeze_time(TIMESTAMP_NOW)