mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #9472 from overleaf/em-promisify-tpdscontroller
Promisify TpdsController GitOrigin-RevId: 35d1db628c44d39ee71bb3127cb25ece6d184457
This commit is contained in:
parent
03d8ad5eea
commit
e3a51ee385
4 changed files with 192 additions and 170 deletions
|
@ -1,5 +1,4 @@
|
||||||
let parseParams
|
const { expressify } = require('../../util/promises')
|
||||||
|
|
||||||
const TpdsUpdateHandler = require('./TpdsUpdateHandler')
|
const TpdsUpdateHandler = require('./TpdsUpdateHandler')
|
||||||
const UpdateMerger = require('./UpdateMerger')
|
const UpdateMerger = require('./UpdateMerger')
|
||||||
const Errors = require('../Errors/Errors')
|
const Errors = require('../Errors/Errors')
|
||||||
|
@ -8,132 +7,122 @@ const Path = require('path')
|
||||||
const metrics = require('@overleaf/metrics')
|
const metrics = require('@overleaf/metrics')
|
||||||
const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
|
const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
|
||||||
const SessionManager = require('../Authentication/SessionManager')
|
const SessionManager = require('../Authentication/SessionManager')
|
||||||
const TpdsQueueManager = require('./TpdsQueueManager').promises
|
const TpdsQueueManager = require('./TpdsQueueManager')
|
||||||
|
|
||||||
module.exports = {
|
// mergeUpdate and deleteUpdate are used by Dropbox, where the project is only passed as the name, as the
|
||||||
// mergeUpdate and deleteUpdate are used by Dropbox, where the project is only passed as the name, as the
|
// first part of the file path. They have to check the project exists, find it, and create it if not.
|
||||||
// first part of the file path. They have to check the project exists, find it, and create it if not.
|
// They also ignore 'noisy' files like .DS_Store, .gitignore, etc.
|
||||||
// They also ignore 'noisy' files like .DS_Store, .gitignore, etc.
|
|
||||||
mergeUpdate(req, res) {
|
|
||||||
metrics.inc('tpds.merge-update')
|
|
||||||
const { filePath, userId, projectName } = parseParams(req)
|
|
||||||
const source = req.headers['x-sl-update-source'] || 'unknown'
|
|
||||||
|
|
||||||
TpdsUpdateHandler.newUpdate(
|
async function mergeUpdate(req, res) {
|
||||||
|
metrics.inc('tpds.merge-update')
|
||||||
|
const { filePath, userId, projectName } = parseParams(req)
|
||||||
|
const source = req.headers['x-sl-update-source'] || 'unknown'
|
||||||
|
|
||||||
|
try {
|
||||||
|
await TpdsUpdateHandler.promises.newUpdate(
|
||||||
userId,
|
userId,
|
||||||
projectName,
|
projectName,
|
||||||
filePath,
|
filePath,
|
||||||
req,
|
req,
|
||||||
source,
|
source
|
||||||
err => {
|
|
||||||
if (err) {
|
|
||||||
if (err.name === 'TooManyRequestsError') {
|
|
||||||
logger.warn(
|
|
||||||
{ err, userId, filePath },
|
|
||||||
'tpds update failed to be processed, too many requests'
|
|
||||||
)
|
|
||||||
res.sendStatus(429)
|
|
||||||
} else if (err.message === 'project_has_too_many_files') {
|
|
||||||
logger.warn(
|
|
||||||
{ err, userId, filePath },
|
|
||||||
'tpds trying to append to project over file limit'
|
|
||||||
)
|
|
||||||
NotificationsBuilder.tpdsFileLimit(userId).create(projectName)
|
|
||||||
res.sendStatus(400)
|
|
||||||
} else {
|
|
||||||
logger.err(
|
|
||||||
{ err, userId, filePath },
|
|
||||||
'error receiving update from tpds'
|
|
||||||
)
|
|
||||||
res.sendStatus(500)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.sendStatus(200)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
},
|
} catch (err) {
|
||||||
|
if (err.name === 'TooManyRequestsError') {
|
||||||
deleteUpdate(req, res) {
|
logger.warn(
|
||||||
metrics.inc('tpds.delete-update')
|
{ err, userId, filePath },
|
||||||
const { filePath, userId, projectName } = parseParams(req)
|
'tpds update failed to be processed, too many requests'
|
||||||
const source = req.headers['x-sl-update-source'] || 'unknown'
|
)
|
||||||
TpdsUpdateHandler.deleteUpdate(
|
return res.sendStatus(429)
|
||||||
userId,
|
} else if (err.message === 'project_has_too_many_files') {
|
||||||
projectName,
|
logger.warn(
|
||||||
filePath,
|
{ err, userId, filePath },
|
||||||
source,
|
'tpds trying to append to project over file limit'
|
||||||
err => {
|
)
|
||||||
if (err) {
|
NotificationsBuilder.tpdsFileLimit(userId).create(projectName)
|
||||||
logger.err(
|
return res.sendStatus(400)
|
||||||
{ err, userId, filePath },
|
|
||||||
'error receiving update from tpds'
|
|
||||||
)
|
|
||||||
res.sendStatus(500)
|
|
||||||
} else {
|
|
||||||
res.sendStatus(200)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
// updateProjectContents and deleteProjectContents are used by GitHub. The project_id is known so we
|
|
||||||
// can skip right ahead to creating/updating/deleting the file. These methods will not ignore noisy
|
|
||||||
// files like .DS_Store, .gitignore, etc because people are generally more explicit with the files they
|
|
||||||
// want in git.
|
|
||||||
updateProjectContents(req, res, next) {
|
|
||||||
const projectId = req.params.project_id
|
|
||||||
const path = `/${req.params[0]}` // UpdateMerger expects leading slash
|
|
||||||
const source = req.headers['x-sl-update-source'] || 'unknown'
|
|
||||||
UpdateMerger.mergeUpdate(null, projectId, path, req, source, error => {
|
|
||||||
if (error) {
|
|
||||||
if (error.constructor === Errors.InvalidNameError) {
|
|
||||||
return res.sendStatus(422)
|
|
||||||
} else {
|
|
||||||
return next(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res.sendStatus(200)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
deleteProjectContents(req, res, next) {
|
|
||||||
const projectId = req.params.project_id
|
|
||||||
const path = `/${req.params[0]}` // UpdateMerger expects leading slash
|
|
||||||
const source = req.headers['x-sl-update-source'] || 'unknown'
|
|
||||||
|
|
||||||
UpdateMerger.deleteUpdate(null, projectId, path, source, error => {
|
|
||||||
if (error) {
|
|
||||||
return next(error)
|
|
||||||
}
|
|
||||||
res.sendStatus(200)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
async getQueues(req, res, next) {
|
|
||||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
|
||||||
try {
|
|
||||||
res.json(await TpdsQueueManager.getQueues(userId))
|
|
||||||
} catch (err) {
|
|
||||||
next(err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
parseParams: (parseParams = function (req) {
|
|
||||||
let filePath, projectName
|
|
||||||
let path = req.params[0]
|
|
||||||
const userId = req.params.user_id
|
|
||||||
|
|
||||||
path = Path.join('/', path)
|
|
||||||
if (path.substring(1).indexOf('/') === -1) {
|
|
||||||
filePath = '/'
|
|
||||||
projectName = path.substring(1)
|
|
||||||
} else {
|
} else {
|
||||||
filePath = path.substring(path.indexOf('/', 1))
|
throw err
|
||||||
projectName = path.substring(0, path.indexOf('/', 1))
|
|
||||||
projectName = projectName.replace('/', '')
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return { filePath, userId, projectName }
|
res.sendStatus(200)
|
||||||
}),
|
}
|
||||||
|
|
||||||
|
async function deleteUpdate(req, res) {
|
||||||
|
metrics.inc('tpds.delete-update')
|
||||||
|
const { filePath, userId, projectName } = parseParams(req)
|
||||||
|
const source = req.headers['x-sl-update-source'] || 'unknown'
|
||||||
|
|
||||||
|
await TpdsUpdateHandler.promises.deleteUpdate(
|
||||||
|
userId,
|
||||||
|
projectName,
|
||||||
|
filePath,
|
||||||
|
source
|
||||||
|
)
|
||||||
|
res.sendStatus(200)
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateProjectContents and deleteProjectContents are used by GitHub. The project_id is known so we
|
||||||
|
// can skip right ahead to creating/updating/deleting the file. These methods will not ignore noisy
|
||||||
|
// files like .DS_Store, .gitignore, etc because people are generally more explicit with the files they
|
||||||
|
// want in git.
|
||||||
|
|
||||||
|
async function updateProjectContents(req, res, next) {
|
||||||
|
const projectId = req.params.project_id
|
||||||
|
const path = `/${req.params[0]}` // UpdateMerger expects leading slash
|
||||||
|
const source = req.headers['x-sl-update-source'] || 'unknown'
|
||||||
|
|
||||||
|
try {
|
||||||
|
await UpdateMerger.promises.mergeUpdate(null, projectId, path, req, source)
|
||||||
|
} catch (error) {
|
||||||
|
if (error.constructor === Errors.InvalidNameError) {
|
||||||
|
return res.sendStatus(422)
|
||||||
|
} else {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.sendStatus(200)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteProjectContents(req, res, next) {
|
||||||
|
const projectId = req.params.project_id
|
||||||
|
const path = `/${req.params[0]}` // UpdateMerger expects leading slash
|
||||||
|
const source = req.headers['x-sl-update-source'] || 'unknown'
|
||||||
|
|
||||||
|
await UpdateMerger.promises.deleteUpdate(null, projectId, path, source)
|
||||||
|
res.sendStatus(200)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getQueues(req, res, next) {
|
||||||
|
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||||
|
res.json(await TpdsQueueManager.promises.getQueues(userId))
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseParams(req) {
|
||||||
|
let filePath, projectName
|
||||||
|
let path = req.params[0]
|
||||||
|
const userId = req.params.user_id
|
||||||
|
|
||||||
|
path = Path.join('/', path)
|
||||||
|
if (path.substring(1).indexOf('/') === -1) {
|
||||||
|
filePath = '/'
|
||||||
|
projectName = path.substring(1)
|
||||||
|
} else {
|
||||||
|
filePath = path.substring(path.indexOf('/', 1))
|
||||||
|
projectName = path.substring(0, path.indexOf('/', 1))
|
||||||
|
projectName = projectName.replace('/', '')
|
||||||
|
}
|
||||||
|
|
||||||
|
return { filePath, userId, projectName }
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mergeUpdate: expressify(mergeUpdate),
|
||||||
|
deleteUpdate: expressify(deleteUpdate),
|
||||||
|
updateProjectContents: expressify(updateProjectContents),
|
||||||
|
deleteProjectContents: expressify(deleteProjectContents),
|
||||||
|
getQueues: expressify(getQueues),
|
||||||
|
|
||||||
|
// for tests only
|
||||||
|
parseParams,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
const { promisify } = require('util')
|
||||||
const UpdateMerger = require('./UpdateMerger')
|
const UpdateMerger = require('./UpdateMerger')
|
||||||
const logger = require('@overleaf/logger')
|
const logger = require('@overleaf/logger')
|
||||||
const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
|
const NotificationsBuilder = require('../Notifications/NotificationsBuilder')
|
||||||
|
@ -167,4 +168,8 @@ function handleDuplicateProjects(userId, projectName, callback) {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
newUpdate,
|
newUpdate,
|
||||||
deleteUpdate,
|
deleteUpdate,
|
||||||
|
promises: {
|
||||||
|
newUpdate: promisify(newUpdate),
|
||||||
|
deleteUpdate: promisify(deleteUpdate),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ const EditorController = require('../Editor/EditorController')
|
||||||
const FileTypeManager = require('../Uploads/FileTypeManager')
|
const FileTypeManager = require('../Uploads/FileTypeManager')
|
||||||
const FileWriter = require('../../infrastructure/FileWriter')
|
const FileWriter = require('../../infrastructure/FileWriter')
|
||||||
const ProjectEntityHandler = require('../Project/ProjectEntityHandler')
|
const ProjectEntityHandler = require('../Project/ProjectEntityHandler')
|
||||||
|
const { promisifyAll } = require('../../util/promises')
|
||||||
|
|
||||||
module.exports = UpdateMerger = {
|
module.exports = UpdateMerger = {
|
||||||
mergeUpdate(user_id, project_id, path, updateRequest, source, callback) {
|
mergeUpdate(user_id, project_id, path, updateRequest, source, callback) {
|
||||||
|
@ -259,3 +260,5 @@ module.exports = UpdateMerger = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports.promises = promisifyAll(module.exports)
|
||||||
|
|
|
@ -1,34 +1,44 @@
|
||||||
const SandboxedModule = require('sandboxed-module')
|
const SandboxedModule = require('sandboxed-module')
|
||||||
const sinon = require('sinon')
|
const sinon = require('sinon')
|
||||||
|
const { expect } = require('chai')
|
||||||
const Errors = require('../../../../app/src/Features/Errors/Errors')
|
const Errors = require('../../../../app/src/Features/Errors/Errors')
|
||||||
const modulePath = require('path').join(
|
|
||||||
__dirname,
|
const MODULE_PATH =
|
||||||
'../../../../app/src/Features/ThirdPartyDataStore/TpdsController.js'
|
'../../../../app/src/Features/ThirdPartyDataStore/TpdsController.js'
|
||||||
)
|
|
||||||
|
|
||||||
describe('TpdsController', function () {
|
describe('TpdsController', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
this.TpdsUpdateHandler = {}
|
this.TpdsUpdateHandler = {
|
||||||
|
promises: {
|
||||||
|
newUpdate: sinon.stub().resolves(),
|
||||||
|
deleteUpdate: sinon.stub().resolves(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
this.UpdateMerger = {
|
||||||
|
promises: {
|
||||||
|
mergeUpdate: sinon.stub().resolves(),
|
||||||
|
deleteUpdate: sinon.stub().resolves(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
this.NotificationsBuilder = {
|
||||||
|
tpdsFileLimit: sinon.stub().returns({ create: sinon.stub() }),
|
||||||
|
}
|
||||||
this.SessionManager = {
|
this.SessionManager = {
|
||||||
getLoggedInUserId: sinon.stub().returns('user-id'),
|
getLoggedInUserId: sinon.stub().returns('user-id'),
|
||||||
}
|
}
|
||||||
this.TpdsQueueManager = {
|
this.TpdsQueueManager = {
|
||||||
promises: {
|
promises: {
|
||||||
getQueues: sinon.stub().returns('queues'),
|
getQueues: sinon.stub().resolves('queues'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
this.TpdsController = SandboxedModule.require(modulePath, {
|
|
||||||
|
this.TpdsController = SandboxedModule.require(MODULE_PATH, {
|
||||||
requires: {
|
requires: {
|
||||||
'./TpdsUpdateHandler': this.TpdsUpdateHandler,
|
'./TpdsUpdateHandler': this.TpdsUpdateHandler,
|
||||||
'./UpdateMerger': (this.UpdateMerger = {}),
|
'./UpdateMerger': this.UpdateMerger,
|
||||||
'../Notifications/NotificationsBuilder': (this.NotificationsBuilder = {
|
'../Notifications/NotificationsBuilder': this.NotificationsBuilder,
|
||||||
tpdsFileLimit: sinon.stub().returns({ create: sinon.stub() }),
|
|
||||||
}),
|
|
||||||
'../Authentication/SessionManager': this.SessionManager,
|
'../Authentication/SessionManager': this.SessionManager,
|
||||||
'./TpdsQueueManager': this.TpdsQueueManager,
|
'./TpdsQueueManager': this.TpdsQueueManager,
|
||||||
'@overleaf/metrics': {
|
|
||||||
inc() {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -48,10 +58,9 @@ describe('TpdsController', function () {
|
||||||
'x-sl-update-source': (this.source = 'dropbox'),
|
'x-sl-update-source': (this.source = 'dropbox'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
this.TpdsUpdateHandler.newUpdate = sinon.stub().callsArg(5)
|
|
||||||
const res = {
|
const res = {
|
||||||
sendStatus: () => {
|
sendStatus: () => {
|
||||||
this.TpdsUpdateHandler.newUpdate
|
this.TpdsUpdateHandler.promises.newUpdate
|
||||||
.calledWith(
|
.calledWith(
|
||||||
this.user_id,
|
this.user_id,
|
||||||
'projectName',
|
'projectName',
|
||||||
|
@ -66,7 +75,7 @@ describe('TpdsController', function () {
|
||||||
this.TpdsController.mergeUpdate(req, res)
|
this.TpdsController.mergeUpdate(req, res)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return a 500 error when the update receiver fails', function () {
|
it('should return a 500 error when the update receiver fails', function (done) {
|
||||||
const path = '/projectName/here.txt'
|
const path = '/projectName/here.txt'
|
||||||
const req = {
|
const req = {
|
||||||
pause() {},
|
pause() {},
|
||||||
|
@ -78,17 +87,18 @@ describe('TpdsController', function () {
|
||||||
'x-sl-update-source': (this.source = 'dropbox'),
|
'x-sl-update-source': (this.source = 'dropbox'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
this.TpdsUpdateHandler.newUpdate = sinon
|
this.TpdsUpdateHandler.promises.newUpdate.rejects(new Error())
|
||||||
.stub()
|
|
||||||
.callsArgWith(5, 'update-receiver-error')
|
|
||||||
const res = {
|
const res = {
|
||||||
sendStatus: sinon.stub(),
|
sendStatus: sinon.stub(),
|
||||||
}
|
}
|
||||||
this.TpdsController.mergeUpdate(req, res)
|
this.TpdsController.mergeUpdate(req, res, err => {
|
||||||
res.sendStatus.calledWith(500).should.equal(true)
|
expect(err).to.exist
|
||||||
|
expect(res.sendStatus).not.to.have.been.called
|
||||||
|
done()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return a 400 error when the project is too big', function () {
|
it('should return a 400 error when the project is too big', function (done) {
|
||||||
const path = '/projectName/here.txt'
|
const path = '/projectName/here.txt'
|
||||||
const req = {
|
const req = {
|
||||||
pause() {},
|
pause() {},
|
||||||
|
@ -100,20 +110,22 @@ describe('TpdsController', function () {
|
||||||
'x-sl-update-source': (this.source = 'dropbox'),
|
'x-sl-update-source': (this.source = 'dropbox'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
this.TpdsUpdateHandler.newUpdate = sinon
|
this.TpdsUpdateHandler.promises.newUpdate.rejects({
|
||||||
.stub()
|
message: 'project_has_too_many_files',
|
||||||
.callsArgWith(5, { message: 'project_has_too_many_files' })
|
})
|
||||||
const res = {
|
const res = {
|
||||||
sendStatus: sinon.stub(),
|
sendStatus: status => {
|
||||||
|
expect(status).to.equal(400)
|
||||||
|
this.NotificationsBuilder.tpdsFileLimit.should.have.been.calledWith(
|
||||||
|
this.user_id
|
||||||
|
)
|
||||||
|
done()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
this.TpdsController.mergeUpdate(req, res)
|
this.TpdsController.mergeUpdate(req, res)
|
||||||
res.sendStatus.calledWith(400).should.equal(true)
|
|
||||||
this.NotificationsBuilder.tpdsFileLimit
|
|
||||||
.calledWith(this.user_id)
|
|
||||||
.should.equal(true)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return a 429 error when the update receiver fails due to too many requests error', function () {
|
it('should return a 429 error when the update receiver fails due to too many requests error', function (done) {
|
||||||
const path = '/projectName/here.txt'
|
const path = '/projectName/here.txt'
|
||||||
const req = {
|
const req = {
|
||||||
pause() {},
|
pause() {},
|
||||||
|
@ -125,14 +137,16 @@ describe('TpdsController', function () {
|
||||||
'x-sl-update-source': (this.source = 'dropbox'),
|
'x-sl-update-source': (this.source = 'dropbox'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
this.TpdsUpdateHandler.newUpdate = sinon
|
this.TpdsUpdateHandler.promises.newUpdate.rejects(
|
||||||
.stub()
|
new Errors.TooManyRequestsError('project on cooldown')
|
||||||
.callsArgWith(5, new Errors.TooManyRequestsError('project on cooldown'))
|
)
|
||||||
const res = {
|
const res = {
|
||||||
sendStatus: sinon.stub(),
|
sendStatus: status => {
|
||||||
|
expect(status).to.equal(429)
|
||||||
|
done()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
this.TpdsController.mergeUpdate(req, res)
|
this.TpdsController.mergeUpdate(req, res)
|
||||||
res.sendStatus.calledWith(429).should.equal(true)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -148,10 +162,9 @@ describe('TpdsController', function () {
|
||||||
'x-sl-update-source': (this.source = 'dropbox'),
|
'x-sl-update-source': (this.source = 'dropbox'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
this.TpdsUpdateHandler.deleteUpdate = sinon.stub().callsArg(4)
|
|
||||||
const res = {
|
const res = {
|
||||||
sendStatus: () => {
|
sendStatus: () => {
|
||||||
this.TpdsUpdateHandler.deleteUpdate
|
this.TpdsUpdateHandler.promises.deleteUpdate
|
||||||
.calledWith(this.user_id, 'projectName', '/here.txt', this.source)
|
.calledWith(this.user_id, 'projectName', '/here.txt', this.source)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
done()
|
done()
|
||||||
|
@ -190,8 +203,7 @@ describe('TpdsController', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('updateProjectContents', function () {
|
describe('updateProjectContents', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function (done) {
|
||||||
this.UpdateMerger.mergeUpdate = sinon.stub().callsArg(5)
|
|
||||||
this.req = {
|
this.req = {
|
||||||
params: {
|
params: {
|
||||||
0: (this.path = 'chapters/main.tex'),
|
0: (this.path = 'chapters/main.tex'),
|
||||||
|
@ -204,13 +216,17 @@ describe('TpdsController', function () {
|
||||||
'x-sl-update-source': (this.source = 'github'),
|
'x-sl-update-source': (this.source = 'github'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
this.res = { sendStatus: sinon.stub() }
|
this.res = {
|
||||||
|
sendStatus: sinon.stub().callsFake(() => {
|
||||||
|
done()
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
this.TpdsController.updateProjectContents(this.req, this.res, this.next)
|
this.TpdsController.updateProjectContents(this.req, this.res, this.next)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should merge the update', function () {
|
it('should merge the update', function () {
|
||||||
this.UpdateMerger.mergeUpdate
|
this.UpdateMerger.promises.mergeUpdate
|
||||||
.calledWith(
|
.calledWith(
|
||||||
null,
|
null,
|
||||||
this.project_id,
|
this.project_id,
|
||||||
|
@ -227,8 +243,7 @@ describe('TpdsController', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('deleteProjectContents', function () {
|
describe('deleteProjectContents', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function (done) {
|
||||||
this.UpdateMerger.deleteUpdate = sinon.stub().callsArg(4)
|
|
||||||
this.req = {
|
this.req = {
|
||||||
params: {
|
params: {
|
||||||
0: (this.path = 'chapters/main.tex'),
|
0: (this.path = 'chapters/main.tex'),
|
||||||
|
@ -241,13 +256,17 @@ describe('TpdsController', function () {
|
||||||
'x-sl-update-source': (this.source = 'github'),
|
'x-sl-update-source': (this.source = 'github'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
this.res = { sendStatus: sinon.stub() }
|
this.res = {
|
||||||
|
sendStatus: sinon.stub().callsFake(() => {
|
||||||
|
done()
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
this.TpdsController.deleteProjectContents(this.req, this.res, this.next)
|
this.TpdsController.deleteProjectContents(this.req, this.res, this.next)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should delete the file', function () {
|
it('should delete the file', function () {
|
||||||
this.UpdateMerger.deleteUpdate
|
this.UpdateMerger.promises.deleteUpdate
|
||||||
.calledWith(null, this.project_id, `/${this.path}`, this.source)
|
.calledWith(null, this.project_id, `/${this.path}`, this.source)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
@ -265,8 +284,11 @@ describe('TpdsController', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('success', function () {
|
describe('success', function () {
|
||||||
beforeEach(async function () {
|
beforeEach(function (done) {
|
||||||
await this.TpdsController.getQueues(this.req, this.res, this.next)
|
this.res.json.callsFake(() => {
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
this.TpdsController.getQueues(this.req, this.res, this.next)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should use userId from session', function () {
|
it('should use userId from session', function () {
|
||||||
|
@ -283,12 +305,15 @@ describe('TpdsController', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('error', function () {
|
describe('error', function () {
|
||||||
beforeEach(async function () {
|
beforeEach(function (done) {
|
||||||
this.err = new Error()
|
this.err = new Error()
|
||||||
this.TpdsQueueManager.promises.getQueues = sinon
|
this.TpdsQueueManager.promises.getQueues = sinon
|
||||||
.stub()
|
.stub()
|
||||||
.rejects(this.err)
|
.rejects(this.err)
|
||||||
await this.TpdsController.getQueues(this.req, this.res, this.next)
|
this.next.callsFake(() => {
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
this.TpdsController.getQueues(this.req, this.res, this.next)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should call next with error', function () {
|
it('should call next with error', function () {
|
||||||
|
|
Loading…
Reference in a new issue