PasswordResetControllerTests.coffee 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. should = require('chai').should()
  2. SandboxedModule = require('sandboxed-module')
  3. assert = require('assert')
  4. path = require('path')
  5. sinon = require('sinon')
  6. modulePath = path.join __dirname, "../../../../app/js/Features/PasswordReset/PasswordResetController"
  7. expect = require("chai").expect
  8. describe "PasswordResetController", ->
  9. beforeEach ->
  10. @settings = {}
  11. @PasswordResetHandler =
  12. generateAndEmailResetToken:sinon.stub()
  13. setNewUserPassword:sinon.stub()
  14. @RateLimiter =
  15. addCount: sinon.stub()
  16. @PasswordResetController = SandboxedModule.require modulePath, requires:
  17. "settings-sharelatex":@settings
  18. "./PasswordResetHandler":@PasswordResetHandler
  19. "logger-sharelatex": log:->
  20. "../../infrastructure/RateLimiter":@RateLimiter
  21. @email = "bob@bob.com "
  22. @token = "my security token that was emailed to me"
  23. @password = "my new password"
  24. @req =
  25. body:
  26. email:@email
  27. passwordResetToken:@token
  28. password:@password
  29. i18n:
  30. translate:->
  31. session: {}
  32. query: {}
  33. @res = {}
  34. describe "requestReset", ->
  35. it "should error if the rate limit is hit", (done)->
  36. @PasswordResetHandler.generateAndEmailResetToken.callsArgWith(1, null, true)
  37. @RateLimiter.addCount.callsArgWith(1, null, false)
  38. @res.send = (code)=>
  39. code.should.equal 500
  40. @PasswordResetHandler.generateAndEmailResetToken.calledWith(@email.trim()).should.equal false
  41. done()
  42. @PasswordResetController.requestReset @req, @res
  43. it "should tell the handler to process that email", (done)->
  44. @RateLimiter.addCount.callsArgWith(1, null, true)
  45. @PasswordResetHandler.generateAndEmailResetToken.callsArgWith(1, null, true)
  46. @res.sendStatus = (code)=>
  47. code.should.equal 200
  48. @PasswordResetHandler.generateAndEmailResetToken.calledWith(@email.trim()).should.equal true
  49. done()
  50. @PasswordResetController.requestReset @req, @res
  51. it "should send a 500 if there is an error", (done)->
  52. @RateLimiter.addCount.callsArgWith(1, null, true)
  53. @PasswordResetHandler.generateAndEmailResetToken.callsArgWith(1, "error")
  54. @res.send = (code)=>
  55. code.should.equal 500
  56. done()
  57. @PasswordResetController.requestReset @req, @res
  58. it "should send a 404 if the email doesn't exist", (done)->
  59. @RateLimiter.addCount.callsArgWith(1, null, true)
  60. @PasswordResetHandler.generateAndEmailResetToken.callsArgWith(1, null, false)
  61. @res.send = (code)=>
  62. code.should.equal 404
  63. done()
  64. @PasswordResetController.requestReset @req, @res
  65. it "should lowercase the email address", (done)->
  66. @email = "UPerCaseEMAIL@example.Com"
  67. @req.body.email = @email
  68. @RateLimiter.addCount.callsArgWith(1, null, true)
  69. @PasswordResetHandler.generateAndEmailResetToken.callsArgWith(1, null, true)
  70. @res.sendStatus = (code)=>
  71. code.should.equal 200
  72. @PasswordResetHandler.generateAndEmailResetToken.calledWith(@email.toLowerCase()).should.equal true
  73. done()
  74. @PasswordResetController.requestReset @req, @res
  75. describe "setNewUserPassword", ->
  76. beforeEach ->
  77. @req.session.resetToken = @token
  78. it "should tell the user handler to reset the password", (done)->
  79. @PasswordResetHandler.setNewUserPassword.callsArgWith(2, null, true)
  80. @res.sendStatus = (code)=>
  81. code.should.equal 200
  82. @PasswordResetHandler.setNewUserPassword.calledWith(@token, @password).should.equal true
  83. done()
  84. @PasswordResetController.setNewUserPassword @req, @res
  85. it "should send 404 if the token didn't work", (done)->
  86. @PasswordResetHandler.setNewUserPassword.callsArgWith(2, null, false)
  87. @res.send = (code)=>
  88. code.should.equal 404
  89. done()
  90. @PasswordResetController.setNewUserPassword @req, @res
  91. it "should return 400 (Bad Request) if there is no password", (done)->
  92. @req.body.password = ""
  93. @PasswordResetHandler.setNewUserPassword.callsArgWith(2)
  94. @res.sendStatus = (code)=>
  95. code.should.equal 400
  96. @PasswordResetHandler.setNewUserPassword.called.should.equal false
  97. done()
  98. @PasswordResetController.setNewUserPassword @req, @res
  99. it "should return 400 (Bad Request) if there is no passwordResetToken", (done)->
  100. @req.body.passwordResetToken = ""
  101. @PasswordResetHandler.setNewUserPassword.callsArgWith(2)
  102. @res.sendStatus = (code)=>
  103. code.should.equal 400
  104. @PasswordResetHandler.setNewUserPassword.called.should.equal false
  105. done()
  106. @PasswordResetController.setNewUserPassword @req, @res
  107. it "should clear the session.resetToken", (done) ->
  108. @PasswordResetHandler.setNewUserPassword.callsArgWith(2, null, true)
  109. @res.sendStatus = (code)=>
  110. code.should.equal 200
  111. @req.session.should.not.have.property 'resetToken'
  112. done()
  113. @PasswordResetController.setNewUserPassword @req, @res
  114. describe "renderSetPasswordForm", ->
  115. describe "with token in query-string", ->
  116. beforeEach ->
  117. @req.query.passwordResetToken = @token
  118. it "should set session.resetToken and redirect", (done) ->
  119. @req.session.should.not.have.property 'resetToken'
  120. @res.redirect = (path) =>
  121. path.should.equal '/user/password/set'
  122. @req.session.resetToken.should.equal @token
  123. done()
  124. @PasswordResetController.renderSetPasswordForm(@req, @res)
  125. describe "without a token in query-string", ->
  126. describe "with token in session", ->
  127. beforeEach ->
  128. @req.session.resetToken = @token
  129. it "should render the page, passing the reset token", (done) ->
  130. @res.render = (template_path, options) =>
  131. options.passwordResetToken.should.equal @req.session.resetToken
  132. done()
  133. @PasswordResetController.renderSetPasswordForm(@req, @res)
  134. describe "without a token in session", ->
  135. it "should redirect to the reset request page", (done) ->
  136. @res.redirect = (path) =>
  137. path.should.equal "/user/password/reset"
  138. @req.session.should.not.have.property 'resetToken'
  139. done()
  140. @PasswordResetController.renderSetPasswordForm(@req, @res)