UserActivateController.test.mjs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import { vi } from 'vitest'
  2. import Path from 'node:path'
  3. import sinon from 'sinon'
  4. const MODULE_PATH = '../../../app/src/UserActivateController.mjs'
  5. const VIEW_PATH = Path.join(
  6. import.meta.dirname,
  7. '../../../app/views/user/activate'
  8. )
  9. describe('UserActivateController', function () {
  10. beforeEach(async function (ctx) {
  11. ctx.user = {
  12. _id: (ctx.user_id = 'kwjewkl'),
  13. features: {},
  14. email: 'joe@example.com',
  15. }
  16. ctx.UserGetter = {
  17. promises: {
  18. getUser: sinon.stub(),
  19. },
  20. }
  21. ctx.UserRegistrationHandler = { promises: {} }
  22. ctx.ErrorController = { notFound: sinon.stub() }
  23. ctx.SplitTestHandler = {
  24. promises: {
  25. getAssignment: sinon.stub().resolves({ variant: 'default' }),
  26. },
  27. }
  28. vi.doMock('../../../../../app/src/Features/User/UserGetter.js', () => ({
  29. default: ctx.UserGetter,
  30. }))
  31. vi.doMock(
  32. '../../../../../app/src/Features/User/UserRegistrationHandler.mjs',
  33. () => ({
  34. default: ctx.UserRegistrationHandler,
  35. })
  36. )
  37. vi.doMock(
  38. '../../../../../app/src/Features/Errors/ErrorController.mjs',
  39. () => ({
  40. default: ctx.ErrorController,
  41. })
  42. )
  43. vi.doMock(
  44. '../../../../../app/src/Features/SplitTests/SplitTestHandler',
  45. () => ({
  46. default: ctx.SplitTestHandler,
  47. })
  48. )
  49. ctx.UserActivateController = (await import(MODULE_PATH)).default
  50. ctx.req = {
  51. body: {},
  52. query: {},
  53. session: {
  54. user: ctx.user,
  55. },
  56. }
  57. ctx.res = {
  58. json: sinon.stub(),
  59. }
  60. })
  61. describe('activateAccountPage', function () {
  62. beforeEach(function (ctx) {
  63. ctx.UserGetter.promises.getUser = sinon.stub().resolves(ctx.user)
  64. ctx.req.query.user_id = ctx.user_id
  65. ctx.req.query.token = ctx.token = 'mock-token-123'
  66. })
  67. it('should 404 without a user_id', async function (ctx) {
  68. delete ctx.req.query.user_id
  69. await new Promise(resolve => {
  70. ctx.ErrorController.notFound = () => resolve()
  71. ctx.UserActivateController.activateAccountPage(ctx.req, ctx.res)
  72. })
  73. })
  74. it('should 404 without a token', async function (ctx) {
  75. await new Promise(resolve => {
  76. delete ctx.req.query.token
  77. ctx.ErrorController.notFound = resolve
  78. ctx.UserActivateController.activateAccountPage(ctx.req, ctx.res)
  79. })
  80. })
  81. it('should 404 without a valid user_id', async function (ctx) {
  82. await new Promise(resolve => {
  83. ctx.UserGetter.promises.getUser = sinon.stub().resolves(null)
  84. ctx.ErrorController.notFound = resolve
  85. ctx.UserActivateController.activateAccountPage(ctx.req, ctx.res)
  86. })
  87. })
  88. it('should 403 for complex user_id', async function (ctx) {
  89. await new Promise(resolve => {
  90. ctx.ErrorController.forbidden = resolve
  91. ctx.req.query.user_id = { first_name: 'X' }
  92. ctx.UserActivateController.activateAccountPage(ctx.req, ctx.res)
  93. })
  94. })
  95. it('should redirect activated users to login', async function (ctx) {
  96. await new Promise(resolve => {
  97. ctx.user.loginCount = 1
  98. ctx.res.redirect = url => {
  99. sinon.assert.calledWith(ctx.UserGetter.promises.getUser, ctx.user_id)
  100. url.should.equal('/login')
  101. resolve()
  102. }
  103. ctx.UserActivateController.activateAccountPage(ctx.req, ctx.res)
  104. })
  105. })
  106. it('render the activation page if the user has not logged in before', async function (ctx) {
  107. await new Promise(resolve => {
  108. ctx.user.loginCount = 0
  109. ctx.res.render = (page, opts) => {
  110. page.should.equal(VIEW_PATH)
  111. opts.email.should.equal(ctx.user.email)
  112. opts.token.should.equal(ctx.token)
  113. resolve()
  114. }
  115. ctx.UserActivateController.activateAccountPage(ctx.req, ctx.res)
  116. })
  117. })
  118. })
  119. describe('register', function () {
  120. beforeEach(async function (ctx) {
  121. ctx.UserRegistrationHandler.promises.registerNewUserAndSendActivationEmail =
  122. sinon.stub().resolves({
  123. user: ctx.user,
  124. setNewPasswordUrl: (ctx.url = 'mock/url'),
  125. })
  126. ctx.req.body.email = ctx.user.email = ctx.email = 'email@example.com'
  127. await ctx.UserActivateController.register(ctx.req, ctx.res)
  128. })
  129. it('should register the user and send them an email', function (ctx) {
  130. sinon.assert.calledWith(
  131. ctx.UserRegistrationHandler.promises
  132. .registerNewUserAndSendActivationEmail,
  133. ctx.email
  134. )
  135. })
  136. it('should return the user and activation url', function (ctx) {
  137. ctx.res.json
  138. .calledWith({
  139. email: ctx.email,
  140. setNewPasswordUrl: ctx.url,
  141. })
  142. .should.equal(true)
  143. })
  144. })
  145. })