diff --git a/templates/tutorialv2/list_page_elements/call_for_helps.html b/templates/tutorialv2/list_page_elements/call_for_helps.html index e4c3c42637..207510f73f 100644 --- a/templates/tutorialv2/list_page_elements/call_for_helps.html +++ b/templates/tutorialv2/list_page_elements/call_for_helps.html @@ -10,11 +10,11 @@

{% trans 'Donnez votre avis' %}

-

{% trans "Aidez à peaufiner le fond et la forme des contenus presque terminés." %}

+

{% trans "Aidez à peaufiner le fond et la forme des publications presque terminées." %}

-

{% trans "Consulter les contenus en bêta" %}

+

{% trans "Consulter les publications en bêta" %}

@@ -24,15 +24,11 @@

{% trans 'Partagez votre savoir' %}

-

{% trans "Vous avez un savoir à partager ? Vous vous sentez pédagogue ? Commencez donc l’écriture d’un contenu !" %}

+

{% trans "Vous avez un savoir à partager ? Vous vous sentez pédagogue ? Commencez donc l’écriture d’une publication !" %}

-

{% trans 'Écrire un tutoriel' %}

-
- - -

{% trans 'Écrire un article' %}

+

{% trans 'Commencer à rédiger' %}

diff --git a/templates/tutorialv2/view/base_categories.html b/templates/tutorialv2/view/base_categories.html index 69bc99b567..9d8a8dd230 100644 --- a/templates/tutorialv2/view/base_categories.html +++ b/templates/tutorialv2/view/base_categories.html @@ -103,9 +103,6 @@

Parcourir

{% if subcategory %} {% trans 'Catégorie :' %} {{subcategory}} {% endif %} - {% if type %} - {% trans 'Type :' %} {{type}} - {% endif %} {% if tag %} {% trans 'Tag :' %} {{tag}} {% endif %} diff --git a/templates/tutorialv2/view/categories.html b/templates/tutorialv2/view/categories.html index ebc2faf6a5..c7e9c0422e 100644 --- a/templates/tutorialv2/view/categories.html +++ b/templates/tutorialv2/view/categories.html @@ -4,24 +4,6 @@ {% block content_category %} - {% comment %} - First level page - - 2 featured tutorials - - all 4 knownledge domains presentation - - 1 column with last 6 contents - - 1 column with 6 most commented contents - - self investment block - -
-

{% trans 'À la une' %}

- -
- {% endcomment %} -
{% captureas url_view_goals %}{% url "content:view-goals" %}{% endcaptureas %} {% blocktrans %} @@ -39,31 +21,19 @@

{% trans 'Domaines de savoir' %}

-
-
-

- {% trans 'Derniers tutoriels' %} - RSS - Atom -

- {% include 'tutorialv2/list_page_elements/list_of_online_contents.html' with public_contents=last_tutorials col_number=1 %} - {% if last_tutorials and more_tutorials %} - Plus de tutoriels - {% endif %} -
- -
-

- {% trans 'Derniers articles' %} - RSS - Atom -

- {% include 'tutorialv2/list_page_elements/list_of_online_contents.html' with public_contents=last_articles col_number=1 %} - {% if last_articles and more_articles %} - Plus d’articles +
+

+ {% trans 'Dernières publications' %} + RSS + Atom +

+
+ {% include 'tutorialv2/list_page_elements/list_of_online_contents.html' with public_contents=last_contents col_number=2 %} + {% if last_contents and more_contents %} + Plus de publications {% endif %} -
-
+ + {% include 'tutorialv2/list_page_elements/call_for_helps.html' %} {% endblock %} diff --git a/templates/tutorialv2/view/category.html b/templates/tutorialv2/view/category.html index 375cb869c6..14c8546c24 100644 --- a/templates/tutorialv2/view/category.html +++ b/templates/tutorialv2/view/category.html @@ -2,10 +2,9 @@ {% load i18n %} {% comment %} - Structure de la page de second level : - - présentation des sous catégories (accessible via {% for subcategory in subcategories %} - - liste des 5 derniers tutos en une colonne - - liste des 5 derniers articles en une colonne + Structure de la page de second niveau : + - présentation des sous catégories + - liste des dernières publications {% endcomment %} {% block content_category %} @@ -14,29 +13,15 @@

Catégories dans {{ category.title }}

{% include 'tutorialv2/list_page_elements/list_subcategories.html' with subcategories=subcategories %} -
-
-

- {% trans "Derniers tutoriels" %} - RSS - Atom -

- {% include 'tutorialv2/list_page_elements/list_of_online_contents.html' with public_contents=last_tutorials col_number=1 %} - {% if last_tutorials and more_tutorials %} - Plus de tutoriels dans {{ category.title }} - {% endif %} -
- -
-

- {% trans "Derniers articles" %} - RSS - Atom -

- {% include 'tutorialv2/list_page_elements/list_of_online_contents.html' with public_contents=last_articles col_number=1 %} - {% if last_articles and more_articles %} - Plus d’articles dans {{ category.title }} - {% endif %} -
-
+
+

+ {% trans "Dernières publications" %} + RSS + Atom +

+ {% include 'tutorialv2/list_page_elements/list_of_online_contents.html' with public_contents=last_contents col_number=1 %} + {% if last_contents and more_contents %} + Plus de publications dans {{ category.title }} + {% endif %} +
{% endblock %} diff --git a/templates/tutorialv2/view/subcategory.html b/templates/tutorialv2/view/subcategory.html index f6b903a6cf..053eb10337 100644 --- a/templates/tutorialv2/view/subcategory.html +++ b/templates/tutorialv2/view/subcategory.html @@ -3,29 +3,16 @@ {% block content_category %} -
-
-

- {% trans "Derniers tutoriels" %} - RSS - Atom -

- {% include 'tutorialv2/list_page_elements/list_of_online_contents.html' with public_contents=last_tutorials col_number=1 %} - {% if last_tutorials and more_tutorials %} - Plus de tutoriels dans {{ subcategory.title }} - {% endif %} -
+
+

+ {% trans "Dernières publications" %} + RSS + Atom +

+ {% include 'tutorialv2/list_page_elements/list_of_online_contents.html' with public_contents=last_contents col_number=2 %} + {% if last_contents and more_contents %} + Plus de publications dans {{ subcategory.title }} + {% endif %} +
-
-

- {% trans "Derniers articles" %} - RSS - Atom -

- {% include 'tutorialv2/list_page_elements/list_of_online_contents.html' with public_contents=last_articles col_number=1 %} - {% if last_articles and more_articles %} - Plus d’articles dans {{ subcategory.title }} - {% endif %} -
-
{% endblock %} diff --git a/zds/settings/abstract_base/zds.py b/zds/settings/abstract_base/zds.py index 044cdfc469..aad1644924 100644 --- a/zds/settings/abstract_base/zds.py +++ b/zds/settings/abstract_base/zds.py @@ -179,9 +179,9 @@ "max_tree_depth": 3, "default_licence_pk": 7, "content_per_page": 42, - "max_last_publications_level_1": 6, - "max_last_publications_level_2": 12, - "max_last_publications_level_3": 12, + "max_last_publications_level_1": 12, + "max_last_publications_level_2": 24, + "max_last_publications_level_3": 24, "notes_per_page": 25, "helps_per_page": 20, "commits_per_page": 20, diff --git a/zds/tutorialv2/tests/factories.py b/zds/tutorialv2/tests/factories.py index 3a44d7a5f8..53c502c755 100644 --- a/zds/tutorialv2/tests/factories.py +++ b/zds/tutorialv2/tests/factories.py @@ -242,7 +242,7 @@ class PublishedContentFactory(PublishableContentFactory): """ @classmethod - def _generate(cls, create, attrs): + def _generate(cls, create, attrs) -> PublishableContent: # This parameter is only used inside _generate() and won't be saved in the database, # which is why we use attrs.pop() (it is removed from attrs). is_major_update = attrs.pop("is_major_update", True) diff --git a/zds/tutorialv2/tests/tests_lists.py b/zds/tutorialv2/tests/tests_lists.py index 5b6027d97d..8b7e044a73 100644 --- a/zds/tutorialv2/tests/tests_lists.py +++ b/zds/tutorialv2/tests/tests_lists.py @@ -65,14 +65,6 @@ def test_public_lists(self): article_unpublished = PublishableContentFactory(author_list=[self.user_author], type="ARTICLE") self.client.logout() - resp = self.client.get(reverse("publication:list") + "?type=tutorial") - self.assertContains(resp, tutorial.title) - self.assertNotContains(resp, tutorial_unpublished.title) - - resp = self.client.get(reverse("publication:list") + "?type=article") - self.assertContains(resp, article.title) - self.assertNotContains(resp, article_unpublished.title) - resp = self.client.get(reverse("tutorial:find-tutorial", args=[self.user_author.username]) + "?filter=public") self.assertContains(resp, tutorial.title) self.assertNotContains(resp, tutorial_unpublished.title) diff --git a/zds/tutorialv2/tests/tests_views/tests_published.py b/zds/tutorialv2/tests/tests_views/tests_published.py index 7e3fbe5d0e..6780458378 100644 --- a/zds/tutorialv2/tests/tests_views/tests_published.py +++ b/zds/tutorialv2/tests/tests_views/tests_published.py @@ -35,8 +35,8 @@ PublishedContentFactory, ) from zds.utils.header_notifications import get_header_notifications -from zds.utils.models import Alert, Hat, Tag -from zds.utils.tests.factories import CategoryFactory, LicenceFactory, SubCategoryFactory +from zds.utils.models import Alert, Hat +from zds.utils.tests.factories import LicenceFactory, SubCategoryFactory overridden_zds_app = deepcopy(settings.ZDS_APP) overridden_zds_app["content"]["repo_private_path"] = settings.BASE_DIR / "contents-private-test" @@ -1599,212 +1599,6 @@ def test_obsolete(self): self.assertEqual(result.status_code, 200) self.assertNotContains(result, _("Ce contenu est obsolète.")) - def test_list_publications(self): - """Test the behavior of the publication list""" - - category_1 = CategoryFactory() - category_2 = CategoryFactory() - subcategory_1 = SubCategoryFactory(category=category_1) - subcategory_2 = SubCategoryFactory(category=category_1) - subcategory_3 = SubCategoryFactory(category=category_2) - subcategory_4 = SubCategoryFactory(category=category_2) - tag_1 = Tag(title="random") - tag_1.save() - - tuto_p_1 = PublishedContentFactory(author_list=[self.user_author]) - tuto_p_2 = PublishedContentFactory(author_list=[self.user_author]) - tuto_p_3 = PublishedContentFactory(author_list=[self.user_author]) - - article_p_1 = PublishedContentFactory(author_list=[self.user_author], type="ARTICLE") - - tuto_p_1.subcategory.add(subcategory_1) - tuto_p_1.subcategory.add(subcategory_2) - tuto_p_1.save() - - tuto_p_2.subcategory.add(subcategory_1) - tuto_p_2.subcategory.add(subcategory_2) - tuto_p_2.save() - - tuto_p_3.subcategory.add(subcategory_3) - tuto_p_3.save() - - article_p_1.subcategory.add(subcategory_4) - article_p_1.tags.add(tag_1) - article_p_1.save() - - tuto_1 = PublishedContent.objects.get(content=tuto_p_1.pk) - tuto_2 = PublishedContent.objects.get(content=tuto_p_2.pk) - tuto_3 = PublishedContent.objects.get(content=tuto_p_3.pk) - article_1 = PublishedContent.objects.get(content=article_p_1.pk) - - self.assertEqual(PublishableContent.objects.filter(type="ARTICLE").count(), 1) - self.assertEqual(PublishableContent.objects.filter(type="TUTORIAL").count(), 4) - - # 1. Publication list - result = self.client.get(reverse("publication:list")) - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["last_articles"]), 1) - self.assertEqual(len(result.context["last_tutorials"]), 4) - - # 2. Category page - result = self.client.get(reverse("publication:category", kwargs={"slug": category_1.slug})) - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["last_articles"]), 0) - self.assertEqual(len(result.context["last_tutorials"]), 2) - - pks = [x.pk for x in result.context["last_tutorials"]] - self.assertIn(tuto_1.pk, pks) - self.assertIn(tuto_2.pk, pks) - - result = self.client.get(reverse("publication:category", kwargs={"slug": category_2.slug})) - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["last_articles"]), 1) - self.assertEqual(len(result.context["last_tutorials"]), 1) - - pks = [x.pk for x in result.context["last_tutorials"]] - self.assertIn(tuto_3.pk, pks) - - pks = [x.pk for x in result.context["last_articles"]] - self.assertIn(article_1.pk, pks) - - # 3. Subcategory page - result = self.client.get( - reverse("publication:subcategory", kwargs={"slug_category": category_1.slug, "slug": subcategory_1.slug}) - ) - - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["last_articles"]), 0) - self.assertEqual(len(result.context["last_tutorials"]), 2) - - pks = [x.pk for x in result.context["last_tutorials"]] - self.assertIn(tuto_1.pk, pks) - self.assertIn(tuto_2.pk, pks) - - result = self.client.get( - reverse("publication:subcategory", kwargs={"slug_category": category_1.slug, "slug": subcategory_2.slug}) - ) - - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["last_articles"]), 0) - self.assertEqual(len(result.context["last_tutorials"]), 2) - - pks = [x.pk for x in result.context["last_tutorials"]] - self.assertIn(tuto_1.pk, pks) - self.assertIn(tuto_2.pk, pks) - - result = self.client.get( - reverse("publication:subcategory", kwargs={"slug_category": category_2.slug, "slug": subcategory_3.slug}) - ) - - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["last_articles"]), 0) - self.assertEqual(len(result.context["last_tutorials"]), 1) - - pks = [x.pk for x in result.context["last_tutorials"]] - self.assertIn(tuto_3.pk, pks) - - result = self.client.get( - reverse("publication:subcategory", kwargs={"slug_category": category_2.slug, "slug": subcategory_4.slug}) - ) - - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["last_articles"]), 1) - self.assertEqual(len(result.context["last_tutorials"]), 0) - - pks = [x.pk for x in result.context["last_articles"]] - self.assertIn(article_1.pk, pks) - - # 4. Final page and filters - result = self.client.get(reverse("publication:list") + f"?category={category_1.slug}") - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["filtered_contents"]), 2) - pks = [x.pk for x in result.context["filtered_contents"]] - self.assertIn(tuto_1.pk, pks) - self.assertIn(tuto_2.pk, pks) - - # filter by category and type - result = self.client.get(reverse("publication:list") + f"?category={category_2.slug}") - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["filtered_contents"]), 2) - pks = [x.pk for x in result.context["filtered_contents"]] - self.assertIn(tuto_3.pk, pks) - self.assertIn(article_1.pk, pks) - - result = self.client.get(reverse("publication:list") + f"?category={category_2.slug}" + "&type=article") - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["filtered_contents"]), 1) - pks = [x.pk for x in result.context["filtered_contents"]] - self.assertIn(article_1.pk, pks) - - result = self.client.get(reverse("publication:list") + f"?category={category_2.slug}" + "&type=tutorial") - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["filtered_contents"]), 1) - pks = [x.pk for x in result.context["filtered_contents"]] - self.assertIn(tuto_3.pk, pks) - - # filter by subcategory - result = self.client.get(reverse("publication:list") + f"?subcategory={subcategory_1.slug}") - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["filtered_contents"]), 2) - pks = [x.pk for x in result.context["filtered_contents"]] - self.assertIn(tuto_1.pk, pks) - self.assertIn(tuto_2.pk, pks) - - # filter by subcategory and type - result = self.client.get(reverse("publication:list") + f"?subcategory={subcategory_3.slug}") - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["filtered_contents"]), 1) - pks = [x.pk for x in result.context["filtered_contents"]] - self.assertIn(tuto_3.pk, pks) - - result = self.client.get(reverse("publication:list") + f"?subcategory={subcategory_3.slug}" + "&type=article") - self.assertEqual(result.status_code, 200) - self.assertEqual(len(result.context["filtered_contents"]), 0) - - result = self.client.get(reverse("publication:list") + f"?subcategory={subcategory_3.slug}" + "&type=tutorial") - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["filtered_contents"]), 1) - pks = [x.pk for x in result.context["filtered_contents"]] - self.assertIn(tuto_3.pk, pks) - - # filter by tag - result = self.client.get(reverse("publication:list") + f"?tag={tag_1.slug}" + "&type=article") - self.assertEqual(result.status_code, 200) - - self.assertEqual(len(result.context["filtered_contents"]), 1) - pks = [x.pk for x in result.context["filtered_contents"]] - self.assertIn(article_1.pk, pks) - - # 5. Everything else results in 404 - wrong_urls = [ - # not existing (sub)categories, types or tags with slug "xxx" - reverse("publication:list") + "?category=xxx", - reverse("publication:list") + "?subcategory=xxx", - reverse("publication:list") + "?type=xxx", - reverse("publication:list") + "?tag=xxx", - reverse("publication:category", kwargs={"slug": "xxx"}), - reverse("publication:subcategory", kwargs={"slug_category": category_2.slug, "slug": "xxx"}), - # subcategory_1 does not belong to category_2: - reverse("publication:subcategory", kwargs={"slug_category": category_2.slug, "slug": subcategory_1.slug}), - ] - - for url in wrong_urls: - self.assertEqual(self.client.get(url).status_code, 404, msg=url) - def test_article_previous_link(self): """Test the behaviour of the article previous link.""" diff --git a/zds/tutorialv2/tests/tests_views/tests_viewpublications.py b/zds/tutorialv2/tests/tests_views/tests_viewpublications.py new file mode 100644 index 0000000000..27d3d4c051 --- /dev/null +++ b/zds/tutorialv2/tests/tests_views/tests_viewpublications.py @@ -0,0 +1,144 @@ +from copy import deepcopy + +from django.conf import settings +from django.test import TestCase +from django.test.utils import override_settings +from django.urls import reverse + +from zds.member.tests.factories import ProfileFactory +from zds.tutorialv2.models.database import PublishableContent +from zds.tutorialv2.tests import TutorialTestMixin +from zds.tutorialv2.tests.factories import PublishableContentFactory, PublishedContentFactory +from zds.utils.models import Tag +from zds.utils.tests.factories import CategoryFactory, SubCategoryFactory + +overridden_zds_app = deepcopy(settings.ZDS_APP) +overridden_zds_app["content"]["repo_private_path"] = settings.BASE_DIR / "contents-private-test" +overridden_zds_app["content"]["repo_public_path"] = settings.BASE_DIR / "contents-public-test" +overridden_zds_app["content"]["extra_content_generation_policy"] = "NOTHING" + + +@override_settings(MEDIA_ROOT=settings.BASE_DIR / "media-test") +@override_settings(ZDS_APP=overridden_zds_app) +@override_settings(SEARCH_ENABLED=False) +class ViewPublicationsTest(TutorialTestMixin, TestCase): + """Test the library pages.""" + + def setUp(self): + self.author = ProfileFactory().user + + self.category_1 = CategoryFactory() + self.category_2 = CategoryFactory() + self.subcategory_1 = SubCategoryFactory(category=self.category_1) + self.subcategory_2 = SubCategoryFactory(category=self.category_1) + self.subcategory_3 = SubCategoryFactory(category=self.category_2) + self.subcategory_4 = SubCategoryFactory(category=self.category_2) + self.tag_1 = Tag.objects.create(title="random") + + # Unpublished content + PublishableContentFactory(author_list=[self.author]) + + tuto_p_1 = PublishedContentFactory(author_list=[self.author]) + tuto_p_1.subcategory.add(self.subcategory_1) + tuto_p_1.subcategory.add(self.subcategory_2) + self.tuto_1 = tuto_p_1.public_version + + tuto_p_2 = PublishedContentFactory(author_list=[self.author]) + tuto_p_2.subcategory.add(self.subcategory_1) + tuto_p_2.subcategory.add(self.subcategory_2) + self.tuto_2 = tuto_p_2.public_version + + tuto_p_3 = PublishedContentFactory(author_list=[self.author]) + tuto_p_3.subcategory.add(self.subcategory_3) + self.tuto_3 = tuto_p_3.public_version + + article_p_1 = PublishedContentFactory(author_list=[self.author], type="ARTICLE") + article_p_1.subcategory.add(self.subcategory_4) + article_p_1.tags.add(self.tag_1) + self.article_1 = article_p_1.public_version + + self.assertEqual(PublishableContent.objects.filter(type="ARTICLE").count(), 1) + self.assertEqual(PublishableContent.objects.filter(type="TUTORIAL").count(), 4) + + def test_library_main_page(self): + result = self.client.get(reverse("publication:list")) + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual( + result.context["last_contents"], [self.article_1, self.tuto_3, self.tuto_2, self.tuto_1] + ) + + def test_category_page_1(self): + result = self.client.get(reverse("publication:category", kwargs={"slug": self.category_1.slug})) + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual(result.context["last_contents"], [self.tuto_2, self.tuto_1]) + + def test_category_page_2(self): + result = self.client.get(reverse("publication:category", kwargs={"slug": self.category_2.slug})) + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual(result.context["last_contents"], [self.article_1, self.tuto_3]) + + def test_subcategory_1(self): + kwargs = {"slug_category": self.category_1.slug, "slug": self.subcategory_1.slug} + result = self.client.get(reverse("publication:subcategory", kwargs=kwargs)) + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual(result.context["last_contents"], [self.tuto_2, self.tuto_1]) + + def test_subcategory_2(self): + kwargs = {"slug_category": self.category_1.slug, "slug": self.subcategory_2.slug} + result = self.client.get(reverse("publication:subcategory", kwargs=kwargs)) + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual(result.context["last_contents"], [self.tuto_2, self.tuto_1]) + + def test_subcategory_3(self): + kwargs = {"slug_category": self.category_2.slug, "slug": self.subcategory_3.slug} + result = self.client.get(reverse("publication:subcategory", kwargs=kwargs)) + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual(result.context["last_contents"], [self.tuto_3]) + + def test_subcategory_4(self): + kwargs = {"slug_category": self.category_2.slug, "slug": self.subcategory_4.slug} + result = self.client.get(reverse("publication:subcategory", kwargs=kwargs)) + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual(result.context["last_contents"], [self.article_1]) + + def test_content_list_page_1(self): + result = self.client.get(reverse("publication:list") + f"?category={self.category_1.slug}") + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual(result.context["filtered_contents"], [self.tuto_2, self.tuto_1]) + + def test_content_list_page_2(self): + result = self.client.get(reverse("publication:list") + f"?category={self.category_2.slug}") + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual(result.context["filtered_contents"], [self.article_1, self.tuto_3]) + + def test_content_list_page_3(self): + result = self.client.get(reverse("publication:list") + f"?subcategory={self.subcategory_1.slug}") + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual(result.context["filtered_contents"], [self.tuto_2, self.tuto_1]) + + def test_content_list_page_4(self): + result = self.client.get(reverse("publication:list") + f"?subcategory={self.subcategory_3.slug}") + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual(result.context["filtered_contents"], [self.tuto_3]) + + def test_content_list_page_(self): + result = self.client.get(reverse("publication:list") + f"?tag={self.tag_1.slug}") + self.assertEqual(result.status_code, 200) + self.assertQuerySetEqual(result.context["filtered_contents"], [self.article_1]) + + def test_wrong_urls(self): + # not existing (sub)categories and tags with slug not existing + wrong_urls = [ + reverse("publication:list") + "?category=xxx", + reverse("publication:list") + "?subcategory=xxx", + reverse("publication:list") + "?tag=xxx", + reverse("publication:category", kwargs={"slug": "xxx"}), + reverse("publication:subcategory", kwargs={"slug_category": self.category_2.slug, "slug": "xxx"}), + # subcategory_1 does not belong to category_2: + reverse( + "publication:subcategory", + kwargs={"slug_category": self.category_2.slug, "slug": self.subcategory_1.slug}, + ), + ] + for url in wrong_urls: + self.assertEqual(self.client.get(url).status_code, 404, msg=url) diff --git a/zds/tutorialv2/views/lists.py b/zds/tutorialv2/views/lists.py index a3d20a76ee..4c38df1b2b 100644 --- a/zds/tutorialv2/views/lists.py +++ b/zds/tutorialv2/views/lists.py @@ -110,20 +110,20 @@ class ViewPublications(TemplateView): 3: "tutorialv2/view/subcategory.html", 4: "tutorialv2/view/browse.html", } - handle_types = ["TUTORIAL", "ARTICLE"] + handled_types = ["TUTORIAL", "ARTICLE"] level = 1 max_last_contents = settings.ZDS_APP["content"]["max_last_publications_level_1"] template_name = templates[level] @staticmethod - def categories_with_contents_count(handle_types): + def categories_with_contents_count(handled_types): """Select categories with subcategories and contents count in two queries""" queryset_category = ( Category.objects.order_by("position") .filter(categorysubcategory__subcategory__publishablecontent__publishedcontent__must_redirect=False) - .filter(categorysubcategory__subcategory__publishablecontent__type__in=handle_types) + .filter(categorysubcategory__subcategory__publishablecontent__type__in=handled_types) .annotate( contents_count=Count( "categorysubcategory__subcategory__publishablecontent__publishedcontent", distinct=True @@ -152,7 +152,7 @@ def categories_with_contents_count(handle_types): return categories @staticmethod - def subcategories_with_contents_count(category, handle_types): + def subcategories_with_contents_count(category, handled_types): """Rewritten to give the number of contents at the same time as the subcategories (in one query)""" # TODO: check if we can use ORM to do that @@ -169,7 +169,7 @@ def subcategories_with_contents_count(category, handle_types): AND `tutorialv2_publishablecontent_subcategory`.`subcategory_id` = `utils_categorysubcategory`.`subcategory_id`) """.format( - ", ".join(f"'{t}'" for t in handle_types) + ", ".join(f"'{t}'" for t in handled_types) ) queryset = ( @@ -198,10 +198,10 @@ def get_context_data(self, **kwargs): self.level = 3 self.max_last_contents = settings.ZDS_APP["content"]["max_last_publications_level_3"] if ( - self.request.GET.get("category", False) - or self.request.GET.get("subcategory", False) - or self.request.GET.get("type", False) - or self.request.GET.get("tag", False) + "category" in self.request.GET + or "subcategory" in self.request.GET + or "type" in self.request.GET + or "tag" in self.request.GET ): self.level = 4 self.max_last_contents = 50 @@ -211,17 +211,17 @@ def get_context_data(self, **kwargs): if self.level == 1: # get categories and subcategories - categories = ViewPublications.categories_with_contents_count(self.handle_types) + categories = ViewPublications.categories_with_contents_count(self.handled_types) context["categories"] = categories context["content_count"] = PublishedContent.objects.last_contents( - content_type=self.handle_types, with_comments_count=False + content_type=self.handled_types, with_comments_count=False ).count() elif self.level == 2: context["category"] = get_object_or_404(Category, slug=self.kwargs.get("slug")) context["subcategories"] = ViewPublications.subcategories_with_contents_count( - context["category"], self.handle_types + context["category"], self.handled_types ) recent_kwargs["subcategories"] = context["subcategories"] @@ -240,28 +240,19 @@ def get_context_data(self, **kwargs): recent_kwargs["subcategories"] = [subcategory] elif self.level == 4: - category = self.request.GET.get("category", None) - subcategory = self.request.GET.get("subcategory", None) + category_slug = self.request.GET.get("category", None) + subcategory_slug = self.request.GET.get("subcategory", None) subcategories = None - if category is not None: - context["category"] = get_object_or_404(Category, slug=category) - subcategories = context["category"].get_subcategories() - elif subcategory is not None: - subcategory = get_object_or_404(SubCategory, slug=self.request.GET.get("subcategory")) + if category_slug is not None: + category = get_object_or_404(Category, slug=category_slug) + context["category"] = category + subcategories = category.get_subcategories() + elif subcategory_slug is not None: + subcategory = get_object_or_404(SubCategory, slug=subcategory_slug) context["category"] = subcategory.get_parent_category() context["subcategory"] = subcategory subcategories = [subcategory] - content_type = self.handle_types - context["type"] = None - if "type" in self.request.GET: - _type = self.request.GET.get("type", "").upper() - if _type in self.handle_types: - content_type = _type - context["type"] = TYPE_CHOICES_DICT[_type] - else: - raise Http404(f"wrong type {_type}") - tag = self.request.GET.get("tag", None) tags = None if tag is not None: @@ -269,7 +260,7 @@ def get_context_data(self, **kwargs): context["tag"] = tags[0] contents_queryset = PublishedContent.objects.last_contents( - subcategories=subcategories, tags=tags, content_type=content_type + subcategories=subcategories, tags=tags, content_type=self.handled_types ) items_per_page = settings.ZDS_APP["content"]["content_per_page"] make_pagination( @@ -282,13 +273,11 @@ def get_context_data(self, **kwargs): ) if self.level < 4: - last_articles = PublishedContent.objects.last_contents(**dict(content_type="ARTICLE", **recent_kwargs)) - context["last_articles"] = last_articles[: self.max_last_contents] - context["more_articles"] = last_articles.count() > self.max_last_contents - - last_tutorials = PublishedContent.objects.last_contents(**dict(content_type="TUTORIAL", **recent_kwargs)) - context["last_tutorials"] = last_tutorials[: self.max_last_contents] - context["more_tutorials"] = last_tutorials.count() > self.max_last_contents + last_contents = PublishedContent.objects.last_contents( + **dict(content_type=self.handled_types, **recent_kwargs) + ) + context["last_contents"] = last_contents[: self.max_last_contents] + context["more_contents"] = last_contents.count() > self.max_last_contents context["beta_forum"] = ( Forum.objects.prefetch_related("category").filter(pk=settings.ZDS_APP["forum"]["beta_forum_id"]).last()