test_forum_models.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. from datetime import datetime
  2. from flask import current_app
  3. from flask.ext.login import login_user, current_user, logout_user
  4. from flaskbb.forum.models import Category, Forum, Topic, Post, ForumsRead, \
  5. TopicsRead, Report
  6. from flaskbb.user.models import User
  7. def test_category_save(database):
  8. """Test the save category method."""
  9. category = Category(title="Test Category")
  10. category.save()
  11. assert category.title == "Test Category"
  12. def test_category_delete(category):
  13. """Test the delete category method."""
  14. category.delete()
  15. category = Category.query.filter_by(id=category.id).first()
  16. assert category is None
  17. def test_category_delete_with_user(topic):
  18. """Test the delete category method with recounting the users post counts."""
  19. user = topic.user
  20. forum = topic.forum
  21. category = topic.forum.category
  22. assert user.post_count == 1
  23. assert forum.post_count == 1
  24. assert forum.topic_count == 1
  25. category.delete([user])
  26. assert user.post_count == 0
  27. category = Category.query.filter_by(id=category.id).first()
  28. topic = Topic.query.filter_by(id=topic.id).first()
  29. assert category is None
  30. # The topic should also be deleted
  31. assert topic is None
  32. def test_category_delete_with_forum(forum):
  33. """When deleting a category, all of his forums should also be deleted."""
  34. forum.category.delete()
  35. assert forum is not None
  36. assert forum.category is not None
  37. category = Category.query.filter_by(id=forum.category.id).first()
  38. forum = Forum.query.filter_by(id=forum.id).first()
  39. assert forum is None
  40. assert category is None
  41. def test_category_get_forums(forum, user):
  42. category = forum.category
  43. with current_app.test_request_context():
  44. # Test with logged in user
  45. login_user(user)
  46. assert current_user.is_authenticated()
  47. cat, forums = Category.get_forums(category.id, current_user)
  48. # Check if it is a list because in a category there are normally more
  49. # than one forum in it (not in these tests)
  50. assert isinstance(forums, list) is True
  51. assert forums == [(forum, None)]
  52. assert cat == category
  53. # Test the same thing with a logged out user
  54. logout_user()
  55. assert not current_user.is_authenticated()
  56. cat, forums = Category.get_forums(category.id, current_user)
  57. # Check if it is a list because in a category there are normally more
  58. # than one forum in it (not in these tests)
  59. assert isinstance(forums, list) is True
  60. assert forums == [(forum, None)]
  61. assert cat == category
  62. def test_category_get_all(forum, user):
  63. category = forum.category
  64. with current_app.test_request_context():
  65. # Test with logged in user
  66. login_user(user)
  67. assert current_user.is_authenticated()
  68. categories = Category.get_all(current_user)
  69. # All categories are stored in a list
  70. assert isinstance(categories, list)
  71. # The forums for a category are also stored in a list
  72. assert isinstance(categories[0][1], list)
  73. assert categories == [(category, [(forum, None)])]
  74. # Test with logged out user
  75. logout_user()
  76. assert not current_user.is_authenticated()
  77. categories = Category.get_all(current_user)
  78. # All categories are stored in a list
  79. assert isinstance(categories, list)
  80. # The forums for a category are also stored in a list
  81. assert isinstance(categories[0][1], list)
  82. assert categories == [(category, [(forum, None)])]
  83. def test_forum_save(category, moderator_user):
  84. """Test the save forum method"""
  85. forum = Forum(title="Test Forum", category_id=category.id)
  86. forum.save()
  87. assert forum.title == "Test Forum"
  88. # Test with adding a moderator
  89. forum.save([moderator_user])
  90. assert forum.moderators == [moderator_user]
  91. def test_forum_delete(forum):
  92. """Test the delete forum method."""
  93. forum.delete()
  94. forum = Forum.query.filter_by(id=forum.id).first()
  95. assert forum is None
  96. def test_forum_delete_with_user_and_topic(topic, user):
  97. """Now test the delete forum method with a topic inside."""
  98. assert user.post_count == 1
  99. topic.forum.delete([user])
  100. forum = Forum.query.filter_by(id=topic.forum_id).first()
  101. assert forum is None
  102. assert user.post_count == 0
  103. def test_forum_update_last_post(topic, user):
  104. """Test the update last post method."""
  105. post = Post(content="Test Content 2")
  106. post.save(topic=topic, user=user)
  107. assert topic.forum.last_post == post
  108. post.delete()
  109. topic.forum.update_last_post()
  110. assert topic.forum.last_post == topic.first_post
  111. def test_forum_update_read(database, user, topic):
  112. """Test the update read method."""
  113. forumsread = ForumsRead.query.\
  114. filter(ForumsRead.user_id == user.id,
  115. ForumsRead.forum_id == topic.forum_id).first()
  116. topicsread = TopicsRead.query.\
  117. filter(TopicsRead.user_id == user.id,
  118. TopicsRead.topic_id == topic.id).first()
  119. forum = topic.forum
  120. with current_app.test_request_context():
  121. # Test with logged in user
  122. login_user(user)
  123. # Should return False because topicsread is None
  124. assert not forum.update_read(current_user, forumsread, topicsread)
  125. # This is the first time the user visits the topic
  126. topicsread = TopicsRead()
  127. topicsread.user_id = user.id
  128. topicsread.topic_id = topic.id
  129. topicsread.forum_id = topic.forum_id
  130. topicsread.last_read = datetime.utcnow()
  131. topicsread.save()
  132. # hence, we also need to create a new forumsread entry
  133. assert forum.update_read(current_user, forumsread, topicsread)
  134. forumsread = ForumsRead.query.\
  135. filter(ForumsRead.user_id == user.id,
  136. ForumsRead.forum_id == topic.forum_id).first()
  137. # everything should be up-to-date now
  138. assert not forum.update_read(current_user, forumsread, topicsread)
  139. post = Post(content="Test Content")
  140. post.save(user=user, topic=topic)
  141. # Updating the topicsread tracker
  142. topicsread.last_read = datetime.utcnow()
  143. topicsread.save()
  144. # now the forumsread tracker should also need a update
  145. assert forum.update_read(current_user, forumsread, topicsread)
  146. logout_user()
  147. # should fail because the user is logged out
  148. assert not forum.update_read(current_user, forumsread, topicsread)
  149. def test_forum_update_read_two_topics(database, user, topic, topic_moderator):
  150. """Test if the ForumsRead tracker will be updated if there are two topics
  151. and where one is unread and the other is read.
  152. """
  153. forumsread = ForumsRead.query.\
  154. filter(ForumsRead.user_id == user.id,
  155. ForumsRead.forum_id == topic.forum_id).first()
  156. forum = topic.forum
  157. with current_app.test_request_context():
  158. # Test with logged in user
  159. login_user(user)
  160. # This is the first time the user visits the topic
  161. topicsread = TopicsRead()
  162. topicsread.user_id = user.id
  163. topicsread.topic_id = topic.id
  164. topicsread.forum_id = topic.forum_id
  165. topicsread.last_read = datetime.utcnow()
  166. topicsread.save()
  167. # will not create a entry because there is still one unread topic
  168. assert not forum.update_read(current_user, forumsread, topicsread)
  169. def test_forum_url(forum):
  170. assert forum.url == "http://localhost:5000/forum/1-test-forum"
  171. def test_forum_slugify(forum):
  172. assert forum.slug == "test-forum"
  173. def test_forum_get_forum(forum, user):
  174. with current_app.test_request_context():
  175. # Test with logged in user
  176. login_user(user)
  177. forum_with_forumsread = \
  178. Forum.get_forum(forum_id=forum.id, user=current_user)
  179. assert forum_with_forumsread == (forum, None)
  180. # Test with logged out user
  181. logout_user()
  182. forum_with_forumsread = \
  183. Forum.get_forum(forum_id=forum.id, user=current_user)
  184. assert forum_with_forumsread == (forum, None)
  185. def test_forum_get_topics(topic, user):
  186. forum = topic.forum
  187. with current_app.test_request_context():
  188. # Test with logged in user
  189. login_user(user)
  190. topics = Forum.get_topics(forum_id=forum.id, user=current_user)
  191. assert topics.items == [(topic, None)]
  192. # Test with logged out user
  193. logout_user()
  194. topics = Forum.get_topics(forum_id=forum.id, user=current_user)
  195. assert topics.items == [(topic, None)]
  196. def test_topic_save(forum, user):
  197. """Test the save topic method with creating and editing a topic."""
  198. post = Post(content="Test Content")
  199. topic = Topic(title="Test Title")
  200. assert forum.last_post_id is None
  201. assert forum.post_count == 0
  202. assert forum.topic_count == 0
  203. topic.save(forum=forum, post=post, user=user)
  204. assert topic.title == "Test Title"
  205. topic.title = "Test Edit Title"
  206. topic.save()
  207. assert topic.title == "Test Edit Title"
  208. # The first post in the topic is also the last post
  209. assert topic.first_post_id == post.id
  210. assert topic.last_post_id == post.id
  211. assert forum.last_post_id == post.id
  212. assert forum.post_count == 1
  213. assert forum.topic_count == 1
  214. def test_topic_delete(topic):
  215. """Test the delete topic method"""
  216. assert topic.user.post_count == 1
  217. assert topic.post_count == 1
  218. assert topic.forum.topic_count == 1
  219. assert topic.forum.post_count == 1
  220. topic.delete(users=[topic.user])
  221. forum = Forum.query.filter_by(id=topic.forum_id).first()
  222. user = User.query.filter_by(id=topic.user_id).first()
  223. topic = Topic.query.filter_by(id=topic.id).first()
  224. assert topic is None
  225. assert user.post_count == 0
  226. assert forum.topic_count == 0
  227. assert forum.post_count == 0
  228. assert forum.last_post_id is None
  229. def test_topic_merge(topic):
  230. """Tests the topic merge method."""
  231. topic_other = Topic(title="Test Topic Merge")
  232. post = Post(content="Test Content Merge")
  233. topic_other.save(post=post, user=topic.user, forum=topic.forum)
  234. # Save the last_post_id in another variable because topic_other will be
  235. # overwritten later
  236. last_post_other = topic_other.last_post_id
  237. assert topic_other.merge(topic)
  238. # I just want to be sure that the topic is deleted
  239. topic_other = Topic.query.filter_by(id=topic_other.id).first()
  240. assert topic_other is None
  241. assert topic.post_count == 2
  242. assert topic.last_post_id == last_post_other
  243. def test_topic_merge_other_forum(topic):
  244. """You cannot merge a topic with a topic from another forum."""
  245. forum_other = Forum(title="Test Forum 2", category_id=1)
  246. forum_other.save()
  247. topic_other = Topic(title="Test Topic 2")
  248. post_other = Post(content="Test Content 2")
  249. topic_other.save(user=topic.user, forum=forum_other, post=post_other)
  250. assert not topic.merge(topic_other)
  251. def test_topic_move(topic):
  252. """Tests the topic move method."""
  253. forum_other = Forum(title="Test Forum 2", category_id=1)
  254. forum_other.save()
  255. forum_old = Forum.query.filter_by(id=topic.forum_id).first()
  256. assert topic.move(forum_other)
  257. assert forum_old.topics == []
  258. assert forum_old.last_post_id == 0
  259. assert forum_old.topic_count == 0
  260. assert forum_old.post_count == 0
  261. assert forum_other.last_post_id == topic.last_post_id
  262. assert forum_other.topic_count == 1
  263. assert forum_other.post_count == 1
  264. def test_topic_move_same_forum(topic):
  265. """You cannot move a topic within the same forum."""
  266. assert not topic.move(topic.forum)
  267. def test_topic_tracker_needs_update(database, user, topic):
  268. """Tests if the topicsread tracker needs an update if a new post has been
  269. submitted.
  270. """
  271. forumsread = ForumsRead.query.\
  272. filter(ForumsRead.user_id == user.id,
  273. ForumsRead.forum_id == topic.forum_id).first()
  274. topicsread = TopicsRead.query.\
  275. filter(TopicsRead.user_id == user.id,
  276. TopicsRead.topic_id == topic.id).first()
  277. with current_app.test_request_context():
  278. assert topic.tracker_needs_update(forumsread, topicsread)
  279. # Update the tracker
  280. topicsread = TopicsRead()
  281. topicsread.user_id = user.id
  282. topicsread.topic_id = topic.id
  283. topicsread.forum_id = topic.forum_id
  284. topicsread.last_read = datetime.utcnow()
  285. topicsread.save()
  286. forumsread = ForumsRead()
  287. forumsread.user_id = user.id
  288. forumsread.forum_id = topic.forum_id
  289. forumsread.last_read = datetime.utcnow()
  290. forumsread.save()
  291. # Now the topic should be read
  292. assert not topic.tracker_needs_update(forumsread, topicsread)
  293. post = Post(content="Test Content")
  294. post.save(topic=topic, user=user)
  295. assert topic.tracker_needs_update(forumsread, topicsread)
  296. def test_topic_tracker_needs_update_cleared(database, user, topic):
  297. """Tests if the topicsread needs an update if the forum has been marked
  298. as cleared.
  299. """
  300. forumsread = ForumsRead.query.\
  301. filter(ForumsRead.user_id == user.id,
  302. ForumsRead.forum_id == topic.forum_id).first()
  303. topicsread = TopicsRead.query.\
  304. filter(TopicsRead.user_id == user.id,
  305. TopicsRead.topic_id == topic.id).first()
  306. with current_app.test_request_context():
  307. assert topic.tracker_needs_update(forumsread, topicsread)
  308. # Update the tracker
  309. forumsread = ForumsRead()
  310. forumsread.user_id = user.id
  311. forumsread.forum_id = topic.forum_id
  312. forumsread.last_read = datetime.utcnow()
  313. forumsread.cleared = datetime.utcnow()
  314. forumsread.save()
  315. # Now the topic should be read
  316. assert not topic.tracker_needs_update(forumsread, topicsread)
  317. def test_topic_update_read(database, user, topic):
  318. """Tests the update read method if the topic is unread/read."""
  319. forumsread = ForumsRead.query.\
  320. filter(ForumsRead.user_id == user.id,
  321. ForumsRead.forum_id == topic.forum_id).first()
  322. with current_app.test_request_context():
  323. # Test with logged in user
  324. login_user(user)
  325. assert current_user.is_authenticated()
  326. # Update the tracker
  327. assert topic.update_read(current_user, topic.forum, forumsread)
  328. # Because the tracker is already up-to-date, it shouldn't update it
  329. # again.
  330. assert not topic.update_read(current_user, topic.forum, forumsread)
  331. # Adding a new post - now the tracker shouldn't be up-to-date anymore.
  332. post = Post(content="Test Content")
  333. post.save(topic=topic, user=user)
  334. forumsread = ForumsRead.query.\
  335. filter(ForumsRead.user_id == user.id,
  336. ForumsRead.forum_id == topic.forum_id).first()
  337. # Test tracker length
  338. current_app.config["TRACKER_LENGTH"] = 0
  339. assert not topic.update_read(current_user, topic.forum, forumsread)
  340. current_app.config["TRACKER_LENGTH"] = 1
  341. assert topic.update_read(current_user, topic.forum, forumsread)
  342. # Test with logged out user
  343. logout_user()
  344. assert not current_user.is_authenticated()
  345. assert not topic.update_read(current_user, topic.forum, forumsread)
  346. def test_topic_url(topic):
  347. assert topic.url == "http://localhost:5000/topic/1-test-topic-normal"
  348. def test_topic_slug(topic):
  349. assert topic.slug == "test-topic-normal"
  350. def test_post_save(topic, user):
  351. """Tests the save post method."""
  352. post = Post(content="Test Content")
  353. post.save(topic=topic, user=user)
  354. assert post.content == "Test Content"
  355. post.content = "Test Edit Content"
  356. post.save()
  357. assert post.content == "Test Edit Content"
  358. assert topic.user.post_count == 2
  359. assert topic.post_count == 2
  360. assert topic.last_post == post
  361. assert topic.forum.post_count == 2
  362. def test_post_delete(topic):
  363. """Tests the delete post method with three different post types.
  364. The three types are:
  365. * First Post
  366. * A post between the first and last post (middle)
  367. * Last Post
  368. """
  369. post_middle = Post(content="Test Content Middle")
  370. post_middle.save(topic=topic, user=topic.user)
  371. post_last = Post(content="Test Content Last")
  372. post_last.save(topic=topic, user=topic.user)
  373. assert topic.post_count == 3
  374. assert topic.forum.post_count == 3
  375. assert topic.user.post_count == 3
  376. post_middle.delete()
  377. # Check the last posts
  378. assert topic.last_post == post_last
  379. assert topic.forum.last_post == post_last
  380. post_last.delete()
  381. # That was a bit trickier..
  382. assert topic.post_count == 1
  383. assert topic.forum.post_count == 1
  384. assert topic.user.post_count == 1
  385. assert topic.first_post_id == topic.last_post_id
  386. assert topic.forum.last_post_id == topic.last_post_id
  387. def test_report(topic, user):
  388. """Tests if the reports can be saved/edited and deleted with the
  389. implemented save and delete methods."""
  390. report = Report(reason="Test Report")
  391. report.save(user=user, post=topic.first_post)
  392. assert report.reason == "Test Report"
  393. report.reason = "Test Report Edited"
  394. report.save()
  395. assert report.reason == "Test Report Edited"
  396. report.delete()
  397. report = Report.query.filter_by(id=report.id).first()
  398. assert report is None
  399. def test_forumsread(topic, user):
  400. """Tests if the forumsread tracker can be saved/edited and deleted with the
  401. implemented save and delete methods."""
  402. forumsread = ForumsRead()
  403. forumsread.user_id = user.id
  404. forumsread.forum_id = topic.forum_id
  405. forumsread.last_read = datetime.utcnow()
  406. forumsread.save()
  407. assert forumsread is not None
  408. forumsread.delete()
  409. forumsread = ForumsRead.query.filter_by(forum_id=forumsread.forum_id).first()
  410. assert forumsread is None
  411. def test_topicsread(topic, user):
  412. """Tests if the topicsread trakcer can be saved/edited and deleted with the
  413. implemented save and delete methods."""
  414. topicsread = TopicsRead()
  415. topicsread.user_id = user.id
  416. topicsread.topic_id = topic.id
  417. topicsread.forum_id = topic.forum_id
  418. topicsread.last_read = datetime.utcnow()
  419. topicsread.save()
  420. assert topicsread is not None
  421. topicsread.delete()
  422. topicsread = TopicsRead.query.filter_by(topic_id=topicsread.topic_id).first()
  423. assert topicsread is None