test_threadslists.py 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530
  1. from datetime import timedelta
  2. from json import loads as json_loads
  3. from django.conf import settings
  4. from django.utils import timezone
  5. from misago.acl.testutils import override_acl
  6. from misago.categories.models import Category
  7. from misago.core import threadstore
  8. from misago.core.cache import cache
  9. from misago.readtracker import categoriestracker, threadstracker
  10. from misago.users.testutils import AuthenticatedUserTestCase
  11. from misago.threads import testutils
  12. LISTS_URLS = (
  13. '',
  14. 'my/',
  15. 'new/',
  16. 'unread/',
  17. 'subscribed/',
  18. )
  19. class ThreadsListTestCase(AuthenticatedUserTestCase):
  20. def setUp(self):
  21. super(ThreadsListTestCase, self).setUp()
  22. self.api_link = '/api/threads/'
  23. self.root = Category.objects.root_category()
  24. self.first_category = Category.objects.get(slug='first-category')
  25. """
  26. Create categories tree for test cases:
  27. First category (created by migration)
  28. Category A
  29. + Category B
  30. + Subcategory C
  31. + Subcategory D
  32. Category E
  33. + Subcategory F
  34. """
  35. Category(
  36. name='Category A',
  37. slug='category-a',
  38. css_class='showing-category-a',
  39. ).insert_at(self.root, position='last-child', save=True)
  40. Category(
  41. name='Category E',
  42. slug='category-e',
  43. css_class='showing-category-e',
  44. ).insert_at(self.root, position='last-child', save=True)
  45. self.root = Category.objects.root_category()
  46. self.category_a = Category.objects.get(slug='category-a')
  47. Category(
  48. name='Category B',
  49. slug='category-b',
  50. css_class='showing-category-b',
  51. ).insert_at(self.category_a, position='last-child', save=True)
  52. self.category_b = Category.objects.get(slug='category-b')
  53. Category(
  54. name='Category C',
  55. slug='category-c',
  56. css_class='showing-category-c',
  57. ).insert_at(self.category_b, position='last-child', save=True)
  58. Category(
  59. name='Category D',
  60. slug='category-d',
  61. css_class='showing-category-d',
  62. ).insert_at(self.category_b, position='last-child', save=True)
  63. self.category_c = Category.objects.get(slug='category-c')
  64. self.category_d = Category.objects.get(slug='category-d')
  65. self.category_e = Category.objects.get(slug='category-e')
  66. Category(
  67. name='Category F',
  68. slug='category-f',
  69. css_class='showing-category-f',
  70. ).insert_at(self.category_e, position='last-child', save=True)
  71. self.category_f = Category.objects.get(slug='category-f')
  72. self.clear_state()
  73. Category.objects.partial_rebuild(self.root.tree_id)
  74. self.root = Category.objects.root_category()
  75. self.category_a = Category.objects.get(slug='category-a')
  76. self.category_b = Category.objects.get(slug='category-b')
  77. self.category_c = Category.objects.get(slug='category-c')
  78. self.category_d = Category.objects.get(slug='category-d')
  79. self.category_e = Category.objects.get(slug='category-e')
  80. self.category_f = Category.objects.get(slug='category-f')
  81. self.access_all_categories()
  82. def access_all_categories(self, extra=None):
  83. self.clear_state()
  84. categories_acl = {
  85. 'categories': {},
  86. 'visible_categories': [],
  87. 'can_approve_content': [],
  88. }
  89. for category in Category.objects.all_categories(include_root=True):
  90. categories_acl['visible_categories'].append(category.pk)
  91. categories_acl['categories'][category.pk] = {
  92. 'can_see': 1,
  93. 'can_browse': 1,
  94. 'can_see_all_threads': 1,
  95. 'can_see_own_threads': 0,
  96. 'can_hide_threads': 0,
  97. 'can_approve_content': 0,
  98. }
  99. if extra:
  100. categories_acl['categories'][category.pk].update(extra)
  101. if extra.get('can_approve_content'):
  102. categories_acl['can_approve_content'].append(category.pk)
  103. override_acl(self.user, categories_acl)
  104. return categories_acl
  105. class AllThreadsListTests(ThreadsListTestCase):
  106. def test_list_renders_empty(self):
  107. """empty threads list renders"""
  108. for url in LISTS_URLS:
  109. self.access_all_categories()
  110. response = self.client.get('/' + url)
  111. self.assertEqual(response.status_code, 200)
  112. self.assertIn("empty-message", response.content)
  113. self.access_all_categories()
  114. response = self.client.get(self.category_b.get_absolute_url() + url)
  115. self.assertEqual(response.status_code, 200)
  116. self.assertIn(self.category_b.name, response.content)
  117. self.assertIn("empty-message", response.content)
  118. self.access_all_categories()
  119. response = self.client.get(
  120. '%s?list=%s' % (self.api_link, url.strip('/')))
  121. self.assertEqual(response.status_code, 200)
  122. response_json = json_loads(response.content)
  123. self.assertEqual(len(response_json['results']), 0)
  124. def test_list_authenticated_only_views(self):
  125. """authenticated only views return 403 for guests"""
  126. for url in LISTS_URLS:
  127. self.access_all_categories()
  128. response = self.client.get('/' + url)
  129. self.assertEqual(response.status_code, 200)
  130. self.access_all_categories()
  131. response = self.client.get(self.category_b.get_absolute_url() + url)
  132. self.assertEqual(response.status_code, 200)
  133. self.assertIn(self.category_b.name, response.content)
  134. self.access_all_categories()
  135. self.access_all_categories()
  136. response = self.client.get('%s?category=%s&list=%s' % (
  137. self.api_link,
  138. self.category_b.pk,
  139. url.strip('/'),
  140. ))
  141. self.assertEqual(response.status_code, 200)
  142. self.logout_user()
  143. self.user = self.get_anonymous_user()
  144. for url in LISTS_URLS[1:]:
  145. self.access_all_categories()
  146. response = self.client.get('/' + url)
  147. self.assertEqual(response.status_code, 403)
  148. self.access_all_categories()
  149. response = self.client.get(self.category_b.get_absolute_url() + url)
  150. self.assertEqual(response.status_code, 403)
  151. self.access_all_categories()
  152. response = self.client.get('%s?category=%s&list=%s' % (
  153. self.api_link,
  154. self.category_b.pk,
  155. url.strip('/'),
  156. ))
  157. self.assertEqual(response.status_code, 403)
  158. def test_empty_list_hides_categories_picker(self):
  159. """categories picker is hidden on empty list"""
  160. Category(
  161. name='Hidden Category',
  162. slug='hidden-category',
  163. ).insert_at(self.root, position='last-child', save=True)
  164. test_category = Category.objects.get(slug='hidden-category')
  165. self.access_all_categories()
  166. response = self.client.get('/')
  167. self.assertEqual(response.status_code, 200)
  168. self.assertNotIn(
  169. 'subcategory-%s' % self.category_a.css_class, response.content)
  170. self.assertNotIn(
  171. 'subcategory-%s' % self.category_e.css_class, response.content)
  172. self.access_all_categories()
  173. response = self.client.get(self.category_a.get_absolute_url())
  174. self.assertEqual(response.status_code, 200)
  175. self.assertNotIn(
  176. 'subcategory-%s' % self.category_b.css_class, response.content)
  177. self.access_all_categories()
  178. response = self.client.get(self.api_link)
  179. self.assertEqual(response.status_code, 200)
  180. response_json = json_loads(response.content)
  181. self.assertEqual(len(response_json['subcategories']), 0)
  182. def test_list_renders_categories_picker(self):
  183. """categories picker renders valid categories"""
  184. Category(
  185. name='Hidden Category',
  186. slug='hidden-category',
  187. ).insert_at(self.root, position='last-child', save=True)
  188. test_category = Category.objects.get(slug='hidden-category')
  189. testutils.post_thread(
  190. category=self.category_b,
  191. )
  192. response = self.client.get('/')
  193. self.assertEqual(response.status_code, 200)
  194. self.assertIn(
  195. 'subcategory-%s' % self.category_a.css_class, response.content)
  196. # readable categories, but non-accessible directly
  197. self.assertNotIn(
  198. 'subcategory-%s' % self.category_b.css_class, response.content)
  199. self.assertNotIn(
  200. 'subcategory-%s' % self.category_c.css_class, response.content)
  201. self.assertNotIn(
  202. 'subcategory-%s' % self.category_d.css_class, response.content)
  203. self.assertNotIn(
  204. 'subcategory-%s' % self.category_f.css_class, response.content)
  205. # hidden category
  206. self.assertNotIn(
  207. 'subcategory-%s' % test_category.css_class, response.content)
  208. self.access_all_categories()
  209. response = self.client.get(self.api_link)
  210. self.assertEqual(response.status_code, 200)
  211. response_json = json_loads(response.content)
  212. self.assertEqual(
  213. response_json['subcategories'][0], self.category_a.pk)
  214. # test category view
  215. self.access_all_categories()
  216. response = self.client.get(self.category_a.get_absolute_url())
  217. self.assertEqual(response.status_code, 200)
  218. self.assertIn(
  219. 'subcategory-%s' % self.category_b.css_class, response.content)
  220. # readable categories, but non-accessible directly
  221. self.assertNotIn(
  222. 'subcategory-%s' % self.category_c.css_class, response.content)
  223. self.assertNotIn(
  224. 'subcategory-%s' % self.category_d.css_class, response.content)
  225. self.assertNotIn(
  226. 'subcategory-%s' % self.category_f.css_class, response.content)
  227. self.access_all_categories()
  228. response = self.client.get(
  229. '%s?category=%s' % (self.api_link, self.category_a.pk))
  230. self.assertEqual(response.status_code, 200)
  231. response_json = json_loads(response.content)
  232. self.assertEqual(
  233. response_json['subcategories'][0], self.category_b.pk)
  234. def test_display_pinned_threads(self):
  235. """
  236. threads list displays globally pinned threads first
  237. and locally ones inbetween other
  238. """
  239. globally = testutils.post_thread(
  240. category=self.first_category,
  241. is_global=True,
  242. )
  243. locally = testutils.post_thread(
  244. category=self.first_category,
  245. is_pinned=True,
  246. )
  247. standard = testutils.post_thread(category=self.first_category)
  248. response = self.client.get('/')
  249. self.assertEqual(response.status_code, 200)
  250. positions = {
  251. 'g': response.content.find(globally.get_absolute_url()),
  252. 'l': response.content.find(locally.get_absolute_url()),
  253. 's': response.content.find(standard.get_absolute_url()),
  254. }
  255. # global announcement before others
  256. self.assertTrue(positions['g'] < positions['l'])
  257. self.assertTrue(positions['g'] < positions['s'])
  258. # standard in the middle
  259. self.assertTrue(positions['s'] < positions['l'])
  260. self.assertTrue(positions['s'] > positions['g'])
  261. # pinned last
  262. self.assertTrue(positions['l'] > positions['g'])
  263. self.assertTrue(positions['l'] > positions['s'])
  264. # API behaviour is identic
  265. response = self.client.get('/api/threads/')
  266. self.assertEqual(response.status_code, 200)
  267. positions = {
  268. 'g': response.content.find(globally.get_absolute_url()),
  269. 'l': response.content.find(locally.get_absolute_url()),
  270. 's': response.content.find(standard.get_absolute_url()),
  271. }
  272. # global announcement before others
  273. self.assertTrue(positions['g'] < positions['l'])
  274. self.assertTrue(positions['g'] < positions['s'])
  275. # standard in the middle
  276. self.assertTrue(positions['s'] < positions['l'])
  277. self.assertTrue(positions['s'] > positions['g'])
  278. # pinned last
  279. self.assertTrue(positions['l'] > positions['g'])
  280. self.assertTrue(positions['l'] > positions['s'])
  281. class CategoryThreadsListTests(ThreadsListTestCase):
  282. def test_access_hidden_category(self):
  283. """hidden category returns 404"""
  284. Category(
  285. name='Hidden Category',
  286. slug='hidden-category',
  287. ).insert_at(self.root, position='last-child', save=True)
  288. test_category = Category.objects.get(slug='hidden-category')
  289. for url in LISTS_URLS:
  290. response = self.client.get(test_category.get_absolute_url() + url)
  291. self.assertEqual(response.status_code, 404)
  292. response = self.client.get(
  293. '%s?category=%s' % (self.api_link, test_category.pk))
  294. self.assertEqual(response.status_code, 404)
  295. def test_access_protected_category(self):
  296. """protected category returns 403"""
  297. Category(
  298. name='Hidden Category',
  299. slug='hidden-category',
  300. ).insert_at(self.root, position='last-child', save=True)
  301. test_category = Category.objects.get(slug='hidden-category')
  302. for url in LISTS_URLS:
  303. override_acl(self.user, {
  304. 'visible_categories': [test_category.pk],
  305. 'categories': {
  306. test_category.pk: {
  307. 'can_see': 1,
  308. 'can_browse': 0,
  309. }
  310. }
  311. });
  312. response = self.client.get(test_category.get_absolute_url() + url)
  313. self.assertEqual(response.status_code, 403)
  314. override_acl(self.user, {
  315. 'visible_categories': [test_category.pk],
  316. 'categories': {
  317. test_category.pk: {
  318. 'can_see': 1,
  319. 'can_browse': 0,
  320. }
  321. }
  322. });
  323. response = self.client.get('%s?category=%s&list=%s' % (
  324. self.api_link,
  325. test_category.pk,
  326. url.strip('/'),
  327. ))
  328. self.assertEqual(response.status_code, 403)
  329. def test_display_pinned_threads(self):
  330. """
  331. category threads list displays globally pinned threads first
  332. then locally ones and unpinned last
  333. """
  334. globally = testutils.post_thread(
  335. category=self.first_category,
  336. is_global=True,
  337. )
  338. locally = testutils.post_thread(
  339. category=self.first_category,
  340. is_pinned=True,
  341. )
  342. standard = testutils.post_thread(category=self.first_category)
  343. response = self.client.get(self.first_category.get_absolute_url())
  344. self.assertEqual(response.status_code, 200)
  345. positions = {
  346. 'g': response.content.find(globally.get_absolute_url()),
  347. 'l': response.content.find(locally.get_absolute_url()),
  348. 's': response.content.find(standard.get_absolute_url()),
  349. }
  350. # global announcement before others
  351. self.assertTrue(positions['g'] < positions['l'])
  352. self.assertTrue(positions['g'] < positions['s'])
  353. # pinned in the middle
  354. self.assertTrue(positions['l'] < positions['s'])
  355. self.assertTrue(positions['l'] > positions['g'])
  356. # standard last
  357. self.assertTrue(positions['s'] > positions['g'])
  358. self.assertTrue(positions['s'] > positions['g'])
  359. # API behaviour is identic
  360. response = self.client.get(
  361. '/api/threads/?category=%s' % self.first_category.pk)
  362. self.assertEqual(response.status_code, 200)
  363. positions = {
  364. 'g': response.content.find(globally.get_absolute_url()),
  365. 'l': response.content.find(locally.get_absolute_url()),
  366. 's': response.content.find(standard.get_absolute_url()),
  367. }
  368. # global announcement before others
  369. self.assertTrue(positions['g'] < positions['l'])
  370. self.assertTrue(positions['g'] < positions['s'])
  371. # pinned in the middle
  372. self.assertTrue(positions['l'] < positions['s'])
  373. self.assertTrue(positions['l'] > positions['g'])
  374. # standard last
  375. self.assertTrue(positions['s'] > positions['g'])
  376. self.assertTrue(positions['s'] > positions['g'])
  377. class ThreadsVisibilityTests(ThreadsListTestCase):
  378. def test_list_renders_test_thread(self):
  379. """list renders test thread with valid top category"""
  380. test_thread = testutils.post_thread(
  381. category=self.category_c,
  382. )
  383. response = self.client.get('/')
  384. self.assertEqual(response.status_code, 200)
  385. self.assertIn(test_thread.get_absolute_url(), response.content)
  386. self.assertIn(
  387. 'subcategory-%s' % self.category_a.css_class, response.content)
  388. self.assertIn(
  389. 'thread-category-%s' % self.category_a.css_class, response.content)
  390. self.assertIn(
  391. 'thread-category-%s' % self.category_c.css_class, response.content)
  392. # other top category is hidden from user
  393. self.assertNotIn(
  394. 'subcategory-%s' % self.category_e.css_class, response.content)
  395. # api displays same data
  396. self.access_all_categories()
  397. response = self.client.get(self.api_link)
  398. self.assertEqual(response.status_code, 200)
  399. response_json = json_loads(response.content)
  400. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  401. self.assertEqual(len(response_json['subcategories']), 1)
  402. self.assertEqual(
  403. response_json['subcategories'][0], self.category_a.pk)
  404. # test category view
  405. self.access_all_categories()
  406. response = self.client.get(self.category_b.get_absolute_url())
  407. self.assertEqual(response.status_code, 200)
  408. # thread displays
  409. self.assertIn(test_thread.get_absolute_url(), response.content)
  410. self.assertNotIn(
  411. 'thread-category-%s' % self.category_b.css_class, response.content)
  412. self.assertIn(
  413. 'thread-category-%s' % self.category_c.css_class, response.content)
  414. # category picker was changed
  415. self.assertIn(
  416. 'subcategory-%s' % self.category_c.css_class, response.content)
  417. self.assertNotIn(
  418. 'subcategory-%s' % self.category_d.css_class, response.content)
  419. # api displays same data
  420. self.access_all_categories()
  421. response = self.client.get(
  422. '%s?category=%s' % (self.api_link, self.category_b.pk))
  423. self.assertEqual(response.status_code, 200)
  424. response_json = json_loads(response.content)
  425. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  426. self.assertEqual(len(response_json['subcategories']), 1)
  427. self.assertEqual(
  428. response_json['subcategories'][0], self.category_c.pk)
  429. def test_list_hides_hidden_thread(self):
  430. """list renders empty due to no permission to see thread"""
  431. Category(
  432. name='Hidden Category',
  433. slug='hidden-category',
  434. ).insert_at(self.root, position='last-child', save=True)
  435. test_category = Category.objects.get(slug='hidden-category')
  436. test_thread = testutils.post_thread(
  437. category=test_category,
  438. )
  439. response = self.client.get('/')
  440. self.assertEqual(response.status_code, 200)
  441. self.assertIn("empty-message", response.content)
  442. def test_api_hides_hidden_thread(self):
  443. """api returns empty due to no permission to see thread"""
  444. Category(
  445. name='Hidden Category',
  446. slug='hidden-category',
  447. ).insert_at(self.root, position='last-child', save=True)
  448. test_category = Category.objects.get(slug='hidden-category')
  449. test_thread = testutils.post_thread(
  450. category=test_category,
  451. )
  452. response = self.client.get(self.api_link)
  453. self.assertEqual(response.status_code, 200)
  454. response_json = json_loads(response.content)
  455. self.assertEqual(len(response_json['results']), 0)
  456. def test_list_user_see_own_unapproved_thread(self):
  457. """list renders unapproved thread that belongs to viewer"""
  458. test_thread = testutils.post_thread(
  459. category=self.category_a,
  460. poster=self.user,
  461. is_unapproved=True,
  462. )
  463. response = self.client.get('/')
  464. self.assertEqual(response.status_code, 200)
  465. self.assertIn(test_thread.get_absolute_url(), response.content)
  466. # test api
  467. self.access_all_categories()
  468. response = self.client.get(self.api_link)
  469. self.assertEqual(response.status_code, 200)
  470. response_json = json_loads(response.content)
  471. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  472. def test_list_user_cant_see_unapproved_thread(self):
  473. """list hides unapproved thread that belongs to other user"""
  474. test_thread = testutils.post_thread(
  475. category=self.category_a,
  476. is_unapproved=True,
  477. )
  478. response = self.client.get('/')
  479. self.assertEqual(response.status_code, 200)
  480. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  481. # test api
  482. self.access_all_categories()
  483. response = self.client.get(self.api_link)
  484. self.assertEqual(response.status_code, 200)
  485. response_json = json_loads(response.content)
  486. self.assertEqual(len(response_json['results']), 0)
  487. def test_list_user_cant_see_hidden_thread(self):
  488. """list hides hidden thread that belongs to other user"""
  489. test_thread = testutils.post_thread(
  490. category=self.category_a,
  491. is_hidden=True,
  492. )
  493. response = self.client.get('/')
  494. self.assertEqual(response.status_code, 200)
  495. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  496. # test api
  497. self.access_all_categories()
  498. response = self.client.get(self.api_link)
  499. self.assertEqual(response.status_code, 200)
  500. response_json = json_loads(response.content)
  501. self.assertEqual(len(response_json['results']), 0)
  502. def test_list_user_cant_see_own_hidden_thread(self):
  503. """list hides hidden thread that belongs to viewer"""
  504. test_thread = testutils.post_thread(
  505. category=self.category_a,
  506. poster=self.user,
  507. is_hidden=True,
  508. )
  509. response = self.client.get('/')
  510. self.assertEqual(response.status_code, 200)
  511. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  512. # test api
  513. self.access_all_categories()
  514. response = self.client.get(self.api_link)
  515. self.assertEqual(response.status_code, 200)
  516. response_json = json_loads(response.content)
  517. self.assertEqual(len(response_json['results']), 0)
  518. def test_list_user_can_see_own_hidden_thread(self):
  519. """list shows hidden thread that belongs to viewer due to permission"""
  520. test_thread = testutils.post_thread(
  521. category=self.category_a,
  522. poster=self.user,
  523. is_hidden=True,
  524. )
  525. self.access_all_categories({
  526. 'can_hide_threads': 1
  527. })
  528. response = self.client.get('/')
  529. self.assertEqual(response.status_code, 200)
  530. self.assertIn(test_thread.get_absolute_url(), response.content)
  531. # test api
  532. self.access_all_categories({
  533. 'can_hide_threads': 1
  534. })
  535. response = self.client.get(self.api_link)
  536. self.assertEqual(response.status_code, 200)
  537. response_json = json_loads(response.content)
  538. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  539. def test_list_user_can_see_hidden_thread(self):
  540. """
  541. list shows hidden thread that belongs to other user due to permission
  542. """
  543. test_thread = testutils.post_thread(
  544. category=self.category_a,
  545. is_hidden=True,
  546. )
  547. self.access_all_categories({
  548. 'can_hide_threads': 1
  549. })
  550. response = self.client.get('/')
  551. self.assertEqual(response.status_code, 200)
  552. self.assertIn(test_thread.get_absolute_url(), response.content)
  553. # test api
  554. self.access_all_categories({
  555. 'can_hide_threads': 1
  556. })
  557. response = self.client.get(self.api_link)
  558. self.assertEqual(response.status_code, 200)
  559. response_json = json_loads(response.content)
  560. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  561. def test_list_user_can_see_unapproved_thread(self):
  562. """
  563. list shows hidden thread that belongs to other user due to permission
  564. """
  565. test_thread = testutils.post_thread(
  566. category=self.category_a,
  567. is_unapproved=True,
  568. )
  569. self.access_all_categories({
  570. 'can_approve_content': 1
  571. })
  572. response = self.client.get('/')
  573. self.assertEqual(response.status_code, 200)
  574. self.assertIn(test_thread.get_absolute_url(), response.content)
  575. # test api
  576. self.access_all_categories({
  577. 'can_approve_content': 1
  578. })
  579. response = self.client.get(self.api_link)
  580. self.assertEqual(response.status_code, 200)
  581. response_json = json_loads(response.content)
  582. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  583. class MyThreadsListTests(ThreadsListTestCase):
  584. def test_list_renders_empty(self):
  585. """list renders empty"""
  586. self.access_all_categories()
  587. response = self.client.get('/my/')
  588. self.assertEqual(response.status_code, 200)
  589. self.assertIn("empty-message", response.content)
  590. self.access_all_categories()
  591. response = self.client.get(self.category_a.get_absolute_url() + 'my/')
  592. self.assertEqual(response.status_code, 200)
  593. self.assertIn("empty-message", response.content)
  594. # test api
  595. self.access_all_categories()
  596. response = self.client.get('%s?list=my' % self.api_link)
  597. self.assertEqual(response.status_code, 200)
  598. response_json = json_loads(response.content)
  599. self.assertEqual(len(response_json['results']), 0)
  600. self.access_all_categories()
  601. response = self.client.get(
  602. '%s?list=my&category=%s' % (self.api_link, self.category_a.pk))
  603. response_json = json_loads(response.content)
  604. self.assertEqual(len(response_json['results']), 0)
  605. def test_list_renders_test_thread(self):
  606. """list renders only threads posted by user"""
  607. test_thread = testutils.post_thread(
  608. category=self.category_a,
  609. poster=self.user,
  610. )
  611. other_thread = testutils.post_thread(
  612. category=self.category_a,
  613. )
  614. self.access_all_categories()
  615. response = self.client.get('/my/')
  616. self.assertEqual(response.status_code, 200)
  617. self.assertIn(test_thread.get_absolute_url(), response.content)
  618. self.assertNotIn(other_thread.get_absolute_url(), response.content)
  619. self.access_all_categories()
  620. response = self.client.get(self.category_a.get_absolute_url() + 'my/')
  621. self.assertEqual(response.status_code, 200)
  622. self.assertIn(test_thread.get_absolute_url(), response.content)
  623. self.assertNotIn(other_thread.get_absolute_url(), response.content)
  624. # test api
  625. self.access_all_categories()
  626. response = self.client.get('%s?list=my' % self.api_link)
  627. self.assertEqual(response.status_code, 200)
  628. response_json = json_loads(response.content)
  629. self.assertEqual(len(response_json['results']), 1)
  630. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  631. self.access_all_categories()
  632. response = self.client.get(
  633. '%s?list=my&category=%s' % (self.api_link, self.category_a.pk))
  634. self.assertEqual(response.status_code, 200)
  635. response_json = json_loads(response.content)
  636. self.assertEqual(len(response_json['results']), 1)
  637. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  638. class NewThreadsListTests(ThreadsListTestCase):
  639. def test_list_renders_empty(self):
  640. """list renders empty"""
  641. self.access_all_categories()
  642. response = self.client.get('/new/')
  643. self.assertEqual(response.status_code, 200)
  644. self.assertIn("empty-message", response.content)
  645. self.access_all_categories()
  646. response = self.client.get(self.category_a.get_absolute_url() + 'new/')
  647. self.assertEqual(response.status_code, 200)
  648. self.assertIn("empty-message", response.content)
  649. # test api
  650. self.access_all_categories()
  651. response = self.client.get('%s?list=new' % self.api_link)
  652. self.assertEqual(response.status_code, 200)
  653. response_json = json_loads(response.content)
  654. self.assertEqual(len(response_json['results']), 0)
  655. self.access_all_categories()
  656. response = self.client.get(
  657. '%s?list=new&category=%s' % (self.api_link, self.category_a.pk))
  658. response_json = json_loads(response.content)
  659. self.assertEqual(len(response_json['results']), 0)
  660. def test_list_renders_new_thread(self):
  661. """list renders new thread"""
  662. test_thread = testutils.post_thread(
  663. category=self.category_a,
  664. )
  665. self.access_all_categories()
  666. response = self.client.get('/new/')
  667. self.assertEqual(response.status_code, 200)
  668. self.assertIn(test_thread.get_absolute_url(), response.content)
  669. self.access_all_categories()
  670. response = self.client.get(self.category_a.get_absolute_url() + 'new/')
  671. self.assertEqual(response.status_code, 200)
  672. self.assertIn(test_thread.get_absolute_url(), response.content)
  673. # test api
  674. self.access_all_categories()
  675. response = self.client.get('%s?list=new' % self.api_link)
  676. self.assertEqual(response.status_code, 200)
  677. response_json = json_loads(response.content)
  678. self.assertEqual(len(response_json['results']), 1)
  679. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  680. self.access_all_categories()
  681. response = self.client.get(
  682. '%s?list=new&category=%s' % (self.api_link, self.category_a.pk))
  683. self.assertEqual(response.status_code, 200)
  684. response_json = json_loads(response.content)
  685. self.assertEqual(len(response_json['results']), 1)
  686. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  687. def test_list_renders_thread_bumped_after_user_cutoff(self):
  688. """list renders new thread bumped after user cutoff"""
  689. self.user.joined_on = timezone.now() - timedelta(days=10)
  690. self.user.save()
  691. test_thread = testutils.post_thread(
  692. category=self.category_a,
  693. started_on=self.user.joined_on - timedelta(days=2)
  694. )
  695. testutils.reply_thread(test_thread,
  696. posted_on=self.user.joined_on + timedelta(days=4)
  697. )
  698. self.access_all_categories()
  699. response = self.client.get('/new/')
  700. self.assertEqual(response.status_code, 200)
  701. self.assertIn(test_thread.get_absolute_url(), response.content)
  702. self.access_all_categories()
  703. response = self.client.get(
  704. self.category_a.get_absolute_url() + 'new/')
  705. self.assertEqual(response.status_code, 200)
  706. self.assertIn(test_thread.get_absolute_url(), response.content)
  707. # test api
  708. self.access_all_categories()
  709. response = self.client.get('%s?list=new' % self.api_link)
  710. self.assertEqual(response.status_code, 200)
  711. response_json = json_loads(response.content)
  712. self.assertEqual(len(response_json['results']), 1)
  713. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  714. self.access_all_categories()
  715. response = self.client.get(
  716. '%s?list=new&category=%s' % (self.api_link, self.category_a.pk))
  717. self.assertEqual(response.status_code, 200)
  718. response_json = json_loads(response.content)
  719. self.assertEqual(len(response_json['results']), 1)
  720. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  721. def test_list_hides_global_cutoff_thread(self):
  722. """list hides thread started before global cutoff"""
  723. self.user.joined_on = timezone.now() - timedelta(days=10)
  724. self.user.save()
  725. test_thread = testutils.post_thread(
  726. category=self.category_a,
  727. started_on=timezone.now() - timedelta(
  728. days=settings.MISAGO_FRESH_CONTENT_PERIOD + 1
  729. )
  730. )
  731. self.access_all_categories()
  732. response = self.client.get('/new/')
  733. self.assertEqual(response.status_code, 200)
  734. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  735. self.access_all_categories()
  736. response = self.client.get(self.category_a.get_absolute_url() + 'new/')
  737. self.assertEqual(response.status_code, 200)
  738. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  739. # test api
  740. self.access_all_categories()
  741. response = self.client.get('%s?list=new' % self.api_link)
  742. self.assertEqual(response.status_code, 200)
  743. response_json = json_loads(response.content)
  744. self.assertEqual(len(response_json['results']), 0)
  745. self.access_all_categories()
  746. response = self.client.get(
  747. '%s?list=new&category=%s' % (self.api_link, self.category_a.pk))
  748. self.assertEqual(response.status_code, 200)
  749. response_json = json_loads(response.content)
  750. self.assertEqual(len(response_json['results']), 0)
  751. def test_list_hides_user_cutoff_thread(self):
  752. """list hides thread started before users cutoff"""
  753. self.user.joined_on = timezone.now() - timedelta(days=5)
  754. self.user.save()
  755. test_thread = testutils.post_thread(
  756. category=self.category_a,
  757. started_on=self.user.joined_on - timedelta(minutes=1)
  758. )
  759. self.access_all_categories()
  760. response = self.client.get('/new/')
  761. self.assertEqual(response.status_code, 200)
  762. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  763. self.access_all_categories()
  764. response = self.client.get(self.category_a.get_absolute_url() + 'new/')
  765. self.assertEqual(response.status_code, 200)
  766. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  767. # test api
  768. self.access_all_categories()
  769. response = self.client.get('%s?list=new' % self.api_link)
  770. self.assertEqual(response.status_code, 200)
  771. response_json = json_loads(response.content)
  772. self.assertEqual(len(response_json['results']), 0)
  773. self.access_all_categories()
  774. response = self.client.get(
  775. '%s?list=new&category=%s' % (self.api_link, self.category_a.pk))
  776. self.assertEqual(response.status_code, 200)
  777. response_json = json_loads(response.content)
  778. self.assertEqual(len(response_json['results']), 0)
  779. def test_list_hides_user_read_thread(self):
  780. """list hides thread already read by user"""
  781. self.user.joined_on = timezone.now() - timedelta(days=5)
  782. self.user.save()
  783. test_thread = testutils.post_thread(
  784. category=self.category_a
  785. )
  786. threadstracker.make_thread_read_aware(self.user, test_thread)
  787. threadstracker.read_thread(
  788. self.user, test_thread, test_thread.last_post)
  789. self.access_all_categories()
  790. response = self.client.get('/new/')
  791. self.assertEqual(response.status_code, 200)
  792. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  793. self.access_all_categories()
  794. response = self.client.get(self.category_a.get_absolute_url() + 'new/')
  795. self.assertEqual(response.status_code, 200)
  796. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  797. # test api
  798. self.access_all_categories()
  799. response = self.client.get('%s?list=new' % self.api_link)
  800. self.assertEqual(response.status_code, 200)
  801. response_json = json_loads(response.content)
  802. self.assertEqual(len(response_json['results']), 0)
  803. self.access_all_categories()
  804. response = self.client.get(
  805. '%s?list=new&category=%s' % (self.api_link, self.category_a.pk))
  806. self.assertEqual(response.status_code, 200)
  807. response_json = json_loads(response.content)
  808. self.assertEqual(len(response_json['results']), 0)
  809. def test_list_hides_category_read_thread(self):
  810. """list hides thread already read by user"""
  811. self.user.joined_on = timezone.now() - timedelta(days=5)
  812. self.user.save()
  813. test_thread = testutils.post_thread(
  814. category=self.category_a
  815. )
  816. self.user.categoryread_set.create(
  817. category=self.category_a,
  818. last_read_on=timezone.now(),
  819. )
  820. self.access_all_categories()
  821. response = self.client.get('/new/')
  822. self.assertEqual(response.status_code, 200)
  823. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  824. self.access_all_categories()
  825. response = self.client.get(self.category_a.get_absolute_url() + 'new/')
  826. self.assertEqual(response.status_code, 200)
  827. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  828. # test api
  829. self.access_all_categories()
  830. response = self.client.get('%s?list=new' % self.api_link)
  831. self.assertEqual(response.status_code, 200)
  832. response_json = json_loads(response.content)
  833. self.assertEqual(len(response_json['results']), 0)
  834. self.access_all_categories()
  835. response = self.client.get(
  836. '%s?list=new&category=%s' % (self.api_link, self.category_a.pk))
  837. self.assertEqual(response.status_code, 200)
  838. response_json = json_loads(response.content)
  839. self.assertEqual(len(response_json['results']), 0)
  840. class UnreadThreadsListTests(ThreadsListTestCase):
  841. def test_list_renders_empty(self):
  842. """list renders empty"""
  843. self.access_all_categories()
  844. response = self.client.get('/unread/')
  845. self.assertEqual(response.status_code, 200)
  846. self.assertIn("empty-message", response.content)
  847. self.access_all_categories()
  848. response = self.client.get(
  849. self.category_a.get_absolute_url() + 'unread/')
  850. self.assertEqual(response.status_code, 200)
  851. self.assertIn("empty-message", response.content)
  852. # test api
  853. self.access_all_categories()
  854. response = self.client.get('%s?list=unread' % self.api_link)
  855. self.assertEqual(response.status_code, 200)
  856. response_json = json_loads(response.content)
  857. self.assertEqual(len(response_json['results']), 0)
  858. self.access_all_categories()
  859. response = self.client.get(
  860. '%s?list=unread&category=%s' % (self.api_link, self.category_a.pk))
  861. self.assertEqual(response.status_code, 200)
  862. response_json = json_loads(response.content)
  863. self.assertEqual(len(response_json['results']), 0)
  864. def test_list_renders_unread_thread(self):
  865. """list renders thread with unread posts"""
  866. self.user.joined_on = timezone.now() - timedelta(days=5)
  867. self.user.save()
  868. test_thread = testutils.post_thread(
  869. category=self.category_a
  870. )
  871. threadstracker.make_thread_read_aware(self.user, test_thread)
  872. threadstracker.read_thread(
  873. self.user, test_thread, test_thread.last_post)
  874. testutils.reply_thread(test_thread)
  875. self.access_all_categories()
  876. response = self.client.get('/unread/')
  877. self.assertEqual(response.status_code, 200)
  878. self.assertIn(test_thread.get_absolute_url(), response.content)
  879. self.access_all_categories()
  880. response = self.client.get(
  881. self.category_a.get_absolute_url() + 'unread/')
  882. self.assertEqual(response.status_code, 200)
  883. self.assertIn(test_thread.get_absolute_url(), response.content)
  884. # test api
  885. self.access_all_categories()
  886. response = self.client.get('%s?list=unread' % self.api_link)
  887. self.assertEqual(response.status_code, 200)
  888. response_json = json_loads(response.content)
  889. self.assertEqual(len(response_json['results']), 1)
  890. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  891. self.access_all_categories()
  892. response = self.client.get(
  893. '%s?list=unread&category=%s' % (self.api_link, self.category_a.pk))
  894. self.assertEqual(response.status_code, 200)
  895. response_json = json_loads(response.content)
  896. self.assertEqual(len(response_json['results']), 1)
  897. self.assertEqual(response_json['results'][0]['id'], test_thread.pk)
  898. def test_list_hides_never_read_thread(self):
  899. """list hides never read thread"""
  900. self.user.joined_on = timezone.now() - timedelta(days=5)
  901. self.user.save()
  902. test_thread = testutils.post_thread(
  903. category=self.category_a
  904. )
  905. self.access_all_categories()
  906. response = self.client.get('/unread/')
  907. self.assertEqual(response.status_code, 200)
  908. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  909. self.access_all_categories()
  910. response = self.client.get(
  911. self.category_a.get_absolute_url() + 'unread/')
  912. self.assertEqual(response.status_code, 200)
  913. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  914. # test api
  915. self.access_all_categories()
  916. response = self.client.get('%s?list=unread' % self.api_link)
  917. self.assertEqual(response.status_code, 200)
  918. response_json = json_loads(response.content)
  919. self.assertEqual(len(response_json['results']), 0)
  920. self.access_all_categories()
  921. response = self.client.get(
  922. '%s?list=unread&category=%s' % (self.api_link, self.category_a.pk))
  923. self.assertEqual(response.status_code, 200)
  924. response_json = json_loads(response.content)
  925. self.assertEqual(len(response_json['results']), 0)
  926. def test_list_hides_read_thread(self):
  927. """list hides read thread"""
  928. self.user.joined_on = timezone.now() - timedelta(days=5)
  929. self.user.save()
  930. test_thread = testutils.post_thread(
  931. category=self.category_a
  932. )
  933. threadstracker.make_thread_read_aware(self.user, test_thread)
  934. threadstracker.read_thread(
  935. self.user, test_thread, test_thread.last_post)
  936. self.access_all_categories()
  937. response = self.client.get('/unread/')
  938. self.assertEqual(response.status_code, 200)
  939. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  940. self.access_all_categories()
  941. response = self.client.get(
  942. self.category_a.get_absolute_url() + 'unread/')
  943. self.assertEqual(response.status_code, 200)
  944. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  945. # test api
  946. self.access_all_categories()
  947. response = self.client.get('%s?list=unread' % self.api_link)
  948. self.assertEqual(response.status_code, 200)
  949. response_json = json_loads(response.content)
  950. self.assertEqual(len(response_json['results']), 0)
  951. self.access_all_categories()
  952. response = self.client.get(
  953. '%s?list=unread&category=%s' % (self.api_link, self.category_a.pk))
  954. self.assertEqual(response.status_code, 200)
  955. response_json = json_loads(response.content)
  956. self.assertEqual(len(response_json['results']), 0)
  957. def test_list_hides_global_cutoff_thread(self):
  958. """list hides thread replied before global cutoff"""
  959. self.user.joined_on = timezone.now() - timedelta(days=10)
  960. self.user.save()
  961. test_thread = testutils.post_thread(
  962. category=self.category_a,
  963. started_on=timezone.now() - timedelta(
  964. days=settings.MISAGO_FRESH_CONTENT_PERIOD + 5
  965. )
  966. )
  967. threadstracker.make_thread_read_aware(self.user, test_thread)
  968. threadstracker.read_thread(
  969. self.user, test_thread, test_thread.last_post)
  970. testutils.reply_thread(test_thread,
  971. posted_on=test_thread.started_on + timedelta(days=1)
  972. )
  973. self.access_all_categories()
  974. response = self.client.get('/unread/')
  975. self.assertEqual(response.status_code, 200)
  976. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  977. self.access_all_categories()
  978. response = self.client.get(
  979. self.category_a.get_absolute_url() + 'unread/')
  980. self.assertEqual(response.status_code, 200)
  981. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  982. # test api
  983. self.access_all_categories()
  984. response = self.client.get('%s?list=unread' % self.api_link)
  985. self.assertEqual(response.status_code, 200)
  986. response_json = json_loads(response.content)
  987. self.assertEqual(len(response_json['results']), 0)
  988. self.access_all_categories()
  989. response = self.client.get(
  990. '%s?list=unread&category=%s' % (self.api_link, self.category_a.pk))
  991. self.assertEqual(response.status_code, 200)
  992. response_json = json_loads(response.content)
  993. self.assertEqual(len(response_json['results']), 0)
  994. def test_list_hides_user_cutoff_thread(self):
  995. """list hides thread replied before user cutoff"""
  996. self.user.joined_on = timezone.now() - timedelta(days=10)
  997. self.user.save()
  998. test_thread = testutils.post_thread(
  999. category=self.category_a,
  1000. started_on=self.user.joined_on - timedelta(days=2)
  1001. )
  1002. threadstracker.make_thread_read_aware(self.user, test_thread)
  1003. threadstracker.read_thread(
  1004. self.user, test_thread, test_thread.last_post)
  1005. testutils.reply_thread(test_thread,
  1006. posted_on=test_thread.started_on + timedelta(days=1)
  1007. )
  1008. self.access_all_categories()
  1009. response = self.client.get('/unread/')
  1010. self.assertEqual(response.status_code, 200)
  1011. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  1012. self.access_all_categories()
  1013. response = self.client.get(
  1014. self.category_a.get_absolute_url() + 'unread/')
  1015. self.assertEqual(response.status_code, 200)
  1016. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  1017. # test api
  1018. self.access_all_categories()
  1019. response = self.client.get('%s?list=unread' % self.api_link)
  1020. self.assertEqual(response.status_code, 200)
  1021. response_json = json_loads(response.content)
  1022. self.assertEqual(len(response_json['results']), 0)
  1023. self.access_all_categories()
  1024. response = self.client.get(
  1025. '%s?list=unread&category=%s' % (self.api_link, self.category_a.pk))
  1026. self.assertEqual(response.status_code, 200)
  1027. response_json = json_loads(response.content)
  1028. self.assertEqual(len(response_json['results']), 0)
  1029. def test_list_hides_category_cutoff_thread(self):
  1030. """list hides thread replied before category cutoff"""
  1031. self.user.joined_on = timezone.now() - timedelta(days=10)
  1032. self.user.save()
  1033. test_thread = testutils.post_thread(
  1034. category=self.category_a,
  1035. started_on=self.user.joined_on - timedelta(days=2)
  1036. )
  1037. threadstracker.make_thread_read_aware(self.user, test_thread)
  1038. threadstracker.read_thread(
  1039. self.user, test_thread, test_thread.last_post)
  1040. testutils.reply_thread(test_thread)
  1041. self.user.categoryread_set.create(
  1042. category=self.category_a,
  1043. last_read_on=timezone.now(),
  1044. )
  1045. self.access_all_categories()
  1046. response = self.client.get('/unread/')
  1047. self.assertEqual(response.status_code, 200)
  1048. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  1049. self.access_all_categories()
  1050. response = self.client.get(
  1051. self.category_a.get_absolute_url() + 'unread/')
  1052. self.assertEqual(response.status_code, 200)
  1053. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  1054. # test api
  1055. self.access_all_categories()
  1056. response = self.client.get('%s?list=unread' % self.api_link)
  1057. self.assertEqual(response.status_code, 200)
  1058. response_json = json_loads(response.content)
  1059. self.assertEqual(len(response_json['results']), 0)
  1060. self.access_all_categories()
  1061. response = self.client.get(
  1062. '%s?list=unread&category=%s' % (self.api_link, self.category_a.pk))
  1063. self.assertEqual(response.status_code, 200)
  1064. response_json = json_loads(response.content)
  1065. self.assertEqual(len(response_json['results']), 0)
  1066. class SubscribedThreadsListTests(ThreadsListTestCase):
  1067. def test_list_shows_subscribed_thread(self):
  1068. """list shows subscribed thread"""
  1069. test_thread = testutils.post_thread(category=self.category_a)
  1070. self.user.subscription_set.create(
  1071. thread=test_thread,
  1072. category=self.category_a,
  1073. last_read_on=test_thread.last_post_on,
  1074. )
  1075. self.access_all_categories()
  1076. response = self.client.get('/subscribed/')
  1077. self.assertEqual(response.status_code, 200)
  1078. self.assertIn(test_thread.get_absolute_url(), response.content)
  1079. self.access_all_categories()
  1080. response = self.client.get(
  1081. self.category_a.get_absolute_url() + 'subscribed/')
  1082. self.assertEqual(response.status_code, 200)
  1083. self.assertIn(test_thread.get_absolute_url(), response.content)
  1084. # test api
  1085. self.access_all_categories()
  1086. response = self.client.get('%s?list=subscribed' % self.api_link)
  1087. self.assertEqual(response.status_code, 200)
  1088. response_json = json_loads(response.content)
  1089. self.assertEqual(len(response_json['results']), 1)
  1090. self.assertIn(test_thread.get_absolute_url(), response.content)
  1091. self.access_all_categories()
  1092. response = self.client.get(
  1093. '%s?list=subscribed&category=%s' % (
  1094. self.api_link, self.category_a.pk
  1095. ))
  1096. self.assertEqual(response.status_code, 200)
  1097. response_json = json_loads(response.content)
  1098. self.assertEqual(len(response_json['results']), 1)
  1099. self.assertIn(test_thread.get_absolute_url(), response.content)
  1100. def test_list_hides_unsubscribed_thread(self):
  1101. """list shows subscribed thread"""
  1102. test_thread = testutils.post_thread(category=self.category_a)
  1103. self.access_all_categories()
  1104. response = self.client.get('/subscribed/')
  1105. self.assertEqual(response.status_code, 200)
  1106. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  1107. self.access_all_categories()
  1108. response = self.client.get(
  1109. self.category_a.get_absolute_url() + 'subscribed/')
  1110. self.assertEqual(response.status_code, 200)
  1111. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  1112. # test api
  1113. self.access_all_categories()
  1114. response = self.client.get('%s?list=subscribed' % self.api_link)
  1115. self.assertEqual(response.status_code, 200)
  1116. response_json = json_loads(response.content)
  1117. self.assertEqual(len(response_json['results']), 0)
  1118. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  1119. self.access_all_categories()
  1120. response = self.client.get(
  1121. '%s?list=subscribed&category=%s' % (
  1122. self.api_link, self.category_a.pk
  1123. ))
  1124. self.assertEqual(response.status_code, 200)
  1125. response_json = json_loads(response.content)
  1126. self.assertEqual(len(response_json['results']), 0)
  1127. self.assertNotIn(test_thread.get_absolute_url(), response.content)
  1128. class UnapprovedListTests(ThreadsListTestCase):
  1129. def test_list_errors_without_permission(self):
  1130. """list errors if user has no permission to access it"""
  1131. self.access_all_categories()
  1132. response = self.client.get('/unapproved/')
  1133. self.assertEqual(response.status_code, 403)
  1134. self.access_all_categories()
  1135. response = self.client.get(
  1136. self.category_a.get_absolute_url() + 'unapproved/')
  1137. self.assertEqual(response.status_code, 403)
  1138. # test api
  1139. self.access_all_categories()
  1140. response = self.client.get('%s?list=unapproved' % self.api_link)
  1141. self.assertEqual(response.status_code, 403)
  1142. def test_list_shows_right_threads(self):
  1143. """list shows threads with unapproved posts"""
  1144. visible_thread = testutils.post_thread(
  1145. category=self.category_b,
  1146. is_unapproved=True,
  1147. )
  1148. hidden_thread = testutils.post_thread(
  1149. category=self.category_b,
  1150. is_unapproved=False,
  1151. )
  1152. self.access_all_categories({
  1153. 'can_approve_content': True
  1154. })
  1155. response = self.client.get('/unapproved/')
  1156. self.assertEqual(response.status_code, 200)
  1157. self.assertIn(visible_thread.get_absolute_url(), response.content)
  1158. self.assertNotIn(hidden_thread.get_absolute_url(), response.content)
  1159. self.access_all_categories({
  1160. 'can_approve_content': True
  1161. })
  1162. response = self.client.get(
  1163. self.category_a.get_absolute_url() + 'unapproved/')
  1164. self.assertEqual(response.status_code, 200)
  1165. self.assertIn(visible_thread.get_absolute_url(), response.content)
  1166. self.assertNotIn(hidden_thread.get_absolute_url(), response.content)
  1167. # test api
  1168. self.access_all_categories({
  1169. 'can_approve_content': True
  1170. })
  1171. response = self.client.get('%s?list=unapproved' % self.api_link)
  1172. self.assertEqual(response.status_code, 200)
  1173. self.assertIn(visible_thread.get_absolute_url(), response.content)
  1174. self.assertNotIn(hidden_thread.get_absolute_url(), response.content)