TokenAccessHandlerTests.coffee 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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/TokenAccess/TokenAccessHandler"
  7. expect = require("chai").expect
  8. ObjectId = require("mongojs").ObjectId
  9. describe "TokenAccessHandler", ->
  10. beforeEach ->
  11. @token = 'sometokenthing'
  12. @projectId = ObjectId()
  13. @project =
  14. _id: @projectId
  15. publicAccesLevel: 'tokenBased'
  16. @userId = ObjectId()
  17. @req = {}
  18. @TokenAccessHandler = SandboxedModule.require modulePath, requires:
  19. '../../models/Project': {Project: @Project = {}}
  20. describe 'findProjectWithReadOnlyToken', ->
  21. beforeEach ->
  22. @Project.findOne = sinon.stub().callsArgWith(2, null, @project)
  23. it 'should call Project.findOne', (done) ->
  24. @TokenAccessHandler.findProjectWithReadOnlyToken @token, (err, project) =>
  25. expect(@Project.findOne.callCount).to.equal 1
  26. expect(@Project.findOne.calledWith({
  27. 'tokens.readOnly': @token,
  28. 'publicAccesLevel': 'tokenBased'
  29. })).to.equal true
  30. done()
  31. it 'should produce a project object with no error', (done) ->
  32. @TokenAccessHandler.findProjectWithReadOnlyToken @token, (err, project) =>
  33. expect(err).to.not.exist
  34. expect(project).to.exist
  35. expect(project).to.deep.equal @project
  36. done()
  37. describe 'when Project.findOne produces an error', ->
  38. beforeEach ->
  39. @Project.findOne = sinon.stub().callsArgWith(2, new Error('woops'))
  40. it 'should produce an error', (done) ->
  41. @TokenAccessHandler.findProjectWithReadOnlyToken @token, (err, project) =>
  42. expect(err).to.exist
  43. expect(project).to.not.exist
  44. expect(err).to.be.instanceof Error
  45. done()
  46. describe 'findProjectWithReadAndWriteToken', ->
  47. beforeEach ->
  48. @Project.findOne = sinon.stub().callsArgWith(2, null, @project)
  49. it 'should call Project.findOne', (done) ->
  50. @TokenAccessHandler.findProjectWithReadAndWriteToken @token, (err, project) =>
  51. expect(@Project.findOne.callCount).to.equal 1
  52. expect(@Project.findOne.calledWith({
  53. 'tokens.readAndWrite': @token,
  54. 'publicAccesLevel': 'tokenBased'
  55. })).to.equal true
  56. done()
  57. it 'should produce a project object with no error', (done) ->
  58. @TokenAccessHandler.findProjectWithReadAndWriteToken @token, (err, project) =>
  59. expect(err).to.not.exist
  60. expect(project).to.exist
  61. expect(project).to.deep.equal @project
  62. done()
  63. describe 'when Project.findOne produces an error', ->
  64. beforeEach ->
  65. @Project.findOne = sinon.stub().callsArgWith(2, new Error('woops'))
  66. it 'should produce an error', (done) ->
  67. @TokenAccessHandler.findProjectWithReadAndWriteToken @token, (err, project) =>
  68. expect(err).to.exist
  69. expect(project).to.not.exist
  70. expect(err).to.be.instanceof Error
  71. done()
  72. describe 'addReadOnlyUserToProject', ->
  73. beforeEach ->
  74. @Project.update = sinon.stub().callsArgWith(2, null)
  75. it 'should call Project.update', (done) ->
  76. @TokenAccessHandler.addReadOnlyUserToProject @userId, @projectId, (err) =>
  77. expect(@Project.update.callCount).to.equal 1
  78. expect(@Project.update.calledWith({
  79. _id: @projectId
  80. })).to.equal true
  81. expect(@Project.update.lastCall.args[1]['$addToSet'])
  82. .to.have.keys 'tokenAccessReadOnly_refs'
  83. done()
  84. it 'should not produce an error', (done) ->
  85. @TokenAccessHandler.addReadOnlyUserToProject @userId, @projectId, (err) =>
  86. expect(err).to.not.exist
  87. done()
  88. describe 'when Project.update produces an error', ->
  89. beforeEach ->
  90. @Project.update = sinon.stub().callsArgWith(2, new Error('woops'))
  91. it 'should produce an error', (done) ->
  92. @TokenAccessHandler.addReadOnlyUserToProject @userId, @projectId, (err) =>
  93. expect(err).to.exist
  94. done()
  95. describe 'addReadAndWriteUserToProject', ->
  96. beforeEach ->
  97. @Project.update = sinon.stub().callsArgWith(2, null)
  98. it 'should call Project.update', (done) ->
  99. @TokenAccessHandler.addReadAndWriteUserToProject @userId, @projectId, (err) =>
  100. expect(@Project.update.callCount).to.equal 1
  101. expect(@Project.update.calledWith({
  102. _id: @projectId
  103. })).to.equal true
  104. expect(@Project.update.lastCall.args[1]['$addToSet'])
  105. .to.have.keys 'tokenAccessReadAndWrite_refs'
  106. done()
  107. it 'should not produce an error', (done) ->
  108. @TokenAccessHandler.addReadAndWriteUserToProject @userId, @projectId, (err) =>
  109. expect(err).to.not.exist
  110. done()
  111. describe 'when Project.update produces an error', ->
  112. beforeEach ->
  113. @Project.update = sinon.stub().callsArgWith(2, new Error('woops'))
  114. it 'should produce an error', (done) ->
  115. @TokenAccessHandler.addReadAndWriteUserToProject @userId, @projectId, (err) =>
  116. expect(err).to.exist
  117. done()
  118. describe 'grantSessionReadOnlyTokenAccess', ->
  119. beforeEach ->
  120. @req = {session: {}, headers: {}}
  121. it 'should add the token to the session', (done) ->
  122. @TokenAccessHandler.grantSessionReadOnlyTokenAccess(@req, @projectId, @token)
  123. expect(@req.session.anonReadOnlyTokenAccess[@projectId.toString()])
  124. .to.equal @token
  125. done()
  126. describe 'isValidReadOnlyToken', ->
  127. beforeEach ->
  128. @TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
  129. .callsArgWith(1, null, @project)
  130. it 'should call findProjectWithReadOnlyToken', (done) ->
  131. @TokenAccessHandler.isValidReadOnlyToken @projectId, @token, (err, allowed) =>
  132. expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
  133. .to.equal 1
  134. done()
  135. it 'should allow access', (done) ->
  136. @TokenAccessHandler.isValidReadOnlyToken @projectId, @token, (err, allowed) =>
  137. expect(err).to.not.exist
  138. expect(allowed).to.equal true
  139. done()
  140. describe 'when no project is found', ->
  141. beforeEach ->
  142. @TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
  143. .callsArgWith(1, null, null)
  144. it 'should call findProjectWithReadOnlyToken', (done) ->
  145. @TokenAccessHandler.isValidReadOnlyToken @projectId, @token, (err, allowed) =>
  146. expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
  147. .to.equal 1
  148. done()
  149. it 'should not allow access', (done) ->
  150. @TokenAccessHandler.isValidReadOnlyToken @req, @projectId, (err, allowed) =>
  151. expect(err).to.not.exist
  152. expect(allowed).to.equal false
  153. done()
  154. describe 'when no findProject produces an error', ->
  155. beforeEach ->
  156. @TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
  157. .callsArgWith(1, new Error('woops'))
  158. it 'should call findProjectWithReadOnlyToken', (done) ->
  159. @TokenAccessHandler.isValidReadOnlyToken @projectId, @token, (err, allowed) =>
  160. expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
  161. .to.equal 1
  162. done()
  163. it 'should produce an error and not allow access', (done) ->
  164. @TokenAccessHandler.isValidReadOnlyToken @projectId, @token, (err, allowed) =>
  165. expect(err).to.exist
  166. expect(err).to.be.instanceof Error
  167. expect(allowed).to.equal undefined
  168. done()
  169. describe 'when project is not set to token-based access', ->
  170. beforeEach ->
  171. @project.publicAccesLevel = 'private'
  172. @TokenAccessHandler.findProjectWithReadOnlyToken = sinon.stub()
  173. .callsArgWith(1, null, @project)
  174. it 'should call findProjectWithReadOnlyToken', (done) ->
  175. @TokenAccessHandler.isValidReadOnlyToken @projectId, @token, (err, allowed) =>
  176. expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
  177. .to.equal 1
  178. done()
  179. it 'should not allow access', (done) ->
  180. @TokenAccessHandler.isValidReadOnlyToken @projectId, @token, (err, allowed) =>
  181. expect(err).to.not.exist
  182. expect(allowed).to.equal false
  183. done()
  184. describe 'with nothing', ->
  185. beforeEach ->
  186. it 'should not call findProjectWithReadOnlyToken', (done) ->
  187. @TokenAccessHandler.isValidReadOnlyToken @projectId, null, (err, allowed) =>
  188. expect(@TokenAccessHandler.findProjectWithReadOnlyToken.callCount)
  189. .to.equal 0
  190. done()
  191. it 'should not allow access', (done) ->
  192. @TokenAccessHandler.isValidReadOnlyToken @req, @projectId, (err, allowed) =>
  193. expect(err).to.not.exist
  194. expect(allowed).to.equal false
  195. done()