Refactor adding and removing collaborators to not go through EditorController

This commit is contained in:
James Allen
2015-10-08 14:15:36 +01:00
parent 8cc7869b03
commit d11d536994
8 changed files with 305 additions and 235 deletions
@@ -11,15 +11,18 @@ ObjectId = require("mongojs").ObjectId
describe "CollaboratorsController", ->
beforeEach ->
@CollaboratorsHandler =
removeUserFromProject:sinon.stub()
@CollaboratorsController = SandboxedModule.require modulePath, requires:
"../Project/ProjectGetter": @ProjectGetter = {}
"./CollaboratorsHandler": @CollaboratorsHandler
"../Editor/EditorController": @EditorController = {}
"./CollaboratorsHandler": @CollaboratorsHandler = {}
"./CollaboratorsEmailHandler": @CollaboratorsEmailHandler = {}
"../User/UserGetter": @UserGetter = {}
"../Editor/EditorRealTimeController": @EditorRealTimeController = {}
'../Subscription/LimitationsManager' : @LimitationsManager = {}
'../Project/ProjectEditorHandler' : @ProjectEditorHandler = {}
@res = new MockResponse()
@req = new MockRequest()
@project_id = "project-id-123"
@callback = sinon.stub()
describe "getCollaborators", ->
@@ -51,40 +54,89 @@ describe "CollaboratorsController", ->
it "should return the formatted collaborators", ->
@res.body.should.equal JSON.stringify(@collaborators)
describe "removeSelfFromProject", ->
beforeEach ->
@req.session =
user: _id: @user_id = "user-id-123"
destroy:->
@req.params = project_id: @project_id
@CollaboratorsHandler.removeUserFromProject = sinon.stub().callsArg(2)
@CollaboratorsController.removeSelfFromProject(@req, @res)
it "should remove the logged in user from the project", ->
@CollaboratorsHandler.removeUserFromProject.calledWith(@project_id, @user_id)
it "should return a success code", ->
@res.statusCode.should.equal 204
describe "addUserToProject", ->
beforeEach ->
@req.params =
Project_id: @project_id = "project-id-123"
Project_id: @project_id
@req.body =
email: @email = "joe@example.com"
privileges: @privileges = "readAndWrite"
email: @email = "Joe@example.com"
privileges: @privileges = "readOnly"
@res.json = sinon.stub()
@EditorController.addUserToProject = sinon.stub().callsArgWith(3, null, @user = {"mock": "user"})
@CollaboratorsController.addUserToProject @req, @res
@user_id = "mock-user-id"
@raw_user = {
_id: @user_id, email: "joe@example.com", first_name: "Joe", last_name: "Example", unused: "foo"
}
@user_view = {
id: @user_id, first_name: "Joe", last_name: "Example", email: "joe@example.com"
}
@LimitationsManager.isCollaboratorLimitReached = sinon.stub().callsArgWith(1, null, false)
@ProjectEditorHandler.buildUserModelView = sinon.stub().returns(@user_view)
@CollaboratorsHandler.addEmailToProject = sinon.stub().callsArgWith(3, null, @user_id)
@UserGetter.getUser = sinon.stub().callsArgWith(1, null, @user)
@CollaboratorsEmailHandler.notifyUserOfProjectShare = sinon.stub()
@EditorRealTimeController.emitToRoom = sinon.stub()
@callback = sinon.stub()
describe "when the project can accept more collaborators", ->
beforeEach ->
@CollaboratorsController.addUserToProject @req, @res, @next
it "should add the user to the project", ->
@CollaboratorsHandler.addEmailToProject
.calledWith(@project_id, @email.toLowerCase(), @privileges)
.should.equal true
it "should emit a userAddedToProject event", ->
@EditorRealTimeController.emitToRoom
.calledWith(@project_id, "userAddedToProject", @user_view, @privileges)
.should.equal true
it "should add the user to the project", ->
@EditorController.addUserToProject
.calledWith(@project_id, @email, @privileges)
.should.equal true
it "should send the back the added user", ->
@res.json.calledWith(user: @user).should.equal true
it "should send an email to the shared-with user", ->
@CollaboratorsEmailHandler.notifyUserOfProjectShare
.calledWith(@project_id, @email.toLowerCase())
.should.equal true
it "should send the user as the response body", ->
@res.json
.calledWith({
user: @user_view
})
.should.equal true
describe "when the project cannot accept more collaborators", ->
beforeEach ->
@LimitationsManager.isCollaboratorLimitReached = sinon.stub().callsArgWith(1, null, true)
@CollaboratorsController.addUserToProject @req, @res, @next
it "should not add the user to the project", ->
@CollaboratorsHandler.addEmailToProject.called.should.equal false
it "should not emit a userAddedToProject event", ->
@EditorRealTimeController.emitToRoom.called.should.equal false
it "should send user: false as the response body", ->
@res.json
.calledWith({
user: false
})
.should.equal true
describe "when the email is not valid", ->
beforeEach ->
@req.body.email = "not-valid"
@res.status = sinon.stub().returns @res
@res.send = sinon.stub()
@CollaboratorsController.addUserToProject @req, @res, @next
it "should not add the user to the project", ->
@CollaboratorsHandler.addEmailToProject.called.should.equal false
it "should not emit a userAddedToProject event", ->
@EditorRealTimeController.emitToRoom.called.should.equal false
it "should return a 400 response", ->
@res.status.calledWith(400).should.equal true
@res.send.calledWith("invalid email address").should.equal true
describe "removeUserFromProject", ->
beforeEach ->
@@ -92,17 +144,45 @@ describe "CollaboratorsController", ->
Project_id: @project_id = "project-id-123"
user_id: @user_id = "user-id-123"
@res.sendStatus = sinon.stub()
@EditorController.removeUserFromProject = sinon.stub().callsArg(2)
@EditorRealTimeController.emitToRoom = sinon.stub()
@CollaboratorsHandler.removeUserFromProject = sinon.stub().callsArg(2)
@CollaboratorsController.removeUserFromProject @req, @res
it "should from the user from the project", ->
@EditorController.removeUserFromProject
@CollaboratorsHandler.removeUserFromProject
.calledWith(@project_id, @user_id)
.should.equal true
it "should emit a userRemovedFromProject event to the proejct", ->
@EditorRealTimeController.emitToRoom
.calledWith(@project_id, 'userRemovedFromProject', @user_id)
.should.equal true
it "should send the back a success response", ->
@res.sendStatus.calledWith(204).should.equal true
describe "removeSelfFromProject", ->
beforeEach ->
@req.session =
user: _id: @user_id = "user-id-123"
@req.params = Project_id: @project_id
@res.sendStatus = sinon.stub()
@EditorRealTimeController.emitToRoom = sinon.stub()
@CollaboratorsHandler.removeUserFromProject = sinon.stub().callsArg(2)
@CollaboratorsController.removeSelfFromProject(@req, @res)
it "should remove the logged in user from the project", ->
@CollaboratorsHandler.removeUserFromProject
.calledWith(@project_id, @user_id)
.should.equal true
it "should emit a userRemovedFromProject event to the proejct", ->
@EditorRealTimeController.emitToRoom
.calledWith(@project_id, 'userRemovedFromProject', @user_id)
.should.equal true
it "should return a success code", ->
@res.sendStatus.calledWith(204).should.equal true
describe "_formatCollaborators", ->
beforeEach ->
@@ -7,42 +7,110 @@ modulePath = path.join __dirname, "../../../../app/js/Features/Collaborators/Col
expect = require("chai").expect
describe "CollaboratorsHandler", ->
beforeEach ->
@user =
email:"bob@bob.com"
@UserModel =
findById:sinon.stub().callsArgWith(1, null, @user)
update: sinon.stub()
@settings = {}
@ProjectModel =
update: sinon.stub().callsArgWith(1)
@CollaboratorHandler = SandboxedModule.require modulePath, requires:
"settings-sharelatex":@settings
"logger-sharelatex":
log:->
err:->
'../../models/User': User:@UserModel
"../../models/Project": Project:@ProjectModel
"../Email/EmailHandler": {}
"logger-sharelatex": @logger = { log: sinon.stub(), err: sinon.stub() }
'../User/UserCreator': @UserCreator = {}
"../../models/Project": Project: @Project = {}
"../Project/ProjectEntityHandler": @ProjectEntityHandler = {}
@project_id = "123l2j13lkj"
@user_id = "132kj1lk2j"
@project_id = "mock-project-id"
@user_id = "mock-user-id"
@callback = sinon.stub()
describe "removeUserFromProject", ->
beforeEach ->
@ProjectModel.update.callsArgWith(2)
@Project.update = sinon.stub().callsArg(2)
@CollaboratorHandler.removeUserFromProject @project_id, @user_id, @callback
it "should remove the user from mongo", (done)->
@CollaboratorHandler.removeUserFromProject @project_id, @user_id, =>
update = @ProjectModel.update.args[0][1]
assert.deepEqual update, "$pull":{collaberator_refs:@user_id, readOnly_refs:@user_id}
done()
it "should remove the user from mongo", ->
@Project.update
.calledWith({
_id: @project_id
}, {
"$pull":{collaberator_refs:@user_id, readOnly_refs:@user_id}
})
.should.equal true
describe "addUserToProject", ->
beforeEach ->
@Project.update = sinon.stub().callsArg(2)
@ProjectEntityHandler.flushProjectToThirdPartyDataStore = sinon.stub().callsArg(1)
describe "as readOnly", ->
beforeEach ->
@CollaboratorHandler.addUserToProject @project_id, @user_id, "readOnly", @callback
it "should add the user to the readOnly_refs", ->
@Project.update
.calledWith({
_id: @project_id
}, {
"$push":{ readOnly_refs: @user_id }
})
.should.equal true
it "should flush the project to the TPDS", ->
@ProjectEntityHandler.flushProjectToThirdPartyDataStore
.calledWith(@project_id)
.should.equal true
describe "as readAndWrite", ->
beforeEach ->
@CollaboratorHandler.addUserToProject @project_id, @user_id, "readAndWrite", @callback
it "should add the user to the collaberator_refs", ->
@Project.update
.calledWith({
_id: @project_id
}, {
"$push":{ collaberator_refs: @user_id }
})
.should.equal true
it "should flush the project to the TPDS", ->
@ProjectEntityHandler.flushProjectToThirdPartyDataStore
.calledWith(@project_id)
.should.equal true
describe "with invalid privilegeLevel", ->
beforeEach ->
@CollaboratorHandler.addUserToProject @project_id, @user_id, "notValid", @callback
it "should call the callback with an error", ->
@callback.calledWith(new Error()).should.equal true
describe "addEmailToProject", ->
beforeEach ->
@UserCreator.getUserOrCreateHoldingAccount = sinon.stub().callsArgWith(1, null, @user = {_id: @user_id})
@CollaboratorHandler.addUserToProject = sinon.stub().callsArg(3)
describe "with a valid email", ->
beforeEach ->
@CollaboratorHandler.addEmailToProject @project_id, (@email = "Joe@example.com"), (@privilegeLevel = "readAndWrite"), @callback
it "should get the user with the lowercased email", ->
@UserCreator.getUserOrCreateHoldingAccount
.calledWith(@email.toLowerCase())
.should.equal true
it "should add the user to the project by id", ->
@CollaboratorHandler.addUserToProject
.calledWith(@project_id, @user_id, @privilegeLevel)
.should.equal true
it "should return the callback with the user_id", ->
@callback.calledWith(null, @user_id).should.equal true
describe "with an invalid email", ->
beforeEach ->
@CollaboratorHandler.addEmailToProject @project_id, "not-and-email", (@privilegeLevel = "readAndWrite"), @callback
it "should call the callback with an error", ->
@callback.calledWith(new Error()).should.equal true
it "should not add any users to the proejct", ->
@CollaboratorHandler.addUserToProject.called.should.equal false
@@ -33,10 +33,8 @@ describe "EditorController", ->
setSpellCheckLanguage: sinon.spy()
@ProjectEntityHandler =
flushProjectToThirdPartyDataStore:sinon.stub()
@ProjectEditorHandler = {}
@Project =
findPopulatedById: sinon.stub().callsArgWith(1, null, @project)
@LimitationsManager = {}
@client = new MockClient()
@settings =
@@ -56,14 +54,12 @@ describe "EditorController", ->
releaseLock : sinon.stub()
@EditorController = SandboxedModule.require modulePath, requires:
"../../infrastructure/Server" : io : @io
'../Project/ProjectEditorHandler' : @ProjectEditorHandler
'../Project/ProjectEntityHandler' : @ProjectEntityHandler
'../Project/ProjectOptionsHandler' : @ProjectOptionsHandler
'../Project/ProjectDetailsHandler': @ProjectDetailsHandler
'../Project/ProjectDeleter' : @ProjectDeleter
'../Collaborators/CollaboratorsHandler': @CollaboratorsHandler
'../DocumentUpdater/DocumentUpdaterHandler' : @DocumentUpdaterHandler
'../Subscription/LimitationsManager' : @LimitationsManager
'../../models/Project' : Project: @Project
"settings-sharelatex":@settings
'../Dropbox/DropboxProjectLinker':@dropboxProjectLinker
@@ -76,67 +72,6 @@ describe "EditorController", ->
log: sinon.stub()
err: sinon.stub()
describe "addUserToProject", ->
beforeEach ->
@email = "Jane.Doe@example.com"
@priveleges = "readOnly"
@addedUser = { _id: "added-user" }
@ProjectEditorHandler.buildUserModelView = sinon.stub().returns(@addedUser)
@CollaboratorsHandler.addUserToProject = sinon.stub().callsArgWith(3, null, @addedUser)
@EditorRealTimeController.emitToRoom = sinon.stub()
@callback = sinon.stub()
describe "when the project can accept more collaborators", ->
beforeEach ->
@LimitationsManager.isCollaboratorLimitReached = sinon.stub().callsArgWith(1, null, false)
it "should add the user to the project", (done)->
@EditorController.addUserToProject @project_id, @email, @priveleges, =>
@CollaboratorsHandler.addUserToProject.calledWith(@project_id, @email.toLowerCase(), @priveleges).should.equal true
done()
it "should emit a userAddedToProject event", (done)->
@EditorController.addUserToProject @project_id, @email, @priveleges, =>
@EditorRealTimeController.emitToRoom.calledWith(@project_id, "userAddedToProject", @addedUser).should.equal true
done()
it "should return the user to the callback", (done)->
@EditorController.addUserToProject @project_id, @email, @priveleges, (err, result)=>
result.should.equal @addedUser
done()
describe "when the project cannot accept more collaborators", ->
beforeEach ->
@LimitationsManager.isCollaboratorLimitReached = sinon.stub().callsArgWith(1, null, true)
@EditorController.addUserToProject(@project_id, @email, @priveleges, @callback)
it "should not add the user to the project", ->
@CollaboratorsHandler.addUserToProject.called.should.equal false
it "should not emit a userAddedToProject event", ->
@EditorRealTimeController.emitToRoom.called.should.equal false
it "should return false to the callback", ->
@callback.calledWith(null, false).should.equal true
describe "removeUserFromProject", ->
beforeEach ->
@removed_user_id = "removed-user-id"
@CollaboratorsHandler.removeUserFromProject = sinon.stub().callsArgWith(2)
@EditorRealTimeController.emitToRoom = sinon.stub()
@EditorController.removeUserFromProject(@project_id, @removed_user_id)
it "remove the user from the project", ->
@CollaboratorsHandler.removeUserFromProject
.calledWith(@project_id, @removed_user_id)
.should.equal true
it "should emit a userRemovedFromProject event", ->
@EditorRealTimeController.emitToRoom.calledWith(@project_id, "userRemovedFromProject", @removed_user_id).should.equal true
describe "updating compiler used for project", ->
it "should send the new compiler and project id to the project options handler", (done)->
compiler = "latex"