mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #1126 from sharelatex/mm-ensure-valid-rootdoc
Ensure project's root doc is valid before exporting GitOrigin-RevId: 6f15955015097df9464267f458b8dbb126c22173
This commit is contained in:
parent
ecd7e1d0c2
commit
de4f1a5abd
4 changed files with 147 additions and 24 deletions
|
@ -29,7 +29,7 @@ module.exports = ExportsHandler = self =
|
||||||
ProjectGetter.getProject project_id, cb
|
ProjectGetter.getProject project_id, cb
|
||||||
# TODO: when we update async, signature will change from (cb, results) to (results, cb)
|
# TODO: when we update async, signature will change from (cb, results) to (results, cb)
|
||||||
rootDoc: [ 'project', (cb, results) ->
|
rootDoc: [ 'project', (cb, results) ->
|
||||||
ProjectRootDocManager.ensureRootDocumentIsSet project_id, (error) ->
|
ProjectRootDocManager.ensureRootDocumentIsValid project_id, (error) ->
|
||||||
return callback(error) if error?
|
return callback(error) if error?
|
||||||
ProjectLocator.findRootDoc {project: results.project, project_id: project_id}, cb
|
ProjectLocator.findRootDoc {project: results.project, project_id: project_id}, cb
|
||||||
]
|
]
|
||||||
|
|
|
@ -67,3 +67,24 @@ module.exports = ProjectRootDocManager =
|
||||||
callback()
|
callback()
|
||||||
else
|
else
|
||||||
ProjectRootDocManager.setRootDocAutomatically project_id, callback
|
ProjectRootDocManager.setRootDocAutomatically project_id, callback
|
||||||
|
|
||||||
|
ensureRootDocumentIsValid: (project_id, callback = (error) ->) ->
|
||||||
|
ProjectGetter.getProject project_id, rootDoc_id: 1, (error, project) ->
|
||||||
|
return callback(error) if error?
|
||||||
|
if !project?
|
||||||
|
return callback new Error("project not found")
|
||||||
|
|
||||||
|
if project.rootDoc_id?
|
||||||
|
ProjectEntityHandler.getAllDocPathsFromProjectById project_id, (error, docPaths) ->
|
||||||
|
return callback(error) if error?
|
||||||
|
rootDocValid = false
|
||||||
|
for doc_id, _path of docPaths
|
||||||
|
if doc_id == project.rootDoc_id
|
||||||
|
rootDocValid = true
|
||||||
|
if rootDocValid
|
||||||
|
callback()
|
||||||
|
else
|
||||||
|
ProjectEntityUpdateHandler.setRootDoc project_id, null, ->
|
||||||
|
ProjectRootDocManager.setRootDocAutomatically project_id, callback
|
||||||
|
else
|
||||||
|
ProjectRootDocManager.setRootDocAutomatically project_id, callback
|
||||||
|
|
|
@ -104,7 +104,7 @@ describe 'ExportsHandler', ->
|
||||||
@ProjectGetter.getProject = sinon.stub().yields(null, @project)
|
@ProjectGetter.getProject = sinon.stub().yields(null, @project)
|
||||||
@ProjectHistoryHandler.ensureHistoryExistsForProject = sinon.stub().yields(null)
|
@ProjectHistoryHandler.ensureHistoryExistsForProject = sinon.stub().yields(null)
|
||||||
@ProjectLocator.findRootDoc = sinon.stub().yields(null, [null, {fileSystem: 'main.tex'}])
|
@ProjectLocator.findRootDoc = sinon.stub().yields(null, [null, {fileSystem: 'main.tex'}])
|
||||||
@ProjectRootDocManager.ensureRootDocumentIsSet = sinon.stub().callsArgWith(1, null)
|
@ProjectRootDocManager.ensureRootDocumentIsValid = sinon.stub().callsArgWith(1, null)
|
||||||
@UserGetter.getUser = sinon.stub().yields(null, @user)
|
@UserGetter.getUser = sinon.stub().yields(null, @user)
|
||||||
@ExportsHandler._requestVersion = sinon.stub().yields(null, @historyVersion)
|
@ExportsHandler._requestVersion = sinon.stub().yields(null, @historyVersion)
|
||||||
done()
|
done()
|
||||||
|
@ -214,7 +214,51 @@ describe 'ExportsHandler', ->
|
||||||
done()
|
done()
|
||||||
|
|
||||||
it "should set a root doc", ->
|
it "should set a root doc", ->
|
||||||
@ProjectRootDocManager.ensureRootDocumentIsSet.called
|
@ProjectRootDocManager.ensureRootDocumentIsValid.called
|
||||||
|
.should.equal true
|
||||||
|
|
||||||
|
it "should return export data", ->
|
||||||
|
expected_export_data =
|
||||||
|
project:
|
||||||
|
id: @project_id
|
||||||
|
rootDocPath: 'other.tex'
|
||||||
|
historyId: @project_history_id
|
||||||
|
historyVersion: @historyVersion
|
||||||
|
v1ProjectId: @project_history_id
|
||||||
|
metadata:
|
||||||
|
compiler: 'pdflatex'
|
||||||
|
imageName: 'mock-image-name'
|
||||||
|
title: @title
|
||||||
|
description: @description
|
||||||
|
author: @author
|
||||||
|
license: @license
|
||||||
|
showSource: @show_source
|
||||||
|
user:
|
||||||
|
id: @user_id
|
||||||
|
firstName: @user.first_name
|
||||||
|
lastName: @user.last_name
|
||||||
|
email: @user.email
|
||||||
|
orcidId: null
|
||||||
|
v1UserId: 876
|
||||||
|
destination:
|
||||||
|
brandVariationId: @brand_variation_id
|
||||||
|
options:
|
||||||
|
callbackUrl: null
|
||||||
|
@callback.calledWith(null, expected_export_data)
|
||||||
|
.should.equal true
|
||||||
|
|
||||||
|
describe "when project has an invalid root doc", ->
|
||||||
|
describe "when a new root doc can be set automatically", ->
|
||||||
|
beforeEach (done) ->
|
||||||
|
@fakeDoc_id = '1a2b3c4d5e6f'
|
||||||
|
@project.rootDoc_id = @fakeDoc_id
|
||||||
|
@ProjectLocator.findRootDoc = sinon.stub().yields(null, [null, {fileSystem: 'other.tex'}])
|
||||||
|
@ExportsHandler._buildExport @export_params, (error, export_data) =>
|
||||||
|
@callback(error, export_data)
|
||||||
|
done()
|
||||||
|
|
||||||
|
it "should set a valid root doc", ->
|
||||||
|
@ProjectRootDocManager.ensureRootDocumentIsValid.called
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
|
||||||
it "should return export data", ->
|
it "should return export data", ->
|
||||||
|
|
|
@ -7,6 +7,11 @@ SandboxedModule = require('sandboxed-module')
|
||||||
describe 'ProjectRootDocManager', ->
|
describe 'ProjectRootDocManager', ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@project_id = "project-123"
|
@project_id = "project-123"
|
||||||
|
@docPaths =
|
||||||
|
"doc-id-1": "/chapter1.tex"
|
||||||
|
"doc-id-2": "/main.tex"
|
||||||
|
"doc-id-3": "/nested/chapter1a.tex"
|
||||||
|
"doc-id-4": "/nested/chapter1b.tex"
|
||||||
@sl_req_id = "sl-req-id-123"
|
@sl_req_id = "sl-req-id-123"
|
||||||
@callback = sinon.stub()
|
@callback = sinon.stub()
|
||||||
@ProjectRootDocManager = SandboxedModule.require modulePath, requires:
|
@ProjectRootDocManager = SandboxedModule.require modulePath, requires:
|
||||||
|
@ -98,11 +103,6 @@ describe 'ProjectRootDocManager', ->
|
||||||
|
|
||||||
describe "when there is a suitable root doc but the leading slash is missing", ->
|
describe "when there is a suitable root doc but the leading slash is missing", ->
|
||||||
beforeEach (done)->
|
beforeEach (done)->
|
||||||
@docPaths =
|
|
||||||
"doc-id-1": "/chapter1.tex"
|
|
||||||
"doc-id-2": "/main.tex"
|
|
||||||
"doc-id-3": "/nested/chapter1a.tex"
|
|
||||||
"doc-id-4": "/nested/chapter1b.tex"
|
|
||||||
@ProjectEntityHandler.getAllDocPathsFromProjectById = sinon.stub().callsArgWith(1, null, @docPaths)
|
@ProjectEntityHandler.getAllDocPathsFromProjectById = sinon.stub().callsArgWith(1, null, @docPaths)
|
||||||
@ProjectEntityUpdateHandler.setRootDoc = sinon.stub().callsArgWith(2)
|
@ProjectEntityUpdateHandler.setRootDoc = sinon.stub().callsArgWith(2)
|
||||||
@ProjectRootDocManager.setRootDocFromName @project_id, 'main.tex', done
|
@ProjectRootDocManager.setRootDocFromName @project_id, 'main.tex', done
|
||||||
|
@ -117,11 +117,6 @@ describe 'ProjectRootDocManager', ->
|
||||||
|
|
||||||
describe "when there is a suitable root doc with a basename match", ->
|
describe "when there is a suitable root doc with a basename match", ->
|
||||||
beforeEach (done)->
|
beforeEach (done)->
|
||||||
@docPaths =
|
|
||||||
"doc-id-1": "/chapter1.tex"
|
|
||||||
"doc-id-2": "/main.tex"
|
|
||||||
"doc-id-3": "/nested/chapter1a.tex"
|
|
||||||
"doc-id-4": "/nested/chapter1b.tex"
|
|
||||||
@ProjectEntityHandler.getAllDocPathsFromProjectById = sinon.stub().callsArgWith(1, null, @docPaths)
|
@ProjectEntityHandler.getAllDocPathsFromProjectById = sinon.stub().callsArgWith(1, null, @docPaths)
|
||||||
@ProjectEntityUpdateHandler.setRootDoc = sinon.stub().callsArgWith(2)
|
@ProjectEntityUpdateHandler.setRootDoc = sinon.stub().callsArgWith(2)
|
||||||
@ProjectRootDocManager.setRootDocFromName @project_id, 'chapter1a.tex', done
|
@ProjectRootDocManager.setRootDocFromName @project_id, 'chapter1a.tex', done
|
||||||
|
@ -136,11 +131,6 @@ describe 'ProjectRootDocManager', ->
|
||||||
|
|
||||||
describe "when there is a suitable root doc but the filename is in quotes", ->
|
describe "when there is a suitable root doc but the filename is in quotes", ->
|
||||||
beforeEach (done)->
|
beforeEach (done)->
|
||||||
@docPaths =
|
|
||||||
"doc-id-1": "/chapter1.tex"
|
|
||||||
"doc-id-2": "/main.tex"
|
|
||||||
"doc-id-3": "/nested/chapter1a.tex"
|
|
||||||
"doc-id-4": "/nested/chapter1b.tex"
|
|
||||||
@ProjectEntityHandler.getAllDocPathsFromProjectById = sinon.stub().callsArgWith(1, null, @docPaths)
|
@ProjectEntityHandler.getAllDocPathsFromProjectById = sinon.stub().callsArgWith(1, null, @docPaths)
|
||||||
@ProjectEntityUpdateHandler.setRootDoc = sinon.stub().callsArgWith(2)
|
@ProjectEntityUpdateHandler.setRootDoc = sinon.stub().callsArgWith(2)
|
||||||
@ProjectRootDocManager.setRootDocFromName @project_id, "'main.tex'", done
|
@ProjectRootDocManager.setRootDocFromName @project_id, "'main.tex'", done
|
||||||
|
@ -155,11 +145,6 @@ describe 'ProjectRootDocManager', ->
|
||||||
|
|
||||||
describe "when there is no suitable root doc", ->
|
describe "when there is no suitable root doc", ->
|
||||||
beforeEach (done)->
|
beforeEach (done)->
|
||||||
@docPaths =
|
|
||||||
"doc-id-1": "/chapter1.tex"
|
|
||||||
"doc-id-2": "/main.tex"
|
|
||||||
"doc-id-3": "/nested/chapter1a.tex"
|
|
||||||
"doc-id-4": "/nested/chapter1b.tex"
|
|
||||||
@ProjectEntityHandler.getAllDocPathsFromProjectById = sinon.stub().callsArgWith(1, null, @docPaths)
|
@ProjectEntityHandler.getAllDocPathsFromProjectById = sinon.stub().callsArgWith(1, null, @docPaths)
|
||||||
@ProjectEntityUpdateHandler.setRootDoc = sinon.stub().callsArgWith(2)
|
@ProjectEntityUpdateHandler.setRootDoc = sinon.stub().callsArgWith(2)
|
||||||
@ProjectRootDocManager.setRootDocFromName @project_id, "other.tex", done
|
@ProjectRootDocManager.setRootDocFromName @project_id, "other.tex", done
|
||||||
|
@ -179,7 +164,7 @@ describe 'ProjectRootDocManager', ->
|
||||||
@project.rootDoc_id = "root-doc-id"
|
@project.rootDoc_id = "root-doc-id"
|
||||||
@ProjectRootDocManager.ensureRootDocumentIsSet(@project_id, @callback)
|
@ProjectRootDocManager.ensureRootDocumentIsSet(@project_id, @callback)
|
||||||
|
|
||||||
it "should find the project with only the rootDoc_id fiel", ->
|
it "should find the project fetching only the rootDoc_id field", ->
|
||||||
@ProjectGetter.getProject
|
@ProjectGetter.getProject
|
||||||
.calledWith(@project_id, rootDoc_id: 1)
|
.calledWith(@project_id, rootDoc_id: 1)
|
||||||
.should.equal true
|
.should.equal true
|
||||||
|
@ -216,3 +201,76 @@ describe 'ProjectRootDocManager', ->
|
||||||
it "should call the callback with an error", ->
|
it "should call the callback with an error", ->
|
||||||
@callback.calledWith(new Error("project not found")).should.equal true
|
@callback.calledWith(new Error("project not found")).should.equal true
|
||||||
|
|
||||||
|
describe "ensureRootDocumentIsValid", ->
|
||||||
|
beforeEach ->
|
||||||
|
@project = {}
|
||||||
|
@ProjectGetter.getProject = sinon.stub().callsArgWith(2, null, @project)
|
||||||
|
@ProjectEntityUpdateHandler.setRootDoc = sinon.stub().yields()
|
||||||
|
@ProjectEntityHandler.getAllDocPathsFromProjectById = sinon.stub().callsArgWith(1, null, @docPaths)
|
||||||
|
@ProjectRootDocManager.setRootDocAutomatically = sinon.stub().callsArgWith(1, null)
|
||||||
|
|
||||||
|
describe "when the root doc is set", ->
|
||||||
|
describe "when the root doc is valid", ->
|
||||||
|
beforeEach ->
|
||||||
|
@project.rootDoc_id = "doc-id-2"
|
||||||
|
@ProjectRootDocManager.ensureRootDocumentIsValid(@project_id, @callback)
|
||||||
|
|
||||||
|
it "should find the project fetching only the rootDoc_id field", ->
|
||||||
|
@ProjectGetter.getProject
|
||||||
|
.calledWith(@project_id, rootDoc_id: 1)
|
||||||
|
.should.equal true
|
||||||
|
|
||||||
|
it "should not try to update the project rootDoc_id", ->
|
||||||
|
@ProjectRootDocManager.setRootDocAutomatically
|
||||||
|
.called.should.equal false
|
||||||
|
|
||||||
|
it "should call the callback", ->
|
||||||
|
@callback.called.should.equal true
|
||||||
|
|
||||||
|
describe "when the root doc is not valid", ->
|
||||||
|
beforeEach ->
|
||||||
|
@project.rootDoc_id = "bogus-doc-id"
|
||||||
|
@ProjectRootDocManager.ensureRootDocumentIsValid(@project_id, @callback)
|
||||||
|
|
||||||
|
it "should find the project fetching only the rootDoc_id field", ->
|
||||||
|
@ProjectGetter.getProject
|
||||||
|
.calledWith(@project_id, rootDoc_id: 1)
|
||||||
|
.should.equal true
|
||||||
|
|
||||||
|
it "should null the rootDoc_id field", ->
|
||||||
|
@ProjectEntityUpdateHandler.setRootDoc
|
||||||
|
.calledWith(@project_id, null)
|
||||||
|
.should.equal true
|
||||||
|
|
||||||
|
it "should try to find a new rootDoc", ->
|
||||||
|
@ProjectRootDocManager.setRootDocAutomatically
|
||||||
|
.called.should.equal true
|
||||||
|
|
||||||
|
it "should call the callback", ->
|
||||||
|
@callback.called.should.equal true
|
||||||
|
|
||||||
|
describe "when the root doc is not set", ->
|
||||||
|
beforeEach ->
|
||||||
|
@ProjectRootDocManager.ensureRootDocumentIsSet(@project_id, @callback)
|
||||||
|
|
||||||
|
it "should find the project fetching only the rootDoc_id fiel", ->
|
||||||
|
@ProjectGetter.getProject
|
||||||
|
.calledWith(@project_id, rootDoc_id: 1)
|
||||||
|
.should.equal true
|
||||||
|
|
||||||
|
it "should update the project rootDoc_id", ->
|
||||||
|
@ProjectRootDocManager.setRootDocAutomatically
|
||||||
|
.calledWith(@project_id)
|
||||||
|
.should.equal true
|
||||||
|
|
||||||
|
it "should call the callback", ->
|
||||||
|
@callback.called.should.equal true
|
||||||
|
|
||||||
|
describe "when the project does not exist", ->
|
||||||
|
beforeEach ->
|
||||||
|
@ProjectGetter.getProject = sinon.stub().callsArgWith(2, null, null)
|
||||||
|
@ProjectRootDocManager.ensureRootDocumentIsSet(@project_id, @callback)
|
||||||
|
|
||||||
|
it "should call the callback with an error", ->
|
||||||
|
@callback.calledWith(new Error("project not found")).should.equal true
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue