|
|
|
|
@ -1,109 +1,103 @@
|
|
|
|
|
from django.test import Client, RequestFactory, TransactionTestCase
|
|
|
|
|
from django.urls import reverse
|
|
|
|
|
# 导入Django测试核心模块、URL工具及项目内模型/工具
|
|
|
|
|
from django.test import Client, RequestFactory, TransactionTestCase # Django测试类:Client模拟HTTP请求,RequestFactory构造请求对象,TransactionTestCase支持事务回滚
|
|
|
|
|
from django.urls import reverse # 生成URL(通过URL名称反向解析,避免硬编码)
|
|
|
|
|
|
|
|
|
|
# 导入项目内关联模型:用户、分类、文章、评论模型
|
|
|
|
|
from accounts.models import BlogUser
|
|
|
|
|
from blog.models import Category, Article
|
|
|
|
|
from comments.models import Comment
|
|
|
|
|
# 导入评论相关自定义模板标签和通用工具函数
|
|
|
|
|
from comments.templatetags.comments_tags import *
|
|
|
|
|
from djangoblog.utils import get_max_articleid_commentid
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Create your tests here.
|
|
|
|
|
|
|
|
|
|
class CommentsTest(TransactionTestCase):
|
|
|
|
|
"""
|
|
|
|
|
评论功能测试类:继承TransactionTestCase,用于测试评论的提交、状态更新等核心逻辑
|
|
|
|
|
支持数据库事务回滚,确保测试用例间数据隔离
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
|
"""
|
|
|
|
|
测试前置初始化方法:每个测试用例执行前自动调用
|
|
|
|
|
作用:创建测试所需的基础数据(客户端、用户、系统配置等)
|
|
|
|
|
"""
|
|
|
|
|
# 1. 初始化测试工具:Client模拟浏览器请求,RequestFactory构造原始请求对象
|
|
|
|
|
self.client = Client()
|
|
|
|
|
self.factory = RequestFactory()
|
|
|
|
|
from blog.models import BlogSettings
|
|
|
|
|
value = BlogSettings()
|
|
|
|
|
value.comment_need_review = True
|
|
|
|
|
value.save()
|
|
|
|
|
|
|
|
|
|
# 2. 初始化博客系统配置:设置“评论需审核”(模拟真实场景中评论需管理员审核才能显示)
|
|
|
|
|
from blog.models import BlogSettings # 局部导入避免循环引用
|
|
|
|
|
value = BlogSettings() # 创建配置对象
|
|
|
|
|
value.comment_need_review = True # 开启评论审核开关
|
|
|
|
|
value.save() # 保存到测试数据库
|
|
|
|
|
|
|
|
|
|
# 3. 创建测试超级用户:用于模拟登录状态下提交评论
|
|
|
|
|
self.user = BlogUser.objects.create_superuser(
|
|
|
|
|
email="liangliangyy1@gmail.com",
|
|
|
|
|
username="liangliangyy1",
|
|
|
|
|
password="liangliangyy1")
|
|
|
|
|
email="liangliangyy1@gmail.com", # 测试邮箱
|
|
|
|
|
username="liangliangyy1", # 测试用户名
|
|
|
|
|
password="liangliangyy1" # 测试密码(明文,Django会自动加密存储)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def update_article_comment_status(self, article):
|
|
|
|
|
"""
|
|
|
|
|
辅助方法:批量更新某篇文章下所有评论的启用状态(设为“启用”)
|
|
|
|
|
模拟管理员审核通过评论的操作,用于测试审核后评论的显示逻辑
|
|
|
|
|
参数:
|
|
|
|
|
- article:目标文章对象(需更新其下所有评论)
|
|
|
|
|
"""
|
|
|
|
|
# 获取该文章下所有评论
|
|
|
|
|
comments = article.comment_set.all()
|
|
|
|
|
# 遍历评论,将“是否启用”字段设为True并保存
|
|
|
|
|
for comment in comments:
|
|
|
|
|
comment.is_enable = True
|
|
|
|
|
comment.save()
|
|
|
|
|
|
|
|
|
|
def test_validate_comment(self):
|
|
|
|
|
"""
|
|
|
|
|
核心测试用例:验证评论提交流程(登录→创建文章→提交评论→验证状态)
|
|
|
|
|
覆盖场景:登录用户提交评论、评论未审核时不显示、审核后正常显示
|
|
|
|
|
"""
|
|
|
|
|
# 1. 模拟用户登录:使用之前创建的测试超级用户登录
|
|
|
|
|
self.client.login(username='liangliangyy1', password='liangliangyy1')
|
|
|
|
|
|
|
|
|
|
# 2. 创建测试分类:文章需关联分类,先创建分类数据
|
|
|
|
|
category = Category()
|
|
|
|
|
category.name = "categoryccc"
|
|
|
|
|
category.save()
|
|
|
|
|
category.name = "categoryccc" # 分类名称
|
|
|
|
|
category.save() # 保存到测试数据库
|
|
|
|
|
|
|
|
|
|
# 3. 创建测试文章:评论需关联文章,创建一篇已发布的文章
|
|
|
|
|
article = Article()
|
|
|
|
|
article.title = "nicetitleccc"
|
|
|
|
|
article.body = "nicecontentccc"
|
|
|
|
|
article.author = self.user
|
|
|
|
|
article.category = category
|
|
|
|
|
article.type = 'a'
|
|
|
|
|
article.status = 'p'
|
|
|
|
|
article.save()
|
|
|
|
|
|
|
|
|
|
article.title = "nicetitleccc" # 文章标题
|
|
|
|
|
article.body = "nicecontentccc" # 文章内容
|
|
|
|
|
article.author = self.user # 关联作者(测试用户)
|
|
|
|
|
article.category = category # 关联分类(刚创建的测试分类)
|
|
|
|
|
article.type = 'a' # 文章类型(假设'a'代表普通文章)
|
|
|
|
|
article.status = 'p' # 文章状态(假设'p'代表已发布)
|
|
|
|
|
article.save() # 保存到测试数据库
|
|
|
|
|
|
|
|
|
|
# 4. 构造评论提交URL:通过URL名称“comments:postcomment”反向解析,传入文章ID
|
|
|
|
|
comment_url = reverse(
|
|
|
|
|
'comments:postcomment', kwargs={
|
|
|
|
|
'article_id': article.id})
|
|
|
|
|
'comments:postcomment',
|
|
|
|
|
kwargs={'article_id': article.id} # URL参数:文章ID(指定评论所属文章)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
response = self.client.post(comment_url,
|
|
|
|
|
{
|
|
|
|
|
'body': '123ffffffffff'
|
|
|
|
|
})
|
|
|
|
|
# 5. 模拟POST请求提交评论:向评论URL发送包含评论内容的请求
|
|
|
|
|
response = self.client.post(
|
|
|
|
|
comment_url,
|
|
|
|
|
{'body': '123ffffffffff'} # 请求参数:评论正文
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# 6. 验证评论提交结果:检查响应状态码是否为302(重定向,通常提交后跳回文章页)
|
|
|
|
|
self.assertEqual(response.status_code, 302)
|
|
|
|
|
|
|
|
|
|
article = Article.objects.get(pk=article.pk)
|
|
|
|
|
self.assertEqual(len(article.comment_list()), 0)
|
|
|
|
|
self.update_article_comment_status(article)
|
|
|
|
|
|
|
|
|
|
self.assertEqual(len(article.comment_list()), 1)
|
|
|
|
|
|
|
|
|
|
response = self.client.post(comment_url,
|
|
|
|
|
{
|
|
|
|
|
'body': '123ffffffffff',
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 302)
|
|
|
|
|
# 7. 验证“未审核评论不显示”:重新获取文章,检查其评论列表长度是否为0(因评论需审核)
|
|
|
|
|
article = Article.objects.get(pk=article.pk) # 从数据库重新查询(避免缓存)
|
|
|
|
|
self.assertEqual(len(article.comment_list()), 0) # comment_list()应为自定义方法,返回启用的评论
|
|
|
|
|
|
|
|
|
|
article = Article.objects.get(pk=article.pk)
|
|
|
|
|
# 8. 模拟审核通过:调用辅助方法,将该文章下所有评论设为“启用”
|
|
|
|
|
self.update_article_comment_status(article)
|
|
|
|
|
self.assertEqual(len(article.comment_list()), 2)
|
|
|
|
|
parent_comment_id = article.comment_list()[0].id
|
|
|
|
|
|
|
|
|
|
response = self.client.post(comment_url,
|
|
|
|
|
{
|
|
|
|
|
'body': '''
|
|
|
|
|
# Title1
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
import os
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
[url](https://www.lylinux.net/)
|
|
|
|
|
|
|
|
|
|
[ddd](http://www.baidu.com)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
''',
|
|
|
|
|
'parent_comment_id': parent_comment_id
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 302)
|
|
|
|
|
self.update_article_comment_status(article)
|
|
|
|
|
article = Article.objects.get(pk=article.pk)
|
|
|
|
|
self.assertEqual(len(article.comment_list()), 3)
|
|
|
|
|
comment = Comment.objects.get(id=parent_comment_id)
|
|
|
|
|
tree = parse_commenttree(article.comment_list(), comment)
|
|
|
|
|
self.assertEqual(len(tree), 1)
|
|
|
|
|
data = show_comment_item(comment, True)
|
|
|
|
|
self.assertIsNotNone(data)
|
|
|
|
|
s = get_max_articleid_commentid()
|
|
|
|
|
self.assertIsNotNone(s)
|
|
|
|
|
|
|
|
|
|
from comments.utils import send_comment_email
|
|
|
|
|
send_comment_email(comment)
|
|
|
|
|
# 9. 验证“审核后评论显示”:再次检查评论列表长度是否为1(审核通过后应显示)
|
|
|
|
|
self.assertEqual(len(article.comment_list()), 1)
|