#hz 评论模块的单元测试
#hz 本模块包含评论功能的单元测试用例，用于测试评论的创建、验证、嵌套评论和模板标签等功能

from django.test import Client, RequestFactory, TransactionTestCase
from django.urls import reverse

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.

#hz 评论功能测试类
#hz 继承自TransactionTestCase，用于测试评论相关的功能，包括评论提交、审核、嵌套评论等
class CommentsTest(TransactionTestCase):
    #hz 测试用例的初始化方法
    #hz 在每个测试方法执行前运行，用于设置测试环境和测试数据
    def setUp(self):
        #hz 创建测试客户端，用于模拟HTTP请求
        self.client = Client()
        #hz 创建请求工厂，用于创建请求对象
        self.factory = RequestFactory()
        #hz 设置博客配置：启用评论审核功能
        from blog.models import BlogSettings
        value = BlogSettings()
        value.comment_need_review = True
        value.save()

        #hz 创建测试用的超级用户
        self.user = BlogUser.objects.create_superuser(
            email="liangliangyy1@gmail.com",
            username="liangliangyy1",
            password="liangliangyy1")

    #hz 更新文章评论状态的辅助方法
    #hz 将指定文章的所有评论设置为启用状态（用于测试中模拟审核通过）
    def update_article_comment_status(self, article):
        #hz 获取文章的所有评论
        comments = article.comment_set.all()
        #hz 遍历所有评论，将is_enable字段设置为True
        for comment in comments:
            comment.is_enable = True
            comment.save()

    #hz 测试评论验证功能
    #hz 测试评论的创建、审核、嵌套评论和模板标签等功能
    def test_validate_comment(self):
        #hz 登录测试用户
        self.client.login(username='liangliangyy1', password='liangliangyy1')

        #hz 创建测试用的分类
        category = Category()
        category.name = "categoryccc"
        category.save()

        #hz 创建测试用的文章
        article = Article()
        article.title = "nicetitleccc"
        article.body = "nicecontentccc"
        article.author = self.user
        article.category = category
        article.type = 'a'  #hz 文章类型
        article.status = 'p'  #hz 文章状态：已发布
        article.save()

        #hz 获取评论提交的URL
        comment_url = reverse(
            'comments:postcomment', kwargs={
                'article_id': article.id})

        #hz 测试提交第一条评论
        response = self.client.post(comment_url,
                                    {
                                        'body': '123ffffffffff'
                                    })

        #hz 验证响应状态码为302（重定向）
        self.assertEqual(response.status_code, 302)

        #hz 重新获取文章对象，检查评论列表
        article = Article.objects.get(pk=article.pk)
        #hz 验证评论列表长度为0（因为评论需要审核，初始状态为未启用）
        self.assertEqual(len(article.comment_list()), 0)
        #hz 更新评论状态为启用（模拟审核通过）
        self.update_article_comment_status(article)

        #hz 验证评论列表长度为1（审核通过后可见）
        self.assertEqual(len(article.comment_list()), 1)

        #hz 测试提交第二条评论
        response = self.client.post(comment_url,
                                    {
                                        'body': '123ffffffffff',
                                    })

        #hz 验证响应状态码为302（重定向）
        self.assertEqual(response.status_code, 302)

        #hz 重新获取文章对象，更新评论状态，验证评论数量
        article = Article.objects.get(pk=article.pk)
        self.update_article_comment_status(article)
        #hz 验证评论列表长度为2
        self.assertEqual(len(article.comment_list()), 2)
        #hz 获取第一条评论的ID，用于测试嵌套评论
        parent_comment_id = article.comment_list()[0].id

        #hz 测试提交嵌套评论（回复评论）
        #hz 评论内容包含Markdown格式，测试复杂内容的处理
        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  #hz 指定父评论ID，创建嵌套评论
                                    })

        #hz 验证响应状态码为302（重定向）
        self.assertEqual(response.status_code, 302)
        #hz 更新评论状态为启用
        self.update_article_comment_status(article)
        #hz 重新获取文章对象
        article = Article.objects.get(pk=article.pk)
        #hz 验证评论列表长度为3（包含2条顶级评论和1条回复评论）
        self.assertEqual(len(article.comment_list()), 3)
        #hz 获取父评论对象
        comment = Comment.objects.get(id=parent_comment_id)
        #hz 测试评论树解析功能：解析父评论的所有子评论
        tree = parse_commenttree(article.comment_list(), comment)
        #hz 验证子评论数量为1
        self.assertEqual(len(tree), 1)
        #hz 测试评论项显示模板标签
        data = show_comment_item(comment, True)
        #hz 验证返回数据不为空
        self.assertIsNotNone(data)
        #hz 测试获取最大文章ID和评论ID的工具函数
        s = get_max_articleid_commentid()
        #hz 验证返回结果不为空
        self.assertIsNotNone(s)

        #hz 测试发送评论邮件功能
        from comments.utils import send_comment_email
        send_comment_email(comment)
