You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DjangoBlog/comments/tests.py

146 lines
7.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 赵瑞萍:评论功能测试模块,用于验证评论发布、回复、审核及显示等核心流程
# 基于Django TransactionTestCase支持数据库事务操作覆盖评论功能的关键场景测试
# 赵瑞萍导入Django测试核心工具提供请求模拟、URL解析等能力
from django.test import Client, RequestFactory, TransactionTestCase
from django.urls import reverse # 用于反向解析视图URL避免硬编码
# 赵瑞萍:导入测试所需的模型和工具,覆盖用户、文章、评论等关联数据
from accounts.models import BlogUser # 自定义用户模型,用于创建测试用户
from blog.models import Category, Article, BlogSettings # 博客分类、文章、设置模型
from comments.models import Comment # 评论模型,测试核心对象
from comments.templatetags.comments_tags import * # 评论模板标签,用于测试评论树解析
from djangoblog.utils import get_max_articleid_commentid # 工具函数,辅助测试数据处理
class CommentsTest(TransactionTestCase):
"""
赵瑞萍评论功能测试类继承TransactionTestCase支持事务回滚确保测试独立性
覆盖场景:评论发布、回复评论、评论审核状态、评论列表显示等核心功能
"""
def setUp(self):
"""
赵瑞萍:测试前置初始化方法,每个测试函数执行前自动调用
初始化测试客户端、请求工厂、测试数据(用户、博客设置),为测试提供基础环境
"""
# 赵瑞萍创建测试客户端用于模拟用户发起HTTP请求如提交评论
self.client = Client()
# 赵瑞萍:创建请求工厂,用于构造自定义请求对象(灵活模拟请求场景)
self.factory = RequestFactory()
# 赵瑞萍:配置博客评论设置,开启"评论需要审核"功能(模拟真实业务场景)
value = BlogSettings()
value.comment_need_review = True # 评论需审核后才显示
value.save() # 保存设置到数据库
# 赵瑞萍:创建超级用户,用于测试登录状态下的评论发布权限
self.user = BlogUser.objects.create_superuser(
email="liangliangyy1@gmail.com",
username="liangliangyy1",
password="liangliangyy1"
)
def update_article_comment_status(self, article):
"""
赵瑞萍:测试辅助方法,用于批量更新文章评论为"启用"状态(模拟审核通过)
参数article - 目标文章对象,需启用其下所有评论
"""
# 赵瑞萍:获取该文章关联的所有评论查询集
comments = article.comment_set.all()
# 赵瑞萍遍历评论将is_enable设为True审核通过并保存
for comment in comments:
comment.is_enable = True
comment.save()
def test_validate_comment(self):
"""
赵瑞萍:核心测试方法,验证评论发布、回复、审核显示等完整流程
包含登录验证、文章创建、普通评论发布、嵌套回复、Markdown内容测试
"""
# 赵瑞萍:模拟用户登录,获取评论发布权限(需登录才能评论)
self.client.login(username='liangliangyy1', password='liangliangyy1')
# 赵瑞萍:创建测试分类(文章必须关联分类,满足模型约束)
category = Category()
category.name = "categoryccc"
category.save()
# 赵瑞萍:创建测试文章(评论需关联文章,为评论提供目标对象)
article = Article()
article.title = "nicetitleccc" # 文章标题
article.body = "nicecontentccc" # 文章内容
article.author = self.user # 关联创建者(超级用户)
article.category = category # 关联分类
article.type = 'a' # 假设'a'为普通文章类型(符合项目定义)
article.status = 'p' # 假设'p'为已发布状态(只有已发布文章可评论)
article.save()
# 赵瑞萍反向解析评论提交视图的URL传入文章ID参数
comment_url = reverse(
'comments:postcomment', kwargs={'article_id': article.id}
)
# 赵瑞萍测试场景1 - 发布第一条普通评论
response = self.client.post(
comment_url,
{'body': '123ffffffffff'} # 评论内容
)
# 赵瑞萍验证评论提交后是否重定向通常跳回文章详情页状态码302
self.assertEqual(response.status_code, 302)
# 赵瑞萍:从数据库刷新文章对象(获取最新关联的评论数据)
article = Article.objects.get(pk=article.pk)
# 赵瑞萍未审核的评论is_enable=False评论列表长度应为0
self.assertEqual(len(article.comment_list()), 0)
# 赵瑞萍:调用辅助方法模拟审核通过,启用评论
self.update_article_comment_status(article)
# 赵瑞萍审核后评论应显示列表长度应为1
self.assertEqual(len(article.comment_list()), 1)
# 赵瑞萍测试场景2 - 发布第二条普通评论(验证多评论存储)
response = self.client.post(
comment_url,
{'body': '123ffffffffff'}
)
self.assertEqual(response.status_code, 302) # 验证重定向
article = Article.objects.get(pk=article.pk)
self.update_article_comment_status(article)
self.assertEqual(len(article.comment_list()), 2) # 验证评论数量增加
# 赵瑞萍测试场景3 - 回复评论(嵌套回复功能)
# 获取第一条评论的ID作为父评论ID建立回复关联
parent_comment_id = article.comment_list()[0].id
# 赵瑞萍发布带Markdown格式的回复测试富文本内容支持
response = self.client.post(
comment_url,
{
'body': '''
# Title1 Markdown标题
```python
import os # Markdown代码块
''',
'parent_comment_id': parent_comment_id # 传入父评论ID标识为回复
}
)
# 赵瑞萍:验证回复提交是否成功(重定向)
self.assertEqual(response.status_code, 302)
# 赵瑞萍:刷新文章对象并启用所有评论(模拟审核)
article = Article.objects.get(pk=article.pk)
self.update_article_comment_status(article)
# 赵瑞萍验证总评论数原有2条+1条回复=3条
self.assertEqual(len(article.comment_list()), 3)
# 赵瑞萍测试场景4 - 验证评论树解析(通过模板标签解析嵌套关系)
# 获取所有已启用的评论查询集
comment_list = Comment.objects.filter(is_enable=True)
# 获取第一条评论(父评论)
parent_comment = comment_list.first()
# 调用模板标签函数,解析该父评论的所有子评论
child_comments = parse_commenttree(comment_list, parent_comment)
# 赵瑞萍验证子评论数量仅1条回复
self.assertEqual(len(child_comments), 1)
# 赵瑞萍验证子评论的父评论ID是否正确匹配
self.assertEqual(child_comments[0].parent_comment.id, parent_comment.id)