Merge pull request #7251 from overleaf/jpa-convert-doc-to-file-script

[web] convert convert-to-file endpoint into a script

GitOrigin-RevId: 5babebae5df8510b83f09ec4a2bb4064cca5ec75
This commit is contained in:
Alf Eaton 2022-03-28 11:24:04 +01:00 committed by Copybot
parent 2130aeb6f9
commit a079aa1fae
4 changed files with 45 additions and 102 deletions

View file

@ -11,8 +11,6 @@ const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler') const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
const SessionManager = require('../Authentication/SessionManager') const SessionManager = require('../Authentication/SessionManager')
const Errors = require('../Errors/Errors') const Errors = require('../Errors/Errors')
const HttpErrorHandler = require('../Errors/HttpErrorHandler')
const ProjectEntityUpdateHandler = require('../Project/ProjectEntityUpdateHandler')
const DocstoreManager = require('../Docstore/DocstoreManager') const DocstoreManager = require('../Docstore/DocstoreManager')
const logger = require('@overleaf/logger') const logger = require('@overleaf/logger')
const { expressify } = require('../../util/promises') const { expressify } = require('../../util/promises')
@ -27,7 +25,6 @@ module.exports = {
deleteFile: expressify(deleteFile), deleteFile: expressify(deleteFile),
deleteFolder: expressify(deleteFolder), deleteFolder: expressify(deleteFolder),
deleteEntity: expressify(deleteEntity), deleteEntity: expressify(deleteEntity),
convertDocToFile: expressify(convertDocToFile),
_nameIsAcceptableLength, _nameIsAcceptableLength,
} }
@ -275,29 +272,3 @@ async function deleteEntity(req, res, next) {
) )
res.sendStatus(204) res.sendStatus(204)
} }
async function convertDocToFile(req, res, next) {
const projectId = req.params.Project_id
const docId = req.params.entity_id
const { userId } = req.body
try {
const fileRef = await ProjectEntityUpdateHandler.promises.convertDocToFile(
projectId,
docId,
userId
)
res.json({ fileId: fileRef._id.toString() })
} catch (err) {
if (err instanceof Errors.NotFoundError) {
return HttpErrorHandler.notFound(req, res, 'Document not found')
} else if (err instanceof Errors.DocHasRangesError) {
return HttpErrorHandler.unprocessableEntity(
req,
res,
'Document has comments or tracked changes'
)
} else {
throw err
}
}
}

View file

@ -2,7 +2,6 @@ const EditorHttpController = require('./EditorHttpController')
const AuthenticationController = require('../Authentication/AuthenticationController') const AuthenticationController = require('../Authentication/AuthenticationController')
const AuthorizationMiddleware = require('../Authorization/AuthorizationMiddleware') const AuthorizationMiddleware = require('../Authorization/AuthorizationMiddleware')
const RateLimiterMiddleware = require('../Security/RateLimiterMiddleware') const RateLimiterMiddleware = require('../Security/RateLimiterMiddleware')
const { Joi, validate } = require('../../infrastructure/Validation')
module.exports = { module.exports = {
apply(webRouter, privateApiRouter) { apply(webRouter, privateApiRouter) {
@ -55,16 +54,6 @@ module.exports = {
AuthorizationMiddleware.ensureUserCanWriteProjectContent, AuthorizationMiddleware.ensureUserCanWriteProjectContent,
EditorHttpController.deleteFolder EditorHttpController.deleteFolder
) )
privateApiRouter.post(
'/project/:Project_id/doc/:entity_id/convert-to-file',
AuthenticationController.requirePrivateApiAuth(),
validate({
body: Joi.object({
userId: Joi.objectId().required(),
}),
}),
EditorHttpController.convertDocToFile
)
// Called by the real-time API to load up the current project state. // Called by the real-time API to load up the current project state.
// This is a post request because it's more than just a getting of data. We take actions // This is a post request because it's more than just a getting of data. We take actions

View file

@ -0,0 +1,45 @@
const minimist = require('minimist')
const { waitForDb, ObjectId } = require('../app/src/infrastructure/mongodb')
const ProjectEntityUpdateHandler = require('../app/src/Features/Project/ProjectEntityUpdateHandler')
const Errors = require('../app/src/Features/Errors/Errors')
async function main() {
const argv = minimist(process.argv.slice(2))
const projectId = argv['project-id']
const docId = argv['doc-id']
const userId = argv['user-id']
if ([projectId, docId, userId].some(it => !it || !ObjectId.isValid(it))) {
throw new Error(
'provide a valid object id as --project-id, --doc-id and --user-id'
)
}
console.log(`Converting doc ${projectId}/${docId} as user ${userId}`)
await waitForDb()
try {
await ProjectEntityUpdateHandler.promises.convertDocToFile(
projectId,
docId,
userId
)
} catch (err) {
if (err instanceof Errors.NotFoundError) {
throw new Error('Document not found')
} else if (err instanceof Errors.DocHasRangesError) {
throw new Error('Document has comments or tracked changes')
} else {
throw err
}
}
}
main()
.then(() => {
console.log('Done.')
process.exit(0)
})
.catch(err => {
console.error(err)
process.exit(1)
})

View file

@ -510,66 +510,4 @@ describe('EditorHttpController', function () {
expect(this.res.sendStatus).to.have.been.calledWith(204) expect(this.res.sendStatus).to.have.been.calledWith(204)
}) })
}) })
describe('convertDocToFile', function () {
beforeEach(function (done) {
this.req.params = {
Project_id: this.project._id.toString(),
entity_id: this.doc._id.toString(),
}
this.req.body = { userId: this.user._id.toString() }
this.res.json.callsFake(() => done())
this.EditorHttpController.convertDocToFile(this.req, this.res)
})
describe('when successful', function () {
it('should convert the doc to a file', function () {
expect(
this.ProjectEntityUpdateHandler.promises.convertDocToFile
).to.have.been.calledWith(
this.project._id.toString(),
this.doc._id.toString(),
this.user._id.toString()
)
})
it('should return the file id in the response', function () {
expect(this.res.json).to.have.been.calledWith({
fileId: this.file._id.toString(),
})
})
})
describe('when the doc has ranges', function () {
it('should return a 422 - Unprocessable Entity', function (done) {
this.ProjectEntityUpdateHandler.promises.convertDocToFile.rejects(
new Errors.DocHasRangesError({})
)
this.HttpErrorHandler.unprocessableEntity = sinon.spy(
(req, res, message) => {
expect(req).to.exist
expect(res).to.exist
expect(message).to.equal('Document has comments or tracked changes')
done()
}
)
this.EditorHttpController.convertDocToFile(this.req, this.res)
})
})
describe("when the doc does't exist", function () {
it('should return a 404 - not found', function (done) {
this.ProjectEntityUpdateHandler.promises.convertDocToFile.rejects(
new Errors.NotFoundError({})
)
this.HttpErrorHandler.notFound = sinon.spy((req, res, message) => {
expect(req).to.exist
expect(res).to.exist
expect(message).to.equal('Document not found')
done()
})
this.EditorHttpController.convertDocToFile(this.req, this.res)
})
})
})
}) })