followers.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. import assert from 'assert';
  2. import moment from 'moment';
  3. import React from 'react'; // jshint ignore:line
  4. import Followers from 'misago/components/profile/followers'; // jshint ignore:line
  5. import misago from 'misago/index';
  6. import reducer from 'misago/reducers/users';
  7. import snackbar from 'misago/services/snackbar';
  8. import store from 'misago/services/store';
  9. import * as testUtils from 'misago/utils/test-utils';
  10. let snackbarStore = null;
  11. /* jshint ignore:start */
  12. let userMock = {
  13. id: 42,
  14. username: 'TestUser',
  15. avatar_hash: 'abcdfefa'
  16. };
  17. let profileMock = {
  18. id: 123,
  19. username: 'BobBoberson',
  20. avatar_hash: 'abcdfefa'
  21. };
  22. /* jshint ignore:end */
  23. describe("User Profile Followers List", function() {
  24. beforeEach(function() {
  25. misago._context = {
  26. USERS_API: '/test-api/users/'
  27. };
  28. snackbarStore = testUtils.snackbarStoreMock();
  29. snackbar.init(snackbarStore);
  30. store.constructor();
  31. store.addReducer('users', reducer, []);
  32. store.init();
  33. });
  34. afterEach(function() {
  35. testUtils.unmountComponents();
  36. $.mockjax.clear();
  37. });
  38. it("preloads empty", function(done) {
  39. misago._context.PROFILE_FOLLOWERS = {
  40. count: 0,
  41. more: 0,
  42. page: 1,
  43. pages: 1,
  44. results: []
  45. };
  46. /* jshint ignore:start */
  47. testUtils.render(
  48. <Followers user={userMock}
  49. profile={profileMock}
  50. users={[]} />
  51. );
  52. /* jshint ignore:end */
  53. testUtils.onElement('#test-mount p.lead', function(element) {
  54. assert.ok(element.length, "element renders");
  55. assert.equal($('#test-mount h3').text(),
  56. "BobBoberson has 0 followers.",
  57. "component has valid header");
  58. assert.equal(element.text(), "BobBoberson has no followers.",
  59. "empty message was displayed");
  60. done();
  61. });
  62. });
  63. it("preloads empty (owned)", function(done) {
  64. misago._context.PROFILE_FOLLOWERS = {
  65. count: 0,
  66. more: 0,
  67. page: 1,
  68. pages: 1,
  69. results: []
  70. };
  71. /* jshint ignore:start */
  72. testUtils.render(
  73. <Followers user={Object.assign({}, userMock, {id: 123})}
  74. profile={profileMock}
  75. users={[]} />
  76. );
  77. /* jshint ignore:end */
  78. testUtils.onElement('#test-mount p.lead', function(element) {
  79. assert.ok(element.length, "element renders");
  80. assert.equal($('#test-mount h3').text(),
  81. "You have 0 followers.",
  82. "component has valid header");
  83. assert.equal(element.text(), "You have no followers.",
  84. "empty message was displayed");
  85. done();
  86. });
  87. });
  88. it("loads empty", function(done) {
  89. $.mockjax({
  90. url: '/test-api/users/?followers=123&name=&page=1',
  91. status: 200,
  92. responseText: {
  93. count: 0,
  94. more: 0,
  95. page: 1,
  96. pages: 1,
  97. results: []
  98. }
  99. });
  100. /* jshint ignore:start */
  101. testUtils.render(
  102. <Followers user={userMock}
  103. profile={profileMock}
  104. users={[]} />
  105. );
  106. /* jshint ignore:end */
  107. testUtils.onElement('#test-mount p.lead', function(element) {
  108. assert.ok(element.length, "element renders");
  109. assert.equal(element.text(), "BobBoberson has no followers.",
  110. "empty message was displayed");
  111. done();
  112. });
  113. });
  114. it("loads empty (owned)", function(done) {
  115. $.mockjax({
  116. url: '/test-api/users/?followers=123&name=&page=1',
  117. status: 200,
  118. responseText: {
  119. count: 0,
  120. more: 0,
  121. page: 1,
  122. pages: 1,
  123. results: []
  124. }
  125. });
  126. /* jshint ignore:start */
  127. testUtils.render(
  128. <Followers user={Object.assign({}, userMock, {id: 123})}
  129. profile={profileMock}
  130. users={[]} />
  131. );
  132. /* jshint ignore:end */
  133. testUtils.onElement('#test-mount p.lead', function(element) {
  134. assert.ok(element.length, "element renders");
  135. assert.equal(element.text(), "You have no followers.",
  136. "empty message was displayed");
  137. done();
  138. });
  139. });
  140. it("loads users list", function(done) {
  141. $.mockjax({
  142. url: '/test-api/users/?followers=123&name=&page=1',
  143. status: 200,
  144. responseText: {
  145. count: 5,
  146. more: 0,
  147. page: 1,
  148. pages: 1,
  149. results: [1, 2, 3, 4, 5].map(function(id) {
  150. return {
  151. id: id,
  152. username: 'BobBoberson' + id,
  153. avatar_hash: 'abcdfefa',
  154. joined_on: moment().format(),
  155. rank: {
  156. name: 'Test Rank',
  157. absolute_url: '/users/test-rank'
  158. }
  159. };
  160. })
  161. }
  162. });
  163. /* jshint ignore:start */
  164. testUtils.render(
  165. <Followers user={userMock}
  166. profile={profileMock}
  167. users={[]} />
  168. );
  169. /* jshint ignore:end */
  170. testUtils.onElement('#test-mount .users-cards-list.ui-ready', function() {
  171. assert.equal($('#test-mount h3').text(), "BobBoberson has 5 followers.",
  172. "component has valid header");
  173. assert.equal(store.getState().users.length, 5,
  174. "component renders with five items");
  175. done();
  176. });
  177. });
  178. it("loads more changes", function(done) {
  179. $.mockjax({
  180. url: '/test-api/users/?followers=123&name=&page=1',
  181. status: 200,
  182. responseText: {
  183. count: 10,
  184. more: 5,
  185. page: 1,
  186. pages: 2,
  187. results: [1, 2, 3, 4, 5].map(function(id) {
  188. return {
  189. id: id,
  190. username: 'BobBoberson' + id,
  191. avatar_hash: 'abcdfefa',
  192. joined_on: moment().format(),
  193. rank: {
  194. name: 'Test Rank',
  195. absolute_url: '/users/test-rank'
  196. }
  197. };
  198. })
  199. }
  200. });
  201. $.mockjax({
  202. url: '/test-api/users/?followers=123&name=&page=2',
  203. status: 200,
  204. responseText: {
  205. count: 10,
  206. more: 0,
  207. page: 2,
  208. pages: 2,
  209. results: [1, 2, 3, 4, 5].map(function(id) {
  210. return {
  211. id: 5 + id,
  212. username: 'BobBoberson' + (5 + id),
  213. avatar_hash: 'abcdfefa',
  214. joined_on: moment().format(),
  215. rank: {
  216. name: 'Test Rank',
  217. absolute_url: '/users/test-rank'
  218. }
  219. };
  220. })
  221. }
  222. });
  223. /* jshint ignore:start */
  224. testUtils.render(
  225. <Followers user={userMock}
  226. profile={profileMock}
  227. users={[]} />
  228. );
  229. /* jshint ignore:end */
  230. testUtils.onElement('#test-mount .pager-more .btn', function() {
  231. assert.equal($('#test-mount h3').text(), "BobBoberson has 10 followers.",
  232. "component has valid header");
  233. testUtils.simulateClick('#test-mount .pager-more .btn');
  234. window.setTimeout(function() {
  235. assert.equal(store.getState().users.length, 10,
  236. "component renders with ten items");
  237. done();
  238. }, 300);
  239. });
  240. });
  241. it("loads search results", function(done) {
  242. $.mockjax({
  243. url: '/test-api/users/?followers=123&name=&page=1',
  244. status: 200,
  245. responseText: {
  246. count: 10,
  247. more: 5,
  248. page: 1,
  249. pages: 2,
  250. results: [1, 2, 3, 4, 5].map(function(id) {
  251. return {
  252. id: id,
  253. username: 'BobBoberson' + id,
  254. avatar_hash: 'abcdfefa',
  255. joined_on: moment().format(),
  256. rank: {
  257. name: 'Test Rank',
  258. absolute_url: '/users/test-rank'
  259. }
  260. };
  261. })
  262. }
  263. });
  264. $.mockjax({
  265. url: '/test-api/users/?followers=123&name=test&page=1',
  266. status: 200,
  267. responseText: {
  268. count: 3,
  269. more: 0,
  270. page: 1,
  271. pages: 1,
  272. results: [1, 2, 3].map(function(id) {
  273. return {
  274. id: 10 + id,
  275. username: 'BobBoberson' + (10 + id),
  276. avatar_hash: 'abcdfefa',
  277. joined_on: moment().format(),
  278. rank: {
  279. name: 'Test Rank',
  280. absolute_url: '/users/test-rank'
  281. }
  282. };
  283. })
  284. }
  285. });
  286. /* jshint ignore:start */
  287. testUtils.render(
  288. <Followers user={userMock}
  289. profile={profileMock}
  290. users={[]} />
  291. );
  292. /* jshint ignore:end */
  293. testUtils.onElement('#test-mount .pager-more .btn', function() {
  294. assert.equal($('#test-mount h3').text(),
  295. "BobBoberson has 10 followers.",
  296. "component has valid header");
  297. testUtils.simulateChange('#test-mount .form-control', 'test');
  298. window.setTimeout(function() {
  299. assert.equal(store.getState().users.length, 3,
  300. "component renders with three found items");
  301. assert.equal($('#test-mount h3').text(), "Found 3 users.",
  302. "component has valid header");
  303. done();
  304. }, 300);
  305. });
  306. });
  307. it("loads empty search results", function(done) {
  308. $.mockjax({
  309. url: '/test-api/users/?followers=123&name=&page=1',
  310. status: 200,
  311. responseText: {
  312. count: 10,
  313. more: 5,
  314. page: 1,
  315. pages: 2,
  316. results: [1, 2, 3, 4, 5].map(function(id) {
  317. return {
  318. id: id,
  319. username: 'BobBoberson' + id,
  320. avatar_hash: 'abcdfefa',
  321. joined_on: moment().format(),
  322. rank: {
  323. name: 'Test Rank',
  324. absolute_url: '/users/test-rank'
  325. }
  326. };
  327. })
  328. }
  329. });
  330. $.mockjax({
  331. url: '/test-api/users/?followers=123&name=test&page=1',
  332. status: 200,
  333. responseText: {
  334. count: 0,
  335. more: 0,
  336. page: 1,
  337. pages: 1,
  338. results: []
  339. }
  340. });
  341. /* jshint ignore:start */
  342. testUtils.render(
  343. <Followers user={userMock}
  344. profile={profileMock}
  345. users={[]} />
  346. );
  347. /* jshint ignore:end */
  348. testUtils.onElement('#test-mount .pager-more .btn', function() {
  349. assert.equal($('#test-mount h3').text(),
  350. "BobBoberson has 10 followers.",
  351. "component has valid header");
  352. testUtils.simulateChange('#test-mount .form-control', 'test');
  353. window.setTimeout(function() {
  354. assert.equal(store.getState().users.length, 0,
  355. "store is emptied");
  356. assert.equal($('#test-mount h3').text(), "Found 0 users.",
  357. "component has valid header");
  358. done();
  359. }, 300);
  360. });
  361. });
  362. it("handles backend error", function(done) {
  363. $.mockjax({
  364. url: '/test-api/users/?followers=123&name=&page=1',
  365. status: 500
  366. });
  367. snackbarStore.callback(function(message) {
  368. assert.deepEqual(message, {
  369. message: "Unknown error has occured.",
  370. type: 'error'
  371. }, "error message was shown");
  372. done();
  373. });
  374. /* jshint ignore:start */
  375. testUtils.render(
  376. <Followers user={userMock}
  377. profile={profileMock}
  378. users={[]} />
  379. );
  380. /* jshint ignore:end */
  381. });
  382. it("handles backend rejection", function(done) {
  383. $.mockjax({
  384. url: '/test-api/users/?followers=123&name=&page=1',
  385. status: 403,
  386. responseText: {
  387. detail: "You can't see it yo!"
  388. }
  389. });
  390. snackbarStore.callback(function(message) {
  391. assert.deepEqual(message, {
  392. message: "You can't see it yo!",
  393. type: 'error'
  394. }, "error message was shown");
  395. done();
  396. });
  397. /* jshint ignore:start */
  398. testUtils.render(
  399. <Followers user={userMock}
  400. profile={profileMock}
  401. users={[]} />
  402. );
  403. /* jshint ignore:end */
  404. });
  405. });