mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 22:23:42 +01:00
Merge pull request #4761 from overleaf/em-peek-doc
Do not unarchive docs when resyncing project history GitOrigin-RevId: c7df75789c01e6c85b464a9b94b14654d8568407
This commit is contained in:
@@ -1,303 +1,277 @@
|
||||
/* eslint-disable
|
||||
camelcase,
|
||||
node/handle-callback-err,
|
||||
max-len,
|
||||
no-unused-vars,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
const { promisify } = require('util')
|
||||
const { promisifyMultiResult } = require('../../util/promises')
|
||||
const request = require('request').defaults({ jar: false })
|
||||
const OError = require('@overleaf/o-error')
|
||||
const logger = require('logger-sharelatex')
|
||||
const settings = require('@overleaf/settings')
|
||||
const Errors = require('../Errors/Errors')
|
||||
const { promisifyAll } = require('../../util/promises')
|
||||
|
||||
const TIMEOUT = 30 * 1000 // request timeout
|
||||
|
||||
const DocstoreManager = {
|
||||
deleteDoc(project_id, doc_id, name, deletedAt, callback) {
|
||||
if (callback == null) {
|
||||
callback = function (error) {}
|
||||
function deleteDoc(projectId, docId, name, deletedAt, callback) {
|
||||
const url = `${settings.apis.docstore.url}/project/${projectId}/doc/${docId}`
|
||||
const docMetaData = { deleted: true, deletedAt, name }
|
||||
const options = { url, json: docMetaData, timeout: TIMEOUT }
|
||||
request.patch(options, (error, res) => {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
const url = `${settings.apis.docstore.url}/project/${project_id}/doc/${doc_id}`
|
||||
const docMetaData = { deleted: true, deletedAt, name }
|
||||
const options = { url, json: docMetaData, timeout: TIMEOUT }
|
||||
request.patch(options, function (error, res) {
|
||||
if (error != null) {
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
callback(null)
|
||||
} else if (res.statusCode === 404) {
|
||||
error = new Errors.NotFoundError({
|
||||
message: 'tried to delete doc not in docstore',
|
||||
info: {
|
||||
projectId,
|
||||
docId,
|
||||
},
|
||||
})
|
||||
callback(error) // maybe suppress the error when delete doc which is not present?
|
||||
} else {
|
||||
error = new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{
|
||||
projectId,
|
||||
docId,
|
||||
}
|
||||
)
|
||||
callback(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getAllDocs(projectId, callback) {
|
||||
const url = `${settings.apis.docstore.url}/project/${projectId}/doc`
|
||||
request.get(
|
||||
{
|
||||
url,
|
||||
timeout: TIMEOUT,
|
||||
json: true,
|
||||
},
|
||||
(error, res, docs) => {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
return callback(null)
|
||||
} else if (res.statusCode === 404) {
|
||||
error = new Errors.NotFoundError({
|
||||
message: 'tried to delete doc not in docstore',
|
||||
info: {
|
||||
project_id,
|
||||
doc_id,
|
||||
},
|
||||
})
|
||||
return callback(error) // maybe suppress the error when delete doc which is not present?
|
||||
callback(null, docs)
|
||||
} else {
|
||||
error = new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{
|
||||
project_id,
|
||||
doc_id,
|
||||
}
|
||||
)
|
||||
return callback(error)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getAllDocs(project_id, callback) {
|
||||
if (callback == null) {
|
||||
callback = function (error) {}
|
||||
}
|
||||
const url = `${settings.apis.docstore.url}/project/${project_id}/doc`
|
||||
return request.get(
|
||||
{
|
||||
url,
|
||||
timeout: TIMEOUT,
|
||||
json: true,
|
||||
},
|
||||
function (error, res, docs) {
|
||||
if (error != null) {
|
||||
return callback(error)
|
||||
}
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
return callback(null, docs)
|
||||
} else {
|
||||
error = new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{ project_id }
|
||||
)
|
||||
return callback(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
getAllDeletedDocs(project_id, callback) {
|
||||
const url = `${settings.apis.docstore.url}/project/${project_id}/doc-deleted`
|
||||
request.get(
|
||||
{ url, timeout: TIMEOUT, json: true },
|
||||
function (error, res, docs) {
|
||||
if (error) {
|
||||
callback(
|
||||
OError.tag(error, 'could not get deleted docs from docstore')
|
||||
)
|
||||
} else if (res.statusCode === 200) {
|
||||
callback(null, docs)
|
||||
} else {
|
||||
callback(
|
||||
new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{ project_id }
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
getAllRanges(project_id, callback) {
|
||||
if (callback == null) {
|
||||
callback = function (error) {}
|
||||
}
|
||||
const url = `${settings.apis.docstore.url}/project/${project_id}/ranges`
|
||||
return request.get(
|
||||
{
|
||||
url,
|
||||
timeout: TIMEOUT,
|
||||
json: true,
|
||||
},
|
||||
function (error, res, docs) {
|
||||
if (error != null) {
|
||||
return callback(error)
|
||||
}
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
return callback(null, docs)
|
||||
} else {
|
||||
error = new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{ project_id }
|
||||
)
|
||||
return callback(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
getDoc(project_id, doc_id, options, callback) {
|
||||
if (options == null) {
|
||||
options = {}
|
||||
}
|
||||
if (callback == null) {
|
||||
callback = function (error, lines, rev, version) {}
|
||||
}
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
}
|
||||
let url = `${settings.apis.docstore.url}/project/${project_id}/doc/${doc_id}`
|
||||
if (options.include_deleted) {
|
||||
url += '?include_deleted=true'
|
||||
}
|
||||
return request.get(
|
||||
{
|
||||
url,
|
||||
timeout: TIMEOUT,
|
||||
json: true,
|
||||
},
|
||||
function (error, res, doc) {
|
||||
if (error != null) {
|
||||
return callback(error)
|
||||
}
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
logger.log(
|
||||
{ doc_id, project_id, version: doc.version, rev: doc.rev },
|
||||
'got doc from docstore api'
|
||||
)
|
||||
return callback(null, doc.lines, doc.rev, doc.version, doc.ranges)
|
||||
} else if (res.statusCode === 404) {
|
||||
error = new Errors.NotFoundError({
|
||||
message: 'doc not found in docstore',
|
||||
info: {
|
||||
project_id,
|
||||
doc_id,
|
||||
},
|
||||
})
|
||||
return callback(error)
|
||||
} else {
|
||||
error = new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{
|
||||
project_id,
|
||||
doc_id,
|
||||
}
|
||||
)
|
||||
return callback(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
isDocDeleted(project_id, doc_id, callback) {
|
||||
const url = `${settings.apis.docstore.url}/project/${project_id}/doc/${doc_id}/deleted`
|
||||
request.get(
|
||||
{ url, timeout: TIMEOUT, json: true },
|
||||
function (err, res, body) {
|
||||
if (err) {
|
||||
callback(err)
|
||||
} else if (res.statusCode === 200) {
|
||||
callback(null, body.deleted)
|
||||
} else if (res.statusCode === 404) {
|
||||
callback(
|
||||
new Errors.NotFoundError({
|
||||
message: 'doc does not exist in project',
|
||||
info: { project_id, doc_id },
|
||||
})
|
||||
)
|
||||
} else {
|
||||
callback(
|
||||
new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{ project_id, doc_id }
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
updateDoc(project_id, doc_id, lines, version, ranges, callback) {
|
||||
if (callback == null) {
|
||||
callback = function (error, modified, rev) {}
|
||||
}
|
||||
const url = `${settings.apis.docstore.url}/project/${project_id}/doc/${doc_id}`
|
||||
return request.post(
|
||||
{
|
||||
url,
|
||||
timeout: TIMEOUT,
|
||||
json: {
|
||||
lines,
|
||||
version,
|
||||
ranges,
|
||||
},
|
||||
},
|
||||
function (error, res, result) {
|
||||
if (error != null) {
|
||||
return callback(error)
|
||||
}
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
logger.log(
|
||||
{ project_id, doc_id },
|
||||
'update doc in docstore url finished'
|
||||
)
|
||||
return callback(null, result.modified, result.rev)
|
||||
} else {
|
||||
error = new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{ project_id, doc_id }
|
||||
)
|
||||
return callback(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
archiveProject(project_id, callback) {
|
||||
DocstoreManager._operateOnProject(project_id, 'archive', callback)
|
||||
},
|
||||
|
||||
unarchiveProject(project_id, callback) {
|
||||
DocstoreManager._operateOnProject(project_id, 'unarchive', callback)
|
||||
},
|
||||
|
||||
destroyProject(project_id, callback) {
|
||||
DocstoreManager._operateOnProject(project_id, 'destroy', callback)
|
||||
},
|
||||
|
||||
_operateOnProject(project_id, method, callback) {
|
||||
const url = `${settings.apis.docstore.url}/project/${project_id}/${method}`
|
||||
logger.log({ project_id }, `calling ${method} for project in docstore`)
|
||||
// use default timeout for archiving/unarchiving/destroying
|
||||
request.post(url, function (err, res, docs) {
|
||||
if (err != null) {
|
||||
OError.tag(err, `error calling ${method} project in docstore`, {
|
||||
project_id,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
callback()
|
||||
} else {
|
||||
const error = new Error(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`
|
||||
)
|
||||
logger.warn(
|
||||
{ err: error, project_id },
|
||||
`error calling ${method} project in docstore`
|
||||
{ projectId }
|
||||
)
|
||||
callback(error)
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = DocstoreManager
|
||||
module.exports.promises = promisifyAll(DocstoreManager, {
|
||||
multiResult: {
|
||||
getDoc: ['lines', 'rev', 'version', 'ranges'],
|
||||
updateDoc: ['modified', 'rev'],
|
||||
function getAllDeletedDocs(projectId, callback) {
|
||||
const url = `${settings.apis.docstore.url}/project/${projectId}/doc-deleted`
|
||||
request.get({ url, timeout: TIMEOUT, json: true }, (error, res, docs) => {
|
||||
if (error) {
|
||||
callback(OError.tag(error, 'could not get deleted docs from docstore'))
|
||||
} else if (res.statusCode === 200) {
|
||||
callback(null, docs)
|
||||
} else {
|
||||
callback(
|
||||
new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{ projectId }
|
||||
)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getAllRanges(projectId, callback) {
|
||||
const url = `${settings.apis.docstore.url}/project/${projectId}/ranges`
|
||||
request.get(
|
||||
{
|
||||
url,
|
||||
timeout: TIMEOUT,
|
||||
json: true,
|
||||
},
|
||||
(error, res, docs) => {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
callback(null, docs)
|
||||
} else {
|
||||
error = new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{ projectId }
|
||||
)
|
||||
callback(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function getDoc(projectId, docId, options, callback) {
|
||||
if (options == null) {
|
||||
options = {}
|
||||
}
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
}
|
||||
const requestParams = { timeout: TIMEOUT, json: true }
|
||||
if (options.peek) {
|
||||
requestParams.url = `${settings.apis.docstore.url}/project/${projectId}/doc/${docId}/peek`
|
||||
} else {
|
||||
requestParams.url = `${settings.apis.docstore.url}/project/${projectId}/doc/${docId}`
|
||||
}
|
||||
if (options.include_deleted) {
|
||||
requestParams.qs = { include_deleted: 'true' }
|
||||
}
|
||||
request.get(requestParams, (error, res, doc) => {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
logger.log(
|
||||
{ docId, projectId, version: doc.version, rev: doc.rev },
|
||||
'got doc from docstore api'
|
||||
)
|
||||
callback(null, doc.lines, doc.rev, doc.version, doc.ranges)
|
||||
} else if (res.statusCode === 404) {
|
||||
error = new Errors.NotFoundError({
|
||||
message: 'doc not found in docstore',
|
||||
info: {
|
||||
projectId,
|
||||
docId,
|
||||
},
|
||||
})
|
||||
callback(error)
|
||||
} else {
|
||||
error = new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{
|
||||
projectId,
|
||||
docId,
|
||||
}
|
||||
)
|
||||
callback(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function isDocDeleted(projectId, docId, callback) {
|
||||
const url = `${settings.apis.docstore.url}/project/${projectId}/doc/${docId}/deleted`
|
||||
request.get({ url, timeout: TIMEOUT, json: true }, (err, res, body) => {
|
||||
if (err) {
|
||||
callback(err)
|
||||
} else if (res.statusCode === 200) {
|
||||
callback(null, body.deleted)
|
||||
} else if (res.statusCode === 404) {
|
||||
callback(
|
||||
new Errors.NotFoundError({
|
||||
message: 'doc does not exist in project',
|
||||
info: { projectId, docId },
|
||||
})
|
||||
)
|
||||
} else {
|
||||
callback(
|
||||
new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{ projectId, docId }
|
||||
)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function updateDoc(projectId, docId, lines, version, ranges, callback) {
|
||||
const url = `${settings.apis.docstore.url}/project/${projectId}/doc/${docId}`
|
||||
request.post(
|
||||
{
|
||||
url,
|
||||
timeout: TIMEOUT,
|
||||
json: {
|
||||
lines,
|
||||
version,
|
||||
ranges,
|
||||
},
|
||||
},
|
||||
(error, res, result) => {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
logger.log({ projectId, docId }, 'update doc in docstore url finished')
|
||||
callback(null, result.modified, result.rev)
|
||||
} else {
|
||||
error = new OError(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`,
|
||||
{ projectId, docId }
|
||||
)
|
||||
callback(error)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function archiveProject(projectId, callback) {
|
||||
_operateOnProject(projectId, 'archive', callback)
|
||||
}
|
||||
|
||||
function unarchiveProject(projectId, callback) {
|
||||
_operateOnProject(projectId, 'unarchive', callback)
|
||||
}
|
||||
|
||||
function destroyProject(projectId, callback) {
|
||||
_operateOnProject(projectId, 'destroy', callback)
|
||||
}
|
||||
|
||||
function _operateOnProject(projectId, method, callback) {
|
||||
const url = `${settings.apis.docstore.url}/project/${projectId}/${method}`
|
||||
logger.log({ projectId }, `calling ${method} for project in docstore`)
|
||||
// use default timeout for archiving/unarchiving/destroying
|
||||
request.post(url, (err, res, docs) => {
|
||||
if (err) {
|
||||
OError.tag(err, `error calling ${method} project in docstore`, {
|
||||
projectId,
|
||||
})
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
callback()
|
||||
} else {
|
||||
const error = new Error(
|
||||
`docstore api responded with non-success code: ${res.statusCode}`
|
||||
)
|
||||
logger.warn(
|
||||
{ err: error, projectId },
|
||||
`error calling ${method} project in docstore`
|
||||
)
|
||||
callback(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
deleteDoc,
|
||||
getAllDocs,
|
||||
getAllDeletedDocs,
|
||||
getAllRanges,
|
||||
getDoc,
|
||||
isDocDeleted,
|
||||
updateDoc,
|
||||
archiveProject,
|
||||
unarchiveProject,
|
||||
destroyProject,
|
||||
promises: {
|
||||
deleteDoc: promisify(deleteDoc),
|
||||
getAllDocs: promisify(getAllDocs),
|
||||
getAllDeletedDocs: promisify(getAllDeletedDocs),
|
||||
getAllRanges: promisify(getAllRanges),
|
||||
getDoc: promisifyMultiResult(getDoc, ['lines', 'rev', 'version', 'ranges']),
|
||||
isDocDeleted: promisify(isDocDeleted),
|
||||
updateDoc: promisifyMultiResult(updateDoc, ['modified', 'rev']),
|
||||
archiveProject: promisify(archiveProject),
|
||||
unarchiveProject: promisify(unarchiveProject),
|
||||
destroyProject: promisify(destroyProject),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
/* eslint-disable
|
||||
camelcase,
|
||||
node/handle-callback-err,
|
||||
max-len,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS103: Rewrite code to no longer use __guard__
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
const ProjectGetter = require('../Project/ProjectGetter')
|
||||
const OError = require('@overleaf/o-error')
|
||||
const ProjectLocator = require('../Project/ProjectLocator')
|
||||
@@ -20,122 +6,109 @@ const ProjectEntityUpdateHandler = require('../Project/ProjectEntityUpdateHandle
|
||||
const logger = require('logger-sharelatex')
|
||||
const _ = require('lodash')
|
||||
|
||||
module.exports = {
|
||||
getDocument(req, res, next) {
|
||||
if (next == null) {
|
||||
next = function (error) {}
|
||||
}
|
||||
const project_id = req.params.Project_id
|
||||
const { doc_id } = req.params
|
||||
const plain =
|
||||
__guard__(req != null ? req.query : undefined, x => x.plain) === 'true'
|
||||
return ProjectGetter.getProject(
|
||||
project_id,
|
||||
{ rootFolder: true, overleaf: true },
|
||||
function (error, project) {
|
||||
if (error != null) {
|
||||
return next(error)
|
||||
}
|
||||
if (project == null) {
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
return ProjectLocator.findElement(
|
||||
{ project, element_id: doc_id, type: 'doc' },
|
||||
function (error, doc, path) {
|
||||
if (error != null) {
|
||||
OError.tag(error, 'error finding element for getDocument', {
|
||||
doc_id,
|
||||
project_id,
|
||||
})
|
||||
return next(error)
|
||||
}
|
||||
return ProjectEntityHandler.getDoc(
|
||||
project_id,
|
||||
doc_id,
|
||||
function (error, lines, rev, version, ranges) {
|
||||
if (error != null) {
|
||||
OError.tag(
|
||||
error,
|
||||
'error finding doc contents for getDocument',
|
||||
{
|
||||
doc_id,
|
||||
project_id,
|
||||
}
|
||||
)
|
||||
return next(error)
|
||||
}
|
||||
if (plain) {
|
||||
res.type('text/plain')
|
||||
return res.send(lines.join('\n'))
|
||||
} else {
|
||||
const projectHistoryId = _.get(project, 'overleaf.history.id')
|
||||
const projectHistoryDisplay = _.get(
|
||||
project,
|
||||
'overleaf.history.display'
|
||||
)
|
||||
const sendToBothHistorySystems = _.get(
|
||||
project,
|
||||
'overleaf.history.allowDowngrade'
|
||||
)
|
||||
// if project has been switched but has 'allowDowngrade' set
|
||||
// then leave projectHistoryType undefined to (temporarily)
|
||||
// continue sending updates to both SL and full project history
|
||||
const projectHistoryType =
|
||||
projectHistoryDisplay && !sendToBothHistorySystems
|
||||
? 'project-history'
|
||||
: undefined // for backwards compatibility, don't send anything if the project is still on track-changes
|
||||
return res.json({
|
||||
lines,
|
||||
version,
|
||||
ranges,
|
||||
pathname: path.fileSystem,
|
||||
projectHistoryId,
|
||||
projectHistoryType,
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
function getDocument(req, res, next) {
|
||||
const { Project_id: projectId, doc_id: docId } = req.params
|
||||
const plain = req.query.plain === 'true'
|
||||
const peek = req.query.peek === 'true'
|
||||
ProjectGetter.getProject(
|
||||
projectId,
|
||||
{ rootFolder: true, overleaf: true },
|
||||
(error, project) => {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
if (!project) {
|
||||
return res.sendStatus(404)
|
||||
}
|
||||
ProjectLocator.findElement(
|
||||
{ project, element_id: docId, type: 'doc' },
|
||||
(error, doc, path) => {
|
||||
if (error) {
|
||||
OError.tag(error, 'error finding element for getDocument', {
|
||||
docId,
|
||||
projectId,
|
||||
})
|
||||
return next(error)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
setDocument(req, res, next) {
|
||||
if (next == null) {
|
||||
next = function (error) {}
|
||||
}
|
||||
const project_id = req.params.Project_id
|
||||
const { doc_id } = req.params
|
||||
const { lines, version, ranges, lastUpdatedAt, lastUpdatedBy } = req.body
|
||||
return ProjectEntityUpdateHandler.updateDocLines(
|
||||
project_id,
|
||||
doc_id,
|
||||
lines,
|
||||
version,
|
||||
ranges,
|
||||
lastUpdatedAt,
|
||||
lastUpdatedBy,
|
||||
function (error) {
|
||||
if (error != null) {
|
||||
OError.tag(error, 'error finding element for getDocument', {
|
||||
doc_id,
|
||||
project_id,
|
||||
})
|
||||
return next(error)
|
||||
ProjectEntityHandler.getDoc(
|
||||
projectId,
|
||||
docId,
|
||||
{ peek },
|
||||
(error, lines, rev, version, ranges) => {
|
||||
if (error) {
|
||||
OError.tag(
|
||||
error,
|
||||
'error finding doc contents for getDocument',
|
||||
{
|
||||
docId,
|
||||
projectId,
|
||||
}
|
||||
)
|
||||
return next(error)
|
||||
}
|
||||
if (plain) {
|
||||
res.type('text/plain')
|
||||
res.send(lines.join('\n'))
|
||||
} else {
|
||||
const projectHistoryId = _.get(project, 'overleaf.history.id')
|
||||
const projectHistoryDisplay = _.get(
|
||||
project,
|
||||
'overleaf.history.display'
|
||||
)
|
||||
const sendToBothHistorySystems = _.get(
|
||||
project,
|
||||
'overleaf.history.allowDowngrade'
|
||||
)
|
||||
// if project has been switched but has 'allowDowngrade' set
|
||||
// then leave projectHistoryType undefined to (temporarily)
|
||||
// continue sending updates to both SL and full project history
|
||||
const projectHistoryType =
|
||||
projectHistoryDisplay && !sendToBothHistorySystems
|
||||
? 'project-history'
|
||||
: undefined // for backwards compatibility, don't send anything if the project is still on track-changes
|
||||
res.json({
|
||||
lines,
|
||||
version,
|
||||
ranges,
|
||||
pathname: path.fileSystem,
|
||||
projectHistoryId,
|
||||
projectHistoryType,
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
logger.log(
|
||||
{ doc_id, project_id },
|
||||
'finished receiving set document request from api (docupdater)'
|
||||
)
|
||||
return res.sendStatus(200)
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function __guard__(value, transform) {
|
||||
return typeof value !== 'undefined' && value !== null
|
||||
? transform(value)
|
||||
: undefined
|
||||
function setDocument(req, res, next) {
|
||||
const { Project_id: projectId, doc_id: docId } = req.params
|
||||
const { lines, version, ranges, lastUpdatedAt, lastUpdatedBy } = req.body
|
||||
ProjectEntityUpdateHandler.updateDocLines(
|
||||
projectId,
|
||||
docId,
|
||||
lines,
|
||||
version,
|
||||
ranges,
|
||||
lastUpdatedAt,
|
||||
lastUpdatedBy,
|
||||
error => {
|
||||
if (error) {
|
||||
OError.tag(error, 'error finding element for getDocument', {
|
||||
docId,
|
||||
projectId,
|
||||
})
|
||||
return next(error)
|
||||
}
|
||||
logger.log(
|
||||
{ docId, projectId },
|
||||
'finished receiving set document request from api (docupdater)'
|
||||
)
|
||||
res.sendStatus(200)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = { getDocument, setDocument }
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
/* eslint-disable
|
||||
max-len,
|
||||
no-return-assign,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
const sinon = require('sinon')
|
||||
const modulePath = '../../../../app/src/Features/Docstore/DocstoreManager'
|
||||
const SandboxedModule = require('sandboxed-module')
|
||||
@@ -37,7 +26,7 @@ describe('DocstoreManager', function () {
|
||||
|
||||
this.project_id = 'project-id-123'
|
||||
this.doc_id = 'doc-id-123'
|
||||
return (this.callback = sinon.stub())
|
||||
this.callback = sinon.stub()
|
||||
})
|
||||
|
||||
describe('deleteDoc', function () {
|
||||
@@ -54,7 +43,7 @@ describe('DocstoreManager', function () {
|
||||
this.request.patch = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 204 }, '')
|
||||
return this.DocstoreManager.deleteDoc(
|
||||
this.DocstoreManager.deleteDoc(
|
||||
this.project_id,
|
||||
this.doc_id,
|
||||
'wombat.tex',
|
||||
@@ -64,7 +53,7 @@ describe('DocstoreManager', function () {
|
||||
})
|
||||
|
||||
it('should delete the doc in the docstore api', function () {
|
||||
return this.request.patch
|
||||
this.request.patch
|
||||
.calledWith({
|
||||
url: `${this.settings.apis.docstore.url}/project/${this.project_id}/doc/${this.doc_id}`,
|
||||
json: { deleted: true, deletedAt: new Date(), name: 'wombat.tex' },
|
||||
@@ -74,7 +63,7 @@ describe('DocstoreManager', function () {
|
||||
})
|
||||
|
||||
it('should call the callback without an error', function () {
|
||||
return this.callback.calledWith(null).should.equal(true)
|
||||
this.callback.calledWith(null).should.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -83,7 +72,7 @@ describe('DocstoreManager', function () {
|
||||
this.request.patch = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 500 }, '')
|
||||
return this.DocstoreManager.deleteDoc(
|
||||
this.DocstoreManager.deleteDoc(
|
||||
this.project_id,
|
||||
this.doc_id,
|
||||
'main.tex',
|
||||
@@ -93,7 +82,7 @@ describe('DocstoreManager', function () {
|
||||
})
|
||||
|
||||
it('should call the callback with an error', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(
|
||||
sinon.match
|
||||
.instanceOf(Error)
|
||||
@@ -113,7 +102,7 @@ describe('DocstoreManager', function () {
|
||||
this.request.patch = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 404 }, '')
|
||||
return this.DocstoreManager.deleteDoc(
|
||||
this.DocstoreManager.deleteDoc(
|
||||
this.project_id,
|
||||
this.doc_id,
|
||||
'main.tex',
|
||||
@@ -145,7 +134,7 @@ describe('DocstoreManager', function () {
|
||||
this.rev = 5
|
||||
this.version = 42
|
||||
this.ranges = { mock: 'ranges' }
|
||||
return (this.modified = true)
|
||||
this.modified = true
|
||||
})
|
||||
|
||||
describe('with a successful response code', function () {
|
||||
@@ -158,7 +147,7 @@ describe('DocstoreManager', function () {
|
||||
{ statusCode: 204 },
|
||||
{ modified: this.modified, rev: this.rev }
|
||||
)
|
||||
return this.DocstoreManager.updateDoc(
|
||||
this.DocstoreManager.updateDoc(
|
||||
this.project_id,
|
||||
this.doc_id,
|
||||
this.lines,
|
||||
@@ -169,7 +158,7 @@ describe('DocstoreManager', function () {
|
||||
})
|
||||
|
||||
it('should update the doc in the docstore api', function () {
|
||||
return this.request.post
|
||||
this.request.post
|
||||
.calledWith({
|
||||
url: `${this.settings.apis.docstore.url}/project/${this.project_id}/doc/${this.doc_id}`,
|
||||
timeout: 30 * 1000,
|
||||
@@ -183,7 +172,7 @@ describe('DocstoreManager', function () {
|
||||
})
|
||||
|
||||
it('should call the callback with the modified status and revision', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(null, this.modified, this.rev)
|
||||
.should.equal(true)
|
||||
})
|
||||
@@ -194,7 +183,7 @@ describe('DocstoreManager', function () {
|
||||
this.request.post = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 500 }, '')
|
||||
return this.DocstoreManager.updateDoc(
|
||||
this.DocstoreManager.updateDoc(
|
||||
this.project_id,
|
||||
this.doc_id,
|
||||
this.lines,
|
||||
@@ -205,7 +194,7 @@ describe('DocstoreManager', function () {
|
||||
})
|
||||
|
||||
it('should call the callback with an error', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(
|
||||
sinon.match
|
||||
.instanceOf(Error)
|
||||
@@ -223,12 +212,12 @@ describe('DocstoreManager', function () {
|
||||
|
||||
describe('getDoc', function () {
|
||||
beforeEach(function () {
|
||||
return (this.doc = {
|
||||
this.doc = {
|
||||
lines: (this.lines = ['mock', 'doc', 'lines']),
|
||||
rev: (this.rev = 5),
|
||||
version: (this.version = 42),
|
||||
ranges: (this.ranges = { mock: 'ranges' }),
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
describe('with a successful response code', function () {
|
||||
@@ -236,25 +225,19 @@ describe('DocstoreManager', function () {
|
||||
this.request.get = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 204 }, this.doc)
|
||||
return this.DocstoreManager.getDoc(
|
||||
this.project_id,
|
||||
this.doc_id,
|
||||
this.callback
|
||||
)
|
||||
this.DocstoreManager.getDoc(this.project_id, this.doc_id, this.callback)
|
||||
})
|
||||
|
||||
it('should get the doc from the docstore api', function () {
|
||||
return this.request.get
|
||||
.calledWith({
|
||||
url: `${this.settings.apis.docstore.url}/project/${this.project_id}/doc/${this.doc_id}`,
|
||||
timeout: 30 * 1000,
|
||||
json: true,
|
||||
})
|
||||
.should.equal(true)
|
||||
this.request.get.should.have.been.calledWith({
|
||||
url: `${this.settings.apis.docstore.url}/project/${this.project_id}/doc/${this.doc_id}`,
|
||||
timeout: 30 * 1000,
|
||||
json: true,
|
||||
})
|
||||
})
|
||||
|
||||
it('should call the callback with the lines, version and rev', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(null, this.lines, this.rev, this.version, this.ranges)
|
||||
.should.equal(true)
|
||||
})
|
||||
@@ -265,15 +248,11 @@ describe('DocstoreManager', function () {
|
||||
this.request.get = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 500 }, '')
|
||||
return this.DocstoreManager.getDoc(
|
||||
this.project_id,
|
||||
this.doc_id,
|
||||
this.callback
|
||||
)
|
||||
this.DocstoreManager.getDoc(this.project_id, this.doc_id, this.callback)
|
||||
})
|
||||
|
||||
it('should call the callback with an error', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(
|
||||
sinon.match
|
||||
.instanceOf(Error)
|
||||
@@ -293,7 +272,7 @@ describe('DocstoreManager', function () {
|
||||
this.request.get = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 204 }, this.doc)
|
||||
return this.DocstoreManager.getDoc(
|
||||
this.DocstoreManager.getDoc(
|
||||
this.project_id,
|
||||
this.doc_id,
|
||||
{ include_deleted: true },
|
||||
@@ -302,36 +281,53 @@ describe('DocstoreManager', function () {
|
||||
})
|
||||
|
||||
it('should get the doc from the docstore api (including deleted)', function () {
|
||||
return this.request.get
|
||||
.calledWith({
|
||||
url: `${this.settings.apis.docstore.url}/project/${this.project_id}/doc/${this.doc_id}?include_deleted=true`,
|
||||
timeout: 30 * 1000,
|
||||
json: true,
|
||||
})
|
||||
.should.equal(true)
|
||||
this.request.get.should.have.been.calledWith({
|
||||
url: `${this.settings.apis.docstore.url}/project/${this.project_id}/doc/${this.doc_id}`,
|
||||
qs: { include_deleted: 'true' },
|
||||
timeout: 30 * 1000,
|
||||
json: true,
|
||||
})
|
||||
})
|
||||
|
||||
it('should call the callback with the lines, version and rev', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(null, this.lines, this.rev, this.version, this.ranges)
|
||||
.should.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with peek=true', function () {
|
||||
beforeEach(function () {
|
||||
this.request.get = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 204 }, this.doc)
|
||||
this.DocstoreManager.getDoc(
|
||||
this.project_id,
|
||||
this.doc_id,
|
||||
{ peek: true },
|
||||
this.callback
|
||||
)
|
||||
})
|
||||
|
||||
it('should call the docstore peek url', function () {
|
||||
this.request.get.should.have.been.calledWith({
|
||||
url: `${this.settings.apis.docstore.url}/project/${this.project_id}/doc/${this.doc_id}/peek`,
|
||||
timeout: 30 * 1000,
|
||||
json: true,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a missing (404) response code', function () {
|
||||
beforeEach(function () {
|
||||
this.request.get = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 404 }, '')
|
||||
return this.DocstoreManager.getDoc(
|
||||
this.project_id,
|
||||
this.doc_id,
|
||||
this.callback
|
||||
)
|
||||
this.DocstoreManager.getDoc(this.project_id, this.doc_id, this.callback)
|
||||
})
|
||||
|
||||
it('should call the callback with an error', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(
|
||||
sinon.match
|
||||
.instanceOf(Errors.NotFoundError)
|
||||
@@ -353,11 +349,11 @@ describe('DocstoreManager', function () {
|
||||
{ statusCode: 204 },
|
||||
(this.docs = [{ _id: 'mock-doc-id' }])
|
||||
)
|
||||
return this.DocstoreManager.getAllDocs(this.project_id, this.callback)
|
||||
this.DocstoreManager.getAllDocs(this.project_id, this.callback)
|
||||
})
|
||||
|
||||
it('should get all the project docs in the docstore api', function () {
|
||||
return this.request.get
|
||||
this.request.get
|
||||
.calledWith({
|
||||
url: `${this.settings.apis.docstore.url}/project/${this.project_id}/doc`,
|
||||
timeout: 30 * 1000,
|
||||
@@ -367,7 +363,7 @@ describe('DocstoreManager', function () {
|
||||
})
|
||||
|
||||
it('should call the callback with the docs', function () {
|
||||
return this.callback.calledWith(null, this.docs).should.equal(true)
|
||||
this.callback.calledWith(null, this.docs).should.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -376,11 +372,11 @@ describe('DocstoreManager', function () {
|
||||
this.request.get = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 500 }, '')
|
||||
return this.DocstoreManager.getAllDocs(this.project_id, this.callback)
|
||||
this.DocstoreManager.getAllDocs(this.project_id, this.callback)
|
||||
})
|
||||
|
||||
it('should call the callback with an error', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(
|
||||
sinon.match
|
||||
.instanceOf(Error)
|
||||
@@ -473,11 +469,11 @@ describe('DocstoreManager', function () {
|
||||
{ statusCode: 204 },
|
||||
(this.docs = [{ _id: 'mock-doc-id', ranges: 'mock-ranges' }])
|
||||
)
|
||||
return this.DocstoreManager.getAllRanges(this.project_id, this.callback)
|
||||
this.DocstoreManager.getAllRanges(this.project_id, this.callback)
|
||||
})
|
||||
|
||||
it('should get all the project doc ranges in the docstore api', function () {
|
||||
return this.request.get
|
||||
this.request.get
|
||||
.calledWith({
|
||||
url: `${this.settings.apis.docstore.url}/project/${this.project_id}/ranges`,
|
||||
timeout: 30 * 1000,
|
||||
@@ -487,7 +483,7 @@ describe('DocstoreManager', function () {
|
||||
})
|
||||
|
||||
it('should call the callback with the docs', function () {
|
||||
return this.callback.calledWith(null, this.docs).should.equal(true)
|
||||
this.callback.calledWith(null, this.docs).should.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -496,11 +492,11 @@ describe('DocstoreManager', function () {
|
||||
this.request.get = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 500 }, '')
|
||||
return this.DocstoreManager.getAllRanges(this.project_id, this.callback)
|
||||
this.DocstoreManager.getAllRanges(this.project_id, this.callback)
|
||||
})
|
||||
|
||||
it('should call the callback with an error', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(
|
||||
sinon.match
|
||||
.instanceOf(Error)
|
||||
@@ -522,14 +518,11 @@ describe('DocstoreManager', function () {
|
||||
this.request.post = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 204 })
|
||||
return this.DocstoreManager.archiveProject(
|
||||
this.project_id,
|
||||
this.callback
|
||||
)
|
||||
this.DocstoreManager.archiveProject(this.project_id, this.callback)
|
||||
})
|
||||
|
||||
it('should call the callback', function () {
|
||||
return this.callback.called.should.equal(true)
|
||||
this.callback.called.should.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -538,14 +531,11 @@ describe('DocstoreManager', function () {
|
||||
this.request.post = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 500 })
|
||||
return this.DocstoreManager.archiveProject(
|
||||
this.project_id,
|
||||
this.callback
|
||||
)
|
||||
this.DocstoreManager.archiveProject(this.project_id, this.callback)
|
||||
})
|
||||
|
||||
it('should call the callback with an error', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(
|
||||
sinon.match
|
||||
.instanceOf(Error)
|
||||
@@ -567,14 +557,11 @@ describe('DocstoreManager', function () {
|
||||
this.request.post = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 204 })
|
||||
return this.DocstoreManager.unarchiveProject(
|
||||
this.project_id,
|
||||
this.callback
|
||||
)
|
||||
this.DocstoreManager.unarchiveProject(this.project_id, this.callback)
|
||||
})
|
||||
|
||||
it('should call the callback', function () {
|
||||
return this.callback.called.should.equal(true)
|
||||
this.callback.called.should.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -583,14 +570,11 @@ describe('DocstoreManager', function () {
|
||||
this.request.post = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 500 })
|
||||
return this.DocstoreManager.unarchiveProject(
|
||||
this.project_id,
|
||||
this.callback
|
||||
)
|
||||
this.DocstoreManager.unarchiveProject(this.project_id, this.callback)
|
||||
})
|
||||
|
||||
it('should call the callback with an error', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(
|
||||
sinon.match
|
||||
.instanceOf(Error)
|
||||
@@ -612,14 +596,11 @@ describe('DocstoreManager', function () {
|
||||
this.request.post = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 204 })
|
||||
return this.DocstoreManager.destroyProject(
|
||||
this.project_id,
|
||||
this.callback
|
||||
)
|
||||
this.DocstoreManager.destroyProject(this.project_id, this.callback)
|
||||
})
|
||||
|
||||
it('should call the callback', function () {
|
||||
return this.callback.called.should.equal(true)
|
||||
this.callback.called.should.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -628,14 +609,11 @@ describe('DocstoreManager', function () {
|
||||
this.request.post = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, null, { statusCode: 500 })
|
||||
return this.DocstoreManager.destroyProject(
|
||||
this.project_id,
|
||||
this.callback
|
||||
)
|
||||
this.DocstoreManager.destroyProject(this.project_id, this.callback)
|
||||
})
|
||||
|
||||
it('should call the callback with an error', function () {
|
||||
return this.callback
|
||||
this.callback
|
||||
.calledWith(
|
||||
sinon.match
|
||||
.instanceOf(Error)
|
||||
|
||||
@@ -1,21 +1,7 @@
|
||||
/* eslint-disable
|
||||
max-len,
|
||||
no-return-assign,
|
||||
no-unused-vars,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
const sinon = require('sinon')
|
||||
const { expect } = require('chai')
|
||||
const modulePath =
|
||||
'../../../../app/src/Features/Documents/DocumentController.js'
|
||||
const SandboxedModule = require('sandboxed-module')
|
||||
const events = require('events')
|
||||
const MockRequest = require('../helpers/MockRequest')
|
||||
const MockResponse = require('../helpers/MockResponse')
|
||||
const Errors = require('../../../../app/src/Features/Errors/Errors')
|
||||
@@ -41,23 +27,23 @@ describe('DocumentController', function () {
|
||||
this.pathname = '/a/b/c/file.tex'
|
||||
this.lastUpdatedAt = new Date().getTime()
|
||||
this.lastUpdatedBy = 'fake-last-updater-id'
|
||||
return (this.rev = 5)
|
||||
this.rev = 5
|
||||
})
|
||||
|
||||
describe('getDocument', function () {
|
||||
beforeEach(function () {
|
||||
return (this.req.params = {
|
||||
this.req.params = {
|
||||
Project_id: this.project_id,
|
||||
doc_id: this.doc_id,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
describe('when the project exists without project history enabled', function () {
|
||||
beforeEach(function () {
|
||||
this.project = { _id: this.project_id }
|
||||
return (this.ProjectGetter.getProject = sinon
|
||||
this.ProjectGetter.getProject = sinon
|
||||
.stub()
|
||||
.callsArgWith(2, null, this.project))
|
||||
.callsArgWith(2, null, this.project)
|
||||
})
|
||||
|
||||
describe('when the document exists', function () {
|
||||
@@ -68,29 +54,18 @@ describe('DocumentController', function () {
|
||||
.callsArgWith(1, null, this.doc, { fileSystem: this.pathname })
|
||||
this.ProjectEntityHandler.getDoc = sinon
|
||||
.stub()
|
||||
.callsArgWith(
|
||||
2,
|
||||
null,
|
||||
this.doc_lines,
|
||||
this.rev,
|
||||
this.version,
|
||||
this.ranges
|
||||
)
|
||||
return this.DocumentController.getDocument(
|
||||
this.req,
|
||||
this.res,
|
||||
this.next
|
||||
)
|
||||
.yields(null, this.doc_lines, this.rev, this.version, this.ranges)
|
||||
this.DocumentController.getDocument(this.req, this.res, this.next)
|
||||
})
|
||||
|
||||
it('should get the project', function () {
|
||||
return this.ProjectGetter.getProject
|
||||
this.ProjectGetter.getProject
|
||||
.calledWith(this.project_id, { rootFolder: true, overleaf: true })
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
it('should get the pathname of the document', function () {
|
||||
return this.ProjectLocator.findElement
|
||||
this.ProjectLocator.findElement
|
||||
.calledWith({
|
||||
project: this.project,
|
||||
element_id: this.doc_id,
|
||||
@@ -100,14 +75,14 @@ describe('DocumentController', function () {
|
||||
})
|
||||
|
||||
it('should get the document content', function () {
|
||||
return this.ProjectEntityHandler.getDoc
|
||||
this.ProjectEntityHandler.getDoc
|
||||
.calledWith(this.project_id, this.doc_id)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
it('should return the document data to the client as JSON', function () {
|
||||
this.res.type.should.equal('application/json')
|
||||
return this.res.body.should.equal(
|
||||
this.res.body.should.equal(
|
||||
JSON.stringify({
|
||||
lines: this.doc_lines,
|
||||
version: this.version,
|
||||
@@ -123,15 +98,11 @@ describe('DocumentController', function () {
|
||||
this.ProjectLocator.findElement = sinon
|
||||
.stub()
|
||||
.callsArgWith(1, new Errors.NotFoundError('not found'))
|
||||
return this.DocumentController.getDocument(
|
||||
this.req,
|
||||
this.res,
|
||||
this.next
|
||||
)
|
||||
this.DocumentController.getDocument(this.req, this.res, this.next)
|
||||
})
|
||||
|
||||
it('should call next with the NotFoundError', function () {
|
||||
return this.next
|
||||
this.next
|
||||
.calledWith(sinon.match.instanceOf(Errors.NotFoundError))
|
||||
.should.equal(true)
|
||||
})
|
||||
@@ -161,24 +132,13 @@ describe('DocumentController', function () {
|
||||
.callsArgWith(1, null, this.doc, { fileSystem: this.pathname })
|
||||
this.ProjectEntityHandler.getDoc = sinon
|
||||
.stub()
|
||||
.callsArgWith(
|
||||
2,
|
||||
null,
|
||||
this.doc_lines,
|
||||
this.rev,
|
||||
this.version,
|
||||
this.ranges
|
||||
)
|
||||
return this.DocumentController.getDocument(
|
||||
this.req,
|
||||
this.res,
|
||||
this.next
|
||||
)
|
||||
.yields(null, this.doc_lines, this.rev, this.version, this.ranges)
|
||||
this.DocumentController.getDocument(this.req, this.res, this.next)
|
||||
})
|
||||
|
||||
it('should return the history id and display setting to the client as JSON', function () {
|
||||
this.res.type.should.equal('application/json')
|
||||
return this.res.body.should.equal(
|
||||
this.res.body.should.equal(
|
||||
JSON.stringify({
|
||||
lines: this.doc_lines,
|
||||
version: this.version,
|
||||
@@ -215,14 +175,7 @@ describe('DocumentController', function () {
|
||||
.callsArgWith(1, null, this.doc, { fileSystem: this.pathname })
|
||||
this.ProjectEntityHandler.getDoc = sinon
|
||||
.stub()
|
||||
.callsArgWith(
|
||||
2,
|
||||
null,
|
||||
this.doc_lines,
|
||||
this.rev,
|
||||
this.version,
|
||||
this.ranges
|
||||
)
|
||||
.yields(null, this.doc_lines, this.rev, this.version, this.ranges)
|
||||
return this.DocumentController.getDocument(
|
||||
this.req,
|
||||
this.res,
|
||||
@@ -248,25 +201,21 @@ describe('DocumentController', function () {
|
||||
describe('when the project does not exist', function () {
|
||||
beforeEach(function () {
|
||||
this.ProjectGetter.getProject = sinon.stub().callsArgWith(2, null, null)
|
||||
return this.DocumentController.getDocument(
|
||||
this.req,
|
||||
this.res,
|
||||
this.next
|
||||
)
|
||||
this.DocumentController.getDocument(this.req, this.res, this.next)
|
||||
})
|
||||
|
||||
it('returns a 404', function () {
|
||||
return this.res.statusCode.should.equal(404)
|
||||
this.res.statusCode.should.equal(404)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('setDocument', function () {
|
||||
beforeEach(function () {
|
||||
return (this.req.params = {
|
||||
this.req.params = {
|
||||
Project_id: this.project_id,
|
||||
doc_id: this.doc_id,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
describe('when the document exists', function () {
|
||||
@@ -279,15 +228,11 @@ describe('DocumentController', function () {
|
||||
lastUpdatedAt: this.lastUpdatedAt,
|
||||
lastUpdatedBy: this.lastUpdatedBy,
|
||||
}
|
||||
return this.DocumentController.setDocument(
|
||||
this.req,
|
||||
this.res,
|
||||
this.next
|
||||
)
|
||||
this.DocumentController.setDocument(this.req, this.res, this.next)
|
||||
})
|
||||
|
||||
it('should update the document in Mongo', function () {
|
||||
return sinon.assert.calledWith(
|
||||
sinon.assert.calledWith(
|
||||
this.ProjectEntityUpdateHandler.updateDocLines,
|
||||
this.project_id,
|
||||
this.doc_id,
|
||||
@@ -300,7 +245,7 @@ describe('DocumentController', function () {
|
||||
})
|
||||
|
||||
it('should return a successful response', function () {
|
||||
return this.res.success.should.equal(true)
|
||||
this.res.success.should.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -310,15 +255,11 @@ describe('DocumentController', function () {
|
||||
.stub()
|
||||
.yields(new Errors.NotFoundError('document does not exist'))
|
||||
this.req.body = { lines: this.doc_lines }
|
||||
return this.DocumentController.setDocument(
|
||||
this.req,
|
||||
this.res,
|
||||
this.next
|
||||
)
|
||||
this.DocumentController.setDocument(this.req, this.res, this.next)
|
||||
})
|
||||
|
||||
it('should call next with the NotFoundError', function () {
|
||||
return this.next
|
||||
this.next
|
||||
.calledWith(sinon.match.instanceOf(Errors.NotFoundError))
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user