sign-in.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. import assert from 'assert';
  2. import React from 'react'; // jshint ignore:line
  3. import ReactDOM from 'react-dom'; // jshint ignore:line
  4. import misago from 'misago/index';
  5. import SignIn from 'misago/components/sign-in'; // jshint ignore:line
  6. import modal from 'misago/services/modal';
  7. import snackbar from 'misago/services/snackbar';
  8. let component = null;
  9. let snackbarStore = null;
  10. describe("Sign In", function() {
  11. beforeEach(function() {
  12. snackbarStore = window.snackbarStoreMock();
  13. snackbar.init(snackbarStore);
  14. window.initModal(modal);
  15. misago._context = {
  16. 'SETTINGS': {
  17. forum_name: 'Test Forum'
  18. },
  19. 'AUTH_API': '/test-api/auth/',
  20. 'REQUEST_ACTIVATION_URL': '/request-activation/',
  21. 'FORGOTTEN_PASSWORD_URL': '/forgotten-password/'
  22. };
  23. /* jshint ignore:start */
  24. component = ReactDOM.render(
  25. <SignIn />,
  26. document.getElementById('test-mount')
  27. );
  28. /* jshint ignore:end */
  29. });
  30. afterEach(function() {
  31. window.emptyTestContainers();
  32. window.snackbarClear(snackbar);
  33. $.mockjax.clear();
  34. });
  35. it("renders", function() {
  36. assert.ok($('#test-mount .modal-sign-in #id_username').length,
  37. "username input rendered");
  38. assert.ok($('#test-mount .modal-sign-in #id_password').length,
  39. "password input rendered");
  40. assert.equal(
  41. $('#test-mount .modal-footer .btn-default').attr('href'),
  42. misago.get('FORGOTTEN_PASSWORD_URL'),
  43. "forgotten password form url is valid");
  44. });
  45. it("handles empty submit", function() {
  46. window.simulateSubmit('#test-mount form');
  47. assert.deepEqual(snackbarStore.message, {
  48. message: "Fill out both fields.",
  49. type: 'error'
  50. }, "form validation rejected empty form");
  51. });
  52. it("handles partial submit", function() {
  53. window.simulateChange('#id_username', 'loremipsum');
  54. window.simulateSubmit('#test-mount form');
  55. assert.deepEqual(snackbarStore.message, {
  56. message: "Fill out both fields.",
  57. type: 'error'
  58. }, "form validation rejected empty form");
  59. });
  60. it("handles backend error", function(done) {
  61. $.mockjax({
  62. url: '/test-api/auth/',
  63. status: 500
  64. });
  65. window.simulateChange('#id_username', 'SomeFake');
  66. window.simulateChange('#id_password', 'pass1234');
  67. window.simulateSubmit('#test-mount form');
  68. window.afterAjax(component, function() {
  69. assert.deepEqual(snackbarStore.message, {
  70. message: "Unknown error has occured.",
  71. type: 'error'
  72. }, "form raised alert about backend error");
  73. done();
  74. });
  75. });
  76. it("handles invalid credentials", function(done) {
  77. let message = 'Login or password is incorrect.';
  78. $.mockjax({
  79. url: '/test-api/auth/',
  80. status: 400,
  81. responseText: {
  82. 'detail': message,
  83. 'code': 'invalid_login'
  84. }
  85. });
  86. window.simulateChange('#id_username', 'SomeFake');
  87. window.simulateChange('#id_password', 'pass1234');
  88. window.simulateSubmit('#test-mount form');
  89. window.afterAjax(component, function() {
  90. assert.deepEqual(snackbarStore.message, {
  91. message: message,
  92. type: 'error'
  93. }, "form raised alert about invalid credentials");
  94. done();
  95. });
  96. });
  97. it("to admin-activated account", function(done) {
  98. let message = "This account has to be activated by admin.";
  99. $.mockjax({
  100. url: '/test-api/auth/',
  101. status: 400,
  102. responseText: {
  103. 'detail': message,
  104. 'code': 'inactive_admin'
  105. }
  106. });
  107. window.simulateChange('#id_username', 'SomeFake');
  108. window.simulateChange('#id_password', 'pass1234');
  109. window.simulateSubmit('#test-mount form');
  110. window.afterAjax(component, function() {
  111. assert.deepEqual(snackbarStore.message, {
  112. message: message,
  113. type: 'info'
  114. }, "form raised alert about admin-activated account");
  115. done();
  116. });
  117. });
  118. it("to user-activated account", function(done) {
  119. let message = "This account has to be activated.";
  120. $.mockjax({
  121. url: '/test-api/auth/',
  122. status: 400,
  123. responseText: {
  124. 'detail': message,
  125. 'code': 'inactive_user'
  126. }
  127. });
  128. window.simulateChange('#id_username', 'SomeFake');
  129. window.simulateChange('#id_password', 'pass1234');
  130. window.simulateSubmit('#test-mount form');
  131. window.afterAjax(component, function() {
  132. assert.deepEqual(snackbarStore.message, {
  133. message: message,
  134. type: 'info'
  135. }, "form raised alert about user-activated account");
  136. let activateButton = $('#test-mount .modal-footer .btn-success');
  137. assert.ok(activateButton.length, "activation button displayed");
  138. assert.equal(
  139. activateButton.attr('href'), misago.get('REQUEST_ACTIVATION_URL'),
  140. "button to activation form has valid url");
  141. done();
  142. });
  143. });
  144. it("from banned IP", function(done) {
  145. $.mockjax({
  146. url: '/test-api/auth/',
  147. status: 403,
  148. responseText: {
  149. 'ban': {
  150. 'expires_on': null,
  151. 'message': {
  152. 'plain': 'Your ip is banned for spamming.',
  153. 'html': '<p>Your ip is banned for spamming.</p>',
  154. }
  155. }
  156. }
  157. });
  158. window.simulateChange('#id_username', 'SomeFake');
  159. window.simulateChange('#id_password', 'pass1234');
  160. window.simulateSubmit('#test-mount form');
  161. window.onElement('.page-error-banned .lead', function() {
  162. assert.equal(
  163. $('.page .message-body .lead p').text().trim(),
  164. "Your ip is banned for spamming.",
  165. "displayed error banned page with ban message.");
  166. done();
  167. });
  168. });
  169. it("to banned account", function(done) {
  170. $.mockjax({
  171. url: '/test-api/auth/',
  172. status: 400,
  173. responseText: {
  174. 'detail': {
  175. 'expires_on': null,
  176. 'message': {
  177. 'plain': 'You are banned for trolling.',
  178. 'html': '<p>You are banned for trolling.</p>',
  179. }
  180. },
  181. 'code': 'banned'
  182. }
  183. });
  184. window.simulateChange('#id_username', 'SomeFake');
  185. window.simulateChange('#id_password', 'pass1234');
  186. window.simulateSubmit('#test-mount form');
  187. window.onElement('.page-error-banned .lead', function() {
  188. assert.equal(
  189. $('.page .message-body .lead p').text().trim(),
  190. "You are banned for trolling.",
  191. "displayed error banned page with ban message.");
  192. done();
  193. });
  194. });
  195. it("login successfully", function(done) {
  196. $('body').append('<div id="hidden-login-form"></div>');
  197. $.mockjax({
  198. url: '/test-api/auth/',
  199. status: 200,
  200. responseText: {
  201. 'detail': 'ok'
  202. }
  203. });
  204. let form = $('#hidden-login-form');
  205. form.on('submit', function(e) {
  206. e.stopPropagation();
  207. assert.equal(form.find('input[name="username"]').val(), 'SomeFake',
  208. "form was filled with valid username.");
  209. assert.equal(form.find('input[name="password"]').val(), 'pass1234',
  210. "form was filled with valid password.");
  211. form.remove();
  212. done();
  213. return false;
  214. });
  215. window.simulateChange('#id_username', 'SomeFake');
  216. window.simulateChange('#id_password', 'pass1234');
  217. window.simulateSubmit('#test-mount form');
  218. });
  219. });