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

[DOCUMENTATION] creer les catégories et les fiches pratiques sans passer par l'admin #593

31 changes: 2 additions & 29 deletions lacommunaute/forum/factories.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import factory
from machina.core.db.models import get_model
from machina.test.factories.forum import ForumFactory as BaseForumFactory

from lacommunaute.forum.models import Forum
from lacommunaute.forum_upvote.models import UpVote
from lacommunaute.users.factories import GroupFactory


ForumPermission = get_model("forum_permission", "ForumPermission")
UserForumPermission = get_model("forum_permission", "UserForumPermission")
from lacommunaute.utils.perms import add_public_perms_on_forum


class ForumFactory(BaseForumFactory):
Expand All @@ -26,30 +22,7 @@ def with_public_perms(self, create, extracted, **kwargs):
if not create or not extracted:
return

perms = [
"can_see_forum",
"can_read_forum",
"can_start_new_topics",
"can_reply_to_topics",
"can_edit_own_posts",
"can_delete_own_posts",
"can_post_without_approval",
]

anonymous_authorized_perms = [
UserForumPermission(
anonymous_user=True, authenticated_user=False, permission=permission, has_perm=True, forum=self
)
for permission in ForumPermission.objects.filter(codename__in=perms)
]

authentified_authorized_perms = [
UserForumPermission(
anonymous_user=False, authenticated_user=True, permission=permission, has_perm=True, forum=self
)
for permission in ForumPermission.objects.filter(codename__in=perms)
]
UserForumPermission.objects.bulk_create(anonymous_authorized_perms + authentified_authorized_perms)
add_public_perms_on_forum(self)

@factory.post_generation
def upvoted_by(self, create, extracted, **kwargs):
Expand Down
9 changes: 9 additions & 0 deletions lacommunaute/forum/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django import forms

from lacommunaute.forum.models import Forum


class ForumForm(forms.ModelForm):
class Meta:
model = Forum
fields = ["name", "short_description", "description"]
61 changes: 61 additions & 0 deletions lacommunaute/forum/tests/test_categoryforum_createview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import pytest # noqa
from django.urls import reverse

from machina.core.db.models import get_model
from pytest_django.asserts import assertContains
from lacommunaute.forum.enums import Kind as ForumKind
from lacommunaute.forum.models import Forum
from lacommunaute.users.factories import UserFactory


UserForumPermission = get_model("forum_permission", "UserForumPermission")


def test_user_access(client, db):
url = reverse("forum_extension:create_category")
response = client.get(url)
assert response.status_code == 302

user = UserFactory()
client.force_login(user)
response = client.get(url)
assert response.status_code == 403

user.is_staff = True
user.save()
response = client.get(url)
assert response.status_code == 403

user.is_superuser = True
user.save()
response = client.get(url)
assert response.status_code == 200


def test_form_title(client, db):
client.force_login(UserFactory(is_superuser=True))
url = reverse("forum_extension:create_category")
response = client.get(url)
assertContains(response, "Créer une nouvelle catégorie documentaire")


def test_success_url(client, db):
client.force_login(UserFactory(is_superuser=True))
url = reverse("forum_extension:create_category")
response = client.post(url, data={"name": "Test", "description": "Test", "short_description": "Test"})
assert response.status_code == 302
assert response.url == reverse("forum_extension:documentation")


def test_create_category_with_perms(client, db):
client.force_login(UserFactory(is_superuser=True))
url = reverse("forum_extension:create_category")
response = client.post(url, data={"name": "Test", "description": "Test", "short_description": "Test"})
assert response.status_code == 302

forum = Forum.objects.get()
assert forum.type == Forum.FORUM_CAT
assert forum.kind == ForumKind.PUBLIC_FORUM
assert forum.parent is None

assert UserForumPermission.objects.filter(forum=forum).count() == 14
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import pytest # noqa
from django.urls import reverse
from pytest_django.asserts import assertContains
from pytest_django.asserts import assertContains, assertNotContains

from lacommunaute.forum.enums import Kind as ForumKind
from lacommunaute.forum.factories import ForumFactory
from lacommunaute.forum.models import Forum
from lacommunaute.users.factories import UserFactory


def test_context(client, db):
Expand All @@ -28,3 +29,19 @@ def test_queryset(client, db):
assert forum in response.context_data["forums"]
for unvisible_forum in unvisible_forums:
assert unvisible_forum not in response.context_data["forums"]


def test_display_create_category_button(client, db):
url = reverse("forum_extension:documentation")
response = client.get(url)
assertNotContains(response, reverse("forum_extension:create_category"), status_code=200)

user = UserFactory()
client.force_login(user)
response = client.get(url)
assertNotContains(response, reverse("forum_extension:create_category"), status_code=200)

user.is_superuser = True
user.save()
response = client.get(url)
assertContains(response, reverse("forum_extension:create_category"), status_code=200)
68 changes: 68 additions & 0 deletions lacommunaute/forum/tests/test_subcategoryforum_createview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import pytest # noqa
from django.urls import reverse
from machina.core.db.models import get_model
from pytest_django.asserts import assertContains

from lacommunaute.forum.enums import Kind as ForumKind
from lacommunaute.forum.models import Forum
from lacommunaute.users.factories import UserFactory
from lacommunaute.forum.factories import CategoryForumFactory


UserForumPermission = get_model("forum_permission", "UserForumPermission")


def test_user_access(client, db):
category_forum = CategoryForumFactory()
url = reverse("forum_extension:create_subcategory", kwargs={"pk": category_forum.pk})
response = client.get(url)
assert response.status_code == 302

user = UserFactory()
client.force_login(user)
response = client.get(url)
assert response.status_code == 403

user.is_staff = True
user.save()
response = client.get(url)
assert response.status_code == 403

user.is_superuser = True
user.save()
response = client.get(url)
assert response.status_code == 200


def test_form_title(client, db):
client.force_login(UserFactory(is_superuser=True))
category_forum = CategoryForumFactory()
url = reverse("forum_extension:create_subcategory", kwargs={"pk": category_forum.pk})
response = client.get(url)
assertContains(response, f"Créer une fiche pratique dans la catégorie {category_forum.name}", html=True)


def test_success_url(client, db):
client.force_login(UserFactory(is_superuser=True))
category_forum = CategoryForumFactory()
url = reverse("forum_extension:create_subcategory", kwargs={"pk": category_forum.pk})
response = client.post(url, data={"name": "Test", "description": "Test", "short_description": "Test"})
assert response.status_code == 302
assert response.url == reverse(
"forum_extension:forum", kwargs={"pk": category_forum.children.first().pk, "slug": "test"}
)


def test_create_subcategory_with_perms(client, db):
client.force_login(UserFactory(is_superuser=True))
category_forum = CategoryForumFactory()
url = reverse("forum_extension:create_subcategory", kwargs={"pk": category_forum.pk})
response = client.post(url, data={"name": "Test", "description": "Test", "short_description": "Test"})
assert response.status_code == 302

forum = category_forum.children.get()
assert forum.type == Forum.FORUM_POST
assert forum.kind == ForumKind.PUBLIC_FORUM
assert forum.parent == category_forum

assert UserForumPermission.objects.filter(forum=forum).count() == 14
18 changes: 18 additions & 0 deletions lacommunaute/forum/tests/tests_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,24 @@ def test_descendants_are_in_cards_if_forum_is_category_type(self):
response, reverse("forum_extension:forum", kwargs={"pk": child_forum.pk, "slug": child_forum.slug})
)

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

user = UserFactory()
self.client.force_login(user)
response = self.client.get(url)
self.assertNotContains(
response, reverse("forum_extension:create_subcategory", kwargs={"pk": forum.pk}), status_code=200
)

user.is_superuser = True
user.save()
response = self.client.get(url)
self.assertContains(
response, reverse("forum_extension:create_subcategory", kwargs={"pk": forum.pk}), status_code=200
)

def test_siblings_in_context(self):
forum = CategoryForumFactory(with_public_perms=True, with_child=True)
child_forum = forum.get_children().first()
Expand Down
9 changes: 8 additions & 1 deletion lacommunaute/forum/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
from django.urls import path
from machina.apps.forum.views import IndexView

from lacommunaute.forum.views import CategoryForumListView, ForumView
from lacommunaute.forum.views import (
CategoryForumCreateView,
CategoryForumListView,
ForumView,
SubCategoryForumCreateView,
)


app_name = "forum_extension"
Expand All @@ -11,4 +16,6 @@
path("forum/<str:slug>-<int:pk>/", ForumView.as_view(), name="forum"),
path("forums/", IndexView.as_view(), name="index"),
path("documentation/", CategoryForumListView.as_view(), name="documentation"),
path("documentation/category/create/", CategoryForumCreateView.as_view(), name="create_category"),
path("documentation/category/<int:pk>/create/", SubCategoryForumCreateView.as_view(), name="create_subcategory"),
]
53 changes: 51 additions & 2 deletions lacommunaute/forum/views.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import logging

from django.conf import settings
from django.contrib.auth.mixins import UserPassesTestMixin
from django.contrib.contenttypes.models import ContentType
from django.db.models.query import QuerySet
from django.urls import reverse
from django.views.generic import ListView
from django.urls import reverse, reverse_lazy
from django.views.generic import CreateView, ListView
from machina.apps.forum.views import ForumView as BaseForumView
from machina.core.loading import get_class

from lacommunaute.forum.enums import Kind as ForumKind
from lacommunaute.forum.forms import ForumForm
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.utils.perms import add_public_perms_on_forum


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -71,3 +74,49 @@ class CategoryForumListView(ListView):

def get_queryset(self) -> QuerySet[Forum]:
return Forum.objects.filter(type=Forum.FORUM_CAT, kind=ForumKind.PUBLIC_FORUM, level=0)


class BaseCategoryForumCreateView(UserPassesTestMixin, CreateView):
template_name = "forum/forum_create.html"
form_class = ForumForm

def test_func(self):
return self.request.user.is_superuser

def form_valid(self, form):
form.instance.kind = ForumKind.PUBLIC_FORUM
response = super().form_valid(form)
add_public_perms_on_forum(form.instance)
return response


class CategoryForumCreateView(BaseCategoryForumCreateView):
success_url = reverse_lazy("forum_extension:documentation")

def form_valid(self, form):
form.instance.parent = None
form.instance.type = Forum.FORUM_CAT
return super().form_valid(form)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["title"] = "Créer une nouvelle catégorie documentaire"
return context


class SubCategoryForumCreateView(BaseCategoryForumCreateView):
def get_success_url(self):
return reverse("forum_extension:forum", kwargs={"pk": self.object.pk, "slug": self.object.slug})

def get_parent_forum(self):
return Forum.objects.get(pk=self.kwargs["pk"])

def form_valid(self, form):
form.instance.type = Forum.FORUM_POST
form.instance.parent = self.get_parent_forum()
return super().form_valid(form)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["title"] = f"Créer une fiche pratique dans la catégorie {self.get_parent_forum().name}"
return context
11 changes: 11 additions & 0 deletions lacommunaute/templates/forum/category_forum_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,15 @@ <h2 class="mt-3">
</div>
</div>
</section>
{% if user.is_superuser %}
<section class="s-section">
<div class="s-section__container container">
<div class="s-section__row row">
<div class="col-12">
<a href="{% url 'forum_extension:create_category' %}" aria-label="Ajouter une catégorie documentaire" role="button" class="btn btn-outline-primary">Ajouter une catégorie documentaire</a>
</div>
</div>
</div>
</section>
{% endif %}
{% endblock content %}
16 changes: 16 additions & 0 deletions lacommunaute/templates/forum/forum_create.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% extends "board_base.html" %}
{% block sub_title %}
{{ title }}
{% endblock sub_title %}
{% block content %}
<div class="row">
<div class="col-12">
<div class="card post-edit">
<div class="card-header">
<h3 class="m-0 h4 card-title">{{ title }}</h3>
</div>
<div class="card-body">{% include "forum/partials/forum_form.html" %}</div>
</div>
</div>
</div>
{% endblock content %}
7 changes: 7 additions & 0 deletions lacommunaute/templates/forum/forum_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ <h3 class="h3 mb-0">
</div>
{% endfor %}
</div>
{% if user.is_superuser %}
<div class="row mt-4">
<div class="col-12">
<a href="{% url 'forum_extension:create_subcategory' forum_contents.top_nodes.0.obj.parent.pk %}" aria-label="Ajouter une fiche pratique" role="button" class="btn btn-outline-primary">Ajouter une fiche pratique</a>
</div>
</div>
{% endif %}
{% else %}
<ul class="list-group mb-3 mb-md-5">
{% for node in forum_contents.top_nodes %}
Expand Down
Loading
Loading