Почему результат тестирования с помощью Unittest в Джанго отличается от результата мануального теста в моём проекте?

Пишу тесты для проверки функции комментирования постов в проекте на Джанго.

При тестировании в ручном режиме происходит следующее:

  • все пользователи могут просматривать пост, и видят форму для комментария.
  • неавторизованный пользователь при нажатии кнопки "Отправить" под формой комментария перенаправляется на страницу авторизации. После авторизации он попадает обратно на страницу поста, где может видеть свой только что опубликованный комментарий.

Так и должно быть. Но Unittest показывает, что после авторизации переадресация происходит на главную страницу.

class PostUrlTests(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()

        cls.author = User.objects.create_user(username='author')
        cls.creator = User.objects.create_user(username='creator')
        cls.group = Group.objects.create(
            title='Тестовая группа',
            slug='test_slug',
            description='Тестовое описание',
            creator=cls.creator,
        )
        cls.post = Post.objects.create(
            author=cls.author,
            text='Тестовый не очень длинный пост',
            group=cls.group
        )

    def setUp(self):
        self.authorized_client_creator = Client()
        self.authorized_client_creator.force_login(PostUrlTests.creator)
        self.authorized_client_author = Client()
        self.authorized_client_author.force_login(PostUrlTests.author)

    def test_redirect_to_post_detail_after_login(self):
        """Пользователь перенаправляется на страницу поста после авторизации"""
        self.user_with_password = User.objects.create_user(
            username='user_with_password', password='password')
        comment_text = 'Test comment after login'
        post_detail_url = reverse('posts:post_detail', args=[self.post.id])
        
        # Пытаемся оставить комментарий, будучи неавторизованным пользователем
        response = self.client.post(post_detail_url, {'text': comment_text})
        
        login_url = reverse('users:login')
        expected_redirect_url = f'{login_url}?next={post_detail_url}'
        self.assertRedirects(response, expected_redirect_url)
        
        # Имитация логина через форму
        login_response = self.client.post(
            login_url,
            {'username': 'user_with_password', 'password': 'password'}
        )
        
        # Проверяем, что после авторизации нас перенаправило на страницу поста
        self.assertRedirects(login_response, post_detail_url)
        
        # Проверяем, что комментарий успешно добавлен
        self.assertTrue(Comment.objects.filter(
            text=comment_text, post=self.post).exists())

Текст ошибки:

FAIL: test_redirect_to_post_detail_after_login (posts.tests.test_urls.PostUrlTests)
Пользователь перенаправляется на страницу поста после авторизации  
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Dev\Yandex_Practicum\yatube_project\yatube\posts\tests\test_urls.py", line 97, in test_redirect_to_post_detail_after_login 
    self.assertRedirects(login_response, post_detail_url)
  File "C:\Dev\Yandex_Practicum\yatube_project\venv\lib\site-packages\django\test\testcases.py", line 381, in assertRedirects
    self.assertURLEqual(
  File "C:\Dev\Yandex_Practicum\yatube_project\venv\lib\site-packages\django\test\testcases.py", line 401, in assertURLEqual
    self.assertEqual(
AssertionError: '/' != '/posts/1/'
- /
+ /posts/1/
 : Response redirected to '/', expected '/posts/1/'Expected '/' to 
equal '/posts/1/'.

На всякий случай покажу код класса представления, но надеюсь, это не нужно, потому что он очень длинный:

class PostDetail(View):
    def get(self, request, pk):
        post = get_object_or_404(Post, pk=pk)
        author = post.author
        author_posts = Post.objects.filter(author=author)
        post_count = author_posts.count()
        comments = Comment.objects.filter(post=post)
        form = CommentForm()

        if (request.user.is_authenticated
                and 'comment_form_data' in request.session):
            form_data = request.session.pop('comment_form_data')
            form = CommentForm(form_data)
            if form.is_valid():
                comment = form.save(commit=False)
                comment.post = post
                comment.author = request.user
                comment.save()
                return redirect('posts:post_detail', pk=pk)

        context = {
            'post_count': post_count,
            'post': post,
            'author_posts': author_posts,
            'comments': comments,
            'form': form,
        }
        return render(request, 'posts/post_detail.html', context)

    def post(self, request, pk):
        post = get_object_or_404(Post, pk=pk)
        form = self.get_comment_form(request)
        if not request.user.is_authenticated:
            return self.handle_unauthenticated_user(request)

        form_data = request.session.pop('comment_form_data', request.POST)
        form = CommentForm(form_data)

        if 'comment_id' in form_data:
            return self.edit_comment(request, form_data, pk)

        if 'delete_comment_id' in request.POST:
            return self.delete_comment(request, pk)

        return self.add_or_render_comment(request, form, post, pk)

    def get_comment_form(self, request):
        return CommentForm(request.POST)

    def handle_unauthenticated_user(self, request):
        request.session['comment_form_data'] = request.POST
        return redirect(f'{reverse("login")}?next={request.path}')

    def edit_comment(self, request, form_data, pk):
        comment_id = form_data['comment_id']
        comment = get_object_or_404(Comment, pk=comment_id)
        if comment.author != request.user:
            return redirect('posts:post_detail', pk=pk)
        form = CommentForm(form_data, instance=comment)
        if form.is_valid():
            form.save()
            if request.is_ajax():
                return JsonResponse({'text': comment.text})
        return redirect('posts:post_detail', pk=pk)

    def delete_comment(self, request, pk):
        comment_id = request.POST['delete_comment_id']
        comment = get_object_or_404(Comment, pk=comment_id)
        if comment.author == request.user:
            comment.delete()
        return redirect('posts:post_detail', pk=pk)

    def add_or_render_comment(self, request, form, post, pk):
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.author = request.user
            comment.save()
            if request.is_ajax():
                return JsonResponse({
                    'id': comment.id,
                    'username': comment.author.username,
                    'text': comment.text,
                    'profile_url': reverse(
                        'posts:profile', args=[comment.author.username])
                })
            return redirect('posts:post_detail', pk=pk)
        comments = Comment.objects.filter(post=post)
        author_posts = Post.objects.filter(author=post.author)
        post_count = author_posts.count()
        context = {
            'post_count': post_count,
            'post': post,
            'author_posts': author_posts,
            'comments': comments,
            'form': form,
        }
        return render(request, 'posts/post_detail.html', context)
Вернуться на верх