2019-05-29 05:21:06 -04:00
|
|
|
const SandboxedModule = require('sandboxed-module')
|
|
|
|
const sinon = require('sinon')
|
2019-06-27 06:10:28 -04:00
|
|
|
const Errors = require('../../../../app/src/Features/Errors/Errors')
|
2019-05-29 05:21:06 -04:00
|
|
|
const modulePath = require('path').join(
|
|
|
|
__dirname,
|
|
|
|
'../../../../app/src/Features/ThirdPartyDataStore/TpdsController.js'
|
|
|
|
)
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('TpdsController', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.TpdsUpdateHandler = {}
|
2020-04-16 12:26:02 -04:00
|
|
|
this.AuthenticationController = {
|
2021-04-27 03:52:58 -04:00
|
|
|
getLoggedInUserId: sinon.stub().returns('user-id'),
|
2020-04-16 12:26:02 -04:00
|
|
|
}
|
|
|
|
this.TpdsQueueManager = {
|
|
|
|
promises: {
|
2021-04-27 03:52:58 -04:00
|
|
|
getQueues: sinon.stub().returns('queues'),
|
|
|
|
},
|
2020-04-16 12:26:02 -04:00
|
|
|
}
|
2019-05-29 05:21:06 -04:00
|
|
|
this.TpdsController = SandboxedModule.require(modulePath, {
|
|
|
|
requires: {
|
|
|
|
'./TpdsUpdateHandler': this.TpdsUpdateHandler,
|
|
|
|
'./UpdateMerger': (this.UpdateMerger = {}),
|
2020-03-03 11:36:39 -05:00
|
|
|
'../Notifications/NotificationsBuilder': (this.NotificationsBuilder = {
|
2021-04-27 03:52:58 -04:00
|
|
|
tpdsFileLimit: sinon.stub().returns({ create: sinon.stub() }),
|
2020-03-03 11:36:39 -05:00
|
|
|
}),
|
2020-04-16 12:26:02 -04:00
|
|
|
'../Authentication/AuthenticationController': this
|
|
|
|
.AuthenticationController,
|
|
|
|
'./TpdsQueueManager': this.TpdsQueueManager,
|
2020-10-30 04:10:50 -04:00
|
|
|
'@overleaf/metrics': {
|
2021-04-27 03:52:58 -04:00
|
|
|
inc() {},
|
|
|
|
},
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2019-06-27 06:10:28 -04:00
|
|
|
this.user_id = 'dsad29jlkjas'
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('getting an update', function () {
|
|
|
|
it('should process the update with the update receiver', function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
const path = '/projectName/here.txt'
|
|
|
|
const req = {
|
|
|
|
pause() {},
|
|
|
|
params: { 0: path, user_id: this.user_id },
|
|
|
|
session: {
|
2021-04-27 03:52:58 -04:00
|
|
|
destroy() {},
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
headers: {
|
2021-04-27 03:52:58 -04:00
|
|
|
'x-sl-update-source': (this.source = 'dropbox'),
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
this.TpdsUpdateHandler.newUpdate = sinon.stub().callsArg(5)
|
|
|
|
const res = {
|
|
|
|
sendStatus: () => {
|
|
|
|
this.TpdsUpdateHandler.newUpdate
|
|
|
|
.calledWith(
|
|
|
|
this.user_id,
|
|
|
|
'projectName',
|
|
|
|
'/here.txt',
|
|
|
|
req,
|
|
|
|
this.source
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
2019-06-27 06:10:28 -04:00
|
|
|
done()
|
2021-04-27 03:52:58 -04:00
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2019-06-27 06:10:28 -04:00
|
|
|
this.TpdsController.mergeUpdate(req, res)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should return a 500 error when the update receiver fails', function () {
|
2019-06-27 06:10:28 -04:00
|
|
|
const path = '/projectName/here.txt'
|
|
|
|
const req = {
|
|
|
|
pause() {},
|
|
|
|
params: { 0: path, user_id: this.user_id },
|
|
|
|
session: {
|
2021-04-27 03:52:58 -04:00
|
|
|
destroy() {},
|
2019-06-27 06:10:28 -04:00
|
|
|
},
|
|
|
|
headers: {
|
2021-04-27 03:52:58 -04:00
|
|
|
'x-sl-update-source': (this.source = 'dropbox'),
|
|
|
|
},
|
2019-06-27 06:10:28 -04:00
|
|
|
}
|
|
|
|
this.TpdsUpdateHandler.newUpdate = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(5, 'update-receiver-error')
|
|
|
|
const res = {
|
2021-04-27 03:52:58 -04:00
|
|
|
sendStatus: sinon.stub(),
|
2019-06-27 06:10:28 -04:00
|
|
|
}
|
|
|
|
this.TpdsController.mergeUpdate(req, res)
|
|
|
|
res.sendStatus.calledWith(500).should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should return a 400 error when the project is too big', function () {
|
2020-03-03 11:36:39 -05:00
|
|
|
const path = '/projectName/here.txt'
|
|
|
|
const req = {
|
|
|
|
pause() {},
|
|
|
|
params: { 0: path, user_id: this.user_id, projectName: 'projectName' },
|
|
|
|
session: {
|
2021-04-27 03:52:58 -04:00
|
|
|
destroy() {},
|
2020-03-03 11:36:39 -05:00
|
|
|
},
|
|
|
|
headers: {
|
2021-04-27 03:52:58 -04:00
|
|
|
'x-sl-update-source': (this.source = 'dropbox'),
|
|
|
|
},
|
2020-03-03 11:36:39 -05:00
|
|
|
}
|
|
|
|
this.TpdsUpdateHandler.newUpdate = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(5, { message: 'project_has_too_many_files' })
|
|
|
|
const res = {
|
2021-04-27 03:52:58 -04:00
|
|
|
sendStatus: sinon.stub(),
|
2020-03-03 11:36:39 -05:00
|
|
|
}
|
|
|
|
this.TpdsController.mergeUpdate(req, res)
|
|
|
|
res.sendStatus.calledWith(400).should.equal(true)
|
|
|
|
this.NotificationsBuilder.tpdsFileLimit
|
|
|
|
.calledWith(this.user_id)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should return a 429 error when the update receiver fails due to too many requests error', function () {
|
2019-06-27 06:10:28 -04:00
|
|
|
const path = '/projectName/here.txt'
|
|
|
|
const req = {
|
|
|
|
pause() {},
|
|
|
|
params: { 0: path, user_id: this.user_id },
|
|
|
|
session: {
|
2021-04-27 03:52:58 -04:00
|
|
|
destroy() {},
|
2019-06-27 06:10:28 -04:00
|
|
|
},
|
|
|
|
headers: {
|
2021-04-27 03:52:58 -04:00
|
|
|
'x-sl-update-source': (this.source = 'dropbox'),
|
|
|
|
},
|
2019-06-27 06:10:28 -04:00
|
|
|
}
|
|
|
|
this.TpdsUpdateHandler.newUpdate = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(5, new Errors.TooManyRequestsError('project on cooldown'))
|
|
|
|
const res = {
|
2021-04-27 03:52:58 -04:00
|
|
|
sendStatus: sinon.stub(),
|
2019-06-27 06:10:28 -04:00
|
|
|
}
|
|
|
|
this.TpdsController.mergeUpdate(req, res)
|
|
|
|
res.sendStatus.calledWith(429).should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('getting a delete update', function () {
|
|
|
|
it('should process the delete with the update receiver', function (done) {
|
2019-05-29 05:21:06 -04:00
|
|
|
const path = '/projectName/here.txt'
|
|
|
|
const req = {
|
|
|
|
params: { 0: path, user_id: this.user_id },
|
|
|
|
session: {
|
2021-04-27 03:52:58 -04:00
|
|
|
destroy() {},
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
headers: {
|
2021-04-27 03:52:58 -04:00
|
|
|
'x-sl-update-source': (this.source = 'dropbox'),
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
this.TpdsUpdateHandler.deleteUpdate = sinon.stub().callsArg(4)
|
|
|
|
const res = {
|
|
|
|
sendStatus: () => {
|
|
|
|
this.TpdsUpdateHandler.deleteUpdate
|
|
|
|
.calledWith(this.user_id, 'projectName', '/here.txt', this.source)
|
|
|
|
.should.equal(true)
|
2019-06-27 06:10:28 -04:00
|
|
|
done()
|
2021-04-27 03:52:58 -04:00
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
2019-06-27 06:10:28 -04:00
|
|
|
this.TpdsController.deleteUpdate(req, res)
|
2019-08-07 10:04:04 -04:00
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('parseParams', function () {
|
|
|
|
it('should take the project name off the start and replace with slash', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
const path = 'noSlashHere'
|
|
|
|
const req = { params: { 0: path, user_id: this.user_id } }
|
|
|
|
const result = this.TpdsController.parseParams(req)
|
2021-02-17 08:00:48 -05:00
|
|
|
result.userId.should.equal(this.user_id)
|
2019-05-29 05:21:06 -04:00
|
|
|
result.filePath.should.equal('/')
|
2019-06-27 06:10:28 -04:00
|
|
|
result.projectName.should.equal(path)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should take the project name off the start and it with no slashes in', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
const path = '/project/file.tex'
|
|
|
|
const req = { params: { 0: path, user_id: this.user_id } }
|
|
|
|
const result = this.TpdsController.parseParams(req)
|
2021-02-17 08:00:48 -05:00
|
|
|
result.userId.should.equal(this.user_id)
|
2019-05-29 05:21:06 -04:00
|
|
|
result.filePath.should.equal('/file.tex')
|
2019-06-27 06:10:28 -04:00
|
|
|
result.projectName.should.equal('project')
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should take the project name of and return a slash for the file path', function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
const path = '/project_name'
|
|
|
|
const req = { params: { 0: path, user_id: this.user_id } }
|
|
|
|
const result = this.TpdsController.parseParams(req)
|
|
|
|
result.projectName.should.equal('project_name')
|
2019-06-27 06:10:28 -04:00
|
|
|
result.filePath.should.equal('/')
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('updateProjectContents', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.UpdateMerger.mergeUpdate = sinon.stub().callsArg(5)
|
|
|
|
this.req = {
|
|
|
|
params: {
|
|
|
|
0: (this.path = 'chapters/main.tex'),
|
2021-04-27 03:52:58 -04:00
|
|
|
project_id: (this.project_id = 'project-id-123'),
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
session: {
|
2021-04-27 03:52:58 -04:00
|
|
|
destroy: sinon.stub(),
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
headers: {
|
2021-04-27 03:52:58 -04:00
|
|
|
'x-sl-update-source': (this.source = 'github'),
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
this.res = { sendStatus: sinon.stub() }
|
|
|
|
|
2021-02-17 08:00:48 -05:00
|
|
|
this.TpdsController.updateProjectContents(this.req, this.res, this.next)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should merge the update', function () {
|
2019-06-27 06:10:28 -04:00
|
|
|
this.UpdateMerger.mergeUpdate
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(
|
|
|
|
null,
|
|
|
|
this.project_id,
|
|
|
|
`/${this.path}`,
|
|
|
|
this.req,
|
|
|
|
this.source
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should return a success', function () {
|
2019-06-27 06:10:28 -04:00
|
|
|
this.res.sendStatus.calledWith(200).should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('deleteProjectContents', function () {
|
|
|
|
beforeEach(function () {
|
2019-05-29 05:21:06 -04:00
|
|
|
this.UpdateMerger.deleteUpdate = sinon.stub().callsArg(4)
|
|
|
|
this.req = {
|
|
|
|
params: {
|
|
|
|
0: (this.path = 'chapters/main.tex'),
|
2021-04-27 03:52:58 -04:00
|
|
|
project_id: (this.project_id = 'project-id-123'),
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
session: {
|
2021-04-27 03:52:58 -04:00
|
|
|
destroy: sinon.stub(),
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
headers: {
|
2021-04-27 03:52:58 -04:00
|
|
|
'x-sl-update-source': (this.source = 'github'),
|
|
|
|
},
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
this.res = { sendStatus: sinon.stub() }
|
|
|
|
|
2021-02-17 08:00:48 -05:00
|
|
|
this.TpdsController.deleteProjectContents(this.req, this.res, this.next)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should delete the file', function () {
|
2019-06-27 06:10:28 -04:00
|
|
|
this.UpdateMerger.deleteUpdate
|
2019-05-29 05:21:06 -04:00
|
|
|
.calledWith(null, this.project_id, `/${this.path}`, this.source)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should return a success', function () {
|
2019-06-27 06:10:28 -04:00
|
|
|
this.res.sendStatus.calledWith(200).should.equal(true)
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
})
|
2020-04-16 12:26:02 -04:00
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('getQueues', function () {
|
|
|
|
beforeEach(function () {
|
2020-04-16 12:26:02 -04:00
|
|
|
this.req = {}
|
|
|
|
this.res = { json: sinon.stub() }
|
|
|
|
this.next = sinon.stub()
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('success', function () {
|
|
|
|
beforeEach(async function () {
|
2020-04-16 12:26:02 -04:00
|
|
|
await this.TpdsController.getQueues(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should use userId from session', function () {
|
2020-04-16 12:26:02 -04:00
|
|
|
this.AuthenticationController.getLoggedInUserId.should.have.been
|
|
|
|
.calledOnce
|
|
|
|
this.TpdsQueueManager.promises.getQueues.should.have.been.calledWith(
|
|
|
|
'user-id'
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should call json with response', function () {
|
2020-04-16 12:26:02 -04:00
|
|
|
this.res.json.should.have.been.calledWith('queues')
|
|
|
|
this.next.should.not.have.been.called
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
describe('error', function () {
|
|
|
|
beforeEach(async function () {
|
2020-04-16 12:26:02 -04:00
|
|
|
this.err = new Error()
|
|
|
|
this.TpdsQueueManager.promises.getQueues = sinon
|
|
|
|
.stub()
|
|
|
|
.rejects(this.err)
|
|
|
|
await this.TpdsController.getQueues(this.req, this.res, this.next)
|
|
|
|
})
|
|
|
|
|
2021-04-14 09:17:21 -04:00
|
|
|
it('should call next with error', function () {
|
2020-04-16 12:26:02 -04:00
|
|
|
this.res.json.should.not.have.been.called
|
|
|
|
this.next.should.have.been.calledWith(this.err)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|