overleaf/services/document-updater/test/unit/coffee/ProjectManager/updateProjectTests.coffee

181 lines
7.3 KiB
CoffeeScript
Raw Normal View History

2017-11-01 19:16:49 +00:00
sinon = require('sinon')
chai = require('chai')
should = chai.should()
modulePath = "../../../../app/js/ProjectManager.js"
SandboxedModule = require('sandboxed-module')
_ = require('lodash')
2017-11-01 19:16:49 +00:00
describe "ProjectManager", ->
beforeEach ->
@ProjectManager = SandboxedModule.require modulePath, requires:
"./RedisManager": @RedisManager = {}
2018-03-09 14:14:14 +00:00
"./ProjectHistoryRedisManager": @ProjectHistoryRedisManager = {}
2017-11-01 19:16:49 +00:00
"./DocumentManager": @DocumentManager = {}
"logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() }
2018-02-15 15:55:12 +00:00
"./HistoryManager": @HistoryManager = {}
2017-11-01 19:16:49 +00:00
"./Metrics": @Metrics =
Timer: class Timer
done: sinon.stub()
@project_id = "project-id-123"
@projectHistoryId = 'history-id-123'
2017-11-01 19:16:49 +00:00
@user_id = "user-id-123"
@version = 1234567
2018-02-15 15:55:12 +00:00
@HistoryManager.shouldFlushHistoryOps = sinon.stub().returns(false)
@HistoryManager.flushProjectChangesAsync = sinon.stub()
2017-11-01 19:16:49 +00:00
@callback = sinon.stub()
describe "updateProjectWithLocks", ->
2017-11-10 14:54:56 +00:00
describe "rename operations", ->
2017-11-01 19:16:49 +00:00
beforeEach ->
2017-11-10 14:54:56 +00:00
@firstDocUpdate =
id: 1
pathname: 'foo'
newPathname: 'foo'
@secondDocUpdate =
id: 2
pathname: 'bar'
newPathname: 'bar2'
@docUpdates = [ @firstDocUpdate, @secondDocUpdate ]
@firstFileUpdate =
id: 2
pathname: 'bar'
newPathname: 'bar2'
@fileUpdates = [ @firstFileUpdate ]
@DocumentManager.renameDocWithLock = sinon.stub().yields()
2018-03-09 14:14:14 +00:00
@ProjectHistoryRedisManager.queueRenameEntity = sinon.stub().yields()
2017-11-01 19:16:49 +00:00
2017-11-10 14:54:56 +00:00
describe "successfully", ->
beforeEach ->
@ProjectManager.updateProjectWithLocks @project_id, @projectHistoryId, @user_id, @docUpdates, @fileUpdates, @version, @callback
2017-11-06 16:14:27 +00:00
2017-11-10 14:54:56 +00:00
it "should rename the docs in the updates", ->
firstDocUpdateWithVersion = _.extend({}, @firstDocUpdate, {version: "#{@version}.0"})
secondDocUpdateWithVersion = _.extend({}, @secondDocUpdate, {version: "#{@version}.1"})
2017-11-10 14:54:56 +00:00
@DocumentManager.renameDocWithLock
.calledWith(@project_id, @firstDocUpdate.id, @user_id, firstDocUpdateWithVersion, @projectHistoryId)
2017-11-10 14:54:56 +00:00
.should.equal true
@DocumentManager.renameDocWithLock
.calledWith(@project_id, @secondDocUpdate.id, @user_id, secondDocUpdateWithVersion, @projectHistoryId)
2017-11-10 14:54:56 +00:00
.should.equal true
2017-11-01 19:16:49 +00:00
2017-11-10 14:54:56 +00:00
it "should rename the files in the updates", ->
firstFileUpdateWithVersion = _.extend({}, @firstFileUpdate, {version: "#{@version}.2"})
2018-03-09 14:14:14 +00:00
@ProjectHistoryRedisManager.queueRenameEntity
.calledWith(@project_id, @projectHistoryId, 'file', @firstFileUpdate.id, @user_id, firstFileUpdateWithVersion)
2017-11-10 14:54:56 +00:00
.should.equal true
2017-11-01 19:16:49 +00:00
2018-02-15 15:55:12 +00:00
it "should not flush the history", ->
@HistoryManager.flushProjectChangesAsync
.calledWith(@project_id)
.should.equal false
2017-11-10 14:54:56 +00:00
it "should call the callback", ->
@callback.called.should.equal true
describe "when renaming a doc fails", ->
beforeEach ->
@error = new Error('error')
@DocumentManager.renameDocWithLock = sinon.stub().yields(@error)
@ProjectManager.updateProjectWithLocks @project_id, @projectHistoryId, @user_id, @docUpdates, @fileUpdates, @version, @callback
2017-11-10 14:54:56 +00:00
it "should call the callback with the error", ->
@callback.calledWith(@error).should.equal true
2017-11-06 16:14:27 +00:00
2017-11-10 14:54:56 +00:00
describe "when renaming a file fails", ->
beforeEach ->
@error = new Error('error')
2018-03-09 14:14:14 +00:00
@ProjectHistoryRedisManager.queueRenameEntity = sinon.stub().yields(@error)
@ProjectManager.updateProjectWithLocks @project_id, @projectHistoryId, @user_id, @docUpdates, @fileUpdates, @version, @callback
2017-11-06 16:14:27 +00:00
2017-11-10 14:54:56 +00:00
it "should call the callback with the error", ->
@callback.calledWith(@error).should.equal true
2018-02-15 15:55:12 +00:00
describe "with enough ops to flush", ->
beforeEach ->
@HistoryManager.shouldFlushHistoryOps = sinon.stub().returns(true)
@ProjectManager.updateProjectWithLocks @project_id, @projectHistoryId, @user_id, @docUpdates, @fileUpdates, @version, @callback
2018-02-15 15:55:12 +00:00
it "should flush the history", ->
@HistoryManager.flushProjectChangesAsync
.calledWith(@project_id)
.should.equal true
2017-11-10 14:54:56 +00:00
describe "add operations", ->
2017-11-06 16:14:27 +00:00
beforeEach ->
2017-11-10 14:54:56 +00:00
@firstDocUpdate =
id: 1
docLines: "a\nb"
@secondDocUpdate =
id: 2
docLines: "a\nb"
@docUpdates = [ @firstDocUpdate, @secondDocUpdate ]
@firstFileUpdate =
2018-03-07 17:06:42 +00:00
id: 3
2017-11-10 14:54:56 +00:00
url: 'filestore.example.com/2'
2018-03-07 17:06:42 +00:00
@secondFileUpdate =
id: 4
url: 'filestore.example.com/3'
@fileUpdates = [ @firstFileUpdate, @secondFileUpdate ]
2018-03-09 14:14:14 +00:00
@ProjectHistoryRedisManager.queueAddEntity = sinon.stub().yields()
2017-11-10 14:54:56 +00:00
describe "successfully", ->
beforeEach ->
@ProjectManager.updateProjectWithLocks @project_id, @projectHistoryId, @user_id, @docUpdates, @fileUpdates, @version, @callback
2017-11-10 14:54:56 +00:00
it "should add the docs in the updates", ->
firstDocUpdateWithVersion = _.extend({}, @firstDocUpdate, {version: "#{@version}.0"})
secondDocUpdateWithVersion = _.extend({}, @secondDocUpdate, {version: "#{@version}.1"})
2018-03-07 17:06:42 +00:00
@ProjectHistoryRedisManager.queueAddEntity.getCall(0)
.calledWith(@project_id, @projectHistoryId, 'doc', @firstDocUpdate.id, @user_id, firstDocUpdateWithVersion)
2017-11-10 14:54:56 +00:00
.should.equal true
2018-03-07 17:06:42 +00:00
@ProjectHistoryRedisManager.queueAddEntity.getCall(1)
.calledWith(@project_id, @projectHistoryId, 'doc', @secondDocUpdate.id, @user_id, secondDocUpdateWithVersion)
2017-11-10 14:54:56 +00:00
.should.equal true
it "should add the files in the updates", ->
firstFileUpdateWithVersion = _.extend({}, @firstFileUpdate, {version: "#{@version}.2"})
2018-03-07 17:06:42 +00:00
secondFileUpdateWithVersion = _.extend({}, @secondFileUpdate, {version: "#{@version}.3"})
@ProjectHistoryRedisManager.queueAddEntity.getCall(2)
.calledWith(@project_id, @projectHistoryId, 'file', @firstFileUpdate.id, @user_id, firstFileUpdateWithVersion)
2017-11-10 14:54:56 +00:00
.should.equal true
2018-03-07 17:06:42 +00:00
@ProjectHistoryRedisManager.queueAddEntity.getCall(3)
.calledWith(@project_id, @projectHistoryId, 'file', @secondFileUpdate.id, @user_id, secondFileUpdateWithVersion)
2018-03-07 17:06:42 +00:00
.should.equal true
2017-11-10 14:54:56 +00:00
2018-02-15 15:55:12 +00:00
it "should not flush the history", ->
@HistoryManager.flushProjectChangesAsync
.calledWith(@project_id)
.should.equal false
2017-11-10 14:54:56 +00:00
it "should call the callback", ->
@callback.called.should.equal true
describe "when adding a doc fails", ->
beforeEach ->
@error = new Error('error')
2018-03-09 14:14:14 +00:00
@ProjectHistoryRedisManager.queueAddEntity = sinon.stub().yields(@error)
@ProjectManager.updateProjectWithLocks @project_id, @projectHistoryId, @user_id, @docUpdates, @fileUpdates, @version, @callback
2017-11-10 14:54:56 +00:00
it "should call the callback with the error", ->
@callback.calledWith(@error).should.equal true
describe "when adding a file fails", ->
beforeEach ->
@error = new Error('error')
2018-03-09 14:14:14 +00:00
@ProjectHistoryRedisManager.queueAddEntity = sinon.stub().yields(@error)
@ProjectManager.updateProjectWithLocks @project_id, @projectHistoryId, @user_id, @docUpdates, @fileUpdates, @version, @callback
2017-11-10 14:54:56 +00:00
it "should call the callback with the error", ->
@callback.calledWith(@error).should.equal true
2017-11-01 19:16:49 +00:00
2018-02-15 15:55:12 +00:00
describe "with enough ops to flush", ->
beforeEach ->
@HistoryManager.shouldFlushHistoryOps = sinon.stub().returns(true)
@ProjectManager.updateProjectWithLocks @project_id, @projectHistoryId, @user_id, @docUpdates, @fileUpdates, @version, @callback
2018-02-15 15:55:12 +00:00
it "should flush the history", ->
@HistoryManager.flushProjectChangesAsync
.calledWith(@project_id)
.should.equal true