From 7540020b88b12579f3b20fcde9e3ae59afe0e98c Mon Sep 17 00:00:00 2001 From: rafalp Date: Wed, 4 Sep 2024 19:00:03 +0200 Subject: [PATCH] Test redirect to unread post --- misago/readtracker/tracker.py | 2 +- misago/threads/tests/test_redirects_views.py | 151 ++++++++++++++++++- misago/threads/views/redirect.py | 2 + 3 files changed, 152 insertions(+), 3 deletions(-) diff --git a/misago/readtracker/tracker.py b/misago/readtracker/tracker.py index 43da4c2a7..b2445fa79 100644 --- a/misago/readtracker/tracker.py +++ b/misago/readtracker/tracker.py @@ -148,7 +148,7 @@ def get_thread_read_time(request: HttpRequest, thread: Thread) -> datetime: def mark_thread_read(user: "User", thread: Thread, read_time: datetime): create_row = True - if thread.read_time: + if getattr(thread, "read_time", None): create_row = not ReadThread.objects.filter( user=user, thread=thread, diff --git a/misago/threads/tests/test_redirects_views.py b/misago/threads/tests/test_redirects_views.py index 1690d1fcc..192627f1c 100644 --- a/misago/threads/tests/test_redirects_views.py +++ b/misago/threads/tests/test_redirects_views.py @@ -1,9 +1,11 @@ from django.urls import reverse +from django.utils import timezone +from ...readtracker.tracker import mark_thread_read from ..test import reply_thread -def test_thread_last_post_redirect_view_returns_redirect_link(client, thread): +def test_thread_last_post_redirect_view_returns_redirect(client, thread): reply = reply_thread(thread) response = client.get( @@ -24,7 +26,7 @@ def test_thread_last_post_redirect_view_returns_redirect_link(client, thread): ) -def test_private_thread_last_post_redirect_view_returns_redirect_link( +def test_private_thread_last_post_redirect_view_returns_redirect( user_client, user_private_thread ): reply = reply_thread(user_private_thread) @@ -45,3 +47,148 @@ def test_private_thread_last_post_redirect_view_returns_redirect_link( ) + f"#post-{reply.id}" ) + + +def test_thread_unread_post_redirect_view_returns_redirect_to_last_post_for_anonymous_user( + client, thread +): + reply_thread(thread, posted_on=timezone.now()) + reply = reply_thread(thread, posted_on=timezone.now()) + + response = client.get( + reverse( + "misago:thread-unread-post", + kwargs={"id": thread.id, "slug": thread.slug}, + ) + ) + + assert response.status_code == 302 + assert ( + response["location"] + == reverse( + "misago:thread", + kwargs={"id": thread.id, "slug": thread.slug}, + ) + + f"#post-{reply.id}" + ) + + +def test_thread_unread_post_redirect_view_returns_redirect_to_first_unread_post_for_user( + user, user_client, thread +): + mark_thread_read(user, thread, thread.first_post.posted_on) + + reply = reply_thread(thread, posted_on=timezone.now()) + reply_thread(thread, posted_on=timezone.now()) + + response = user_client.get( + reverse( + "misago:thread-unread-post", + kwargs={"id": thread.id, "slug": thread.slug}, + ) + ) + + assert response.status_code == 302 + assert ( + response["location"] + == reverse( + "misago:thread", + kwargs={"id": thread.id, "slug": thread.slug}, + ) + + f"#post-{reply.id}" + ) + + +def test_thread_unread_post_redirect_view_returns_redirect_to_last_post_for_read_thread( + user, user_client, thread +): + reply_thread(thread, posted_on=timezone.now()) + reply = reply_thread(thread, posted_on=timezone.now()) + + read_on = timezone.now() + mark_thread_read(user, thread, read_on) + + response = user_client.get( + reverse( + "misago:thread-unread-post", + kwargs={"id": thread.id, "slug": thread.slug}, + ) + ) + + assert response.status_code == 302 + assert ( + response["location"] + == reverse( + "misago:thread", + kwargs={"id": thread.id, "slug": thread.slug}, + ) + + f"#post-{reply.id}" + ) + + +def test_private_thread_unread_post_redirect_view_returns_error_404_for_anonymous_client( + client, user_private_thread +): + response = client.get( + reverse( + "misago:private-thread-unread-post", + kwargs={"id": user_private_thread.id, "slug": user_private_thread.slug}, + ) + ) + + assert response.status_code == 403 + + +def test_private_thread_unread_post_redirect_view_returns_redirect_to_first_unread_post_for_user( + user, user_client, user_private_thread +): + mark_thread_read( + user, user_private_thread, user_private_thread.first_post.posted_on + ) + + reply = reply_thread(user_private_thread, posted_on=timezone.now()) + reply_thread(user_private_thread, posted_on=timezone.now()) + + response = user_client.get( + reverse( + "misago:private-thread-unread-post", + kwargs={"id": user_private_thread.id, "slug": user_private_thread.slug}, + ) + ) + + assert response.status_code == 302 + assert ( + response["location"] + == reverse( + "misago:private-thread", + kwargs={"id": user_private_thread.id, "slug": user_private_thread.slug}, + ) + + f"#post-{reply.id}" + ) + + +def test_private_thread_unread_post_redirect_view_returns_redirect_to_last_post_for_read_thread( + user, user_client, user_private_thread +): + reply_thread(user_private_thread, posted_on=timezone.now()) + reply = reply_thread(user_private_thread, posted_on=timezone.now()) + + read_on = timezone.now() + mark_thread_read(user, user_private_thread, read_on) + + response = user_client.get( + reverse( + "misago:private-thread-unread-post", + kwargs={"id": user_private_thread.id, "slug": user_private_thread.slug}, + ) + ) + + assert response.status_code == 302 + assert ( + response["location"] + == reverse( + "misago:private-thread", + kwargs={"id": user_private_thread.id, "slug": user_private_thread.slug}, + ) + + f"#post-{reply.id}" + ) diff --git a/misago/threads/views/redirect.py b/misago/threads/views/redirect.py index 70360297a..8b267adc7 100644 --- a/misago/threads/views/redirect.py +++ b/misago/threads/views/redirect.py @@ -17,6 +17,7 @@ def get(self, request: HttpRequest, id: int, slug: str, **kwargs) -> HttpRespons paginator = self.get_thread_posts_paginator(request, queryset) if post: + print(post.id, post.posted_on) post_id = post.id offset = queryset.filter(id__lt=post_id).count() page = paginator.get_item_page(offset) @@ -62,6 +63,7 @@ def get_post( read_times.append(thread.category_read_time) read_time = max(read_times) + print(read_time) return queryset.filter(posted_on__gt=read_time).first()