test_privatethreads_api.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. from django.urls import reverse
  2. from .. import test
  3. from ...acl.test import patch_user_acl
  4. from ..models import Thread, ThreadParticipant
  5. from ..test import patch_private_threads_acl
  6. from .test_privatethreads import PrivateThreadsTestCase
  7. class PrivateThreadsListApiTests(PrivateThreadsTestCase):
  8. def setUp(self):
  9. super().setUp()
  10. self.api_link = reverse("misago:api:private-thread-list")
  11. def test_unauthenticated(self):
  12. """api requires user to sign in and be able to access it"""
  13. self.logout_user()
  14. response = self.client.get(self.api_link)
  15. self.assertEqual(response.status_code, 403)
  16. self.assertEqual(
  17. response.json(), {"detail": "You have to sign in to use private threads."}
  18. )
  19. @patch_user_acl({"can_use_private_threads": False})
  20. def test_no_permission(self):
  21. """api requires user to have permission to be able to access it"""
  22. response = self.client.get(self.api_link)
  23. self.assertEqual(response.status_code, 403)
  24. self.assertEqual(response.json(), {"detail": "You can't use private threads."})
  25. @patch_user_acl({"can_use_private_threads": True})
  26. def test_empty_list(self):
  27. """api has no showstoppers on returning empty list"""
  28. response = self.client.get(self.api_link)
  29. self.assertEqual(response.status_code, 200)
  30. response_json = response.json()
  31. self.assertEqual(len(response_json["results"]), 0)
  32. @patch_user_acl({"can_use_private_threads": True})
  33. def test_thread_visibility(self):
  34. """only participated threads are returned by private threads api"""
  35. visible = test.post_thread(category=self.category, poster=self.user)
  36. reported = test.post_thread(category=self.category, poster=self.user)
  37. # hidden thread
  38. test.post_thread(category=self.category, poster=self.user)
  39. ThreadParticipant.objects.add_participants(visible, [self.user])
  40. reported.has_reported_posts = True
  41. reported.save()
  42. response = self.client.get(self.api_link)
  43. self.assertEqual(response.status_code, 200)
  44. response_json = response.json()
  45. self.assertEqual(len(response_json["results"]), 1)
  46. self.assertEqual(response_json["results"][0]["id"], visible.id)
  47. # threads with reported posts will also show to moderators
  48. with patch_user_acl({"can_moderate_private_threads": True}):
  49. response = self.client.get(self.api_link)
  50. self.assertEqual(response.status_code, 200)
  51. response_json = response.json()
  52. self.assertEqual(len(response_json["results"]), 2)
  53. self.assertEqual(response_json["results"][0]["id"], reported.id)
  54. self.assertEqual(response_json["results"][1]["id"], visible.id)
  55. class PrivateThreadRetrieveApiTests(PrivateThreadsTestCase):
  56. def setUp(self):
  57. super().setUp()
  58. self.thread = test.post_thread(self.category, poster=self.user)
  59. self.api_link = self.thread.get_api_url()
  60. def test_anonymous(self):
  61. """anonymous user can't see private thread"""
  62. self.logout_user()
  63. response = self.client.get(self.api_link)
  64. self.assertEqual(response.status_code, 403)
  65. self.assertEqual(
  66. response.json(), {"detail": "You have to sign in to use private threads."}
  67. )
  68. @patch_user_acl({"can_use_private_threads": False})
  69. def test_no_permission(self):
  70. """user needs to have permission to see private thread"""
  71. response = self.client.get(self.api_link)
  72. self.assertEqual(response.status_code, 403)
  73. self.assertEqual(response.json(), {"detail": "You can't use private threads."})
  74. @patch_user_acl({"can_use_private_threads": True})
  75. def test_no_participant(self):
  76. """user cant see thread he isn't part of"""
  77. response = self.client.get(self.api_link)
  78. self.assertEqual(response.status_code, 404)
  79. @patch_user_acl(
  80. {"can_use_private_threads": True, "can_moderate_private_threads": True}
  81. )
  82. def test_mod_not_reported(self):
  83. """moderator can't see private thread that has no reports"""
  84. response = self.client.get(self.api_link)
  85. self.assertEqual(response.status_code, 404)
  86. @patch_user_acl(
  87. {"can_use_private_threads": True, "can_moderate_private_threads": False}
  88. )
  89. def test_reported_not_mod(self):
  90. """non-mod can't see private thread that has reported posts"""
  91. self.thread.has_reported_posts = True
  92. self.thread.save()
  93. response = self.client.get(self.api_link)
  94. self.assertEqual(response.status_code, 404)
  95. @patch_user_acl({"can_use_private_threads": True})
  96. def test_can_see_owner(self):
  97. """user can see thread he is owner of"""
  98. ThreadParticipant.objects.set_owner(self.thread, self.user)
  99. response = self.client.get(self.api_link)
  100. self.assertEqual(response.status_code, 200)
  101. response_json = response.json()
  102. self.assertEqual(response_json["title"], self.thread.title)
  103. self.assertEqual(
  104. response_json["participants"],
  105. [
  106. {
  107. "id": self.user.id,
  108. "username": self.user.username,
  109. "avatars": self.user.avatars,
  110. "url": self.user.get_absolute_url(),
  111. "is_owner": True,
  112. }
  113. ],
  114. )
  115. @patch_user_acl({"can_use_private_threads": True})
  116. def test_can_see_participant(self):
  117. """user can see thread he is participant of"""
  118. ThreadParticipant.objects.add_participants(self.thread, [self.user])
  119. response = self.client.get(self.api_link)
  120. self.assertEqual(response.status_code, 200)
  121. response_json = response.json()
  122. self.assertEqual(response_json["title"], self.thread.title)
  123. self.assertEqual(
  124. response_json["participants"],
  125. [
  126. {
  127. "id": self.user.id,
  128. "username": self.user.username,
  129. "avatars": self.user.avatars,
  130. "url": self.user.get_absolute_url(),
  131. "is_owner": False,
  132. }
  133. ],
  134. )
  135. @patch_user_acl(
  136. {"can_use_private_threads": True, "can_moderate_private_threads": True}
  137. )
  138. def test_mod_can_see_reported(self):
  139. """moderator can see private thread that has reports"""
  140. self.thread.has_reported_posts = True
  141. self.thread.save()
  142. response = self.client.get(self.api_link)
  143. self.assertEqual(response.status_code, 200)
  144. response_json = response.json()
  145. self.assertEqual(response_json["title"], self.thread.title)
  146. self.assertEqual(response_json["participants"], [])
  147. class PrivateThreadDeleteApiTests(PrivateThreadsTestCase):
  148. def setUp(self):
  149. super().setUp()
  150. self.thread = test.post_thread(self.category, poster=self.user)
  151. self.api_link = self.thread.get_api_url()
  152. ThreadParticipant.objects.add_participants(self.thread, [self.user])
  153. @patch_private_threads_acl({"can_hide_threads": 0})
  154. def test_hide_thread_no_permission(self):
  155. """api tests permission to delete threads"""
  156. response = self.client.delete(self.api_link)
  157. self.assertEqual(response.status_code, 403)
  158. self.assertEqual(
  159. response.json()["detail"], "You can't delete threads in this category."
  160. )
  161. @patch_private_threads_acl({"can_hide_threads": 1})
  162. def test_delete_thread_no_permission(self):
  163. """api tests permission to delete threads"""
  164. response = self.client.delete(self.api_link)
  165. self.assertEqual(response.status_code, 403)
  166. self.assertEqual(
  167. response.json()["detail"], "You can't delete threads in this category."
  168. )
  169. @patch_private_threads_acl({"can_hide_threads": 2})
  170. def test_delete_thread(self):
  171. """DELETE to API link with permission deletes thread"""
  172. response = self.client.delete(self.api_link)
  173. self.assertEqual(response.status_code, 200)
  174. with self.assertRaises(Thread.DoesNotExist):
  175. Thread.objects.get(pk=self.thread.pk)