change-username.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. import assert from 'assert';
  2. import moment from 'moment'; // jshint ignore:line
  3. import React from 'react'; // jshint ignore:line
  4. import FormLoading from 'misago/components/options/change-username/form-loading'; // jshint ignore:line
  5. import FormLocked from 'misago/components/options/change-username/form-locked'; // jshint ignore:line
  6. import Form from 'misago/components/options/change-username/form'; // jshint ignore:line
  7. import Root from 'misago/components/options/change-username/root'; // jshint ignore:line
  8. import misago from 'misago/index';
  9. import snackbar from 'misago/services/snackbar';
  10. import store from 'misago/services/store';
  11. import * as testUtils from 'misago/utils/test-utils';
  12. let snackbarStore = null;
  13. let user = testUtils.mockUser();
  14. user.acl.name_changes_expire = 2;
  15. describe("Change Username Form", function() {
  16. beforeEach(function() {
  17. snackbarStore = testUtils.snackbarStoreMock();
  18. snackbar.init(snackbarStore);
  19. testUtils.initEmptyStore(store);
  20. });
  21. afterEach(function() {
  22. testUtils.unmountComponents();
  23. testUtils.snackbarClear(snackbar);
  24. $.mockjax.clear();
  25. });
  26. it("renders", function(done) {
  27. /* jshint ignore:start */
  28. let options = {
  29. changes_left: 5,
  30. length_min: 3,
  31. length_max: 14,
  32. next_on: null
  33. };
  34. testUtils.render(
  35. <Form user={user}
  36. options={options} />
  37. );
  38. /* jshint ignore:end */
  39. testUtils.onElement('#test-mount .form-horizontal', function() {
  40. assert.ok(true, "component renders");
  41. assert.equal($('#test-mount form .help-block').text().trim(),
  42. "You can change your username 5 more times. Used changes redeem after 2 days.",
  43. "valid help text is displayed in form");
  44. done();
  45. });
  46. });
  47. it("handles empty submit", function(done) {
  48. /* jshint ignore:start */
  49. let options = {
  50. changes_left: 5,
  51. length_min: 3,
  52. length_max: 14,
  53. next_on: null
  54. };
  55. testUtils.render(
  56. <Form user={user}
  57. options={options} />
  58. );
  59. /* jshint ignore:end */
  60. snackbarStore.callback(function(message) {
  61. assert.deepEqual(message, {
  62. message: "This field is required.",
  63. type: 'error'
  64. }, "error message was shown");
  65. done();
  66. });
  67. testUtils.onElement('#test-mount form', function() {
  68. testUtils.simulateSubmit('#test-mount form');
  69. });
  70. });
  71. it("handles invalid submit", function(done) {
  72. /* jshint ignore:start */
  73. let options = {
  74. changes_left: 5,
  75. length_min: 10,
  76. length_max: 14,
  77. next_on: null
  78. };
  79. testUtils.render(
  80. <Form user={user}
  81. options={options} />
  82. );
  83. /* jshint ignore:end */
  84. snackbarStore.callback(function(message) {
  85. assert.deepEqual(message, {
  86. message: "Username must be at least 10 characters long.",
  87. type: 'error'
  88. }, "error message was shown");
  89. done();
  90. });
  91. testUtils.onElement('#test-mount form', function() {
  92. testUtils.simulateChange('#test-mount form #id_username', 'NewName');
  93. testUtils.simulateSubmit('#test-mount form');
  94. });
  95. });
  96. it("handles backend rejection", function(done) {
  97. $.mockjax({
  98. url: user.api_url.username,
  99. status: 400,
  100. responseText: {
  101. detail: "Lol nope!"
  102. }
  103. });
  104. /* jshint ignore:start */
  105. let options = {
  106. changes_left: 5,
  107. length_min: 3,
  108. length_max: 14,
  109. next_on: null
  110. };
  111. testUtils.render(
  112. <Form user={user}
  113. options={options} />
  114. );
  115. /* jshint ignore:end */
  116. snackbarStore.callback(function(message) {
  117. assert.deepEqual(message, {
  118. message: "Lol nope!",
  119. type: 'error'
  120. }, "error message from backend was shown");
  121. done();
  122. });
  123. testUtils.onElement('#test-mount form', function() {
  124. testUtils.simulateChange('#test-mount form #id_username', 'Newt');
  125. testUtils.simulateSubmit('#test-mount form');
  126. });
  127. });
  128. it("handles backend error", function(done) {
  129. $.mockjax({
  130. url: user.api_url.username,
  131. status: 500
  132. });
  133. /* jshint ignore:start */
  134. let options = {
  135. changes_left: 5,
  136. length_min: 3,
  137. length_max: 14,
  138. next_on: null
  139. };
  140. testUtils.render(
  141. <Form user={user}
  142. options={options} />
  143. );
  144. /* jshint ignore:end */
  145. snackbarStore.callback(function(message) {
  146. assert.deepEqual(message, {
  147. message: "Unknown error has occured.",
  148. type: 'error'
  149. }, "error message from backend was shown");
  150. done();
  151. });
  152. testUtils.onElement('#test-mount form', function() {
  153. testUtils.simulateChange('#test-mount form #id_username', 'Newt');
  154. testUtils.simulateSubmit('#test-mount form');
  155. });
  156. });
  157. it("handles successfull submission", function(done) { // jshint ignore:line
  158. $.mockjax({
  159. url: user.api_url.username,
  160. status: 200,
  161. responseText: {
  162. username: 'Newt',
  163. slug: 'newt',
  164. options: {
  165. changes_left: 4,
  166. length_min: 3,
  167. length_max: 14,
  168. next_on: null
  169. }
  170. }
  171. });
  172. /* jshint ignore:start */
  173. let options = {
  174. changes_left: 5,
  175. length_min: 3,
  176. length_max: 14,
  177. next_on: null
  178. };
  179. let callback = function(username, slug, options) {
  180. assert.equal(username, 'Newt', "new username is passed to callback");
  181. assert.equal(slug, 'newt', "new slug is passed to callback");
  182. assert.deepEqual(options, {
  183. changes_left: 4,
  184. length_min: 3,
  185. length_max: 14,
  186. next_on: null
  187. }, "new options are passed to callback");
  188. done();
  189. };
  190. testUtils.render(
  191. <Form user={user}
  192. options={options}
  193. complete={callback} />
  194. );
  195. /* jshint ignore:end */
  196. testUtils.onElement('#test-mount form', function() {
  197. testUtils.simulateChange('#test-mount form #id_username', 'newt');
  198. testUtils.simulateSubmit('#test-mount form');
  199. });
  200. });
  201. });
  202. describe("Change Username Form Locked", function() {
  203. afterEach(function() {
  204. testUtils.unmountComponents();
  205. });
  206. it("renders", function(done) {
  207. /* jshint ignore:start */
  208. let options = {
  209. changes_left: 5,
  210. length_min: 3,
  211. length_max: 14,
  212. next_on: null
  213. };
  214. testUtils.render(<FormLocked options={options} />);
  215. /* jshint ignore:end */
  216. testUtils.onElement('#test-mount .panel-message-body', function() {
  217. assert.ok(true, "component renders");
  218. assert.equal($('#test-mount .help-block').text().trim(),
  219. "You have used up available name changes.",
  220. "valid help text is displayed in message");
  221. done();
  222. });
  223. });
  224. it("renders with next change message", function(done) {
  225. /* jshint ignore:start */
  226. let options = {
  227. changes_left: 5,
  228. length_min: 3,
  229. length_max: 14,
  230. next_on: moment().add(5, 'days')
  231. };
  232. testUtils.render(<FormLocked options={options} />);
  233. /* jshint ignore:end */
  234. testUtils.onElement('#test-mount .panel-message-body', function() {
  235. assert.ok(true, "component renders");
  236. assert.equal($('#test-mount .help-block').text().trim(),
  237. "You will be able to change your username in 5 days.",
  238. "valid help text is displayed in message");
  239. done();
  240. });
  241. });
  242. });
  243. describe("Change Username Form Loading", function() {
  244. afterEach(function() {
  245. testUtils.unmountComponents();
  246. });
  247. it("renders", function(done) {
  248. /* jshint ignore:start */
  249. testUtils.render(<FormLoading />);
  250. /* jshint ignore:end */
  251. testUtils.onElement('#test-mount .panel-body-loading', function() {
  252. assert.ok(true, "component renders");
  253. done();
  254. });
  255. });
  256. });
  257. describe("Change Username Integration", function() {
  258. beforeEach(function() {
  259. snackbarStore = testUtils.snackbarStoreMock();
  260. snackbar.init(snackbarStore);
  261. testUtils.initEmptyStore(store);
  262. misago._context = {
  263. USERNAME_CHANGES_API: '/test-api/name-history/'
  264. };
  265. });
  266. afterEach(function() {
  267. testUtils.unmountComponents();
  268. testUtils.snackbarClear(snackbar);
  269. $.mockjax.clear();
  270. });
  271. it("renders", function(done) {
  272. $.mockjax({
  273. url: user.api_url.username,
  274. status: 200,
  275. responseText: {
  276. changes_left: 2,
  277. length_min: 3,
  278. length_max: 14,
  279. next_on: null
  280. }
  281. });
  282. $.mockjax({
  283. url: '/test-api/name-history/?user=' + user.id,
  284. status: 200,
  285. responseText: {
  286. results: []
  287. }
  288. });
  289. /* jshint ignore:start */
  290. testUtils.render(
  291. <Root user={user}
  292. username-history={[]} />
  293. );
  294. /* jshint ignore:end */
  295. testUtils.onElement('#test-mount .username-history.ui-ready', function() {
  296. assert.ok(true, "root component renders");
  297. done();
  298. });
  299. });
  300. it("renders with no changes left", function(done) {
  301. $.mockjax({
  302. url: user.api_url.username,
  303. status: 200,
  304. responseText: {
  305. changes_left: 0,
  306. length_min: 3,
  307. length_max: 14,
  308. next_on: null
  309. }
  310. });
  311. $.mockjax({
  312. url: '/test-api/name-history/?user=' + user.id,
  313. status: 200,
  314. responseText: {
  315. results: []
  316. }
  317. });
  318. /* jshint ignore:start */
  319. testUtils.render(
  320. <Root user={user}
  321. username-history={[]} />
  322. );
  323. /* jshint ignore:end */
  324. testUtils.onElement('#test-mount .panel-message-body', function() {
  325. assert.ok(true, "root component renders");
  326. assert.equal($('#test-mount .help-block').text().trim(),
  327. "You have used up available name changes.",
  328. "valid help text is displayed in message");
  329. done();
  330. });
  331. });
  332. it("handles username change", function(done) {
  333. $.mockjax({
  334. url: user.api_url.username,
  335. status: 200,
  336. type: 'GET',
  337. responseText: {
  338. changes_left: 2,
  339. length_min: 3,
  340. length_max: 14,
  341. next_on: null
  342. }
  343. });
  344. $.mockjax({
  345. url: user.api_url.username,
  346. status: 200,
  347. type: 'POST',
  348. responseText: {
  349. username: 'Newt',
  350. slug: 'newt',
  351. options: {
  352. changes_left: 2,
  353. length_min: 3,
  354. length_max: 14,
  355. next_on: null
  356. }
  357. }
  358. });
  359. $.mockjax({
  360. url: '/test-api/name-history/?user=' + user.id,
  361. status: 200,
  362. responseText: {
  363. results: []
  364. }
  365. });
  366. /* jshint ignore:start */
  367. testUtils.render(
  368. <Root user={user}
  369. username-history={[]} />
  370. );
  371. /* jshint ignore:end */
  372. snackbarStore.callback(function(message) {
  373. assert.deepEqual(message, {
  374. message: "Your username has been changed successfully.",
  375. type: 'success'
  376. }, "error message was shown");
  377. done();
  378. });
  379. testUtils.onElement('#test-mount form #id_username', function() {
  380. testUtils.simulateChange('#test-mount form #id_username', 'newt');
  381. testUtils.simulateSubmit('#test-mount form');
  382. });
  383. });
  384. });