Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UPVOTE] sauvegarder un forum #362

Merged
merged 7 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lacommunaute/forum/models.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import uuid

from django.contrib.auth.models import Group
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from django.urls import reverse
from django.utils.functional import cached_property
from machina.apps.forum.abstract_models import AbstractForum

from lacommunaute.forum.enums import Kind as Forum_Kind
from lacommunaute.forum_conversation.models import Topic
from lacommunaute.forum_upvote.models import UpVote


class ForumQuerySet(models.QuerySet):
Expand All @@ -27,6 +29,8 @@ class Forum(AbstractForum):
max_length=400, blank=True, null=True, verbose_name="Description courte (SEO)"
)

upvotes = GenericRelation(UpVote, related_query_name="forum")

objects = ForumQuerySet().as_manager()

def get_absolute_url(self):
Expand All @@ -44,3 +48,6 @@ def get_unanswered_topics(self):
@cached_property
def count_unanswered_topics(self):
return self.get_unanswered_topics().count()

def upvotes_count(self):
return self.upvotes.count()
vincentporte marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions lacommunaute/forum/tests/test_CategoryForumListView.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest # noqa
from django.urls import reverse
from pytest_django.asserts import assertContains

from lacommunaute.forum.enums import Kind as ForumKind
from lacommunaute.forum.factories import ForumFactory
Expand All @@ -9,9 +10,8 @@
def test_context(client, db):
url = reverse("forum_extension:documentation")
response = client.get(url)
assert response.status_code == 200
assert "forum/category_forum_list.html" == response.templates[0].name
assert reverse("pages:statistiques") in str(response.content)
assertContains(response, reverse("pages:statistiques"), status_code=200)


def test_queryset(client, db):
Expand Down
7 changes: 7 additions & 0 deletions lacommunaute/forum/tests/tests_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from lacommunaute.forum.factories import ForumFactory
from lacommunaute.forum.models import Forum
from lacommunaute.forum_conversation.factories import TopicFactory
from lacommunaute.users.factories import UserFactory


class ForumManagerTest(TestCase):
Expand Down Expand Up @@ -50,3 +51,9 @@ def test_get_absolute_url(self):
forum.get_absolute_url(),
f"/forum/{forum.slug}-{forum.pk}/",
)

def test_upvotes_count(self):
forum = ForumFactory()
self.assertEqual(forum.upvotes_count(), 0)
forum.upvotes.create(voter=UserFactory())
self.assertEqual(forum.upvotes_count(), 1)
122 changes: 95 additions & 27 deletions lacommunaute/forum/tests/tests_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,12 @@ def test_show_comments(self):
self.client.force_login(self.user)
response = self.client.get(self.url)

self.assertEqual(response.status_code, 200)
self.assertNotContains(response, f'<a href="{topic_url}"')
self.assertNotContains(response, f'<a href="{topic_url}"', status_code=200)

PostFactory.create_batch(2, topic=self.topic, poster=self.user)
response = self.client.get(self.url)

self.assertEqual(response.status_code, 200)
self.assertContains(response, f'hx-get="{topic_url}"')
self.assertContains(response, f'hx-get="{topic_url}"', status_code=200)
self.assertContains(response, "Voir les 2 réponses")

def test_show_more_content(self):
Expand All @@ -120,8 +118,7 @@ def test_show_more_content(self):
self.client.force_login(self.user)
response = self.client.get(self.url)

self.assertEqual(response.status_code, 200)
self.assertContains(response, f'hx-get="{topic_url}"')
self.assertContains(response, f'hx-get="{topic_url}"', status_code=200)
self.assertContains(response, "+ voir la suite")
self.assertEqual(response.context_data["loadmoretopic_suffix"], "topicsinforum")

Expand Down Expand Up @@ -206,16 +203,14 @@ def test_poll_form(self):
self.client.force_login(self.user)

response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, poll_option.poll.question)
self.assertContains(response, poll_option.poll.question, status_code=200)
self.assertContains(response, poll_option.text)

def test_can_submit_form(self):
self.client.force_login(self.user)
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertIsInstance(response.context_data["form"], PostForm)
self.assertContains(response, f'id="collapsePost{self.topic.pk}')
self.assertContains(response, f'id="collapsePost{self.topic.pk}', status_code=200)

def test_cannot_submit_post(self, *args):
user = UserFactory()
Expand All @@ -234,7 +229,7 @@ def test_cannot_submit_post(self, *args):
def test_queries(self):
TopicFactory.create_batch(20, with_post=True)
self.client.force_login(self.user)
with self.assertNumQueries(21):
with self.assertNumQueries(22):
self.client.get(self.url)

def test_certified_post_display(self):
Expand Down Expand Up @@ -264,8 +259,7 @@ def test_certified_post_display(self):

response = self.client.get(self.url)

self.assertEqual(response.status_code, 200)
self.assertContains(response, truncatechars_html(post.content.rendered, 200))
self.assertContains(response, truncatechars_html(post.content.rendered, 200), status_code=200)
self.assertContains(response, topic_certified_post_url)
self.assertContains(response, "Certifié par la Plateforme de l'Inclusion")

Expand All @@ -285,26 +279,22 @@ def test_loadmoretopic_url(self):

TopicFactory(with_post=True, forum=self.forum)
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, loadmoretopic_url + "?page=2")
self.assertContains(response, loadmoretopic_url + "?page=2", status_code=200)

TopicFactory.create_batch(10, with_post=True, forum=self.forum)
response = self.client.get(self.url + "?page=2")
self.assertEqual(response.status_code, 200)
self.assertContains(response, loadmoretopic_url + "?page=3")
self.assertContains(response, loadmoretopic_url + "?page=3", status_code=200)

def test_topic_has_tags(self):
tag = f"tag_{faker.word()}"
self.client.force_login(self.user)

response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertNotContains(response, tag)
self.assertNotContains(response, tag, status_code=200)

self.topic.tags.add(tag)
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, tag)
self.assertContains(response, tag, status_code=200)

def test_description_is_markdown_rendered(self):
self.forum.description = "# title"
Expand All @@ -313,18 +303,16 @@ def test_description_is_markdown_rendered(self):

response = self.client.get(self.url)

self.assertEqual(response.status_code, 200)
self.assertContains(response, "<h1>title</h1>")
self.assertContains(response, "<h1>title</h1>", status_code=200)

def test_descendants_are_in_cards_if_forum_is_category_type(self):
forum = CategoryForumFactory(with_public_perms=True, with_child=True)
child_forum = forum.get_children().first()
url = reverse("forum_extension:forum", kwargs={"pk": forum.pk, "slug": forum.slug})

response = self.client.get(url)
self.assertEqual(response.status_code, 200)

self.assertContains(response, '<div class="card-body')
self.assertContains(response, '<div class="card-body', status_code=200)
self.assertContains(response, child_forum.name)
self.assertContains(
response, reverse("forum_extension:forum", kwargs={"pk": child_forum.pk, "slug": child_forum.slug})
Expand Down Expand Up @@ -352,7 +340,87 @@ def test_share_buttons(self):
url = reverse("forum_extension:forum", kwargs={"pk": child_forum.pk, "slug": child_forum.slug})

response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(
response, 'div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuSocialShare">'
response,
'div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuSocialShare">',
status_code=200,
)

def test_upvote_actions(self):
forum = CategoryForumFactory(with_public_perms=True, with_child=True)
child_forum = forum.get_children().first()

# anonymous
anonymous_html = (
'<a href="/inclusion_connect/authorize?next_url=%2Fforum%2F'
f'{child_forum.slug}-{child_forum.pk}%2F%23{child_forum.pk}"'
' class="btn btn-sm btn-ico-only btn-link btn-secondary" data-toggle="tooltip" data-placement="top"'
' title="Connectez-vous pour sauvegarder">'
'\n <i class="ri-bookmark-line" aria-hidden="true"></i><span class="ml-1">0</span>'
)
response = self.client.get(
reverse("forum_extension:forum", kwargs={"pk": child_forum.pk, "slug": child_forum.slug})
)
self.assertContains(response, anonymous_html, status_code=200)

# authenticated
self.client.force_login(self.user)
no_upvote_html = (
'<button type="submit"'
'\n title="Sauvegarder"'
'\n class="btn btn-sm btn-ico-only btn-secondary matomo-event"'
'\n data-matomo-category="engagement"'
'\n data-matomo-action="upvote"'
'\n data-matomo-option="post"'
"\n >"
'\n <i class="ri-bookmark-line" aria-hidden="true"></i>'
'<span class="ml-1">0</span>'
)
response = self.client.get(reverse("forum_extension:forum", kwargs={"pk": child_forum.pk, "slug": forum.slug}))
self.assertContains(response, no_upvote_html, status_code=200)

child_forum.upvotes.create(voter=self.user)
upvoted_html = (
'<button type="submit"'
'\n title="Sauvegarder"'
'\n class="btn btn-sm btn-ico-only btn-secondary matomo-event"'
'\n data-matomo-category="engagement"'
'\n data-matomo-action="upvote"'
'\n data-matomo-option="post"'
"\n >"
'\n <i class="ri-bookmark-fill" aria-hidden="true"></i>'
'<span class="ml-1">1</span>'
)
response = self.client.get(
reverse("forum_extension:forum", kwargs={"pk": child_forum.pk, "slug": child_forum.slug})
)
self.assertContains(response, upvoted_html, status_code=200)

def test_upvotes_count(self):
forum = CategoryForumFactory(with_public_perms=True, with_child=True)
child_forum = forum.get_children().first()

response = self.client.get(
reverse("forum_extension:forum", kwargs={"pk": child_forum.pk, "slug": child_forum.slug})
)
self.assertContains(
response, '<i class="ri-bookmark-line" aria-hidden="true"></i><span class="ml-1">0</span>', status_code=200
)

child_forum.upvotes.create(voter=self.user)

response = self.client.get(
reverse("forum_extension:forum", kwargs={"pk": child_forum.pk, "slug": child_forum.slug})
)
self.assertContains(
response, '<i class="ri-bookmark-line" aria-hidden="true"></i><span class="ml-1">1</span>', status_code=200
)

child_forum.upvotes.create(voter=UserFactory())

response = self.client.get(
reverse("forum_extension:forum", kwargs={"pk": child_forum.pk, "slug": child_forum.slug})
)
self.assertContains(
response, '<i class="ri-bookmark-line" aria-hidden="true"></i><span class="ml-1">2</span>', status_code=200
)
11 changes: 11 additions & 0 deletions lacommunaute/forum/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models import Count, Exists, OuterRef
from django.db.models.query import QuerySet
from django.urls import reverse
Expand All @@ -12,6 +13,7 @@
from lacommunaute.forum.models import Forum
from lacommunaute.forum_conversation.forms import PostForm
from lacommunaute.forum_conversation.models import Topic
from lacommunaute.forum_upvote.models import UpVote
from lacommunaute.users.models import User


Expand All @@ -31,7 +33,16 @@ def get_queryset(self):

def get_context_data(self, **kwargs):
forum = self.get_forum()

if self.request.user.is_authenticated:
forum.has_upvoted = UpVote.objects.filter(
object_id=forum.id,
voter=self.request.user,
content_type_id=ContentType.objects.get_for_model(forum).id,
).exists()

context = super().get_context_data(**kwargs)
context["forum"] = forum
context["FORUM_NUMBER_POSTS_PER_TOPIC"] = settings.FORUM_NUMBER_POSTS_PER_TOPIC
context["next_url"] = reverse("forum_extension:forum", kwargs={"pk": forum.pk, "slug": self.forum.slug})
context["loadmoretopic_url"] = reverse(
Expand Down
Loading