From fdac9572b172dbbb0a8e9fc2046827695f393e81 Mon Sep 17 00:00:00 2001 From: Philippe MILINK Date: Fri, 25 Mar 2022 16:17:32 +0100 Subject: [PATCH] =?UTF-8?q?Permet=20le=20changement=20de=20titre=20d'un=20?= =?UTF-8?q?contenu=20publi=C3=A9=20entre=20deux=20passages=20du=20watchdog?= =?UTF-8?q?=20de=20publication?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zds/tutorialv2/api/tests.py | 5 +- zds/tutorialv2/models/database.py | 10 ++- zds/tutorialv2/publication_utils.py | 7 ++ zds/tutorialv2/tests/tests_opinion_views.py | 96 ++++++++++++++++++++- 4 files changed, 113 insertions(+), 5 deletions(-) diff --git a/zds/tutorialv2/api/tests.py b/zds/tutorialv2/api/tests.py index 3d3b897043..7312856224 100644 --- a/zds/tutorialv2/api/tests.py +++ b/zds/tutorialv2/api/tests.py @@ -239,8 +239,9 @@ def test_request_content_exports_generation(self): response = self.client.post(reverse("api:content:generate_export", args=[content.content.pk])) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # And it should be greater than the previous one as we added new requets - self.assertGreater(PublicationEvent.objects.filter(published_object=content).count(), requests_count) + # And it should be equal than the previous one as we added new request, + # but the watchdog wasn't launched to handle them: + self.assertEqual(PublicationEvent.objects.filter(published_object=content).count(), requests_count) self.client.logout() diff --git a/zds/tutorialv2/models/database.py b/zds/tutorialv2/models/database.py index 650e7b6918..6ca2b64a34 100644 --- a/zds/tutorialv2/models/database.py +++ b/zds/tutorialv2/models/database.py @@ -671,6 +671,7 @@ class Meta: sha_public = models.CharField("Sha1 de la version publiée", blank=True, null=True, max_length=80, db_index=True) char_count = models.IntegerField(default=None, null=True, verbose_name=b"Nombre de lettres du contenu", blank=True) + # NOTE: removing the spurious space in the field description requires a database migration ! must_redirect = models.BooleanField( "Redirection vers une version plus récente", blank=True, db_index=True, default=False ) @@ -696,8 +697,13 @@ def title(self): if self.versioned_model: return self.versioned_model.title else: - self._manifest = self._manifest or self.content.load_manifest(sha=self.sha_public, public=self) - return self._manifest.get("title", "Default title") + title = "Default title" + try: + self._manifest = self._manifest or self.content.load_manifest(sha=self.sha_public, public=self) + title = self._manifest.get("title", title) + except OSError: + title = self.content.title + return title def description(self): if self.versioned_model: diff --git a/zds/tutorialv2/publication_utils.py b/zds/tutorialv2/publication_utils.py index 93c298b3ed..d0288a2988 100644 --- a/zds/tutorialv2/publication_utils.py +++ b/zds/tutorialv2/publication_utils.py @@ -563,6 +563,13 @@ def publish(self, md_file_path, base_name, silently_pass=True, **kwargs): def publish_from_published_content(self, published_content: PublishedContent): for requested_format in PublicatorRegistry.get_all_registered(["watchdog"]): + # Remove previous PublicationEvent for this content, not handled by + # the publication watchdog yet: + PublicationEvent.objects.filter( + state_of_processing="REQUESTED", + published_object__content_pk=published_content.content_pk, + format_requested=requested_format[0], + ).delete() PublicationEvent.objects.create( state_of_processing="REQUESTED", published_object=published_content, diff --git a/zds/tutorialv2/tests/tests_opinion_views.py b/zds/tutorialv2/tests/tests_opinion_views.py index e01b0dbb39..25432499e7 100644 --- a/zds/tutorialv2/tests/tests_opinion_views.py +++ b/zds/tutorialv2/tests/tests_opinion_views.py @@ -1,4 +1,6 @@ import datetime +from django.conf import settings +from django.core.management import call_command from django.urls import reverse from django.test import TestCase from django.utils.translation import gettext_lazy as _ @@ -10,7 +12,12 @@ ExtractFactory, PublishedContentFactory, ) -from zds.tutorialv2.models.database import PublishableContent, PublishedContent, PickListOperation +from zds.tutorialv2.models.database import ( + PublishableContent, + PublishedContent, + PickListOperation, + PublicationEvent, +) from zds.tutorialv2.tests import TutorialTestMixin, override_for_contents from zds.utils.tests.factories import SubCategoryFactory, LicenceFactory from zds.utils.models import Alert @@ -60,6 +67,93 @@ def test_opinion_publication_author(self): self.assertIsNotNone(opinion.public_version) self.assertEqual(opinion.public_version.sha_public, opinion_draft.current_version) + def test_publish_content_change_title_before_watchdog(self): + """ + Test we can publish a content, change its title and publish it again + right away, before the publication watchdog processed the first + publication. + """ + previous_extra_content_generation_policy = self.overridden_zds_app["content"]["extra_content_generation_policy"] + self.overridden_zds_app["content"]["extra_content_generation_policy"] = "WATCHDOG" + + # Create a content: + opinion = PublishableContentFactory(type="OPINION") + + opinion.authors.add(self.user_author) + UserGalleryFactory(gallery=opinion.gallery, user=self.user_author, mode="W") + opinion.licence = self.licence + opinion.save() + + opinion_draft = opinion.load_version() + + # Publish it a first time: + self.client.force_login(self.user_author) + + result = self.client.post( + reverse("validation:publish-opinion", kwargs={"pk": opinion.pk, "slug": opinion.slug}), + {"text": "Blabla", "source": "", "version": opinion_draft.current_version}, + follow=False, + ) + self.assertEqual(result.status_code, 302) + + self.assertEqual(PublishedContent.objects.count(), 1) + + opinion = PublishableContent.objects.get(pk=opinion.pk) + self.assertIsNotNone(opinion.public_version) + self.assertEqual(opinion.public_version.sha_public, opinion_draft.current_version) + + # Change the title: + random = "Whatever, we don't care about the details" + result = self.client.post( + reverse("content:edit", args=[opinion.pk, opinion.slug]), + { + "title": "{} ({})".format(opinion.title, "modified"), + "description": random, + "introduction": random, + "conclusion": random, + "type": "OPINION", + "licence": opinion.licence.pk, + "subcategory": opinion.subcategory.first().pk, + "last_hash": opinion.load_version().compute_hash(), + "image": (settings.BASE_DIR / "fixtures" / "logo.png").open("rb"), + }, + follow=False, + ) + self.assertEqual(result.status_code, 302) + self.assertEqual(PublishedContent.objects.count(), 1) + + opinion = PublishableContent.objects.get(pk=opinion.pk) + self.assertIsNotNone(opinion.public_version) + self.assertEqual(opinion.public_version.sha_public, opinion_draft.current_version) + + # and publish it a second time now it has a new title: + result = self.client.post( + reverse("validation:publish-opinion", kwargs={"pk": opinion.pk, "slug": opinion.slug}), + {"text": "Blabla", "source": "", "version": opinion_draft.current_version}, + follow=False, + ) + self.assertEqual(result.status_code, 302) + + # There are two PublishedContent: one with the old title and the old slug + # redirecting to the current version of the content with the new title: + self.assertEqual(PublishedContent.objects.count(), 2) + + opinion = PublishableContent.objects.get(pk=opinion.pk) + self.assertIsNotNone(opinion.public_version) + opinion_draft = opinion.load_version() + self.assertEqual(opinion.public_version.sha_public, opinion_draft.current_version) + + requested_events = PublicationEvent.objects.filter(state_of_processing="REQUESTED") + self.assertEqual(requested_events.count(), 4) + + # Now, call the watchdog: + call_command("publication_watchdog", "--once") + + requested_events = PublicationEvent.objects.filter(state_of_processing="REQUESTED") + self.assertEqual(requested_events.count(), 0) + + self.overridden_zds_app["content"]["extra_content_generation_policy"] = previous_extra_content_generation_policy + def test_accessible_ui_for_author(self): opinion = PublishedContentFactory(author_list=[self.user_author], type="OPINION") subcategory = SubCategoryFactory()