root.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. import assert from 'assert';
  2. import React from 'react'; // jshint ignore:line
  3. import CategoriesList from 'misago/components/categories/root'; // jshint ignore:line
  4. import misago from 'misago/index';
  5. import ajax from 'misago/services/ajax';
  6. import polls from 'misago/services/polls';
  7. import snackbar from 'misago/services/snackbar';
  8. import * as testUtils from 'misago/utils/test-utils';
  9. let snackbarStore = null;
  10. let categories = [
  11. {
  12. "id": 3,
  13. "name": "Games",
  14. "description": null,
  15. "is_closed": false,
  16. "threads": 82,
  17. "posts": 1944,
  18. "last_post_on": "2016-02-25T21:15:53.231778Z",
  19. "last_thread_title": "Nemo quibusdam sunt ab odit omnis totam.",
  20. "last_poster_name": "Raelyn",
  21. "css_class": "accent",
  22. "is_read": false,
  23. "subcategories": [],
  24. "absolute_url": "/categories/#games-3",
  25. "last_thread_url": "/not-yet-implemented/",
  26. "last_poster_url": "/user/raelyn-74/",
  27. "acl": {
  28. "can_browse": true,
  29. "can_see_all_threads": 1
  30. }
  31. },
  32. {
  33. "id": 4,
  34. "name": "Second category",
  35. "description": {
  36. "plain": "Lorem ipsum dolor met sit amet elit.",
  37. "html": "<p>Lorem ipsum dolor met sit amet elit.</p>"
  38. },
  39. "is_closed": false,
  40. "threads": 418,
  41. "posts": 7741,
  42. "last_post_on": "2016-02-25T21:15:54.483911Z",
  43. "last_thread_title": "Iste officiis debitis velit non magnam aut a.",
  44. "last_poster_name": "Myrna",
  45. "css_class": "",
  46. "is_read": false,
  47. "subcategories": [
  48. {
  49. "id": 5,
  50. "name": "Action",
  51. "description": {
  52. "plain": "Lorem ipsum dolor met sit amet elit pacem bellum sequor.",
  53. "html": "<p>Lorem ipsum dolor met sit amet elit pacem bellum sequor.</p>"
  54. },
  55. "is_closed": true,
  56. "threads": 263,
  57. "posts": 5386,
  58. "last_post_on": "2016-02-25T21:15:54.483911Z",
  59. "last_thread_title": "Iste officiis debitis velit non magnam aut a.",
  60. "last_poster_name": "Myrna",
  61. "css_class": "",
  62. "is_read": false,
  63. "subcategories": [
  64. {
  65. "id": 7,
  66. "name": "Multiplayer",
  67. "description": null,
  68. "is_closed": false,
  69. "threads": 95,
  70. "posts": 1567,
  71. "last_post_on": "2016-02-25T21:15:53.697017Z",
  72. "last_thread_title": "Et debitis unde in eius.",
  73. "last_poster_name": "Morton",
  74. "css_class": "",
  75. "is_read": false,
  76. "subcategories": [],
  77. "absolute_url": "/category/multiplayer-7/",
  78. "last_thread_url": "/not-yet-implemented/",
  79. "last_poster_url": "/user/morton-30/",
  80. "acl": {
  81. "can_browse": true,
  82. "can_see_all_threads": 1
  83. }
  84. },
  85. {
  86. "id": 8,
  87. "name": "Single player",
  88. "description": null,
  89. "is_closed": false,
  90. "threads": 93,
  91. "posts": 2422,
  92. "last_post_on": "2016-02-25T21:15:54.483911Z",
  93. "last_thread_title": "Iste officiis debitis velit non magnam aut a.",
  94. "last_poster_name": "Myrna",
  95. "css_class": "",
  96. "is_read": false,
  97. "subcategories": [],
  98. "absolute_url": "/category/single-player-8/",
  99. "last_thread_url": "/not-yet-implemented/",
  100. "last_poster_url": "/user/myrna-18/",
  101. "acl": {
  102. "can_browse": true,
  103. "can_see_all_threads": 1
  104. }
  105. }
  106. ],
  107. "absolute_url": "/category/action-5/",
  108. "last_thread_url": "/not-yet-implemented/",
  109. "last_poster_url": "/user/myrna-52/",
  110. "acl": {
  111. "can_browse": true,
  112. "can_see_all_threads": 1
  113. }
  114. },
  115. {
  116. "id": 6,
  117. "name": "Sandbox",
  118. "description": null,
  119. "is_closed": false,
  120. "threads": 73,
  121. "posts": 979,
  122. "last_post_on": "2016-02-25T21:15:54.240616Z",
  123. "last_thread_title": "Totam hic excepturi nulla asperiores illum.",
  124. "last_poster_name": "Camille",
  125. "css_class": "",
  126. "is_read": false,
  127. "subcategories": [],
  128. "absolute_url": "/category/sandbox-6/",
  129. "last_thread_url": "/not-yet-implemented/",
  130. "last_poster_url": "/user/camille-29/",
  131. "acl": {
  132. "can_browse": true,
  133. "can_see_all_threads": 1
  134. }
  135. }
  136. ],
  137. "absolute_url": "/categories/#second-category-4",
  138. "last_thread_url": "/not-yet-implemented/",
  139. "last_poster_url": "/user/myrna-88/",
  140. "acl": {
  141. "can_browse": true,
  142. "can_see_all_threads": 1
  143. }
  144. }
  145. ];
  146. let noopAjax = {
  147. get: function() {
  148. return {
  149. then: function() {
  150. /* noop */
  151. }
  152. };
  153. }
  154. };
  155. describe("Categories List", function() {
  156. beforeEach(function() {
  157. misago._context = {
  158. CATEGORIES: categories,
  159. CATEGORIES_API: '/test-api/categories/',
  160. CATEGORIES_ON_INDEX: false
  161. };
  162. snackbarStore = testUtils.snackbarStoreMock();
  163. snackbar.init(snackbarStore);
  164. polls.init(ajax, snackbar);
  165. });
  166. afterEach(function() {
  167. polls.stop('categories');
  168. testUtils.unmountComponents();
  169. $.mockjax.clear();
  170. });
  171. it("renders and loads", function(done) {
  172. $.mockjax({
  173. url: '/test-api/categories/',
  174. status: 200,
  175. responseText: categories
  176. });
  177. /* jshint ignore:start */
  178. testUtils.render(<CategoriesList />);
  179. /* jshint ignore:end */
  180. assert.equal($('#test-mount .panel-category').length, 2,
  181. "two categories rendered initially");
  182. window.setTimeout(function() {
  183. let element = $('#test-mount .page-categories');
  184. assert.ok(element.length, "component renders");
  185. assert.equal(element.find('.panel-category').length, 2,
  186. "two categories rendered");
  187. done();
  188. }, 200);
  189. });
  190. it("renders and loads empty list", function(done) {
  191. misago._context.CATEGORIES = [];
  192. $.mockjax({
  193. url: '/test-api/categories/',
  194. status: 200,
  195. responseText: []
  196. });
  197. /* jshint ignore:start */
  198. testUtils.render(<CategoriesList />);
  199. /* jshint ignore:end */
  200. assert.equal($('#test-mount .panel-category').length, 0,
  201. "no categories rendered initially");
  202. window.setTimeout(function() {
  203. let element = $('#test-mount .page-message .message-body');
  204. assert.ok(element.length, "component renders message about no data");
  205. assert.equal(element.find('.panel-category').length, 0,
  206. "no categories rendered");
  207. done();
  208. }, 200);
  209. });
  210. it("renders and empties list", function(done) {
  211. $.mockjax({
  212. url: '/test-api/categories/',
  213. status: 200,
  214. responseText: []
  215. });
  216. /* jshint ignore:start */
  217. testUtils.render(<CategoriesList />);
  218. /* jshint ignore:end */
  219. assert.equal($('#test-mount .panel-category').length, 2,
  220. "two categories rendered initially");
  221. testUtils.onElement('#test-mount .page-message .message-body', function() {
  222. let element = $('#test-mount .page-message .message-body');
  223. assert.ok(element.length, "component renders message about no data");
  224. assert.equal(element.find('.panel-category').length, 0,
  225. "no categories rendered");
  226. done();
  227. });
  228. });
  229. it("renders empty and populates list", function(done) {
  230. misago._context.CATEGORIES = [];
  231. $.mockjax({
  232. url: '/test-api/categories/',
  233. status: 200,
  234. responseText: categories
  235. });
  236. /* jshint ignore:start */
  237. testUtils.render(<CategoriesList />);
  238. /* jshint ignore:end */
  239. assert.equal($('#test-mount .panel-category').length, 0,
  240. "no categories rendered initially");
  241. testUtils.onElement('#test-mount .categories-list', function(element) {
  242. assert.equal(element.find('.panel-category').length, 2,
  243. "two categories rendered");
  244. done();
  245. });
  246. });
  247. it("has valid header if not forum index", function() {
  248. misago._context.CATEGORIES = [];
  249. misago._context.CATEGORIES_ON_INDEX = false;
  250. polls.init(noopAjax, snackbar);
  251. /* jshint ignore:start */
  252. testUtils.render(<CategoriesList />);
  253. /* jshint ignore:end */
  254. assert.equal($('#test-mount h1').text(), "Categories",
  255. "renders with non-home header");
  256. });
  257. it("has valid header if forum index", function() {
  258. misago._context.CATEGORIES = [];
  259. misago._context.CATEGORIES_ON_INDEX = true;
  260. misago._context.SETTINGS = {
  261. forum_name: "Test Misago Forum"
  262. };
  263. polls.init(noopAjax, snackbar);
  264. /* jshint ignore:start */
  265. testUtils.render(<CategoriesList />);
  266. /* jshint ignore:end */
  267. assert.equal($('#test-mount h1').text(), "Test Misago Forum",
  268. "renders with forum name in header");
  269. });
  270. it("handles backend error", function(done) {
  271. $.mockjax({
  272. url: '/test-api/categories/',
  273. status: 500
  274. });
  275. snackbarStore.callback(function(message) {
  276. assert.deepEqual(message, {
  277. message: "Unknown error has occured.",
  278. type: 'error'
  279. }, "error message was shown");
  280. done();
  281. });
  282. /* jshint ignore:start */
  283. testUtils.render(<CategoriesList />);
  284. /* jshint ignore:end */
  285. });
  286. it("handles backend rejection", function(done) {
  287. $.mockjax({
  288. url: '/test-api/categories/',
  289. status: 403,
  290. responseText: {
  291. detail: "You can't see it yo!"
  292. }
  293. });
  294. snackbarStore.callback(function(message) {
  295. assert.deepEqual(message, {
  296. message: "You can't see it yo!",
  297. type: 'error'
  298. }, "backend returned error message was shown");
  299. done();
  300. });
  301. /* jshint ignore:start */
  302. testUtils.render(<CategoriesList />);
  303. /* jshint ignore:end */
  304. });
  305. });