test_threadslists_views.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. from misago.acl.testutils import override_acl
  2. from misago.categories.models import Category
  3. from misago.core import threadstore
  4. from misago.core.cache import cache
  5. from misago.users.testutils import AuthenticatedUserTestCase
  6. from misago.threads import testutils
  7. class ThreadsListTestCase(AuthenticatedUserTestCase):
  8. def setUp(self):
  9. super(ThreadsListTestCase, self).setUp()
  10. cache.clear()
  11. threadstore.clear()
  12. self.root = Category.objects.root_category()
  13. self.first_category = Category.objects.get(slug='first-category')
  14. """
  15. Create categories tree for test cases:
  16. First category (created by migration)
  17. Category A
  18. + Category B
  19. + Subcategory C
  20. + Subcategory D
  21. Category E
  22. + Subcategory F
  23. """
  24. Category(
  25. name='Category A',
  26. slug='category-a',
  27. ).insert_at(self.root, position='last-child', save=True)
  28. Category(
  29. name='Category E',
  30. slug='category-e',
  31. ).insert_at(self.root, position='last-child', save=True)
  32. self.root = Category.objects.root_category()
  33. self.category_a = Category.objects.get(slug='category-a')
  34. Category(
  35. name='Category B',
  36. slug='category-b',
  37. ).insert_at(self.category_a, position='last-child', save=True)
  38. self.category_b = Category.objects.get(slug='category-b')
  39. Category(
  40. name='Category C',
  41. slug='category-c',
  42. ).insert_at(self.category_b, position='last-child', save=True)
  43. Category(
  44. name='Category D',
  45. slug='category-d',
  46. ).insert_at(self.category_b, position='last-child', save=True)
  47. self.category_c = Category.objects.get(slug='category-c')
  48. self.category_d = Category.objects.get(slug='category-d')
  49. self.category_e = Category.objects.get(slug='category-e')
  50. Category(
  51. name='Category F',
  52. slug='category-f',
  53. ).insert_at(self.category_e, position='last-child', save=True)
  54. self.category_f = Category.objects.get(slug='category-f')
  55. cache.clear()
  56. threadstore.clear()
  57. self.access_all_categories()
  58. def access_all_categories(self):
  59. categories_acl = {'categories': {}, 'visible_categories': []}
  60. for category in Category.objects.all_categories():
  61. categories_acl['visible_categories'].append(category.pk)
  62. categories_acl['categories'][category.pk] = {
  63. 'can_see': 1,
  64. 'can_browse': 1,
  65. 'can_see_all_threads': 1,
  66. 'can_see_own_threads': 0,
  67. }
  68. override_acl(self.user, categories_acl)
  69. return categories_acl
  70. class ThreadsListTests(ThreadsListTestCase):
  71. def test_list_renders_empty(self):
  72. """empty threads list renders"""
  73. LISTS_URLS = (
  74. '/',
  75. '/my/',
  76. '/new/',
  77. '/unread/',
  78. '/subscribed/'
  79. )
  80. for url in LISTS_URLS:
  81. self.access_all_categories()
  82. response = self.client.get(url)
  83. self.assertEqual(response.status_code, 200)
  84. self.assertIn("empty-message", response.content)
  85. def test_list_authenticated_only_views(self):
  86. """authenticated only views return 403 for guests"""
  87. LISTS_URLS = (
  88. '/my/',
  89. '/new/',
  90. '/unread/',
  91. '/subscribed/'
  92. )
  93. self.logout_user()
  94. for url in LISTS_URLS:
  95. response = self.client.get(url)
  96. self.assertEqual(response.status_code, 403)
  97. def test_empty_list_hides_categories_picker(self):
  98. """categories picker is hidden on empty list"""
  99. Category(
  100. name='Hidden Category',
  101. slug='hidden-category',
  102. ).insert_at(self.root, position='last-child', save=True)
  103. test_category = Category.objects.get(slug='hidden-category')
  104. response = self.client.get('/')
  105. self.assertEqual(response.status_code, 200)
  106. self.assertNotIn(self.category_a.get_absolute_url(), response.content)
  107. self.assertNotIn(self.category_e.get_absolute_url(), response.content)
  108. def test_list_renders_categories_picker(self):
  109. """categories picker renders valid categories"""
  110. Category(
  111. name='Hidden Category',
  112. slug='hidden-category',
  113. ).insert_at(self.root, position='last-child', save=True)
  114. test_category = Category.objects.get(slug='hidden-category')
  115. testutils.post_thread(
  116. category=self.category_a,
  117. )
  118. response = self.client.get('/')
  119. self.assertEqual(response.status_code, 200)
  120. self.assertIn(self.category_a.get_absolute_url(), response.content)
  121. # readable categories, but non-accessible directly
  122. self.assertNotIn(self.category_b.get_absolute_url(), response.content)
  123. self.assertNotIn(self.category_c.get_absolute_url(), response.content)
  124. self.assertNotIn(self.category_d.get_absolute_url(), response.content)
  125. self.assertNotIn(self.category_f.get_absolute_url(), response.content)
  126. # hidden category
  127. self.assertNotIn(test_category.get_absolute_url(), response.content)
  128. def test_list_renders_test_thread(self):
  129. """list renders test thread with valid top category"""
  130. Category(
  131. name='Hidden Category',
  132. slug='hidden-category',
  133. ).insert_at(self.root, position='last-child', save=True)
  134. test_category = Category.objects.get(slug='hidden-category')
  135. test_thread = testutils.post_thread(
  136. category=self.category_c,
  137. )
  138. response = self.client.get('/')
  139. self.assertEqual(response.status_code, 200)
  140. self.assertIn(self.category_a.get_absolute_url(), response.content)
  141. self.assertIn(test_thread.get_absolute_url(), response.content)
  142. # other top category is hidden from user
  143. self.assertNotIn(self.category_e.get_absolute_url(), response.content)
  144. # real thread's category is hidden away from user
  145. self.assertNotIn(self.category_c.get_absolute_url(), response.content)
  146. def test_list_renders_hidden_thread(self):
  147. """list renders empty due to no permissions"""
  148. Category(
  149. name='Hidden Category',
  150. slug='hidden-category',
  151. ).insert_at(self.root, position='last-child', save=True)
  152. test_category = Category.objects.get(slug='hidden-category')
  153. test_thread = testutils.post_thread(
  154. category=test_category,
  155. )
  156. response = self.client.get('/')
  157. self.assertEqual(response.status_code, 200)
  158. self.assertIn("empty-message", response.content)
  159. class CategoryThreadsListTests(ThreadsListTestCase):
  160. def test_list_renders_empty(self):
  161. """empty threads list renders"""
  162. LISTS_URLS = (
  163. '',
  164. 'my/',
  165. 'new/',
  166. 'unread/',
  167. 'subscribed/'
  168. )
  169. for url in LISTS_URLS:
  170. self.access_all_categories()
  171. response = self.client.get(self.category_b.get_absolute_url() + url)
  172. self.assertEqual(response.status_code, 200)
  173. self.assertIn(self.category_b.name, response.content)
  174. self.assertIn("empty-message", response.content)
  175. def test_access_hidden_category(self):
  176. """hidden category returns 404"""
  177. Category(
  178. name='Hidden Category',
  179. slug='hidden-category',
  180. ).insert_at(self.root, position='last-child', save=True)
  181. test_category = Category.objects.get(slug='hidden-category')
  182. LISTS_URLS = (
  183. '',
  184. 'my/',
  185. 'new/',
  186. 'unread/',
  187. 'subscribed/'
  188. )
  189. for url in LISTS_URLS:
  190. response = self.client.get(test_category.get_absolute_url() + url)
  191. self.assertEqual(response.status_code, 404)
  192. def test_access_protected_category(self):
  193. """protected category returns 403"""
  194. Category(
  195. name='Hidden Category',
  196. slug='hidden-category',
  197. ).insert_at(self.root, position='last-child', save=True)
  198. test_category = Category.objects.get(slug='hidden-category')
  199. LISTS_URLS = (
  200. '',
  201. 'my/',
  202. 'new/',
  203. 'unread/',
  204. 'subscribed/'
  205. )
  206. for url in LISTS_URLS:
  207. override_acl(self.user, {
  208. 'visible_categories': [test_category.pk],
  209. 'categories': {
  210. test_category.pk: {
  211. 'can_see': 1,
  212. 'can_browse': 0,
  213. }
  214. }
  215. });
  216. response = self.client.get(test_category.get_absolute_url() + url)
  217. self.assertEqual(response.status_code, 403)