Files
guilan-ace-backend/apps/gamification/tests/integration/test_blog.py

130 lines
4.8 KiB
Python

import pytest
from django.contrib import admin
from types import SimpleNamespace
from apps.blog.admin import CommentAdmin, PostAdmin
from apps.blog.models import Comment, Like, Post, SavedPost
from apps.gamification.models import ContributionLedger
from apps.gamification.services import summary_for_user
pytestmark = [pytest.mark.integration, pytest.mark.django_db]
def test_publish_coauthor_like_and_save_award_expected_contributions(user_factory):
author = user_factory()
coauthor = user_factory()
actor = user_factory()
post = Post.objects.create(
title="Community story",
content="A real story",
author=author,
status=Post.StatusChoices.PUBLISHED,
)
post.writers.add(coauthor)
Like.objects.create(post=post, user=actor)
SavedPost.objects.create(post=post, user=actor)
assert summary_for_user(author)["points_total"] == 22
assert summary_for_user(coauthor)["points_total"] == 22
assert summary_for_user(actor)["points_total"] == 2
assert summary_for_user(actor)["activity_counts"]["likes"] == 1
assert summary_for_user(coauthor)["activity_counts"]["likes"] == 1
post.writers.remove(coauthor)
post.writers.remove(author)
assert summary_for_user(author)["points_total"] == 22
assert summary_for_user(coauthor)["points_total"] == 0
assert summary_for_user(actor)["points_total"] == 2
def test_self_like_and_save_count_once_each_and_only_like_advances_badge_ladder(user_factory):
member = user_factory()
post = Post.objects.create(
title="My post",
content="My content",
author=member,
status=Post.StatusChoices.PUBLISHED,
)
Like.objects.create(post=post, user=member)
SavedPost.objects.create(post=post, user=member)
summary = summary_for_user(member)
assert summary["points_total"] == 22
assert summary["activity_counts"]["likes"] == 1
assert not any(badge["category"] == "save" for badge in summary["badges"])
def test_approved_comments_and_replies_score_and_hiding_reverses_them(user_factory):
author = user_factory()
commenter = user_factory()
post = Post.objects.create(
title="Discussion",
content="Discuss this",
author=author,
status=Post.StatusChoices.PUBLISHED,
)
comment = Comment.objects.create(post=post, author=commenter, content="A comment")
reply = Comment.objects.create(post=post, author=author, content="A reply", parent=comment)
assert summary_for_user(commenter)["points_total"] == 5
assert summary_for_user(author)["points_total"] == 25
comment.hide(user=author, note="moderated")
assert summary_for_user(commenter)["points_total"] == 0
assert summary_for_user(author)["points_total"] == 20
assert summary_for_user(commenter)["activity_counts"]["comments"] == 0
assert ContributionLedger.objects.filter(user=commenter).count() == 2
assert ContributionLedger.objects.filter(user=author, source_type="blog_comment", source_id=str(reply.pk)).count() == 2
def test_removing_like_and_unpublishing_post_reverse_only_valid_points(user_factory):
author = user_factory()
actor = user_factory()
post = Post.objects.create(
title="Published then withdrawn",
content="Content",
author=author,
status=Post.StatusChoices.PUBLISHED,
)
like = Like.objects.create(post=post, user=actor)
SavedPost.objects.create(post=post, user=actor)
assert summary_for_user(actor)["points_total"] == 2
like.delete()
assert summary_for_user(actor)["points_total"] == 1
assert summary_for_user(author)["points_total"] == 21
post.status = Post.StatusChoices.ARCHIVED
post.save(update_fields=["status", "updated_at"])
assert summary_for_user(author)["points_total"] == 0
assert summary_for_user(actor)["points_total"] == 0
def test_blog_admin_publish_and_approve_actions_flow_through_scoring(user_factory, mocker):
editor = user_factory(is_staff=True)
author = user_factory()
commenter = user_factory()
draft = Post.objects.create(title="Draft", content="Content", author=author)
post_admin = PostAdmin(Post, admin.site)
comment_admin = CommentAdmin(Comment, admin.site)
mocker.patch.object(PostAdmin, "message_user")
mocker.patch.object(CommentAdmin, "message_user")
post_admin.make_published(SimpleNamespace(user=editor), Post.objects.filter(pk=draft.pk))
draft.refresh_from_db()
pending_comment = Comment.objects.create(
post=draft,
author=commenter,
content="Awaiting approval",
is_approved=False,
)
assert summary_for_user(author)["points_total"] == 20
assert summary_for_user(commenter)["points_total"] == 0
comment_admin.approve_comments(SimpleNamespace(user=editor), Comment.objects.filter(pk=pending_comment.pk))
assert summary_for_user(commenter)["points_total"] == 5