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

N'envoie pas de MP lors de la dépublication de contenu sans auteur inscrit #6356

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
10 changes: 10 additions & 0 deletions zds/mp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ def is_reachable(user):
return settings.ZDS_APP["member"]["bot_group"] not in user_group_names


def filter_reachable(users):
"""
Returns a list with only reachable users.

:param user: a list of users
:return: list of reachable users.
"""
return [u for u in users if is_reachable(u)]


class PrivateTopic(models.Model):
"""
Private topic, containing private posts.
Expand Down
137 changes: 86 additions & 51 deletions zds/tutorialv2/tests/tests_opinion_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
from unittest.mock import patch

from django.conf import settings
from django.contrib.auth.models import Group
from django.core.management import call_command
from django.urls import reverse
from django.test import TestCase
from django.utils.translation import gettext_lazy as _

from zds.forum.tests.factories import TagFactory
from zds.gallery.tests.factories import UserGalleryFactory
from zds.member.tests.factories import ProfileFactory, StaffProfileFactory
from zds.member.tests.factories import ProfileFactory, StaffProfileFactory, UserFactory
from zds.tutorialv2.tests.factories import (
PublishableContentFactory,
ExtractFactory,
Expand All @@ -31,7 +32,16 @@ class PublishedContentTests(TutorialTestMixin, TestCase):
def setUp(self):

self.overridden_zds_app["member"]["bot_account"] = ProfileFactory().user.username
self.bot_group = Group()
self.bot_group.name = settings.ZDS_APP["member"]["bot_group"]
self.bot_group.save()
self.licence = LicenceFactory()
self.anonymous = UserFactory(username=settings.ZDS_APP["member"]["anonymous_account"], password="anything")
self.anonymous.groups.add(self.bot_group)
self.anonymous.save()
self.external = UserFactory(username=settings.ZDS_APP["member"]["external_account"], password="anything")
self.external.groups.add(self.bot_group)
self.external.save()

self.user_author = ProfileFactory().user
self.user_staff = StaffProfileFactory().user
Expand Down Expand Up @@ -360,6 +370,25 @@ def test_opinion_unpublication(self, opinions_management):

self.assertEqual(PublishedContent.objects.count(), 1)

# unregister author and unpublish
self.client.force_login(self.user_author)
result = self.client.post(reverse("member-unregister"), follow=False)
self.assertEqual(result.status_code, 302)

self.client.force_login(self.user_staff)

result = self.client.post(
reverse("validation:unpublish-opinion", kwargs={"pk": opinion.pk, "slug": opinion.slug}),
{"text": text_unpublication, "source": "", "version": opinion_draft.current_version},
follow=False,
)
self.assertEqual(result.status_code, 302)

self.assertEqual(PublishedContent.objects.count(), 0)

opinion = PublishableContent.objects.get(pk=opinion.pk)
self.assertIsNone(opinion.public_version)

def test_opinion_validation(self):
"""
Test the validation of PublishableContent where type is OPINION.
Expand Down Expand Up @@ -545,56 +574,62 @@ def test_ignore_opinion(self):
self.assertNotContains(result, opinion.title)

def test_permanently_unpublish_opinion(self):
opinion = PublishableContentFactory(type="OPINION")

opinion.authors.add(self.user_author)
UserGalleryFactory(gallery=opinion.gallery, user=self.user_author, mode="W")
opinion.licence = self.licence
opinion.save()

opinion_draft = opinion.load_version()
ExtractFactory(container=opinion_draft, db_object=opinion)
ExtractFactory(container=opinion_draft, db_object=opinion)

self.client.force_login(self.user_author)

# publish
result = self.client.post(
reverse("validation:publish-opinion", kwargs={"pk": opinion.pk, "slug": opinion.slug}),
{"source": "", "version": opinion_draft.current_version},
follow=False,
)
self.assertEqual(result.status_code, 302)

# login as staff
self.client.force_login(self.user_staff)

# unpublish opinion
result = self.client.post(
reverse("validation:ignore-opinion", kwargs={"pk": opinion.pk, "slug": opinion.slug}),
{
"operation": "REMOVE_PUB",
},
follow=False,
)
self.assertEqual(result.status_code, 200)

# refresh
opinion = PublishableContent.objects.get(pk=opinion.pk)

# check that the opinion is not published
self.assertFalse(opinion.in_public())

# check that it's impossible to publish the opinion again
result = self.client.get(opinion.get_absolute_url())
self.assertContains(result, _("Billet modéré")) # front

result = self.client.post(
reverse("validation:publish-opinion", kwargs={"pk": opinion.pk, "slug": opinion.slug}),
{"source": "", "version": opinion_draft.current_version},
follow=False,
)
self.assertEqual(result.status_code, 403) # back
for unregister_author in [False, True]:
with self.subTest(unregister_author):
opinion = PublishableContentFactory(type="OPINION")

opinion.authors.add(self.user_author)
UserGalleryFactory(gallery=opinion.gallery, user=self.user_author, mode="W")
opinion.licence = self.licence
opinion.save()

opinion_draft = opinion.load_version()
ExtractFactory(container=opinion_draft, db_object=opinion)
ExtractFactory(container=opinion_draft, db_object=opinion)

self.client.force_login(self.user_author)

# publish
result = self.client.post(
reverse("validation:publish-opinion", kwargs={"pk": opinion.pk, "slug": opinion.slug}),
{"source": "", "version": opinion_draft.current_version},
follow=False,
)
self.assertEqual(result.status_code, 302)

if unregister_author:
result = self.client.post(reverse("member-unregister"), follow=False)
self.assertEqual(result.status_code, 302)

# login as staff
self.client.force_login(self.user_staff)

# unpublish opinion
result = self.client.post(
reverse("validation:ignore-opinion", kwargs={"pk": opinion.pk, "slug": opinion.slug}),
{
"operation": "REMOVE_PUB",
},
follow=False,
)
self.assertEqual(result.status_code, 200)

# refresh
opinion = PublishableContent.objects.get(pk=opinion.pk)

# check that the opinion is not published
self.assertFalse(opinion.in_public())

# check that it's impossible to publish the opinion again
result = self.client.get(opinion.get_absolute_url())
self.assertContains(result, _("Billet modéré")) # front

result = self.client.post(
reverse("validation:publish-opinion", kwargs={"pk": opinion.pk, "slug": opinion.slug}),
{"source": "", "version": opinion_draft.current_version},
follow=False,
)
self.assertEqual(result.status_code, 403) # back

def test_defenitely_unpublish_alerted_opinion(self):
opinion = PublishableContentFactory(type="OPINION")
Expand Down
34 changes: 34 additions & 0 deletions zds/tutorialv2/tests/tests_views/tests_published.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ def setUp(self):
bot = Group(name=overridden_zds_app["member"]["bot_group"])
bot.save()
self.external = UserFactory(username=overridden_zds_app["member"]["external_account"], password="anything")
self.external.groups.add(bot)
self.external.save()
self.anonymous = UserFactory(username=settings.ZDS_APP["member"]["anonymous_account"], password="anything")
self.anonymous.groups.add(bot)
self.anonymous.save()

self.beta_forum = ForumFactory(
pk=overridden_zds_app["forum"]["beta_forum_id"],
Expand Down Expand Up @@ -1364,6 +1369,35 @@ def test_unpublish_with_title_change(self):
self.assertEqual(public_count - 1, PublishedContent.objects.count())
self.assertEqual("PENDING", Validation.objects.get(pk=registered_validation.pk).status)

def test_unpublish_unregistered_author(self):
article = PublishedContentFactory(type="ARTICLE", author_list=[self.user_author], licence=self.licence)
registered_validation = Validation(
content=article,
version=article.sha_draft,
status="ACCEPT",
comment_authors="bla",
comment_validator="bla",
date_reserve=datetime.datetime.now(),
date_proposition=datetime.datetime.now(),
date_validation=datetime.datetime.now(),
)
registered_validation.save()

self.client.force_login(self.user_author)
result = self.client.post(reverse("member-unregister"), follow=False)
self.assertEqual(result.status_code, 302)

self.client.force_login(self.user_staff)
public_count = PublishedContent.objects.count()
result = self.client.post(
reverse("validation:revoke", kwargs={"pk": article.pk, "slug": article.public_version.content_public_slug}),
{"text": "This content was bad", "version": article.public_version.sha_public},
follow=False,
)
self.assertEqual(302, result.status_code)
self.assertEqual(public_count - 1, PublishedContent.objects.count())
self.assertEqual("PENDING", Validation.objects.get(pk=registered_validation.pk).status)

def test_unpublish_with_empty_subscription(self):
article = PublishedContentFactory(type="ARTICLE", author_list=[self.user_author], licence=self.licence)
registered_validation = Validation(
Expand Down
56 changes: 29 additions & 27 deletions zds/tutorialv2/views/validations_contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from django.views.generic import ListView, FormView

from zds.member.decorator import LoggedWithReadWriteHability
from zds.mp.models import mark_read
from zds.mp.models import mark_read, filter_reachable
from zds.tutorialv2 import signals
from zds.tutorialv2.forms import (
AskValidationForm,
Expand Down Expand Up @@ -572,34 +572,36 @@ def form_valid(self, form):
self.object.save()

# send PM
msg = render_to_string(
"tutorialv2/messages/validation_revoke.md",
{
"content": versioned,
"url": versioned.get_absolute_url() + "?version=" + validation.version,
"admin": self.request.user,
"message_reject": "\n".join(["> " + a for a in form.cleaned_data["text"].split("\n")]),
},
)

bot = get_object_or_404(User, username=settings.ZDS_APP["member"]["bot_account"])
if not validation.content.validation_private_message:
validation.content.validation_private_message = send_mp(
bot,
validation.content.authors.all(),
self.object.validation_message_title,
validation.content.title,
msg,
send_by_mail=True,
direct=False,
hat=get_hat_from_settings("validation"),
)
self.object.save()
else:
send_message_mp(
bot, validation.content.validation_private_message, msg, no_notification_for=[self.request.user]
recipients = filter_reachable(validation.content.authors.all())
if len(recipients) > 0:
msg = render_to_string(
"tutorialv2/messages/validation_revoke.md",
{
"content": versioned,
"url": versioned.get_absolute_url() + "?version=" + validation.version,
"admin": self.request.user,
"message_reject": "\n".join(["> " + a for a in form.cleaned_data["text"].split("\n")]),
},
)

bot = get_object_or_404(User, username=settings.ZDS_APP["member"]["bot_account"])
if not validation.content.validation_private_message:
validation.content.validation_private_message = send_mp(
bot,
recipients,
self.object.validation_message_title,
validation.content.title,
msg,
send_by_mail=True,
direct=False,
hat=get_hat_from_settings("validation"),
)
self.object.save()
else:
send_message_mp(
bot, validation.content.validation_private_message, msg, no_notification_for=[self.request.user]
)

messages.success(self.request, _("Le contenu a bien été dépublié."))
self.success_url = self.versioned_object.get_absolute_url() + "?version=" + validation.version
signals.validation_management.send(
Expand Down
Loading