Skip to content

Commit

Permalink
refactor(forum): gabarit séparé pour les forums de documentation (#680)
Browse files Browse the repository at this point in the history
## Description

🎸 Séparation des gabarits servis selon la type de forum, en partageant
le même parent

## Type de changement

🎢 Nouvelle fonctionnalité (changement non cassant qui ajoute une
fonctionnalité).
  • Loading branch information
calummackervoy authored Jul 3, 2024
1 parent 32f59ed commit fedd5ca
Show file tree
Hide file tree
Showing 10 changed files with 551 additions and 240 deletions.
3 changes: 3 additions & 0 deletions lacommunaute/forum/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class Meta:

class Params:
with_image = factory.Trait(image=factory.django.ImageField(filename="banner.jpg"))
for_snapshot = factory.Trait(
name="Test Forum", description="Test description", short_description="Test description"
)

@factory.post_generation
def with_public_perms(self, create, extracted, **kwargs):
Expand Down
121 changes: 119 additions & 2 deletions lacommunaute/forum/tests/__snapshots__/tests_views.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,124 @@
</nav>
'''
# ---
# name: TestForumView.test_not_rated_forum[not_rated_forum]
# name: TestDocumentationCategoryForumContent.test_documentation_category_foot_content[documentation_category_add_file_control]
'''
<section class="s-section" id="add-documentation-to-category-control">
<div class="s-section__container container">
<div class="s-section__row row">
<div class="s-section__col col-12">
<a aria-label="Ajouter une fiche pratique" class="btn btn-outline-primary" href="/documentation/category/9999/create/" role="button">Ajouter une fiche pratique</a>
</div>
</div>
</div>
</section>
'''
# ---
# name: TestDocumentationCategoryForumContent.test_documentation_category_subforum_list[documentation_category_subforum_list]
'''
<div class="row mt-4" id="documentation-category-subforums">

<div class="col-12 col-md-4 mb-3 mb-md-5">
<div class="card c-card has-one-link-inside h-100">

<div class="card-header card-header-thumbnail rounded">
<img alt="Test Forum" class="img-fitcover img-fluid" loading="lazy" src="[img src]"/>
</div>

<div class="card-body pb-0">
<p class="h3 lh-base">Test Forum</p>
<div class="mt-3">Test description</div>
</div>
<div class="card-footer text-end">
<a class="btn btn-sm btn-ico btn-link stretched-link matomo-event" data-matomo-action="view" data-matomo-category="engagement" data-matomo-option="fiches_techniques" href="/forum/test-forum-10000/">
<i class="ri-arrow-right-line ri-lg"></i>
</a>
</div>
</div>
</div>

</div>
'''
# ---
# name: TestDocumentationForumContent.test_documentation_forum_header_content[template_documentation_link_to_parent]
'<a class="matomo-event h3 text-decoration-none d-inline-block" data-matomo-action="view" data-matomo-category="engagement" data-matomo-option="forum" href="/forum/parent-forum-9999/">Les autres fiches du thème Parent-Forum</a>'
# ---
# name: TestDocumentationForumContent.test_documentation_forum_share_actions[template_documentation_social_share]
'''
<button aria-expanded="false" aria-haspopup="true" class="btn btn-sm btn-ico-only btn-secondary" data-bs-toggle="dropdown" id="dropdownMenuSocialShare10000" type="button">
<i aria-label="Partager ce sujet sur " class="ri-share-fill ri-lg"></i>
</button>
'''
# ---
# name: TestDocumentationForumContent.test_documentation_forum_share_actions[template_documentation_upvotes]
'''
<div class="d-inline-block" id="upvotesarea10000">


<a class="btn btn-sm btn-ico-only btn-link btn-secondary" data-bs-placement="top" data-bs-toggle="tooltip" href="/inclusion_connect/authorize?next=%2Fforum%2Ftest-forum-10000%2F%2310000" rel="nofollow" title="Connectez-vous pour sauvegarder">
<i aria-hidden="true" class="ri-bookmark-line me-1"></i><span>0</span>
</a>


</div>
'''
# ---
# name: TestForumDetailContent.test_forum_detail_foot_content[forum_detail_forum_actions_block]
'''
<div class="col-12 col-sm-auto forum-actions-block">

<a class="btn btn-primary btn-ico matomo-event" data-matomo-action="contribute" data-matomo-category="engagement" data-matomo-option="new_topic" href="/forum/test-forum-10000/topic/create/" rel="nofollow">
<i class="ri-chat-new-line ri-lg"></i>
<span>

Poser une question

</span>
</a>


</div>
'''
# ---
# name: TestForumDetailContent.test_forum_detail_header_content[forum_detail_heading]
'''
<section class="s-title-01 mt-lg-5">
<div class="s-title-01__container container">
<div class="s-title-01__row row">
<div class="s-title-01__col col-12">
<h1>Test Forum</h1>

<h2 class="mt-3">Test description</h2>
</div>
</div>
</div>
</section>
'''
# ---
# name: TestForumDetailContent.test_forum_detail_subforum_content_rendered[forum_detail_subforums]
'''
<ul class="list-group mb-3 mb-md-5">

<li class="list-group-item list-group-item-action d-flex flex-column flex-md-row justify-content-md-between">
<div class="flex-grow-1">
<a class="matomo-event h4 d-block mb-0" data-matomo-action="view" data-matomo-category="engagement" data-matomo-option="forum" href="/forum/test-child-10001/">Test-Child</a>
<small class="text-muted">


0 Sujet

-

0 Message

</small>
</div>
</li>

</ul>
'''
# ---
# name: TestForumViewContent.test_not_rated_forum[not_rated_forum]
'''
<div class="mb-5 rating" id="rating-area1">
<hr/>
Expand Down Expand Up @@ -172,7 +289,7 @@
</div>
'''
# ---
# name: TestForumView.test_rated_forum[rated_forum]
# name: TestForumViewContent.test_rated_forum[rated_forum]
'''
<div class="mb-5 rating" id="rating-area1">
<hr/>
Expand Down
159 changes: 156 additions & 3 deletions lacommunaute/forum/tests/tests_views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest # noqa
import re
from django.contrib.contenttypes.models import ContentType
from django.template.defaultfilters import truncatechars_html
from django.test import RequestFactory, TestCase
Expand All @@ -9,13 +10,14 @@

from lacommunaute.forum.enums import Kind as ForumKind
from lacommunaute.forum.factories import CategoryForumFactory, ForumFactory, ForumRatingFactory
from lacommunaute.forum.models import Forum
from lacommunaute.forum.views import ForumView
from lacommunaute.forum_conversation.enums import Filters
from lacommunaute.forum_conversation.factories import CertifiedPostFactory, PostFactory, TopicFactory
from lacommunaute.forum_conversation.forms import PostForm
from lacommunaute.forum_conversation.models import Topic
from lacommunaute.users.factories import UserFactory
from lacommunaute.utils.testing import parse_response_to_soup
from lacommunaute.utils.testing import parse_response_to_soup, reset_model_sequence_fixture


faker = Faker()
Expand Down Expand Up @@ -107,6 +109,15 @@ def test_template_name(self):
response = self.client.get(self.url, **{"HTTP_HX_REQUEST": "true"})
self.assertTemplateUsed(response, "forum_conversation/topic_list.html")

documentation_category_forum = CategoryForumFactory(with_public_perms=True, with_child=True)
documentation_forum = documentation_category_forum.children.first()

response = self.client.get(documentation_category_forum.get_absolute_url())
self.assertTemplateUsed(response, "forum/forum_documentation_category.html")

response = self.client.get(documentation_forum.get_absolute_url())
self.assertTemplateUsed(response, "forum/forum_documentation.html")

def test_show_comments(self):
topic_url = reverse(
"forum_conversation_extension:showmore_posts",
Expand Down Expand Up @@ -334,7 +345,7 @@ def test_siblings_in_context(self):
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

self.assertEqual(response.context_data["forums"].count(), 3)
self.assertEqual(response.context_data["sibling_forums"].count(), 3)
for f in forum.get_children():
self.assertContains(response, f.name)

Expand Down Expand Up @@ -513,7 +524,7 @@ def test_banner_display_on_subcategory_forum(self):
self.assertContains(response, forum.image.url.split("=")[0])


class TestForumView:
class TestForumViewContent:
def test_not_rated_forum(self, client, db, snapshot):
category_forum = CategoryForumFactory(with_public_perms=True, with_child=True, name="B Category")
forum = category_forum.get_children().first()
Expand All @@ -535,6 +546,148 @@ def test_rated_forum(self, client, db, snapshot):
assert str(content) == snapshot(name="rated_forum")


reset_forum_sequence = pytest.fixture(reset_model_sequence_fixture(Forum))


@pytest.fixture(name="forum_for_snapshot")
def forum_for_snapshot_fixture():
return ForumFactory(
parent=ForumFactory(with_public_perms=True, name="Parent-Forum"),
with_public_perms=True,
with_image=True,
for_snapshot=True,
)


@pytest.fixture(name="documentation_forum")
def documentation_forum_fixture():
return ForumFactory(
parent=CategoryForumFactory(with_public_perms=True, name="Parent-Forum"),
with_public_perms=True,
with_image=True,
for_snapshot=True,
)


class TestForumDetailContent:
def test_template_forum_detail_share_actions(self, client, db, snapshot):
forum = ForumFactory(with_public_perms=True)
response = client.get(forum.get_absolute_url())
content = parse_response_to_soup(response, replace_in_href=[forum])

assert len(content.select(f"#upvotesarea{str(forum.pk)}")) == 0
assert len(content.select(f"#dropdownMenuSocialShare{str(forum.pk)}")) == 0

def test_forum_detail_header_content(self, client, db, snapshot, reset_forum_sequence, forum_for_snapshot):
response = client.get(forum_for_snapshot.get_absolute_url())
content = parse_response_to_soup(response)

assert str(content.select("section.s-title-01")[0]) == snapshot(name="forum_detail_heading")
assert (
len(
content.select(
"div.textarea_cms_md", string=(lambda x: x.startswith(str(forum_for_snapshot.description)[:10]))
)
)
== 1
)

# NOTE: tests no subforum content rendered
assert len(content.select("ul.list-group")) == 0

def test_forum_detail_subforum_content_rendered(
self, client, db, snapshot, reset_forum_sequence, forum_for_snapshot
):
# subforum
ForumFactory(parent=forum_for_snapshot, with_public_perms=True, name="Test-Child", for_snapshot=True)

response = client.get(forum_for_snapshot.get_absolute_url())
content = parse_response_to_soup(response)

subforum_content = content.select("ul.list-group")
assert len(subforum_content) == 1
assert str(subforum_content[0]) == snapshot(name="forum_detail_subforums")

def test_forum_detail_foot_content(self, client, db, snapshot, reset_forum_sequence, forum_for_snapshot):
response = client.get(forum_for_snapshot.get_absolute_url())
content = parse_response_to_soup(response)

assert forum_for_snapshot.is_forum
forum_actions_block = content.select("div.forum-actions-block")
assert len(forum_actions_block) == 1
assert str(forum_actions_block[0]) == snapshot(name="forum_detail_forum_actions_block")


class TestDocumentationForumContent:
def test_documentation_forum_share_actions(self, client, db, snapshot, reset_forum_sequence, documentation_forum):
response = client.get(documentation_forum.get_absolute_url())
content = parse_response_to_soup(response)

upvotes_area = content.select(f"#upvotesarea{str(documentation_forum.pk)}")[0]
assert str(upvotes_area) == snapshot(name="template_documentation_upvotes")
social_share_area = content.select(f"#dropdownMenuSocialShare{str(documentation_forum.pk)}")[0]
assert str(social_share_area) == snapshot(name="template_documentation_social_share")

def test_documentation_forum_header_content(self, client, db, snapshot, reset_forum_sequence, documentation_forum):
sibling_forum = ForumFactory(parent=documentation_forum.parent, with_public_perms=True, name="Test-2")

response = client.get(documentation_forum.get_absolute_url())
content = parse_response_to_soup(response)

assert len(content.find_all("img", src=re.compile(documentation_forum.image.name))) == 1
assert (
len(
content.select(
"div.textarea_cms_md", string=(lambda x: x.startswith(str(documentation_forum.description)[:10]))
)
)
== 1
)

user_add_topic = content.find_all(
"a",
href=str(
reverse("forum_conversation:topic_create", args=(documentation_forum.slug, documentation_forum.pk))
),
)
assert len(user_add_topic) == 2

link_to_parent = content.find_all("a", href=documentation_forum.parent.get_absolute_url())
assert len(link_to_parent) == 1
assert (str(link_to_parent[0])) == snapshot(name="template_documentation_link_to_parent")

assert len(content.find_all("a", href=sibling_forum.get_absolute_url())) == 1


class TestDocumentationCategoryForumContent:
def test_documentation_category_subforum_list(
self, client, db, snapshot, reset_forum_sequence, documentation_forum
):
response = client.get(documentation_forum.parent.get_absolute_url())
content = parse_response_to_soup(response, replace_img_src=True)

subforum_content = content.select("#documentation-category-subforums")
assert len(subforum_content) == 1
assert str(subforum_content[0]) == snapshot(name="documentation_category_subforum_list")

def test_documentation_category_foot_content(
self, client, db, snapshot, reset_forum_sequence, documentation_forum
):
response = client.get(documentation_forum.parent.get_absolute_url())
content = parse_response_to_soup(response)

# require superuser permission
assert len(content.select("#add-documentation-to-category-control")) == 0

client.force_login(UserFactory(is_superuser=True))
response = client.get(documentation_forum.parent.get_absolute_url())
content = parse_response_to_soup(response)

add_documentation_control = content.select("#add-documentation-to-category-control")
assert len(add_documentation_control) == 1
assert str(add_documentation_control[0]) == snapshot(name="documentation_category_add_file_control")


@pytest.fixture(name="discussion_area_forum")
def discussion_area_forum_fixture():
return ForumFactory(with_public_perms=True, name="A Forum")
Expand Down
14 changes: 12 additions & 2 deletions lacommunaute/forum/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,18 @@ class ForumView(BaseForumView, FilteredTopicsListViewMixin):
def get_template_names(self):
if self.request.META.get("HTTP_HX_REQUEST"):
return ["forum_conversation/topic_list.html"]
if self.will_render_documentation_variant():
return ["forum/forum_documentation.html"]
if self.will_render_documentation_category_variant():
return ["forum/forum_documentation_category.html"]
return ["forum/forum_detail.html"]

def will_render_documentation_variant(self):
return self.get_forum().parent and self.forum.is_in_documentation_area

def will_render_documentation_category_variant(self):
return self.get_forum().is_in_documentation_area and self.forum.level == 0

def get_queryset(self):
return self.filter_queryset(self.get_forum().topics.optimized_for_topics_list(self.request.user.id))

Expand Down Expand Up @@ -65,8 +75,8 @@ def get_context_data(self, **kwargs):
)
context = context | self.get_topic_filter_context()

if forum.parent and forum.is_in_documentation_area:
context["forums"] = forum.get_siblings(include_self=True)
if self.will_render_documentation_variant():
context["sibling_forums"] = forum.get_siblings(include_self=True)
return context


Expand Down
Loading

0 comments on commit fedd5ca

Please sign in to comment.