diff --git a/templates/tutorialv2/stats/index.html b/templates/tutorialv2/stats/index.html
index 3f3e8e049b..eca63b1a25 100644
--- a/templates/tutorialv2/stats/index.html
+++ b/templates/tutorialv2/stats/index.html
@@ -55,7 +55,7 @@
{% endif %}
{% if cumulative_stats %}
- {% if display == 'global' %}
+ {% if display == 'global' and cumulative_stats|length > 1 %}
{% if form.non_field_errors %}
{{ form.non_field_errors.as_text }}
@@ -70,21 +70,21 @@
{% trans "Vues" %} |
{% trans "Temps moyen sur la page" %} |
{% trans "Visiteurs uniques" %} |
- {% if display == 'global' %} | {% endif %}
+ {% if display == 'global' and cumulative_stats|length > 1 %} | {% endif %}
{% for url, view in cumulative_stats.items %}
{{ url.name }}
- {% if display != 'details' %}
+ {% if display != 'details' and cumulative_stats|length > 1 %}
- {% trans "(détails)" %}
{% endif %}
|
{{ view.nb_hits }} |
{{ view.avg_time_on_page|seconds_to_duration }} |
{{ view.nb_uniq_visitors }} |
- {% if display == 'global' %}
+ {% if display == 'global' and cumulative_stats|length > 1 %}
|
{% endif %}
@@ -92,8 +92,10 @@
{% if display == 'global' %}
- {% trans "Comparer" %}
-
+ {% if cumulative_stats|length > 1 %}
+
+
+ {% endif %}
{% elif not content.has_extracts %}
{% trans "Revenir à la vue globale" %}
{% endif %}
diff --git a/zds/tutorialv2/tests/tests_views/tests_stats.py b/zds/tutorialv2/tests/tests_views/tests_stats.py
index 82513cb984..d05c1b38ed 100644
--- a/zds/tutorialv2/tests/tests_views/tests_stats.py
+++ b/zds/tutorialv2/tests/tests_views/tests_stats.py
@@ -7,11 +7,13 @@
from django.test import TestCase
from django.test.utils import override_settings
from django.urls import reverse
+from django.utils.translation import gettext_lazy as _
from zds.gallery.tests.factories import UserGalleryFactory
from zds.member.tests.factories import ProfileFactory, StaffProfileFactory
from zds.tutorialv2.tests.factories import PublishableContentFactory, ContainerFactory, ExtractFactory
from zds.tutorialv2.models.database import Validation, PublishedContent
+from zds.tutorialv2.publication_utils import publish_content
from zds.tutorialv2.tests import TutorialTestMixin
from zds.utils.tests.factories import LicenceFactory
@@ -32,7 +34,7 @@ def daterange(start_date, end_date):
class StatTests(TestCase, TutorialTestMixin):
def setUp(self):
self.nb_part = 1
- self.nb_chapter = 1
+ self.nb_chapter = 3
self.nb_section = 1
self.user_author = ProfileFactory().user
self.user_staff = StaffProfileFactory().user
@@ -51,7 +53,9 @@ def count_urls(self):
cpt += len(child.children)
return cpt
- def _mock_response(self, start_date=None, end_date=None, duration=7, status=200, raise_for_status=None):
+ def _mock_response(
+ self, start_date=None, end_date=None, duration=7, status=200, raise_for_status=None, count_urls=None
+ ):
methods = ["Referrers.getReferrerType", "Referrers.getWebsites", "Referrers.getKeywords", "Actions.getPageUrl"]
if end_date is None:
@@ -68,7 +72,8 @@ def _mock_response(self, start_date=None, end_date=None, duration=7, status=200,
mock_resp.status_code = status
# add json data if provided
response_data = []
- count_urls = self.count_urls()
+ if count_urls is None:
+ count_urls = self.count_urls()
for method in methods:
for counter in range(count_urls):
json_data = {}
@@ -142,18 +147,63 @@ def test_access_for_guest(self, mock_post):
@mock.patch("requests.post")
def test_access_for_author(self, mock_post):
# author can access to stats
+ text_button_back_to_global_view = _("Revenir à la vue globale")
+ text_button_compare = _("Comparer")
+ text_link_details = _("(détails)")
+
url = reverse(
"content:stats-content",
kwargs={"pk": self.published.content_pk, "slug": self.published.content_public_slug},
)
self.client.force_login(self.user_author)
+
+ # Statistics of the global content:
mock_post.return_value = self._mock_response()
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.context_data["display"], "global")
self.assertEqual(resp.context_data["urls"][0].name, self.published.title())
self.assertEqual(resp.context_data["urls"][0].url, self.published.content.get_absolute_url_online())
- self.assertEqual(len(resp.context_data["urls"]), 3)
+ self.assertEqual(len(resp.context_data["urls"]), 5)
+ self.assertNotContains(resp, text_button_back_to_global_view)
+ self.assertContains(resp, text_button_compare)
+ self.assertContains(resp, text_link_details)
+ global_urls = resp.context_data["urls"]
+
+ # Statistics of a chapter:
+ mock_post.return_value = self._mock_response(count_urls=1)
+ resp = self.client.get(url + "?urls=" + global_urls[-1].url)
+ self.assertEqual(resp.status_code, 200)
+ self.assertEqual(resp.context_data["display"], "details")
+ self.assertEqual(len(resp.context_data["urls"]), 1)
+ self.assertContains(resp, text_button_back_to_global_view)
+ self.assertNotContains(resp, text_button_compare)
+ self.assertNotContains(resp, text_link_details)
+
+ # Comparison of two chapters:
+ mock_post.return_value = self._mock_response(count_urls=2)
+ resp = self.client.post(url, {"urls": [global_urls[-2].url, global_urls[-1].url]})
+ self.assertEqual(resp.status_code, 200)
+ self.assertEqual(resp.context_data["display"], "comparison")
+ self.assertEqual(len(resp.context_data["urls"]), 2)
+ self.assertContains(resp, text_button_back_to_global_view)
+ self.assertNotContains(resp, text_button_compare)
+ self.assertContains(resp, text_link_details)
+
+ # An opinion without extract:
+ opinion = self.get_small_opinion()
+ url = reverse(
+ "content:stats-content",
+ kwargs={"pk": opinion.content_pk, "slug": opinion.content_public_slug},
+ )
+ mock_post.return_value = self._mock_response(count_urls=1)
+ resp = self.client.get(url)
+ self.assertEqual(resp.status_code, 200)
+ self.assertEqual(resp.context_data["display"], "global")
+ self.assertEqual(len(resp.context_data["urls"]), 1)
+ self.assertNotContains(resp, text_button_back_to_global_view)
+ self.assertNotContains(resp, text_button_compare)
+ self.assertNotContains(resp, text_link_details)
def test_access_for_author_matomo_error(self):
# author can access to stats, and if request to Matomo triggers an error,
@@ -313,3 +363,15 @@ def get_published_content(self, author, user_staff, nb_part=1, nb_chapter=1, nb_
published = PublishedContent.objects.filter(content=bigtuto).first()
self.assertIsNotNone(published)
return published
+
+ def get_small_opinion(self):
+ """
+ Returns a published opinion without extract.
+ """
+ opinion = PublishableContentFactory(type="OPINION")
+ opinion.authors.add(self.user_author)
+ UserGalleryFactory(gallery=opinion.gallery, user=self.user_author, mode="W")
+ opinion.licence = LicenceFactory()
+ opinion.save()
+ opinion_draft = opinion.load_version()
+ return publish_content(opinion, opinion_draft)
diff --git a/zds/tutorialv2/views/statistics.py b/zds/tutorialv2/views/statistics.py
index f63fc0caca..707921eaf1 100644
--- a/zds/tutorialv2/views/statistics.py
+++ b/zds/tutorialv2/views/statistics.py
@@ -147,10 +147,10 @@ def get_start_and_end_dates(self):
def get_display_mode(self, urls):
# TODO make display_mode an enum ?
# Good idea, but not straightforward for the template integration
- if len(urls) == 1:
- return "details"
if len(urls) == len(self.get_content_urls()):
return "global"
+ if len(urls) == 1:
+ return "details"
return "comparison"
@staticmethod