test_threadstracker.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. from datetime import timedelta
  2. from django.contrib.auth import get_user_model
  3. from django.test import TestCase
  4. from django.utils import timezone
  5. from misago.acl import add_acl
  6. from misago.acl.useracl import get_user_acl
  7. from misago.categories.models import Category
  8. from misago.conf import settings
  9. from misago.readtracker import poststracker, threadstracker
  10. from misago.readtracker.models import PostRead
  11. from misago.threads import testutils
  12. User = get_user_model()
  13. cache_versions = {"acl": "abcdefgh"}
  14. class AnonymousUser(object):
  15. is_authenticated = False
  16. is_anonymous = True
  17. class ThreadsTrackerTests(TestCase):
  18. def setUp(self):
  19. self.user = User.objects.create_user("UserA", "testa@user.com", 'Pass.123')
  20. self.user_acl = get_user_acl(self.user, cache_versions)
  21. self.category = Category.objects.get(slug='first-category')
  22. add_acl(self.user_acl, self.category)
  23. def test_falsy_value(self):
  24. """passing falsy value to readtracker causes no errors"""
  25. threadstracker.make_read_aware(self.user, self.user_acl, None)
  26. threadstracker.make_read_aware(self.user, self.user_acl, False)
  27. threadstracker.make_read_aware(self.user, self.user_acl, [])
  28. def test_anon_thread_before_cutoff(self):
  29. """non-tracked thread is marked as read for anonymous users"""
  30. started_on = timezone.now() - timedelta(days=settings.MISAGO_READTRACKER_CUTOFF)
  31. thread = testutils.post_thread(self.category, started_on=started_on)
  32. threadstracker.make_read_aware(AnonymousUser(), None, thread)
  33. self.assertTrue(thread.is_read)
  34. self.assertFalse(thread.is_new)
  35. def test_anon_thread_after_cutoff(self):
  36. """tracked thread is marked as read for anonymous users"""
  37. thread = testutils.post_thread(self.category, started_on=timezone.now())
  38. threadstracker.make_read_aware(AnonymousUser(), None, thread)
  39. self.assertTrue(thread.is_read)
  40. self.assertFalse(thread.is_new)
  41. def test_user_thread_before_cutoff(self):
  42. """non-tracked thread is marked as read for authenticated users"""
  43. started_on = timezone.now() - timedelta(days=settings.MISAGO_READTRACKER_CUTOFF)
  44. thread = testutils.post_thread(self.category, started_on=started_on)
  45. threadstracker.make_read_aware(self.user, self.user_acl, thread)
  46. self.assertTrue(thread.is_read)
  47. self.assertFalse(thread.is_new)
  48. def test_user_unread_thread(self):
  49. """tracked thread is marked as unread for authenticated users"""
  50. thread = testutils.post_thread(self.category, started_on=timezone.now())
  51. threadstracker.make_read_aware(self.user, self.user_acl, thread)
  52. self.assertFalse(thread.is_read)
  53. self.assertTrue(thread.is_new)
  54. def test_user_created_after_thread(self):
  55. """tracked thread older than user is marked as read"""
  56. started_on = timezone.now() - timedelta(days=1)
  57. thread = testutils.post_thread(self.category, started_on=started_on)
  58. threadstracker.make_read_aware(self.user, self.user_acl, thread)
  59. self.assertTrue(thread.is_read)
  60. self.assertFalse(thread.is_new)
  61. def test_user_read_post(self):
  62. """tracked thread with read post marked as read"""
  63. thread = testutils.post_thread(self.category, started_on=timezone.now())
  64. poststracker.save_read(self.user, thread.first_post)
  65. threadstracker.make_read_aware(self.user, self.user_acl, thread)
  66. self.assertTrue(thread.is_read)
  67. self.assertFalse(thread.is_new)
  68. def test_user_first_unread_last_read_post(self):
  69. """tracked thread with unread first and last read post marked as unread"""
  70. thread = testutils.post_thread(self.category, started_on=timezone.now())
  71. post = testutils.reply_thread(thread, posted_on=timezone.now())
  72. poststracker.save_read(self.user, post)
  73. threadstracker.make_read_aware(self.user, self.user_acl, thread)
  74. self.assertFalse(thread.is_read)
  75. self.assertTrue(thread.is_new)
  76. def test_user_first_read_post_unread_event(self):
  77. """tracked thread with read first post and unread event"""
  78. thread = testutils.post_thread(self.category, started_on=timezone.now())
  79. poststracker.save_read(self.user, thread.first_post)
  80. testutils.reply_thread(thread, posted_on=timezone.now(), is_event=True)
  81. threadstracker.make_read_aware(self.user, self.user_acl, thread)
  82. self.assertFalse(thread.is_read)
  83. self.assertTrue(thread.is_new)
  84. def test_user_hidden_event(self):
  85. """tracked thread with unread first post and hidden event"""
  86. thread = testutils.post_thread(self.category, started_on=timezone.now())
  87. testutils.reply_thread(
  88. thread,
  89. posted_on=timezone.now(),
  90. is_event=True,
  91. is_hidden=True,
  92. )
  93. threadstracker.make_read_aware(self.user, self.user_acl, thread)
  94. self.assertFalse(thread.is_read)
  95. self.assertTrue(thread.is_new)
  96. def test_user_first_read_post_hidden_event(self):
  97. """tracked thread with read first post and hidden event"""
  98. thread = testutils.post_thread(self.category, started_on=timezone.now())
  99. poststracker.save_read(self.user, thread.first_post)
  100. testutils.reply_thread(
  101. thread,
  102. posted_on=timezone.now(),
  103. is_event=True,
  104. is_hidden=True,
  105. )
  106. threadstracker.make_read_aware(self.user, self.user_acl, thread)
  107. self.assertTrue(thread.is_read)
  108. self.assertFalse(thread.is_new)
  109. def test_user_thread_before_cutoff_unread_post(self):
  110. """non-tracked thread is marked as unread for anonymous users"""
  111. started_on = timezone.now() - timedelta(days=settings.MISAGO_READTRACKER_CUTOFF)
  112. thread = testutils.post_thread(self.category, started_on=started_on)
  113. threadstracker.make_read_aware(self.user, self.user_acl, thread)
  114. self.assertTrue(thread.is_read)
  115. self.assertFalse(thread.is_new)
  116. def test_user_first_read_post_unapproved_post(self):
  117. """tracked thread with read first post and unapproved post"""
  118. thread = testutils.post_thread(self.category, started_on=timezone.now())
  119. poststracker.save_read(self.user, thread.first_post)
  120. testutils.reply_thread(
  121. thread,
  122. posted_on=timezone.now(),
  123. is_unapproved=True,
  124. )
  125. threadstracker.make_read_aware(self.user, self.user_acl, thread)
  126. self.assertTrue(thread.is_read)
  127. self.assertFalse(thread.is_new)
  128. def test_user_first_read_post_unapproved_own_post(self):
  129. """tracked thread with read first post and unapproved own post"""
  130. thread = testutils.post_thread(self.category, started_on=timezone.now())
  131. poststracker.save_read(self.user, thread.first_post)
  132. testutils.reply_thread(
  133. thread,
  134. posted_on=timezone.now(),
  135. poster=self.user,
  136. is_unapproved=True,
  137. )
  138. threadstracker.make_read_aware(self.user, self.user_acl, thread)
  139. self.assertFalse(thread.is_read)
  140. self.assertTrue(thread.is_new)