test_threadslists.py 51 KB

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