mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #151 from overleaf/jpa-bulk-dependency-upgrades
[misc] bulk dependency upgrades
This commit is contained in:
commit
9d790f4eda
33 changed files with 1475 additions and 1568 deletions
|
@ -3,9 +3,9 @@
|
||||||
// https://github.com/sharelatex/sharelatex-dev-environment
|
// https://github.com/sharelatex/sharelatex-dev-environment
|
||||||
{
|
{
|
||||||
"extends": [
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
"standard",
|
"standard",
|
||||||
"prettier",
|
"prettier"
|
||||||
"prettier/standard"
|
|
||||||
],
|
],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 2018
|
"ecmaVersion": 2018
|
||||||
|
@ -20,6 +20,19 @@
|
||||||
"mocha": true
|
"mocha": true
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
|
// TODO(das7pad): remove overrides after fixing all the violations manually (https://github.com/overleaf/issues/issues/3882#issuecomment-878999671)
|
||||||
|
// START of temporary overrides
|
||||||
|
"array-callback-return": "off",
|
||||||
|
"no-dupe-else-if": "off",
|
||||||
|
"no-var": "off",
|
||||||
|
"no-empty": "off",
|
||||||
|
"node/handle-callback-err": "off",
|
||||||
|
"no-loss-of-precision": "off",
|
||||||
|
"node/no-callback-literal": "off",
|
||||||
|
"node/no-path-concat": "off",
|
||||||
|
"prefer-regex-literals": "off",
|
||||||
|
// END of temporary overrides
|
||||||
|
|
||||||
// Swap the no-unused-expressions rule with a more chai-friendly one
|
// Swap the no-unused-expressions rule with a more chai-friendly one
|
||||||
"no-unused-expressions": 0,
|
"no-unused-expressions": 0,
|
||||||
"chai-friendly/no-unused-expressions": "error",
|
"chai-friendly/no-unused-expressions": "error",
|
||||||
|
|
2
services/filestore/.github/dependabot.yml
vendored
2
services/filestore/.github/dependabot.yml
vendored
|
@ -20,4 +20,4 @@ updates:
|
||||||
# future if we reorganise teams
|
# future if we reorganise teams
|
||||||
labels:
|
labels:
|
||||||
- "dependencies"
|
- "dependencies"
|
||||||
- "Team-Magma"
|
- "type:maintenance"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
12.20.1
|
12.22.3
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
# Instead run bin/update_build_scripts from
|
# Instead run bin/update_build_scripts from
|
||||||
# https://github.com/sharelatex/sharelatex-dev-environment
|
# https://github.com/sharelatex/sharelatex-dev-environment
|
||||||
{
|
{
|
||||||
|
"arrowParens": "avoid",
|
||||||
"semi": false,
|
"semi": false,
|
||||||
"singleQuote": true
|
"singleQuote": true,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": false
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Instead run bin/update_build_scripts from
|
# Instead run bin/update_build_scripts from
|
||||||
# https://github.com/sharelatex/sharelatex-dev-environment
|
# https://github.com/sharelatex/sharelatex-dev-environment
|
||||||
|
|
||||||
FROM node:12.20.1 as base
|
FROM node:12.22.3 as base
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY install_deps.sh /app
|
COPY install_deps.sh /app
|
||||||
|
|
|
@ -4,7 +4,7 @@ Metrics.initialize(process.env.METRICS_APP_NAME || 'filestore')
|
||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
logger.initialize(process.env.METRICS_APP_NAME || 'filestore')
|
logger.initialize(process.env.METRICS_APP_NAME || 'filestore')
|
||||||
|
|
||||||
const settings = require('settings-sharelatex')
|
const settings = require('@overleaf/settings')
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const bodyParser = require('body-parser')
|
const bodyParser = require('body-parser')
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ const host = '0.0.0.0'
|
||||||
|
|
||||||
if (!module.parent) {
|
if (!module.parent) {
|
||||||
// Called directly
|
// Called directly
|
||||||
app.listen(port, host, (error) => {
|
app.listen(port, host, error => {
|
||||||
if (error) {
|
if (error) {
|
||||||
logger.error('Error starting Filestore', error)
|
logger.error('Error starting Filestore', error)
|
||||||
throw error
|
throw error
|
||||||
|
@ -153,7 +153,7 @@ process
|
||||||
.on('unhandledRejection', (reason, p) => {
|
.on('unhandledRejection', (reason, p) => {
|
||||||
logger.err(reason, 'Unhandled Rejection at Promise', p)
|
logger.err(reason, 'Unhandled Rejection at Promise', p)
|
||||||
})
|
})
|
||||||
.on('uncaughtException', (err) => {
|
.on('uncaughtException', err => {
|
||||||
logger.err(err, 'Uncaught Exception thrown')
|
logger.err(err, 'Uncaught Exception thrown')
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
|
|
@ -11,7 +11,7 @@ class FailedCommandError extends OError {
|
||||||
constructor(command, code, stdout, stderr) {
|
constructor(command, code, stdout, stderr) {
|
||||||
super('command failed with error exit code', {
|
super('command failed with error exit code', {
|
||||||
command,
|
command,
|
||||||
code
|
code,
|
||||||
})
|
})
|
||||||
this.stdout = stdout
|
this.stdout = stdout
|
||||||
this.stderr = stderr
|
this.stderr = stderr
|
||||||
|
@ -26,5 +26,5 @@ module.exports = {
|
||||||
HealthCheckError,
|
HealthCheckError,
|
||||||
TimeoutError,
|
TimeoutError,
|
||||||
InvalidParametersError,
|
InvalidParametersError,
|
||||||
...Errors
|
...Errors,
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ module.exports = {
|
||||||
copyFile,
|
copyFile,
|
||||||
deleteFile,
|
deleteFile,
|
||||||
deleteProject,
|
deleteProject,
|
||||||
directorySize
|
directorySize,
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFile(req, res, next) {
|
function getFile(req, res, next) {
|
||||||
|
@ -24,7 +24,7 @@ function getFile(req, res, next) {
|
||||||
key,
|
key,
|
||||||
bucket,
|
bucket,
|
||||||
format,
|
format,
|
||||||
style
|
style,
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics.inc('getFile')
|
metrics.inc('getFile')
|
||||||
|
@ -34,7 +34,7 @@ function getFile(req, res, next) {
|
||||||
bucket,
|
bucket,
|
||||||
format,
|
format,
|
||||||
style,
|
style,
|
||||||
cacheWarm: req.query.cacheWarm
|
cacheWarm: req.query.cacheWarm,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (req.headers.range) {
|
if (req.headers.range) {
|
||||||
|
@ -70,7 +70,7 @@ function getFile(req, res, next) {
|
||||||
return res.sendStatus(200).end()
|
return res.sendStatus(200).end()
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline(fileStream, res, (err) => {
|
pipeline(fileStream, res, err => {
|
||||||
if (err && err.code === 'ERR_STREAM_PREMATURE_CLOSE') {
|
if (err && err.code === 'ERR_STREAM_PREMATURE_CLOSE') {
|
||||||
res.end()
|
res.end()
|
||||||
} else if (err) {
|
} else if (err) {
|
||||||
|
@ -134,13 +134,13 @@ function copyFile(req, res, next) {
|
||||||
key,
|
key,
|
||||||
bucket,
|
bucket,
|
||||||
oldProject_id: oldProjectId,
|
oldProject_id: oldProjectId,
|
||||||
oldFile_id: oldFileId
|
oldFile_id: oldFileId,
|
||||||
})
|
})
|
||||||
req.requestLogger.setMessage('copying file')
|
req.requestLogger.setMessage('copying file')
|
||||||
|
|
||||||
PersistorManager.copyObject(bucket, `${oldProjectId}/${oldFileId}`, key)
|
PersistorManager.copyObject(bucket, `${oldProjectId}/${oldFileId}`, key)
|
||||||
.then(() => res.sendStatus(200))
|
.then(() => res.sendStatus(200))
|
||||||
.catch((err) => {
|
.catch(err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err instanceof Errors.NotFoundError) {
|
if (err instanceof Errors.NotFoundError) {
|
||||||
res.sendStatus(404)
|
res.sendStatus(404)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const metrics = require('@overleaf/metrics')
|
const metrics = require('@overleaf/metrics')
|
||||||
const Settings = require('settings-sharelatex')
|
const Settings = require('@overleaf/settings')
|
||||||
const { callbackify } = require('util')
|
const { callbackify } = require('util')
|
||||||
|
|
||||||
const safeExec = require('./SafeExec').promises
|
const safeExec = require('./SafeExec').promises
|
||||||
|
@ -16,8 +16,8 @@ module.exports = {
|
||||||
promises: {
|
promises: {
|
||||||
convert,
|
convert,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
preview
|
preview,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
async function convert(sourcePath, requestedFormat) {
|
async function convert(sourcePath, requestedFormat) {
|
||||||
|
@ -29,7 +29,7 @@ async function convert(sourcePath, requestedFormat) {
|
||||||
'-flatten',
|
'-flatten',
|
||||||
'-density',
|
'-density',
|
||||||
'300',
|
'300',
|
||||||
`${sourcePath}[0]`
|
`${sourcePath}[0]`,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ async function thumbnail(sourcePath) {
|
||||||
`pdf:fit-page=${width}`,
|
`pdf:fit-page=${width}`,
|
||||||
`${sourcePath}[0]`,
|
`${sourcePath}[0]`,
|
||||||
'-resize',
|
'-resize',
|
||||||
width
|
width,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,14 +63,14 @@ async function preview(sourcePath) {
|
||||||
`pdf:fit-page=${width}`,
|
`pdf:fit-page=${width}`,
|
||||||
`${sourcePath}[0]`,
|
`${sourcePath}[0]`,
|
||||||
'-resize',
|
'-resize',
|
||||||
width
|
width,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _convert(sourcePath, requestedFormat, command) {
|
async function _convert(sourcePath, requestedFormat, command) {
|
||||||
if (!APPROVED_FORMATS.includes(requestedFormat)) {
|
if (!APPROVED_FORMATS.includes(requestedFormat)) {
|
||||||
throw new ConversionError('invalid format requested', {
|
throw new ConversionError('invalid format requested', {
|
||||||
format: requestedFormat
|
format: requestedFormat,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ async function _convert(sourcePath, requestedFormat, command) {
|
||||||
try {
|
try {
|
||||||
await safeExec(command, {
|
await safeExec(command, {
|
||||||
killSignal: KILL_SIGNAL,
|
killSignal: KILL_SIGNAL,
|
||||||
timeout: FOURTY_SECONDS
|
timeout: FOURTY_SECONDS,
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new ConversionError(
|
throw new ConversionError(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const Settings = require('settings-sharelatex')
|
const Settings = require('@overleaf/settings')
|
||||||
const { callbackify } = require('util')
|
const { callbackify } = require('util')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const PersistorManager = require('./PersistorManager')
|
const PersistorManager = require('./PersistorManager')
|
||||||
|
@ -23,8 +23,8 @@ module.exports = {
|
||||||
deleteFile,
|
deleteFile,
|
||||||
deleteProject,
|
deleteProject,
|
||||||
getFileSize,
|
getFileSize,
|
||||||
getDirectorySize
|
getDirectorySize,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
async function insertFile(bucket, key, stream) {
|
async function insertFile(bucket, key, stream) {
|
||||||
|
@ -33,7 +33,7 @@ async function insertFile(bucket, key, stream) {
|
||||||
throw new InvalidParametersError('key does not match validation regex', {
|
throw new InvalidParametersError('key does not match validation regex', {
|
||||||
bucket,
|
bucket,
|
||||||
key,
|
key,
|
||||||
convertedKey
|
convertedKey,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (Settings.enableConversions) {
|
if (Settings.enableConversions) {
|
||||||
|
@ -48,7 +48,7 @@ async function deleteFile(bucket, key) {
|
||||||
throw new InvalidParametersError('key does not match validation regex', {
|
throw new InvalidParametersError('key does not match validation regex', {
|
||||||
bucket,
|
bucket,
|
||||||
key,
|
key,
|
||||||
convertedKey
|
convertedKey,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const jobs = [PersistorManager.deleteObject(bucket, key)]
|
const jobs = [PersistorManager.deleteObject(bucket, key)]
|
||||||
|
@ -62,7 +62,7 @@ async function deleteProject(bucket, key) {
|
||||||
if (!key.match(/^[0-9a-f]{24}\//i)) {
|
if (!key.match(/^[0-9a-f]{24}\//i)) {
|
||||||
throw new InvalidParametersError('key does not match validation regex', {
|
throw new InvalidParametersError('key does not match validation regex', {
|
||||||
bucket,
|
bucket,
|
||||||
key
|
key,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
await PersistorManager.deleteDirectory(bucket, key)
|
await PersistorManager.deleteDirectory(bucket, key)
|
||||||
|
@ -172,7 +172,7 @@ async function _convertFile(bucket, originalKey, opts) {
|
||||||
throw new ConversionError('invalid file conversion options', {
|
throw new ConversionError('invalid file conversion options', {
|
||||||
bucket,
|
bucket,
|
||||||
originalKey,
|
originalKey,
|
||||||
opts
|
opts,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
let destPath
|
let destPath
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const Settings = require('settings-sharelatex')
|
const Settings = require('@overleaf/settings')
|
||||||
const streamBuffers = require('stream-buffers')
|
const streamBuffers = require('stream-buffers')
|
||||||
const { promisify } = require('util')
|
const { promisify } = require('util')
|
||||||
const Stream = require('stream')
|
const Stream = require('stream')
|
||||||
|
@ -24,7 +24,7 @@ async function checkCanGetFiles() {
|
||||||
const bucket = Settings.filestore.stores.user_files
|
const bucket = Settings.filestore.stores.user_files
|
||||||
|
|
||||||
const buffer = new streamBuffers.WritableStreamBuffer({
|
const buffer = new streamBuffers.WritableStreamBuffer({
|
||||||
initialSize: 100
|
initialSize: 100,
|
||||||
})
|
})
|
||||||
|
|
||||||
const sourceStream = await FileHandler.getFile(bucket, key, {})
|
const sourceStream = await FileHandler.getFile(bucket, key, {})
|
||||||
|
@ -62,8 +62,8 @@ module.exports = {
|
||||||
check(req, res, next) {
|
check(req, res, next) {
|
||||||
Promise.all([checkCanGetFiles(), checkFileConvert()])
|
Promise.all([checkCanGetFiles(), checkFileConvert()])
|
||||||
.then(() => res.sendStatus(200))
|
.then(() => res.sendStatus(200))
|
||||||
.catch((err) => {
|
.catch(err => {
|
||||||
next(err)
|
next(err)
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ const safeExec = require('./SafeExec').promises
|
||||||
module.exports = {
|
module.exports = {
|
||||||
compressPng: callbackify(compressPng),
|
compressPng: callbackify(compressPng),
|
||||||
promises: {
|
promises: {
|
||||||
compressPng
|
compressPng,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
async function compressPng(localPath, callback) {
|
async function compressPng(localPath, callback) {
|
||||||
|
@ -15,7 +15,7 @@ async function compressPng(localPath, callback) {
|
||||||
const args = ['optipng', localPath]
|
const args = ['optipng', localPath]
|
||||||
const opts = {
|
const opts = {
|
||||||
timeout: 30 * 1000,
|
timeout: 30 * 1000,
|
||||||
killSignal: 'SIGKILL'
|
killSignal: 'SIGKILL',
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const settings = require('settings-sharelatex')
|
const settings = require('@overleaf/settings')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getConvertedFolderKey,
|
getConvertedFolderKey,
|
||||||
|
@ -8,7 +8,7 @@ module.exports = {
|
||||||
publicFileKeyMiddleware,
|
publicFileKeyMiddleware,
|
||||||
publicProjectKeyMiddleware,
|
publicProjectKeyMiddleware,
|
||||||
bucketFileKeyMiddleware,
|
bucketFileKeyMiddleware,
|
||||||
templateFileKeyMiddleware
|
templateFileKeyMiddleware,
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConvertedFolderKey(key) {
|
function getConvertedFolderKey(key) {
|
||||||
|
@ -68,7 +68,7 @@ function templateFileKeyMiddleware(req, res, next) {
|
||||||
template_id: templateId,
|
template_id: templateId,
|
||||||
format,
|
format,
|
||||||
version,
|
version,
|
||||||
sub_type: subType
|
sub_type: subType,
|
||||||
} = req.params
|
} = req.params
|
||||||
|
|
||||||
req.key = `${templateId}/v/${version}/${format}`
|
req.key = `${templateId}/v/${version}/${format}`
|
||||||
|
|
|
@ -4,16 +4,16 @@ const path = require('path')
|
||||||
const Stream = require('stream')
|
const Stream = require('stream')
|
||||||
const { callbackify, promisify } = require('util')
|
const { callbackify, promisify } = require('util')
|
||||||
const metrics = require('@overleaf/metrics')
|
const metrics = require('@overleaf/metrics')
|
||||||
const Settings = require('settings-sharelatex')
|
const Settings = require('@overleaf/settings')
|
||||||
const { WriteError } = require('./Errors')
|
const { WriteError } = require('./Errors')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
promises: {
|
promises: {
|
||||||
writeStream,
|
writeStream,
|
||||||
deleteFile
|
deleteFile,
|
||||||
},
|
},
|
||||||
writeStream: callbackify(writeStream),
|
writeStream: callbackify(writeStream),
|
||||||
deleteFile: callbackify(deleteFile)
|
deleteFile: callbackify(deleteFile),
|
||||||
}
|
}
|
||||||
|
|
||||||
const pipeline = promisify(Stream.pipeline)
|
const pipeline = promisify(Stream.pipeline)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const settings = require('settings-sharelatex')
|
const settings = require('@overleaf/settings')
|
||||||
|
|
||||||
const persistorSettings = settings.filestore
|
const persistorSettings = settings.filestore
|
||||||
persistorSettings.Metrics = require('@overleaf/metrics')
|
persistorSettings.Metrics = require('@overleaf/metrics')
|
||||||
|
|
|
@ -38,7 +38,7 @@ class RequestLogger {
|
||||||
metrics.timing('http_request', responseTime, null, {
|
metrics.timing('http_request', responseTime, null, {
|
||||||
method: req.method,
|
method: req.method,
|
||||||
status_code: res.statusCode,
|
status_code: res.statusCode,
|
||||||
path: routePath.replace(/\//g, '_').replace(/:/g, '').slice(1)
|
path: routePath.replace(/\//g, '_').replace(/:/g, '').slice(1),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,14 +57,14 @@ class RequestLogger {
|
||||||
req.socket.socket &&
|
req.socket.socket &&
|
||||||
req.socket.socket.remoteAddress),
|
req.socket.socket.remoteAddress),
|
||||||
'user-agent': req.headers['user-agent'],
|
'user-agent': req.headers['user-agent'],
|
||||||
'content-length': req.headers['content-length']
|
'content-length': req.headers['content-length'],
|
||||||
},
|
},
|
||||||
res: {
|
res: {
|
||||||
'content-length': res._headers['content-length'],
|
'content-length': res._headers['content-length'],
|
||||||
statusCode: res.statusCode,
|
statusCode: res.statusCode,
|
||||||
'response-time': responseTime
|
'response-time': responseTime,
|
||||||
},
|
},
|
||||||
info: req.requestLogger._logInfo
|
info: req.requestLogger._logInfo,
|
||||||
},
|
},
|
||||||
req.requestLogger._logMessage
|
req.requestLogger._logMessage
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const lodashOnce = require('lodash.once')
|
const lodashOnce = require('lodash.once')
|
||||||
const childProcess = require('child_process')
|
const childProcess = require('child_process')
|
||||||
const Settings = require('settings-sharelatex')
|
const Settings = require('@overleaf/settings')
|
||||||
const { ConversionsDisabledError, FailedCommandError } = require('./Errors')
|
const { ConversionsDisabledError, FailedCommandError } = require('./Errors')
|
||||||
|
|
||||||
// execute a command in the same way as 'exec' but with a timeout that
|
// execute a command in the same way as 'exec' but with a timeout that
|
||||||
|
@ -45,7 +45,7 @@ function safeExec(command, options, callback) {
|
||||||
new FailedCommandError('failed to kill process after timeout', {
|
new FailedCommandError('failed to kill process after timeout', {
|
||||||
command,
|
command,
|
||||||
options,
|
options,
|
||||||
pid: child.pid
|
pid: child.pid,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -62,13 +62,13 @@ function safeExec(command, options, callback) {
|
||||||
cleanup()
|
cleanup()
|
||||||
})
|
})
|
||||||
|
|
||||||
child.on('error', (err) => {
|
child.on('error', err => {
|
||||||
cleanup(err)
|
cleanup(err)
|
||||||
})
|
})
|
||||||
child.stdout.on('data', (chunk) => {
|
child.stdout.on('data', chunk => {
|
||||||
stdout += chunk
|
stdout += chunk
|
||||||
})
|
})
|
||||||
child.stderr.on('data', (chunk) => {
|
child.stderr.on('data', chunk => {
|
||||||
stderr += chunk
|
stderr += chunk
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,6 @@ filestore
|
||||||
--docker-repos=gcr.io/overleaf-ops
|
--docker-repos=gcr.io/overleaf-ops
|
||||||
--env-add=ENABLE_CONVERSIONS="true",USE_PROM_METRICS="true",AWS_S3_USER_FILES_BUCKET_NAME=fake_user_files,AWS_S3_TEMPLATE_FILES_BUCKET_NAME=fake_template_files,AWS_S3_PUBLIC_FILES_BUCKET_NAME=fake_public_files,GCS_USER_FILES_BUCKET_NAME=fake_userfiles,GCS_TEMPLATE_FILES_BUCKET_NAME=fake_templatefiles,GCS_PUBLIC_FILES_BUCKET_NAME=fake_publicfiles
|
--env-add=ENABLE_CONVERSIONS="true",USE_PROM_METRICS="true",AWS_S3_USER_FILES_BUCKET_NAME=fake_user_files,AWS_S3_TEMPLATE_FILES_BUCKET_NAME=fake_template_files,AWS_S3_PUBLIC_FILES_BUCKET_NAME=fake_public_files,GCS_USER_FILES_BUCKET_NAME=fake_userfiles,GCS_TEMPLATE_FILES_BUCKET_NAME=fake_templatefiles,GCS_PUBLIC_FILES_BUCKET_NAME=fake_publicfiles
|
||||||
--env-pass-through=
|
--env-pass-through=
|
||||||
--node-version=12.20.1
|
--node-version=12.22.3
|
||||||
--public-repo=True
|
--public-repo=True
|
||||||
--script-version=3.8.0
|
--script-version=3.11.0
|
||||||
|
|
|
@ -40,8 +40,8 @@ const settings = {
|
||||||
internal: {
|
internal: {
|
||||||
filestore: {
|
filestore: {
|
||||||
port: 3009,
|
port: 3009,
|
||||||
host: process.env.LISTEN_ADDRESS || 'localhost'
|
host: process.env.LISTEN_ADDRESS || 'localhost',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
filestore: {
|
filestore: {
|
||||||
|
@ -57,13 +57,13 @@ const settings = {
|
||||||
? {
|
? {
|
||||||
apiEndpoint: process.env.GCS_API_ENDPOINT,
|
apiEndpoint: process.env.GCS_API_ENDPOINT,
|
||||||
apiScheme: process.env.GCS_API_SCHEME,
|
apiScheme: process.env.GCS_API_SCHEME,
|
||||||
projectId: process.env.GCS_PROJECT_ID
|
projectId: process.env.GCS_PROJECT_ID,
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
unlockBeforeDelete: process.env.GCS_UNLOCK_BEFORE_DELETE === 'true', // unlock an event-based hold before deleting. default false
|
unlockBeforeDelete: process.env.GCS_UNLOCK_BEFORE_DELETE === 'true', // unlock an event-based hold before deleting. default false
|
||||||
deletedBucketSuffix: process.env.GCS_DELETED_BUCKET_SUFFIX, // if present, copy file to another bucket on delete. default null
|
deletedBucketSuffix: process.env.GCS_DELETED_BUCKET_SUFFIX, // if present, copy file to another bucket on delete. default null
|
||||||
deleteConcurrency: parseInt(process.env.GCS_DELETE_CONCURRENCY) || 50,
|
deleteConcurrency: parseInt(process.env.GCS_DELETE_CONCURRENCY) || 50,
|
||||||
signedUrlExpiryInMs: parseInt(process.env.LINK_EXPIRY_TIMEOUT || 60000)
|
signedUrlExpiryInMs: parseInt(process.env.LINK_EXPIRY_TIMEOUT || 60000),
|
||||||
},
|
},
|
||||||
|
|
||||||
s3:
|
s3:
|
||||||
|
@ -76,7 +76,7 @@ const settings = {
|
||||||
partSize: process.env.AWS_S3_PARTSIZE || 100 * 1024 * 1024,
|
partSize: process.env.AWS_S3_PARTSIZE || 100 * 1024 * 1024,
|
||||||
bucketCreds: process.env.S3_BUCKET_CREDENTIALS
|
bucketCreds: process.env.S3_BUCKET_CREDENTIALS
|
||||||
? JSON.parse(process.env.S3_BUCKET_CREDENTIALS)
|
? JSON.parse(process.env.S3_BUCKET_CREDENTIALS)
|
||||||
: undefined
|
: undefined,
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ const settings = {
|
||||||
stores: {
|
stores: {
|
||||||
user_files: process.env.USER_FILES_BUCKET_NAME,
|
user_files: process.env.USER_FILES_BUCKET_NAME,
|
||||||
template_files: process.env.TEMPLATE_FILES_BUCKET_NAME,
|
template_files: process.env.TEMPLATE_FILES_BUCKET_NAME,
|
||||||
public_files: process.env.PUBLIC_FILES_BUCKET_NAME
|
public_files: process.env.PUBLIC_FILES_BUCKET_NAME,
|
||||||
},
|
},
|
||||||
|
|
||||||
fallback: process.env.FALLBACK_BACKEND
|
fallback: process.env.FALLBACK_BACKEND
|
||||||
|
@ -95,28 +95,28 @@ const settings = {
|
||||||
// mapping of bucket names on the fallback, to bucket names on the primary.
|
// mapping of bucket names on the fallback, to bucket names on the primary.
|
||||||
// e.g. { myS3UserFilesBucketName: 'myGoogleUserFilesBucketName' }
|
// e.g. { myS3UserFilesBucketName: 'myGoogleUserFilesBucketName' }
|
||||||
buckets: JSON.parse(process.env.FALLBACK_BUCKET_MAPPING || '{}'),
|
buckets: JSON.parse(process.env.FALLBACK_BUCKET_MAPPING || '{}'),
|
||||||
copyOnMiss: process.env.COPY_ON_MISS === 'true'
|
copyOnMiss: process.env.COPY_ON_MISS === 'true',
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|
||||||
allowRedirects: process.env.ALLOW_REDIRECTS === 'true'
|
allowRedirects: process.env.ALLOW_REDIRECTS === 'true',
|
||||||
},
|
},
|
||||||
|
|
||||||
path: {
|
path: {
|
||||||
// eslint-disable-next-line no-path-concat
|
// eslint-disable-next-line no-path-concat
|
||||||
uploadFolder: Path.resolve(__dirname + '/../uploads')
|
uploadFolder: Path.resolve(__dirname + '/../uploads'),
|
||||||
},
|
},
|
||||||
|
|
||||||
commands: {
|
commands: {
|
||||||
// Any commands to wrap the convert utility in, for example ["nice"], or ["firejail", "--profile=/etc/firejail/convert.profile"]
|
// Any commands to wrap the convert utility in, for example ["nice"], or ["firejail", "--profile=/etc/firejail/convert.profile"]
|
||||||
convertCommandPrefix: []
|
convertCommandPrefix: [],
|
||||||
},
|
},
|
||||||
|
|
||||||
enableConversions: process.env.ENABLE_CONVERSIONS === 'true',
|
enableConversions: process.env.ENABLE_CONVERSIONS === 'true',
|
||||||
|
|
||||||
sentry: {
|
sentry: {
|
||||||
dsn: process.env.SENTRY_DSN
|
dsn: process.env.SENTRY_DSN,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filestore health check
|
// Filestore health check
|
||||||
|
@ -125,7 +125,7 @@ const settings = {
|
||||||
if (process.env.HEALTH_CHECK_PROJECT_ID && process.env.HEALTH_CHECK_FILE_ID) {
|
if (process.env.HEALTH_CHECK_PROJECT_ID && process.env.HEALTH_CHECK_FILE_ID) {
|
||||||
settings.health_check = {
|
settings.health_check = {
|
||||||
project_id: process.env.HEALTH_CHECK_PROJECT_ID,
|
project_id: process.env.HEALTH_CHECK_PROJECT_ID,
|
||||||
file_id: process.env.HEALTH_CHECK_FILE_ID
|
file_id: process.env.HEALTH_CHECK_FILE_ID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2523
services/filestore/package-lock.json
generated
2523
services/filestore/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -13,17 +13,20 @@
|
||||||
"test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
|
"test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
|
||||||
"start": "node $NODE_APP_OPTIONS app.js",
|
"start": "node $NODE_APP_OPTIONS app.js",
|
||||||
"nodemon": "nodemon --config nodemon.json",
|
"nodemon": "nodemon --config nodemon.json",
|
||||||
"lint": "node_modules/.bin/eslint --max-warnings 0 .",
|
"lint": "eslint --max-warnings 0 --format unix .",
|
||||||
"format": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --list-different",
|
"format": "prettier --list-different $PWD/'**/*.js'",
|
||||||
"format:fix": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --write",
|
"format:fix": "prettier --write $PWD/'**/*.js'",
|
||||||
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||||
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js"
|
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
|
||||||
|
"lint:fix": "eslint --fix ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@overleaf/metrics": "^3.5.1",
|
"@overleaf/metrics": "^3.5.1",
|
||||||
"@overleaf/o-error": "^3.0.0",
|
"@overleaf/o-error": "^3.0.0",
|
||||||
"@overleaf/object-persistor": "https://github.com/overleaf/object-persistor/archive/8fbc9ed03206bfb54368578d22b7ac4f285baa25.tar.gz",
|
"@overleaf/object-persistor": "https://github.com/overleaf/object-persistor/archive/8fbc9ed03206bfb54368578d22b7ac4f285baa25.tar.gz",
|
||||||
|
"@overleaf/settings": "^2.1.1",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
|
"bunyan": "^1.8.15",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"fast-crc32c": "^2.0.0",
|
"fast-crc32c": "^2.0.0",
|
||||||
"glob": "^7.1.6",
|
"glob": "^7.1.6",
|
||||||
|
@ -33,34 +36,29 @@
|
||||||
"range-parser": "^1.2.1",
|
"range-parser": "^1.2.1",
|
||||||
"request": "^2.88.2",
|
"request": "^2.88.2",
|
||||||
"request-promise-native": "^1.0.8",
|
"request-promise-native": "^1.0.8",
|
||||||
"settings-sharelatex": "^1.1.0",
|
|
||||||
"stream-buffers": "~0.2.6",
|
"stream-buffers": "~0.2.6",
|
||||||
"tiny-async-pool": "^1.1.0"
|
"tiny-async-pool": "^1.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@google-cloud/storage": "^5.1.2",
|
"@google-cloud/storage": "^5.1.2",
|
||||||
"aws-sdk": "^2.718.0",
|
"aws-sdk": "^2.718.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"chai": "^4.2.0",
|
||||||
"bunyan": "^1.8.14",
|
|
||||||
"chai": "4.2.0",
|
|
||||||
"chai-as-promised": "^7.1.1",
|
"chai-as-promised": "^7.1.1",
|
||||||
"disrequire": "^1.1.0",
|
"disrequire": "^1.1.0",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^7.21.0",
|
||||||
"eslint-config-prettier": "^6.10.0",
|
"eslint-config-prettier": "^8.1.0",
|
||||||
"eslint-config-standard": "^14.1.0",
|
"eslint-config-standard": "^16.0.2",
|
||||||
"eslint-plugin-chai-expect": "^2.1.0",
|
"eslint-plugin-chai-expect": "^2.2.0",
|
||||||
"eslint-plugin-chai-friendly": "^0.5.0",
|
"eslint-plugin-chai-friendly": "^0.6.0",
|
||||||
"eslint-plugin-import": "^2.20.1",
|
"eslint-plugin-import": "^2.22.1",
|
||||||
"eslint-plugin-mocha": "^6.3.0",
|
"eslint-plugin-mocha": "^8.0.0",
|
||||||
"eslint-plugin-node": "^11.0.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"eslint-plugin-prettier": "^3.1.2",
|
"eslint-plugin-prettier": "^3.1.2",
|
||||||
"eslint-plugin-promise": "^4.2.1",
|
"eslint-plugin-promise": "^4.2.1",
|
||||||
"eslint-plugin-standard": "^4.0.1",
|
"mocha": "^8.3.2",
|
||||||
"mocha": "7.2.0",
|
|
||||||
"mongodb": "^3.5.9",
|
"mongodb": "^3.5.9",
|
||||||
"prettier": "^2.0.0",
|
"prettier": "^2.2.1",
|
||||||
"prettier-eslint": "^9.0.2",
|
"prettier-eslint": "^9.0.2",
|
||||||
"prettier-eslint-cli": "^5.0.0",
|
|
||||||
"sandboxed-module": "2.0.4",
|
"sandboxed-module": "2.0.4",
|
||||||
"sinon": "9.0.2",
|
"sinon": "9.0.2",
|
||||||
"sinon-chai": "^3.5.0",
|
"sinon-chai": "^3.5.0",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
const Settings = require('settings-sharelatex')
|
const Settings = require('@overleaf/settings')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const Path = require('path')
|
const Path = require('path')
|
||||||
const { promisify } = require('util')
|
const { promisify } = require('util')
|
||||||
|
@ -33,7 +33,7 @@ class FilestoreApp {
|
||||||
this.server = this.app.listen(
|
this.server = this.app.listen(
|
||||||
Settings.internal.filestore.port,
|
Settings.internal.filestore.port,
|
||||||
'localhost',
|
'localhost',
|
||||||
(err) => {
|
err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return reject(err)
|
return reject(err)
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ class FilestoreApp {
|
||||||
secretAccessKey: Settings.filestore.s3.secret,
|
secretAccessKey: Settings.filestore.s3.secret,
|
||||||
endpoint: Settings.filestore.s3.endpoint,
|
endpoint: Settings.filestore.s3.endpoint,
|
||||||
s3ForcePathStyle: true,
|
s3ForcePathStyle: true,
|
||||||
signatureVersion: 'v4'
|
signatureVersion: 'v4',
|
||||||
})
|
})
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -91,7 +91,7 @@ class FilestoreApp {
|
||||||
.putObject({
|
.putObject({
|
||||||
Key: 'startup',
|
Key: 'startup',
|
||||||
Body: '42',
|
Body: '42',
|
||||||
Bucket: Settings.filestore.stores.user_files
|
Bucket: Settings.filestore.stores.user_files,
|
||||||
})
|
})
|
||||||
.promise()
|
.promise()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -110,7 +110,7 @@ class FilestoreApp {
|
||||||
// unload the app, as we may be doing this on multiple runs with
|
// unload the app, as we may be doing this on multiple runs with
|
||||||
// different settings, which affect startup in some cases
|
// different settings, which affect startup in some cases
|
||||||
const files = await fsReaddir(Path.resolve(__dirname, '../../../app/js'))
|
const files = await fsReaddir(Path.resolve(__dirname, '../../../app/js'))
|
||||||
files.forEach((file) => {
|
files.forEach(file => {
|
||||||
disrequire(Path.resolve(__dirname, '../../../app/js', file))
|
disrequire(Path.resolve(__dirname, '../../../app/js', file))
|
||||||
})
|
})
|
||||||
disrequire(Path.resolve(__dirname, '../../../app'))
|
disrequire(Path.resolve(__dirname, '../../../app'))
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
const chai = require('chai')
|
const chai = require('chai')
|
||||||
const { expect } = chai
|
const { expect } = chai
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const Settings = require('settings-sharelatex')
|
const Settings = require('@overleaf/settings')
|
||||||
const Path = require('path')
|
const Path = require('path')
|
||||||
const FilestoreApp = require('./FilestoreApp')
|
const FilestoreApp = require('./FilestoreApp')
|
||||||
const TestHelper = require('./TestHelper')
|
const TestHelper = require('./TestHelper')
|
||||||
const rp = require('request-promise-native').defaults({
|
const rp = require('request-promise-native').defaults({
|
||||||
resolveWithFullResponse: true
|
resolveWithFullResponse: true,
|
||||||
})
|
})
|
||||||
const S3 = require('aws-sdk/clients/s3')
|
const S3 = require('aws-sdk/clients/s3')
|
||||||
const Stream = require('stream')
|
const Stream = require('stream')
|
||||||
|
@ -29,7 +29,7 @@ if (!process.env.AWS_ACCESS_KEY_ID) {
|
||||||
throw new Error('please provide credentials for the AWS S3 test server')
|
throw new Error('please provide credentials for the AWS S3 test server')
|
||||||
}
|
}
|
||||||
|
|
||||||
process.on('unhandledRejection', (e) => {
|
process.on('unhandledRejection', e => {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log('** Unhandled Promise Rejection **\n', e)
|
console.log('** Unhandled Promise Rejection **\n', e)
|
||||||
throw e
|
throw e
|
||||||
|
@ -51,7 +51,7 @@ describe('Filestore', function () {
|
||||||
|
|
||||||
const badSockets = []
|
const badSockets = []
|
||||||
for (const socket of stdout.split('\n')) {
|
for (const socket of stdout.split('\n')) {
|
||||||
const fields = socket.split(' ').filter((part) => part !== '')
|
const fields = socket.split(' ').filter(part => part !== '')
|
||||||
if (
|
if (
|
||||||
fields.length > 2 &&
|
fields.length > 2 &&
|
||||||
parseInt(fields[1]) &&
|
parseInt(fields[1]) &&
|
||||||
|
@ -79,7 +79,7 @@ describe('Filestore', function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// redefine the test suite for every available backend
|
// redefine the test suite for every available backend
|
||||||
Object.keys(BackendSettings).forEach((backend) => {
|
Object.keys(BackendSettings).forEach(backend => {
|
||||||
describe(backend, function () {
|
describe(backend, function () {
|
||||||
let app, previousEgress, previousIngress, metricPrefix, projectId
|
let app, previousEgress, previousIngress, metricPrefix, projectId
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ describe('Filestore', function () {
|
||||||
constantFileContent = [
|
constantFileContent = [
|
||||||
'hello world',
|
'hello world',
|
||||||
`line 2 goes here ${Math.random()}`,
|
`line 2 goes here ${Math.random()}`,
|
||||||
'there are 3 lines in all'
|
'there are 3 lines in all',
|
||||||
].join('\n')
|
].join('\n')
|
||||||
|
|
||||||
await fsWriteFile(localFileReadPath, constantFileContent)
|
await fsWriteFile(localFileReadPath, constantFileContent)
|
||||||
|
@ -204,8 +204,8 @@ describe('Filestore', function () {
|
||||||
const options = {
|
const options = {
|
||||||
uri: fileUrl,
|
uri: fileUrl,
|
||||||
headers: {
|
headers: {
|
||||||
Range: 'bytes=0-8'
|
Range: 'bytes=0-8',
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
const res = await rp.get(options)
|
const res = await rp.get(options)
|
||||||
expect(res.body).to.equal('hello wor')
|
expect(res.body).to.equal('hello wor')
|
||||||
|
@ -215,8 +215,8 @@ describe('Filestore', function () {
|
||||||
const options = {
|
const options = {
|
||||||
uri: fileUrl,
|
uri: fileUrl,
|
||||||
headers: {
|
headers: {
|
||||||
Range: 'bytes=4-10'
|
Range: 'bytes=4-10',
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
const res = await rp.get(options)
|
const res = await rp.get(options)
|
||||||
expect(res.body).to.equal('o world')
|
expect(res.body).to.equal('o world')
|
||||||
|
@ -240,9 +240,9 @@ describe('Filestore', function () {
|
||||||
json: {
|
json: {
|
||||||
source: {
|
source: {
|
||||||
project_id: projectId,
|
project_id: projectId,
|
||||||
file_id: fileId
|
file_id: fileId,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
let response = await rp(opts)
|
let response = await rp(opts)
|
||||||
expect(response.statusCode).to.equal(200)
|
expect(response.statusCode).to.equal(200)
|
||||||
|
@ -288,8 +288,8 @@ describe('Filestore', function () {
|
||||||
const options = {
|
const options = {
|
||||||
uri: fileUrl,
|
uri: fileUrl,
|
||||||
headers: {
|
headers: {
|
||||||
Range: 'bytes=0-8'
|
Range: 'bytes=0-8',
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
await rp.get(options)
|
await rp.get(options)
|
||||||
const metric = await TestHelper.getMetric(
|
const metric = await TestHelper.getMetric(
|
||||||
|
@ -305,25 +305,25 @@ describe('Filestore', function () {
|
||||||
let fileIds, fileUrls, projectUrl
|
let fileIds, fileUrls, projectUrl
|
||||||
const localFileReadPaths = [
|
const localFileReadPaths = [
|
||||||
'/tmp/filestore_acceptance_tests_file_read_1.txt',
|
'/tmp/filestore_acceptance_tests_file_read_1.txt',
|
||||||
'/tmp/filestore_acceptance_tests_file_read_2.txt'
|
'/tmp/filestore_acceptance_tests_file_read_2.txt',
|
||||||
]
|
]
|
||||||
const constantFileContents = [
|
const constantFileContents = [
|
||||||
[
|
[
|
||||||
'hello world',
|
'hello world',
|
||||||
`line 2 goes here ${Math.random()}`,
|
`line 2 goes here ${Math.random()}`,
|
||||||
'there are 3 lines in all'
|
'there are 3 lines in all',
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
[
|
[
|
||||||
`for reference: ${Math.random()}`,
|
`for reference: ${Math.random()}`,
|
||||||
'cats are the best animals',
|
'cats are the best animals',
|
||||||
'wombats are a close second'
|
'wombats are a close second',
|
||||||
].join('\n')
|
].join('\n'),
|
||||||
]
|
]
|
||||||
|
|
||||||
before(async function () {
|
before(async function () {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
fsWriteFile(localFileReadPaths[0], constantFileContents[0]),
|
fsWriteFile(localFileReadPaths[0], constantFileContents[0]),
|
||||||
fsWriteFile(localFileReadPaths[1], constantFileContents[1])
|
fsWriteFile(localFileReadPaths[1], constantFileContents[1]),
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -332,25 +332,25 @@ describe('Filestore', function () {
|
||||||
fileIds = [ObjectId().toString(), ObjectId().toString()]
|
fileIds = [ObjectId().toString(), ObjectId().toString()]
|
||||||
fileUrls = [
|
fileUrls = [
|
||||||
`${projectUrl}/file/${fileIds[0]}`,
|
`${projectUrl}/file/${fileIds[0]}`,
|
||||||
`${projectUrl}/file/${fileIds[1]}`
|
`${projectUrl}/file/${fileIds[1]}`,
|
||||||
]
|
]
|
||||||
|
|
||||||
const writeStreams = [
|
const writeStreams = [
|
||||||
request.post(fileUrls[0]),
|
request.post(fileUrls[0]),
|
||||||
request.post(fileUrls[1])
|
request.post(fileUrls[1]),
|
||||||
]
|
]
|
||||||
const readStreams = [
|
const readStreams = [
|
||||||
fs.createReadStream(localFileReadPaths[0]),
|
fs.createReadStream(localFileReadPaths[0]),
|
||||||
fs.createReadStream(localFileReadPaths[1])
|
fs.createReadStream(localFileReadPaths[1]),
|
||||||
]
|
]
|
||||||
// hack to consume the result to ensure the http request has been fully processed
|
// hack to consume the result to ensure the http request has been fully processed
|
||||||
const resultStreams = [
|
const resultStreams = [
|
||||||
fs.createWriteStream('/dev/null'),
|
fs.createWriteStream('/dev/null'),
|
||||||
fs.createWriteStream('/dev/null')
|
fs.createWriteStream('/dev/null'),
|
||||||
]
|
]
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
pipeline(readStreams[0], writeStreams[0], resultStreams[0]),
|
pipeline(readStreams[0], writeStreams[0], resultStreams[0]),
|
||||||
pipeline(readStreams[1], writeStreams[1], resultStreams[1])
|
pipeline(readStreams[1], writeStreams[1], resultStreams[1]),
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -433,7 +433,7 @@ describe('Filestore', function () {
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
// test is not 100% reliable, so repeat
|
// test is not 100% reliable, so repeat
|
||||||
// create a new connection and have it time out before reading any data
|
// create a new connection and have it time out before reading any data
|
||||||
await new Promise((resolve) => {
|
await new Promise(resolve => {
|
||||||
const streamThatHangs = new Stream.PassThrough()
|
const streamThatHangs = new Stream.PassThrough()
|
||||||
const stream = request({ url: fileUrl, timeout: 1000 })
|
const stream = request({ url: fileUrl, timeout: 1000 })
|
||||||
stream.pipe(streamThatHangs)
|
stream.pipe(streamThatHangs)
|
||||||
|
@ -461,24 +461,24 @@ describe('Filestore', function () {
|
||||||
const s3ClientSettings = {
|
const s3ClientSettings = {
|
||||||
credentials: {
|
credentials: {
|
||||||
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
||||||
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
||||||
},
|
},
|
||||||
endpoint: process.env.AWS_S3_ENDPOINT,
|
endpoint: process.env.AWS_S3_ENDPOINT,
|
||||||
sslEnabled: false,
|
sslEnabled: false,
|
||||||
s3ForcePathStyle: true
|
s3ForcePathStyle: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
const s3 = new S3(s3ClientSettings)
|
const s3 = new S3(s3ClientSettings)
|
||||||
await s3
|
await s3
|
||||||
.createBucket({
|
.createBucket({
|
||||||
Bucket: bucketName
|
Bucket: bucketName,
|
||||||
})
|
})
|
||||||
.promise()
|
.promise()
|
||||||
await s3
|
await s3
|
||||||
.upload({
|
.upload({
|
||||||
Bucket: bucketName,
|
Bucket: bucketName,
|
||||||
Key: fileId,
|
Key: fileId,
|
||||||
Body: constantFileContent
|
Body: constantFileContent,
|
||||||
})
|
})
|
||||||
.promise()
|
.promise()
|
||||||
})
|
})
|
||||||
|
@ -648,9 +648,9 @@ describe('Filestore', function () {
|
||||||
json: {
|
json: {
|
||||||
source: {
|
source: {
|
||||||
project_id: projectId,
|
project_id: projectId,
|
||||||
file_id: fileId
|
file_id: fileId,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -752,9 +752,8 @@ describe('Filestore', function () {
|
||||||
describe('when sending a file', function () {
|
describe('when sending a file', function () {
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
const writeStream = request.post(fileUrl)
|
const writeStream = request.post(fileUrl)
|
||||||
const readStream = streamifier.createReadStream(
|
const readStream =
|
||||||
constantFileContent
|
streamifier.createReadStream(constantFileContent)
|
||||||
)
|
|
||||||
// hack to consume the result to ensure the http request has been fully processed
|
// hack to consume the result to ensure the http request has been fully processed
|
||||||
const resultStream = fs.createWriteStream('/dev/null')
|
const resultStream = fs.createWriteStream('/dev/null')
|
||||||
await pipeline(readStream, writeStream, resultStream)
|
await pipeline(readStream, writeStream, resultStream)
|
||||||
|
|
|
@ -7,7 +7,7 @@ function s3Config() {
|
||||||
secret: process.env.AWS_SECRET_ACCESS_KEY,
|
secret: process.env.AWS_SECRET_ACCESS_KEY,
|
||||||
endpoint: process.env.AWS_S3_ENDPOINT,
|
endpoint: process.env.AWS_S3_ENDPOINT,
|
||||||
pathStyle: true,
|
pathStyle: true,
|
||||||
partSize: 100 * 1024 * 1024
|
partSize: 100 * 1024 * 1024,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ function s3Stores() {
|
||||||
return {
|
return {
|
||||||
user_files: process.env.AWS_S3_USER_FILES_BUCKET_NAME,
|
user_files: process.env.AWS_S3_USER_FILES_BUCKET_NAME,
|
||||||
template_files: process.env.AWS_S3_TEMPLATE_FILES_BUCKET_NAME,
|
template_files: process.env.AWS_S3_TEMPLATE_FILES_BUCKET_NAME,
|
||||||
public_files: process.env.AWS_S3_PUBLIC_FILES_BUCKET_NAME
|
public_files: process.env.AWS_S3_PUBLIC_FILES_BUCKET_NAME,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,11 +24,11 @@ function gcsConfig() {
|
||||||
endpoint: {
|
endpoint: {
|
||||||
apiEndpoint: process.env.GCS_API_ENDPOINT,
|
apiEndpoint: process.env.GCS_API_ENDPOINT,
|
||||||
apiScheme: process.env.GCS_API_SCHEME,
|
apiScheme: process.env.GCS_API_SCHEME,
|
||||||
projectId: 'fake'
|
projectId: 'fake',
|
||||||
},
|
},
|
||||||
directoryKeyRegex: new RegExp('^[0-9a-fA-F]{24}/[0-9a-fA-F]{24}'),
|
directoryKeyRegex: new RegExp('^[0-9a-fA-F]{24}/[0-9a-fA-F]{24}'),
|
||||||
unlockBeforeDelete: false, // fake-gcs does not support this
|
unlockBeforeDelete: false, // fake-gcs does not support this
|
||||||
deletedBucketSuffix: '-deleted'
|
deletedBucketSuffix: '-deleted',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ function gcsStores() {
|
||||||
return {
|
return {
|
||||||
user_files: process.env.GCS_USER_FILES_BUCKET_NAME,
|
user_files: process.env.GCS_USER_FILES_BUCKET_NAME,
|
||||||
template_files: process.env.GCS_TEMPLATE_FILES_BUCKET_NAME,
|
template_files: process.env.GCS_TEMPLATE_FILES_BUCKET_NAME,
|
||||||
public_files: process.env.GCS_PUBLIC_FILES_BUCKET_NAME
|
public_files: process.env.GCS_PUBLIC_FILES_BUCKET_NAME,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ function fsStores() {
|
||||||
return {
|
return {
|
||||||
user_files: Path.resolve(__dirname, '../../../user_files'),
|
user_files: Path.resolve(__dirname, '../../../user_files'),
|
||||||
public_files: Path.resolve(__dirname, '../../../public_files'),
|
public_files: Path.resolve(__dirname, '../../../public_files'),
|
||||||
template_files: Path.resolve(__dirname, '../../../template_files')
|
template_files: Path.resolve(__dirname, '../../../template_files'),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,24 +52,24 @@ function fallbackStores(primaryConfig, fallbackConfig) {
|
||||||
return {
|
return {
|
||||||
[primaryConfig.user_files]: fallbackConfig.user_files,
|
[primaryConfig.user_files]: fallbackConfig.user_files,
|
||||||
[primaryConfig.public_files]: fallbackConfig.public_files,
|
[primaryConfig.public_files]: fallbackConfig.public_files,
|
||||||
[primaryConfig.template_files]: fallbackConfig.template_files
|
[primaryConfig.template_files]: fallbackConfig.template_files,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
FSPersistor: {
|
FSPersistor: {
|
||||||
backend: 'fs',
|
backend: 'fs',
|
||||||
stores: fsStores()
|
stores: fsStores(),
|
||||||
},
|
},
|
||||||
S3Persistor: {
|
S3Persistor: {
|
||||||
backend: 's3',
|
backend: 's3',
|
||||||
s3: s3Config(),
|
s3: s3Config(),
|
||||||
stores: s3Stores()
|
stores: s3Stores(),
|
||||||
},
|
},
|
||||||
GcsPersistor: {
|
GcsPersistor: {
|
||||||
backend: 'gcs',
|
backend: 'gcs',
|
||||||
gcs: gcsConfig(),
|
gcs: gcsConfig(),
|
||||||
stores: gcsStores()
|
stores: gcsStores(),
|
||||||
},
|
},
|
||||||
FallbackS3ToFSPersistor: {
|
FallbackS3ToFSPersistor: {
|
||||||
backend: 's3',
|
backend: 's3',
|
||||||
|
@ -77,8 +77,8 @@ module.exports = {
|
||||||
stores: s3Stores(),
|
stores: s3Stores(),
|
||||||
fallback: {
|
fallback: {
|
||||||
backend: 'fs',
|
backend: 'fs',
|
||||||
buckets: fallbackStores(s3Stores(), fsStores())
|
buckets: fallbackStores(s3Stores(), fsStores()),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
FallbackFSToS3Persistor: {
|
FallbackFSToS3Persistor: {
|
||||||
backend: 'fs',
|
backend: 'fs',
|
||||||
|
@ -86,8 +86,8 @@ module.exports = {
|
||||||
stores: fsStores(),
|
stores: fsStores(),
|
||||||
fallback: {
|
fallback: {
|
||||||
backend: 's3',
|
backend: 's3',
|
||||||
buckets: fallbackStores(fsStores(), s3Stores())
|
buckets: fallbackStores(fsStores(), s3Stores()),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
FallbackGcsToS3Persistor: {
|
FallbackGcsToS3Persistor: {
|
||||||
backend: 'gcs',
|
backend: 'gcs',
|
||||||
|
@ -96,8 +96,8 @@ module.exports = {
|
||||||
s3: s3Config(),
|
s3: s3Config(),
|
||||||
fallback: {
|
fallback: {
|
||||||
backend: 's3',
|
backend: 's3',
|
||||||
buckets: fallbackStores(gcsStores(), s3Stores())
|
buckets: fallbackStores(gcsStores(), s3Stores()),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
FallbackS3ToGcsPersistor: {
|
FallbackS3ToGcsPersistor: {
|
||||||
backend: 's3',
|
backend: 's3',
|
||||||
|
@ -107,7 +107,7 @@ module.exports = {
|
||||||
gcs: gcsConfig(),
|
gcs: gcsConfig(),
|
||||||
fallback: {
|
fallback: {
|
||||||
backend: 'gcs',
|
backend: 'gcs',
|
||||||
buckets: fallbackStores(s3Stores(), gcsStores())
|
buckets: fallbackStores(s3Stores(), gcsStores()),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const streamifier = require('streamifier')
|
const streamifier = require('streamifier')
|
||||||
const rp = require('request-promise-native').defaults({
|
const rp = require('request-promise-native').defaults({
|
||||||
resolveWithFullResponse: true
|
resolveWithFullResponse: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { expect } = require('chai')
|
const { expect } = require('chai')
|
||||||
|
@ -11,7 +11,7 @@ module.exports = {
|
||||||
expectPersistorToHaveFile,
|
expectPersistorToHaveFile,
|
||||||
expectPersistorNotToHaveFile,
|
expectPersistorNotToHaveFile,
|
||||||
streamToString,
|
streamToString,
|
||||||
getMetric
|
getMetric,
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getMetric(filestoreUrl, metric) {
|
async function getMetric(filestoreUrl, metric) {
|
||||||
|
@ -25,7 +25,7 @@ async function getMetric(filestoreUrl, metric) {
|
||||||
function streamToString(stream) {
|
function streamToString(stream) {
|
||||||
const chunks = []
|
const chunks = []
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
stream.on('data', (chunk) => chunks.push(chunk))
|
stream.on('data', chunk => chunks.push(chunk))
|
||||||
stream.on('error', reject)
|
stream.on('error', reject)
|
||||||
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
|
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
|
||||||
stream.resume()
|
stream.resume()
|
||||||
|
|
|
@ -17,9 +17,9 @@ describe('FileController', function () {
|
||||||
const settings = {
|
const settings = {
|
||||||
s3: {
|
s3: {
|
||||||
buckets: {
|
buckets: {
|
||||||
user_files: 'user_files'
|
user_files: 'user_files',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
const fileSize = 1234
|
const fileSize = 1234
|
||||||
const fileStream = 'fileStream'
|
const fileStream = 'fileStream'
|
||||||
|
@ -33,7 +33,7 @@ describe('FileController', function () {
|
||||||
PersistorManager = {
|
PersistorManager = {
|
||||||
sendStream: sinon.stub().yields(),
|
sendStream: sinon.stub().yields(),
|
||||||
copyObject: sinon.stub().resolves(),
|
copyObject: sinon.stub().resolves(),
|
||||||
deleteObject: sinon.stub().yields()
|
deleteObject: sinon.stub().yields(),
|
||||||
}
|
}
|
||||||
|
|
||||||
FileHandler = {
|
FileHandler = {
|
||||||
|
@ -43,12 +43,12 @@ describe('FileController', function () {
|
||||||
deleteProject: sinon.stub().yields(),
|
deleteProject: sinon.stub().yields(),
|
||||||
insertFile: sinon.stub().yields(),
|
insertFile: sinon.stub().yields(),
|
||||||
getDirectorySize: sinon.stub().yields(null, fileSize),
|
getDirectorySize: sinon.stub().yields(null, fileSize),
|
||||||
getRedirectUrl: sinon.stub().yields(null, null)
|
getRedirectUrl: sinon.stub().yields(null, null),
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalFileWriter = {}
|
LocalFileWriter = {}
|
||||||
stream = {
|
stream = {
|
||||||
pipeline: sinon.stub()
|
pipeline: sinon.stub(),
|
||||||
}
|
}
|
||||||
|
|
||||||
FileController = SandboxedModule.require(modulePath, {
|
FileController = SandboxedModule.require(modulePath, {
|
||||||
|
@ -58,12 +58,12 @@ describe('FileController', function () {
|
||||||
'./PersistorManager': PersistorManager,
|
'./PersistorManager': PersistorManager,
|
||||||
'./Errors': Errors,
|
'./Errors': Errors,
|
||||||
stream: stream,
|
stream: stream,
|
||||||
'settings-sharelatex': settings,
|
'@overleaf/settings': settings,
|
||||||
'@overleaf/metrics': {
|
'@overleaf/metrics': {
|
||||||
inc() {}
|
inc() {},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
globals: { console }
|
},
|
||||||
|
globals: { console },
|
||||||
})
|
})
|
||||||
|
|
||||||
req = {
|
req = {
|
||||||
|
@ -73,19 +73,19 @@ describe('FileController', function () {
|
||||||
query: {},
|
query: {},
|
||||||
params: {
|
params: {
|
||||||
project_id: projectId,
|
project_id: projectId,
|
||||||
file_id: fileId
|
file_id: fileId,
|
||||||
},
|
},
|
||||||
headers: {},
|
headers: {},
|
||||||
requestLogger: {
|
requestLogger: {
|
||||||
setMessage: sinon.stub(),
|
setMessage: sinon.stub(),
|
||||||
addFields: sinon.stub()
|
addFields: sinon.stub(),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
res = {
|
res = {
|
||||||
set: sinon.stub().returnsThis(),
|
set: sinon.stub().returnsThis(),
|
||||||
sendStatus: sinon.stub().returnsThis(),
|
sendStatus: sinon.stub().returnsThis(),
|
||||||
status: sinon.stub().returnsThis()
|
status: sinon.stub().returnsThis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
next = sinon.stub()
|
next = sinon.stub()
|
||||||
|
@ -104,7 +104,7 @@ describe('FileController', function () {
|
||||||
|
|
||||||
it('should send a 200 if the cacheWarm param is true', function (done) {
|
it('should send a 200 if the cacheWarm param is true', function (done) {
|
||||||
req.query.cacheWarm = true
|
req.query.cacheWarm = true
|
||||||
res.sendStatus = (statusCode) => {
|
res.sendStatus = statusCode => {
|
||||||
statusCode.should.equal(200)
|
statusCode.should.equal(200)
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,7 @@ describe('FileController', function () {
|
||||||
bucket,
|
bucket,
|
||||||
key,
|
key,
|
||||||
format: undefined,
|
format: undefined,
|
||||||
style: undefined
|
style: undefined,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ describe('FileController', function () {
|
||||||
new Errors.NotFoundError({ message: 'not found', info: {} })
|
new Errors.NotFoundError({ message: 'not found', info: {} })
|
||||||
)
|
)
|
||||||
|
|
||||||
res.sendStatus = (code) => {
|
res.sendStatus = code => {
|
||||||
expect(code).to.equal(404)
|
expect(code).to.equal(404)
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ describe('FileController', function () {
|
||||||
|
|
||||||
describe('insertFile', function () {
|
describe('insertFile', function () {
|
||||||
it('should send bucket name key and res to PersistorManager', function (done) {
|
it('should send bucket name key and res to PersistorManager', function (done) {
|
||||||
res.sendStatus = (code) => {
|
res.sendStatus = code => {
|
||||||
expect(FileHandler.insertFile).to.have.been.calledWith(bucket, key, req)
|
expect(FileHandler.insertFile).to.have.been.calledWith(bucket, key, req)
|
||||||
expect(code).to.equal(200)
|
expect(code).to.equal(200)
|
||||||
done()
|
done()
|
||||||
|
@ -256,13 +256,13 @@ describe('FileController', function () {
|
||||||
req.body = {
|
req.body = {
|
||||||
source: {
|
source: {
|
||||||
project_id: oldProjectId,
|
project_id: oldProjectId,
|
||||||
file_id: oldFileId
|
file_id: oldFileId,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should send bucket name and both keys to PersistorManager', function (done) {
|
it('should send bucket name and both keys to PersistorManager', function (done) {
|
||||||
res.sendStatus = (code) => {
|
res.sendStatus = code => {
|
||||||
code.should.equal(200)
|
code.should.equal(200)
|
||||||
expect(PersistorManager.copyObject).to.have.been.calledWith(
|
expect(PersistorManager.copyObject).to.have.been.calledWith(
|
||||||
bucket,
|
bucket,
|
||||||
|
@ -278,7 +278,7 @@ describe('FileController', function () {
|
||||||
PersistorManager.copyObject.rejects(
|
PersistorManager.copyObject.rejects(
|
||||||
new Errors.NotFoundError({ message: 'not found', info: {} })
|
new Errors.NotFoundError({ message: 'not found', info: {} })
|
||||||
)
|
)
|
||||||
res.sendStatus = (code) => {
|
res.sendStatus = code => {
|
||||||
code.should.equal(404)
|
code.should.equal(404)
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ describe('FileController', function () {
|
||||||
|
|
||||||
it('should send an error if there was an error', function (done) {
|
it('should send an error if there was an error', function (done) {
|
||||||
PersistorManager.copyObject.rejects(error)
|
PersistorManager.copyObject.rejects(error)
|
||||||
FileController.copyFile(req, res, (err) => {
|
FileController.copyFile(req, res, err => {
|
||||||
expect(err).to.equal(error)
|
expect(err).to.equal(error)
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
@ -296,7 +296,7 @@ describe('FileController', function () {
|
||||||
|
|
||||||
describe('delete file', function () {
|
describe('delete file', function () {
|
||||||
it('should tell the file handler', function (done) {
|
it('should tell the file handler', function (done) {
|
||||||
res.sendStatus = (code) => {
|
res.sendStatus = code => {
|
||||||
code.should.equal(204)
|
code.should.equal(204)
|
||||||
expect(FileHandler.deleteFile).to.have.been.calledWith(bucket, key)
|
expect(FileHandler.deleteFile).to.have.been.calledWith(bucket, key)
|
||||||
done()
|
done()
|
||||||
|
@ -313,7 +313,7 @@ describe('FileController', function () {
|
||||||
|
|
||||||
describe('delete project', function () {
|
describe('delete project', function () {
|
||||||
it('should tell the file handler', function (done) {
|
it('should tell the file handler', function (done) {
|
||||||
res.sendStatus = (code) => {
|
res.sendStatus = code => {
|
||||||
code.should.equal(204)
|
code.should.equal(204)
|
||||||
expect(FileHandler.deleteProject).to.have.been.calledWith(bucket, key)
|
expect(FileHandler.deleteProject).to.have.been.calledWith(bucket, key)
|
||||||
done()
|
done()
|
||||||
|
@ -331,10 +331,10 @@ describe('FileController', function () {
|
||||||
describe('directorySize', function () {
|
describe('directorySize', function () {
|
||||||
it('should return total directory size bytes', function (done) {
|
it('should return total directory size bytes', function (done) {
|
||||||
FileController.directorySize(req, {
|
FileController.directorySize(req, {
|
||||||
json: (result) => {
|
json: result => {
|
||||||
expect(result['total bytes']).to.equal(fileSize)
|
expect(result['total bytes']).to.equal(fileSize)
|
||||||
done()
|
done()
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,13 @@ describe('FileConverter', function () {
|
||||||
const errorMessage = 'guru meditation error'
|
const errorMessage = 'guru meditation error'
|
||||||
const Settings = {
|
const Settings = {
|
||||||
commands: {
|
commands: {
|
||||||
convertCommandPrefix: []
|
convertCommandPrefix: [],
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
SafeExec = {
|
SafeExec = {
|
||||||
promises: sinon.stub().resolves(destPath)
|
promises: sinon.stub().resolves(destPath),
|
||||||
}
|
}
|
||||||
|
|
||||||
const ObjectPersistor = { Errors }
|
const ObjectPersistor = { Errors }
|
||||||
|
@ -30,11 +30,11 @@ describe('FileConverter', function () {
|
||||||
'./SafeExec': SafeExec,
|
'./SafeExec': SafeExec,
|
||||||
'@overleaf/metrics': {
|
'@overleaf/metrics': {
|
||||||
inc: sinon.stub(),
|
inc: sinon.stub(),
|
||||||
Timer: sinon.stub().returns({ done: sinon.stub() })
|
Timer: sinon.stub().returns({ done: sinon.stub() }),
|
||||||
|
},
|
||||||
|
'@overleaf/settings': Settings,
|
||||||
|
'@overleaf/object-persistor': ObjectPersistor,
|
||||||
},
|
},
|
||||||
'settings-sharelatex': Settings,
|
|
||||||
'@overleaf/object-persistor': ObjectPersistor
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ describe('FileHandler', function () {
|
||||||
const redirectUrl = 'https://wombat.potato/giraffe'
|
const redirectUrl = 'https://wombat.potato/giraffe'
|
||||||
const readStream = {
|
const readStream = {
|
||||||
stream: 'readStream',
|
stream: 'readStream',
|
||||||
on: sinon.stub()
|
on: sinon.stub(),
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
|
@ -41,35 +41,35 @@ describe('FileHandler', function () {
|
||||||
sendStream: sinon.stub().resolves(),
|
sendStream: sinon.stub().resolves(),
|
||||||
insertFile: sinon.stub().resolves(),
|
insertFile: sinon.stub().resolves(),
|
||||||
sendFile: sinon.stub().resolves(),
|
sendFile: sinon.stub().resolves(),
|
||||||
directorySize: sinon.stub().resolves()
|
directorySize: sinon.stub().resolves(),
|
||||||
}
|
}
|
||||||
LocalFileWriter = {
|
LocalFileWriter = {
|
||||||
// the callback style is used for detached cleanup calls
|
// the callback style is used for detached cleanup calls
|
||||||
deleteFile: sinon.stub().yields(),
|
deleteFile: sinon.stub().yields(),
|
||||||
promises: {
|
promises: {
|
||||||
writeStream: sinon.stub().resolves(),
|
writeStream: sinon.stub().resolves(),
|
||||||
deleteFile: sinon.stub().resolves()
|
deleteFile: sinon.stub().resolves(),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
FileConverter = {
|
FileConverter = {
|
||||||
promises: {
|
promises: {
|
||||||
convert: sinon.stub().resolves(),
|
convert: sinon.stub().resolves(),
|
||||||
thumbnail: sinon.stub().resolves(),
|
thumbnail: sinon.stub().resolves(),
|
||||||
preview: sinon.stub().resolves()
|
preview: sinon.stub().resolves(),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
KeyBuilder = {
|
KeyBuilder = {
|
||||||
addCachingToKey: sinon.stub().returns(convertedKey),
|
addCachingToKey: sinon.stub().returns(convertedKey),
|
||||||
getConvertedFolderKey: sinon.stub().returns(convertedFolderKey)
|
getConvertedFolderKey: sinon.stub().returns(convertedFolderKey),
|
||||||
}
|
}
|
||||||
ImageOptimiser = {
|
ImageOptimiser = {
|
||||||
promises: {
|
promises: {
|
||||||
compressPng: sinon.stub().resolves()
|
compressPng: sinon.stub().resolves(),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
Settings = {}
|
Settings = {}
|
||||||
fs = {
|
fs = {
|
||||||
createReadStream: sinon.stub().returns(readStream)
|
createReadStream: sinon.stub().returns(readStream),
|
||||||
}
|
}
|
||||||
|
|
||||||
const ObjectPersistor = { Errors }
|
const ObjectPersistor = { Errors }
|
||||||
|
@ -81,11 +81,11 @@ describe('FileHandler', function () {
|
||||||
'./FileConverter': FileConverter,
|
'./FileConverter': FileConverter,
|
||||||
'./KeyBuilder': KeyBuilder,
|
'./KeyBuilder': KeyBuilder,
|
||||||
'./ImageOptimiser': ImageOptimiser,
|
'./ImageOptimiser': ImageOptimiser,
|
||||||
'settings-sharelatex': Settings,
|
'@overleaf/settings': Settings,
|
||||||
'@overleaf/object-persistor': ObjectPersistor,
|
'@overleaf/object-persistor': ObjectPersistor,
|
||||||
fs: fs
|
fs: fs,
|
||||||
},
|
},
|
||||||
globals: { console }
|
globals: { console },
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ describe('FileHandler', function () {
|
||||||
const stream = 'stream'
|
const stream = 'stream'
|
||||||
|
|
||||||
it('should send file to the filestore', function (done) {
|
it('should send file to the filestore', function (done) {
|
||||||
FileHandler.insertFile(bucket, key, stream, (err) => {
|
FileHandler.insertFile(bucket, key, stream, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(PersistorManager.sendStream).to.have.been.calledWith(
|
expect(PersistorManager.sendStream).to.have.been.calledWith(
|
||||||
bucket,
|
bucket,
|
||||||
|
@ -105,7 +105,7 @@ describe('FileHandler', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not make a delete request for the convertedKey folder', function (done) {
|
it('should not make a delete request for the convertedKey folder', function (done) {
|
||||||
FileHandler.insertFile(bucket, key, stream, (err) => {
|
FileHandler.insertFile(bucket, key, stream, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(PersistorManager.deleteDirectory).not.to.have.been.called
|
expect(PersistorManager.deleteDirectory).not.to.have.been.called
|
||||||
done()
|
done()
|
||||||
|
@ -116,7 +116,7 @@ describe('FileHandler', function () {
|
||||||
KeyBuilder.getConvertedFolderKey.returns(
|
KeyBuilder.getConvertedFolderKey.returns(
|
||||||
'5ecba29f1a294e007d0bccb4/v/0/pdf'
|
'5ecba29f1a294e007d0bccb4/v/0/pdf'
|
||||||
)
|
)
|
||||||
FileHandler.insertFile(bucket, key, stream, (err) => {
|
FileHandler.insertFile(bucket, key, stream, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
@ -124,7 +124,7 @@ describe('FileHandler', function () {
|
||||||
|
|
||||||
it('should throw an error when the key is in the wrong format', function (done) {
|
it('should throw an error when the key is in the wrong format', function (done) {
|
||||||
KeyBuilder.getConvertedFolderKey.returns('wombat')
|
KeyBuilder.getConvertedFolderKey.returns('wombat')
|
||||||
FileHandler.insertFile(bucket, key, stream, (err) => {
|
FileHandler.insertFile(bucket, key, stream, err => {
|
||||||
expect(err).to.exist
|
expect(err).to.exist
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
@ -136,7 +136,7 @@ describe('FileHandler', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should delete the convertedKey folder', function (done) {
|
it('should delete the convertedKey folder', function (done) {
|
||||||
FileHandler.insertFile(bucket, key, stream, (err) => {
|
FileHandler.insertFile(bucket, key, stream, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(PersistorManager.deleteDirectory).to.have.been.calledWith(
|
expect(PersistorManager.deleteDirectory).to.have.been.calledWith(
|
||||||
bucket,
|
bucket,
|
||||||
|
@ -150,7 +150,7 @@ describe('FileHandler', function () {
|
||||||
|
|
||||||
describe('deleteFile', function () {
|
describe('deleteFile', function () {
|
||||||
it('should tell the filestore manager to delete the file', function (done) {
|
it('should tell the filestore manager to delete the file', function (done) {
|
||||||
FileHandler.deleteFile(bucket, key, (err) => {
|
FileHandler.deleteFile(bucket, key, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(PersistorManager.deleteObject).to.have.been.calledWith(
|
expect(PersistorManager.deleteObject).to.have.been.calledWith(
|
||||||
bucket,
|
bucket,
|
||||||
|
@ -161,7 +161,7 @@ describe('FileHandler', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not tell the filestore manager to delete the cached folder', function (done) {
|
it('should not tell the filestore manager to delete the cached folder', function (done) {
|
||||||
FileHandler.deleteFile(bucket, key, (err) => {
|
FileHandler.deleteFile(bucket, key, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(PersistorManager.deleteDirectory).not.to.have.been.called
|
expect(PersistorManager.deleteDirectory).not.to.have.been.called
|
||||||
done()
|
done()
|
||||||
|
@ -172,7 +172,7 @@ describe('FileHandler', function () {
|
||||||
KeyBuilder.getConvertedFolderKey.returns(
|
KeyBuilder.getConvertedFolderKey.returns(
|
||||||
'5ecba29f1a294e007d0bccb4/v/0/pdf'
|
'5ecba29f1a294e007d0bccb4/v/0/pdf'
|
||||||
)
|
)
|
||||||
FileHandler.deleteFile(bucket, key, (err) => {
|
FileHandler.deleteFile(bucket, key, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
@ -180,7 +180,7 @@ describe('FileHandler', function () {
|
||||||
|
|
||||||
it('should throw an error when the key is in the wrong format', function (done) {
|
it('should throw an error when the key is in the wrong format', function (done) {
|
||||||
KeyBuilder.getConvertedFolderKey.returns('wombat')
|
KeyBuilder.getConvertedFolderKey.returns('wombat')
|
||||||
FileHandler.deleteFile(bucket, key, (err) => {
|
FileHandler.deleteFile(bucket, key, err => {
|
||||||
expect(err).to.exist
|
expect(err).to.exist
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
@ -192,7 +192,7 @@ describe('FileHandler', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should delete the convertedKey folder', function (done) {
|
it('should delete the convertedKey folder', function (done) {
|
||||||
FileHandler.deleteFile(bucket, key, (err) => {
|
FileHandler.deleteFile(bucket, key, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(PersistorManager.deleteDirectory).to.have.been.calledWith(
|
expect(PersistorManager.deleteDirectory).to.have.been.calledWith(
|
||||||
bucket,
|
bucket,
|
||||||
|
@ -206,7 +206,7 @@ describe('FileHandler', function () {
|
||||||
|
|
||||||
describe('deleteProject', function () {
|
describe('deleteProject', function () {
|
||||||
it('should tell the filestore manager to delete the folder', function (done) {
|
it('should tell the filestore manager to delete the folder', function (done) {
|
||||||
FileHandler.deleteProject(bucket, projectKey, (err) => {
|
FileHandler.deleteProject(bucket, projectKey, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(PersistorManager.deleteDirectory).to.have.been.calledWith(
|
expect(PersistorManager.deleteDirectory).to.have.been.calledWith(
|
||||||
bucket,
|
bucket,
|
||||||
|
@ -217,7 +217,7 @@ describe('FileHandler', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should throw an error when the key is in the wrong format', function (done) {
|
it('should throw an error when the key is in the wrong format', function (done) {
|
||||||
FileHandler.deleteProject(bucket, 'wombat', (err) => {
|
FileHandler.deleteProject(bucket, 'wombat', err => {
|
||||||
expect(err).to.exist
|
expect(err).to.exist
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
@ -235,7 +235,7 @@ describe('FileHandler', function () {
|
||||||
|
|
||||||
it('should pass options through to PersistorManager', function (done) {
|
it('should pass options through to PersistorManager', function (done) {
|
||||||
const options = { start: 0, end: 8 }
|
const options = { start: 0, end: 8 }
|
||||||
FileHandler.getFile(bucket, key, options, (err) => {
|
FileHandler.getFile(bucket, key, options, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(PersistorManager.getObjectStream).to.have.been.calledWith(
|
expect(PersistorManager.getObjectStream).to.have.been.calledWith(
|
||||||
bucket,
|
bucket,
|
||||||
|
@ -305,7 +305,7 @@ describe('FileHandler', function () {
|
||||||
|
|
||||||
describe('when a style is defined', function () {
|
describe('when a style is defined', function () {
|
||||||
it('generates a thumbnail when requested', function (done) {
|
it('generates a thumbnail when requested', function (done) {
|
||||||
FileHandler.getFile(bucket, key, { style: 'thumbnail' }, (err) => {
|
FileHandler.getFile(bucket, key, { style: 'thumbnail' }, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(FileConverter.promises.thumbnail).to.have.been.called
|
expect(FileConverter.promises.thumbnail).to.have.been.called
|
||||||
expect(FileConverter.promises.preview).not.to.have.been.called
|
expect(FileConverter.promises.preview).not.to.have.been.called
|
||||||
|
@ -314,7 +314,7 @@ describe('FileHandler', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('generates a preview when requested', function (done) {
|
it('generates a preview when requested', function (done) {
|
||||||
FileHandler.getFile(bucket, key, { style: 'preview' }, (err) => {
|
FileHandler.getFile(bucket, key, { style: 'preview' }, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(FileConverter.promises.thumbnail).not.to.have.been.called
|
expect(FileConverter.promises.thumbnail).not.to.have.been.called
|
||||||
expect(FileConverter.promises.preview).to.have.been.called
|
expect(FileConverter.promises.preview).to.have.been.called
|
||||||
|
@ -329,8 +329,8 @@ describe('FileHandler', function () {
|
||||||
Settings.filestore = {
|
Settings.filestore = {
|
||||||
allowRedirects: true,
|
allowRedirects: true,
|
||||||
stores: {
|
stores: {
|
||||||
userFiles: bucket
|
userFiles: bucket,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -385,7 +385,7 @@ describe('FileHandler', function () {
|
||||||
|
|
||||||
describe('getDirectorySize', function () {
|
describe('getDirectorySize', function () {
|
||||||
it('should call the filestore manager to get directory size', function (done) {
|
it('should call the filestore manager to get directory size', function (done) {
|
||||||
FileHandler.getDirectorySize(bucket, key, (err) => {
|
FileHandler.getDirectorySize(bucket, key, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(PersistorManager.directorySize).to.have.been.calledWith(
|
expect(PersistorManager.directorySize).to.have.been.calledWith(
|
||||||
bucket,
|
bucket,
|
||||||
|
|
|
@ -11,29 +11,29 @@ describe('ImageOptimiser', function () {
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
SafeExec = {
|
SafeExec = {
|
||||||
promises: sinon.stub().resolves()
|
promises: sinon.stub().resolves(),
|
||||||
}
|
}
|
||||||
logger = {
|
logger = {
|
||||||
warn: sinon.stub()
|
warn: sinon.stub(),
|
||||||
}
|
}
|
||||||
ImageOptimiser = SandboxedModule.require(modulePath, {
|
ImageOptimiser = SandboxedModule.require(modulePath, {
|
||||||
requires: {
|
requires: {
|
||||||
'./SafeExec': SafeExec,
|
'./SafeExec': SafeExec,
|
||||||
'logger-sharelatex': logger,
|
'logger-sharelatex': logger,
|
||||||
'@overleaf/metrics': {
|
'@overleaf/metrics': {
|
||||||
Timer: sinon.stub().returns({ done: sinon.stub() })
|
Timer: sinon.stub().returns({ done: sinon.stub() }),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('compressPng', function () {
|
describe('compressPng', function () {
|
||||||
it('should convert the file', function (done) {
|
it('should convert the file', function (done) {
|
||||||
ImageOptimiser.compressPng(sourcePath, (err) => {
|
ImageOptimiser.compressPng(sourcePath, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(SafeExec.promises).to.have.been.calledWith([
|
expect(SafeExec.promises).to.have.been.calledWith([
|
||||||
'optipng',
|
'optipng',
|
||||||
sourcePath
|
sourcePath,
|
||||||
])
|
])
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
@ -41,7 +41,7 @@ describe('ImageOptimiser', function () {
|
||||||
|
|
||||||
it('should return the error', function (done) {
|
it('should return the error', function (done) {
|
||||||
SafeExec.promises.rejects('wombat herding failure')
|
SafeExec.promises.rejects('wombat herding failure')
|
||||||
ImageOptimiser.compressPng(sourcePath, (err) => {
|
ImageOptimiser.compressPng(sourcePath, err => {
|
||||||
expect(err.toString()).to.equal('wombat herding failure')
|
expect(err.toString()).to.equal('wombat herding failure')
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
@ -54,7 +54,7 @@ describe('ImageOptimiser', function () {
|
||||||
|
|
||||||
beforeEach(function (done) {
|
beforeEach(function (done) {
|
||||||
SafeExec.promises.rejects(expectedError)
|
SafeExec.promises.rejects(expectedError)
|
||||||
ImageOptimiser.compressPng(sourcePath, (err) => {
|
ImageOptimiser.compressPng(sourcePath, err => {
|
||||||
error = err
|
error = err
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
|
|
@ -8,7 +8,7 @@ describe('KeybuilderTests', function () {
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
KeyBuilder = SandboxedModule.require(modulePath, {
|
KeyBuilder = SandboxedModule.require(modulePath, {
|
||||||
requires: { 'settings-sharelatex': {} }
|
requires: { '@overleaf/settings': {} },
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ describe('KeybuilderTests', function () {
|
||||||
it('should add format first, then style', function () {
|
it('should add format first, then style', function () {
|
||||||
const opts = {
|
const opts = {
|
||||||
style: 'thumbnail',
|
style: 'thumbnail',
|
||||||
format: 'png'
|
format: 'png',
|
||||||
}
|
}
|
||||||
const newKey = KeyBuilder.addCachingToKey(key, opts)
|
const newKey = KeyBuilder.addCachingToKey(key, opts)
|
||||||
newKey.should.equal(`${key}-converted-cache/format-png-style-thumbnail`)
|
newKey.should.equal(`${key}-converted-cache/format-png-style-thumbnail`)
|
||||||
|
|
|
@ -17,10 +17,10 @@ describe('LocalFileWriter', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
fs = {
|
fs = {
|
||||||
createWriteStream: sinon.stub().returns(writeStream),
|
createWriteStream: sinon.stub().returns(writeStream),
|
||||||
unlink: sinon.stub().yields()
|
unlink: sinon.stub().yields(),
|
||||||
}
|
}
|
||||||
stream = {
|
stream = {
|
||||||
pipeline: sinon.stub().yields()
|
pipeline: sinon.stub().yields(),
|
||||||
}
|
}
|
||||||
|
|
||||||
const ObjectPersistor = { Errors }
|
const ObjectPersistor = { Errors }
|
||||||
|
@ -29,13 +29,13 @@ describe('LocalFileWriter', function () {
|
||||||
requires: {
|
requires: {
|
||||||
fs,
|
fs,
|
||||||
stream,
|
stream,
|
||||||
'settings-sharelatex': settings,
|
'@overleaf/settings': settings,
|
||||||
'@overleaf/metrics': {
|
'@overleaf/metrics': {
|
||||||
inc: sinon.stub(),
|
inc: sinon.stub(),
|
||||||
Timer: sinon.stub().returns({ done: sinon.stub() })
|
Timer: sinon.stub().returns({ done: sinon.stub() }),
|
||||||
|
},
|
||||||
|
'@overleaf/object-persistor': ObjectPersistor,
|
||||||
},
|
},
|
||||||
'@overleaf/object-persistor': ObjectPersistor
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ describe('LocalFileWriter', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should wrap the error', function () {
|
it('should wrap the error', function () {
|
||||||
LocalFileWriter.writeStream(readStream, filename, (err) => {
|
LocalFileWriter.writeStream(readStream, filename, err => {
|
||||||
expect(err).to.exist
|
expect(err).to.exist
|
||||||
expect(err.cause).to.equal(error)
|
expect(err.cause).to.equal(error)
|
||||||
})
|
})
|
||||||
|
@ -73,7 +73,7 @@ describe('LocalFileWriter', function () {
|
||||||
|
|
||||||
describe('deleteFile', function () {
|
describe('deleteFile', function () {
|
||||||
it('should unlink the file', function (done) {
|
it('should unlink the file', function (done) {
|
||||||
LocalFileWriter.deleteFile(fsPath, (err) => {
|
LocalFileWriter.deleteFile(fsPath, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(fs.unlink).to.have.been.calledWith(fsPath)
|
expect(fs.unlink).to.have.been.calledWith(fsPath)
|
||||||
done()
|
done()
|
||||||
|
@ -81,7 +81,7 @@ describe('LocalFileWriter', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not call unlink with an empty path', function (done) {
|
it('should not call unlink with an empty path', function (done) {
|
||||||
LocalFileWriter.deleteFile('', (err) => {
|
LocalFileWriter.deleteFile('', err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
expect(fs.unlink).not.to.have.been.called
|
expect(fs.unlink).not.to.have.been.called
|
||||||
done()
|
done()
|
||||||
|
@ -92,7 +92,7 @@ describe('LocalFileWriter', function () {
|
||||||
const error = new Error('file not found')
|
const error = new Error('file not found')
|
||||||
error.code = 'ENOENT'
|
error.code = 'ENOENT'
|
||||||
fs.unlink = sinon.stub().yields(error)
|
fs.unlink = sinon.stub().yields(error)
|
||||||
LocalFileWriter.deleteFile(fsPath, (err) => {
|
LocalFileWriter.deleteFile(fsPath, err => {
|
||||||
expect(err).not.to.exist
|
expect(err).not.to.exist
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
@ -101,7 +101,7 @@ describe('LocalFileWriter', function () {
|
||||||
it('should wrap the error', function (done) {
|
it('should wrap the error', function (done) {
|
||||||
const error = new Error('failed to reticulate splines')
|
const error = new Error('failed to reticulate splines')
|
||||||
fs.unlink = sinon.stub().yields(error)
|
fs.unlink = sinon.stub().yields(error)
|
||||||
LocalFileWriter.deleteFile(fsPath, (err) => {
|
LocalFileWriter.deleteFile(fsPath, err => {
|
||||||
expect(err).to.exist
|
expect(err).to.exist
|
||||||
expect(err.cause).to.equal(error)
|
expect(err.cause).to.equal(error)
|
||||||
done()
|
done()
|
||||||
|
|
|
@ -17,9 +17,9 @@ describe('SafeExec', function () {
|
||||||
safeExec = SandboxedModule.require(modulePath, {
|
safeExec = SandboxedModule.require(modulePath, {
|
||||||
globals: { process },
|
globals: { process },
|
||||||
requires: {
|
requires: {
|
||||||
'settings-sharelatex': settings,
|
'@overleaf/settings': settings,
|
||||||
'@overleaf/object-persistor': ObjectPersistor
|
'@overleaf/object-persistor': ObjectPersistor,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -35,14 +35,14 @@ describe('SafeExec', function () {
|
||||||
|
|
||||||
it('should error when conversions are disabled', function (done) {
|
it('should error when conversions are disabled', function (done) {
|
||||||
settings.enableConversions = false
|
settings.enableConversions = false
|
||||||
safeExec(['/bin/echo', 'hello'], options, (err) => {
|
safeExec(['/bin/echo', 'hello'], options, err => {
|
||||||
expect(err).to.exist
|
expect(err).to.exist
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should execute a command with non-zero exit status', function (done) {
|
it('should execute a command with non-zero exit status', function (done) {
|
||||||
safeExec(['/usr/bin/env', 'false'], options, (err) => {
|
safeExec(['/usr/bin/env', 'false'], options, err => {
|
||||||
expect(err).to.exist
|
expect(err).to.exist
|
||||||
expect(err.name).to.equal('FailedCommandError')
|
expect(err.name).to.equal('FailedCommandError')
|
||||||
expect(err.code).to.equal(1)
|
expect(err.code).to.equal(1)
|
||||||
|
@ -53,7 +53,7 @@ describe('SafeExec', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should handle an invalid command', function (done) {
|
it('should handle an invalid command', function (done) {
|
||||||
safeExec(['/bin/foobar'], options, (err) => {
|
safeExec(['/bin/foobar'], options, err => {
|
||||||
err.code.should.equal('ENOENT')
|
err.code.should.equal('ENOENT')
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
@ -63,7 +63,7 @@ describe('SafeExec', function () {
|
||||||
safeExec(
|
safeExec(
|
||||||
['/bin/sleep', '10'],
|
['/bin/sleep', '10'],
|
||||||
{ timeout: 500, killSignal: 'SIGTERM' },
|
{ timeout: 500, killSignal: 'SIGTERM' },
|
||||||
(err) => {
|
err => {
|
||||||
expect(err).to.exist
|
expect(err).to.exist
|
||||||
expect(err.name).to.equal('FailedCommandError')
|
expect(err.name).to.equal('FailedCommandError')
|
||||||
expect(err.code).to.equal('SIGTERM')
|
expect(err.code).to.equal('SIGTERM')
|
||||||
|
|
|
@ -8,12 +8,12 @@ describe('Settings', function () {
|
||||||
const s3Settings = {
|
const s3Settings = {
|
||||||
bucket1: {
|
bucket1: {
|
||||||
auth_key: 'bucket1_key',
|
auth_key: 'bucket1_key',
|
||||||
auth_secret: 'bucket1_secret'
|
auth_secret: 'bucket1_secret',
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
process.env.S3_BUCKET_CREDENTIALS = JSON.stringify(s3Settings)
|
process.env.S3_BUCKET_CREDENTIALS = JSON.stringify(s3Settings)
|
||||||
const settings = SandboxedModule.require('settings-sharelatex', {
|
const settings = SandboxedModule.require('@overleaf/settings', {
|
||||||
globals: { console, process }
|
globals: { console, process },
|
||||||
})
|
})
|
||||||
expect(settings.filestore.s3.bucketCreds).to.deep.equal(s3Settings)
|
expect(settings.filestore.s3.bucketCreds).to.deep.equal(s3Settings)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue