mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 06:33:55 +01:00
Merge pull request #1145 from sharelatex/ew-collabratec-create-project2
Collabratec create project api GitOrigin-RevId: 5f421625baa5c48f1745a15e15fe3a18fc1a4884
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
Project = require("../../models/Project").Project
|
||||||
|
|
||||||
|
module.exports = ProjectCollabratecDetailsHandler =
|
||||||
|
initializeCollabratecProject: (project_id, name, user_id, collabratec_document_id, collabratec_privategroup_id, callback=(err)->) ->
|
||||||
|
update = $set: { name, collabratecUsers: [ { user_id, collabratec_document_id, collabratec_privategroup_id } ] }
|
||||||
|
Project.update { _id: project_id }, update, callback
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
ProjectGetter = require("./ProjectGetter")
|
ProjectGetter = require("./ProjectGetter")
|
||||||
UserGetter = require("../User/UserGetter")
|
UserGetter = require("../User/UserGetter")
|
||||||
Project = require('../../models/Project').Project
|
Project = require('../../models/Project').Project
|
||||||
|
ObjectId = require("mongojs").ObjectId
|
||||||
logger = require("logger-sharelatex")
|
logger = require("logger-sharelatex")
|
||||||
tpdsUpdateSender = require '../ThirdPartyDataStore/TpdsUpdateSender'
|
tpdsUpdateSender = require '../ThirdPartyDataStore/TpdsUpdateSender'
|
||||||
_ = require("underscore")
|
_ = require("underscore")
|
||||||
@@ -109,7 +110,7 @@ module.exports = ProjectDetailsHandler =
|
|||||||
return callback new Errors.InvalidNameError("Project name could not be made unique")
|
return callback new Errors.InvalidNameError("Project name could not be made unique")
|
||||||
|
|
||||||
fixProjectName: (name) ->
|
fixProjectName: (name) ->
|
||||||
if name == ""
|
if name == "" || !name
|
||||||
name = "Untitled"
|
name = "Untitled"
|
||||||
if name.indexOf('/') > -1
|
if name.indexOf('/') > -1
|
||||||
# v2 does not allow / in a project name
|
# v2 does not allow / in a project name
|
||||||
|
|||||||
@@ -1,16 +1,7 @@
|
|||||||
path = require('path')
|
path = require('path')
|
||||||
Project = require('../../../js/models/Project').Project
|
|
||||||
ProjectUploadManager = require('../../../js/Features/Uploads/ProjectUploadManager')
|
|
||||||
ProjectOptionsHandler = require('../../../js/Features/Project/ProjectOptionsHandler')
|
|
||||||
ProjectRootDocManager = require('../../../js/Features/Project/ProjectRootDocManager')
|
|
||||||
ProjectDetailsHandler = require('../../../js/Features/Project/ProjectDetailsHandler')
|
|
||||||
AuthenticationController = require('../../../js/Features/Authentication/AuthenticationController')
|
AuthenticationController = require('../../../js/Features/Authentication/AuthenticationController')
|
||||||
settings = require('settings-sharelatex')
|
TemplatesManager = require('./TemplatesManager')
|
||||||
fs = require('fs')
|
|
||||||
request = require('request')
|
|
||||||
uuid = require('uuid')
|
|
||||||
logger = require('logger-sharelatex')
|
logger = require('logger-sharelatex')
|
||||||
async = require("async")
|
|
||||||
|
|
||||||
ENGINE_TO_COMPILER_MAP = {
|
ENGINE_TO_COMPILER_MAP = {
|
||||||
latex_dvipdf: "latex"
|
latex_dvipdf: "latex"
|
||||||
@@ -36,82 +27,9 @@ module.exports = TemplatesController =
|
|||||||
data.brandVariationId = req.query.brandVariationId
|
data.brandVariationId = req.query.brandVariationId
|
||||||
res.render path.resolve(__dirname, "../../../views/project/editor/new_from_template"), data
|
res.render path.resolve(__dirname, "../../../views/project/editor/new_from_template"), data
|
||||||
|
|
||||||
createProjectFromV1Template: (req, res)->
|
createProjectFromV1Template: (req, res, next)->
|
||||||
currentUserId = AuthenticationController.getLoggedInUserId(req)
|
user_id = AuthenticationController.getLoggedInUserId(req)
|
||||||
zipUrl = "#{settings.apis.v1.url}/api/v1/sharelatex/templates/#{req.body.templateVersionId}"
|
TemplatesManager.createProjectFromV1Template req.body.brandVariationId, req.body.compiler, req.body.mainFile, req.body.templateId, req.body.templateName, req.body.templateVersionId, user_id, (err, project) ->
|
||||||
zipReq = request(zipUrl, {
|
return next err if err?
|
||||||
'auth': {
|
delete req.session.templateData
|
||||||
'user': settings.apis.v1.user,
|
res.redirect "/project/#{project._id}"
|
||||||
'pass': settings.apis.v1.pass
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
TemplatesController.createFromZip(
|
|
||||||
zipReq,
|
|
||||||
{
|
|
||||||
templateName: req.body.templateName,
|
|
||||||
currentUserId: currentUserId,
|
|
||||||
compiler: req.body.compiler
|
|
||||||
docId: req.body.docId
|
|
||||||
mainFile: req.body.mainFile
|
|
||||||
templateId: req.body.templateId
|
|
||||||
templateVersionId: req.body.templateVersionId
|
|
||||||
brandVariationId: req.body.brandVariationId
|
|
||||||
image: 'wl_texlive:2018.1'
|
|
||||||
},
|
|
||||||
req,
|
|
||||||
res
|
|
||||||
)
|
|
||||||
|
|
||||||
createFromZip: (zipReq, options, req, res)->
|
|
||||||
# remove any invalid characters from template name
|
|
||||||
projectName = ProjectDetailsHandler.fixProjectName(options.templateName)
|
|
||||||
dumpPath = "#{settings.path.dumpFolder}/#{uuid.v4()}"
|
|
||||||
writeStream = fs.createWriteStream(dumpPath)
|
|
||||||
|
|
||||||
zipReq.on "error", (error) ->
|
|
||||||
logger.error err: error, "error getting zip from template API"
|
|
||||||
zipReq.pipe(writeStream)
|
|
||||||
writeStream.on 'close', ->
|
|
||||||
ProjectUploadManager.createProjectFromZipArchive options.currentUserId, projectName, dumpPath, (err, project)->
|
|
||||||
if err?
|
|
||||||
logger.err err:err, zipReq:zipReq, "problem building project from zip"
|
|
||||||
return res.sendStatus 500
|
|
||||||
setCompiler project._id, options.compiler, ->
|
|
||||||
setImage project._id, options.image, ->
|
|
||||||
setMainFile project._id, options.mainFile, ->
|
|
||||||
setBrandVariationId project._id, options.brandVariationId, ->
|
|
||||||
fs.unlink dumpPath, ->
|
|
||||||
delete req.session.templateData
|
|
||||||
conditions = {_id:project._id}
|
|
||||||
update = {
|
|
||||||
fromV1TemplateId:options.templateId,
|
|
||||||
fromV1TemplateVersionId:options.templateVersionId
|
|
||||||
}
|
|
||||||
Project.update conditions, update, {}, (err)->
|
|
||||||
res.redirect "/project/#{project._id}"
|
|
||||||
|
|
||||||
setCompiler = (project_id, compiler, callback)->
|
|
||||||
if compiler?
|
|
||||||
ProjectOptionsHandler.setCompiler project_id, compiler, callback
|
|
||||||
else
|
|
||||||
callback()
|
|
||||||
|
|
||||||
setImage = (project_id, imageName, callback)->
|
|
||||||
if imageName?
|
|
||||||
ProjectOptionsHandler.setImageName project_id, imageName, callback
|
|
||||||
else
|
|
||||||
callback()
|
|
||||||
|
|
||||||
setMainFile = (project_id, mainFile, callback) ->
|
|
||||||
if mainFile?
|
|
||||||
ProjectRootDocManager.setRootDocFromName project_id, mainFile, callback
|
|
||||||
else
|
|
||||||
callback()
|
|
||||||
|
|
||||||
setBrandVariationId = (project_id, brandVariationId, callback) ->
|
|
||||||
if brandVariationId?
|
|
||||||
ProjectOptionsHandler.setBrandVariationId project_id, brandVariationId, callback
|
|
||||||
else
|
|
||||||
callback()
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
Project = require('../../../js/models/Project').Project
|
||||||
|
ProjectDetailsHandler = require "../../../js/Features/Project/ProjectDetailsHandler"
|
||||||
|
ProjectOptionsHandler = require "../../../js/Features/Project/ProjectOptionsHandler"
|
||||||
|
ProjectRootDocManager = require "../../../js/Features/Project/ProjectRootDocManager"
|
||||||
|
ProjectUploadManager = require "../../../js/Features/Uploads/ProjectUploadManager"
|
||||||
|
async = require "async"
|
||||||
|
fs = require "fs"
|
||||||
|
logger = require "logger-sharelatex"
|
||||||
|
request = require "request"
|
||||||
|
settings = require "settings-sharelatex"
|
||||||
|
uuid = require "uuid"
|
||||||
|
|
||||||
|
module.exports = TemplatesManager =
|
||||||
|
createProjectFromV1Template: (brandVariationId, compiler, mainFile, templateId, templateName, templateVersionId, user_id, callback) ->
|
||||||
|
zipUrl = "#{settings.apis.v1.url}/api/v1/sharelatex/templates/#{templateVersionId}"
|
||||||
|
zipReq = request zipUrl, {
|
||||||
|
auth:
|
||||||
|
user: settings.apis.v1.user
|
||||||
|
pass: settings.apis.v1.pass
|
||||||
|
}
|
||||||
|
zipReq.on "error", (err) ->
|
||||||
|
logger.error { err }, "error getting zip from template API"
|
||||||
|
callback err
|
||||||
|
projectName = ProjectDetailsHandler.fixProjectName templateName
|
||||||
|
dumpPath = "#{settings.path.dumpFolder}/#{uuid.v4()}"
|
||||||
|
writeStream = fs.createWriteStream dumpPath
|
||||||
|
writeStream.on "close", ->
|
||||||
|
if zipReq.response.statusCode != 200
|
||||||
|
logger.err { uri: zipUrl, statusCode: zipReq.response.statusCode }, "non-success code getting zip from template API"
|
||||||
|
return callback new Error("get zip failed")
|
||||||
|
ProjectUploadManager.createProjectFromZipArchive user_id, projectName, dumpPath, (err, project) ->
|
||||||
|
if err?
|
||||||
|
logger.err { err, zipReq }, "problem building project from zip"
|
||||||
|
return callback err
|
||||||
|
async.series [
|
||||||
|
(cb) -> TemplatesManager._setCompiler project._id, compiler, cb
|
||||||
|
(cb) -> TemplatesManager._setImage project._id, "wl_texlive:2018.1", cb
|
||||||
|
(cb) -> TemplatesManager._setMainFile project._id, mainFile, cb
|
||||||
|
(cb) -> TemplatesManager._setBrandVariationId project._id, brandVariationId, cb
|
||||||
|
], (err) ->
|
||||||
|
return callback err if err?
|
||||||
|
fs.unlink dumpPath, (err) ->
|
||||||
|
logger.err {err}, "error unlinking template zip" if err?
|
||||||
|
update =
|
||||||
|
fromV1TemplateId: templateId,
|
||||||
|
fromV1TemplateVersionId: templateVersionId
|
||||||
|
Project.update { _id: project._id }, update, {}, (err) ->
|
||||||
|
return callback err if err?
|
||||||
|
callback null, project
|
||||||
|
zipReq.pipe(writeStream)
|
||||||
|
|
||||||
|
_setCompiler: (project_id, compiler, callback) ->
|
||||||
|
return callback() unless compiler?
|
||||||
|
ProjectOptionsHandler.setCompiler project_id, compiler, callback
|
||||||
|
|
||||||
|
_setImage: (project_id, imageName, callback) ->
|
||||||
|
return callback() unless imageName?
|
||||||
|
ProjectOptionsHandler.setImageName project_id, imageName, callback
|
||||||
|
|
||||||
|
_setMainFile: (project_id, mainFile, callback) ->
|
||||||
|
return callback() unless mainFile?
|
||||||
|
ProjectRootDocManager.setRootDocFromName project_id, mainFile, callback
|
||||||
|
|
||||||
|
_setBrandVariationId: (project_id, brandVariationId, callback) ->
|
||||||
|
return callback() unless brandVariationId?
|
||||||
|
ProjectOptionsHandler.setBrandVariationId project_id, brandVariationId, callback
|
||||||
@@ -65,6 +65,14 @@ ProjectSchema = new Schema
|
|||||||
history :
|
history :
|
||||||
id : { type: Number }
|
id : { type: Number }
|
||||||
display : { type: Boolean }
|
display : { type: Boolean }
|
||||||
|
collabratecUsers : [
|
||||||
|
{
|
||||||
|
user_id : { type: ObjectId, ref:'User' }
|
||||||
|
collabratec_document_id : { type: String }
|
||||||
|
collabratec_privategroup_id : { type: String }
|
||||||
|
added_at : { type: Date, default: () -> new Date() }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
ProjectSchema.statics.getProject = (project_or_id, fields, callback)->
|
ProjectSchema.statics.getProject = (project_or_id, fields, callback)->
|
||||||
if project_or_id._id?
|
if project_or_id._id?
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ module.exports = MockDocUpdaterApi =
|
|||||||
|
|
||||||
run: () ->
|
run: () ->
|
||||||
app.post "/project/:project_id/flush", (req, res, next) =>
|
app.post "/project/:project_id/flush", (req, res, next) =>
|
||||||
res.sendStatus 200
|
res.sendStatus 204
|
||||||
|
|
||||||
app.post "/project/:project_id", jsonParser, (req, res, next) =>
|
app.post "/project/:project_id", jsonParser, (req, res, next) =>
|
||||||
project_id = req.params.project_id
|
project_id = req.params.project_id
|
||||||
@@ -35,6 +35,9 @@ module.exports = MockDocUpdaterApi =
|
|||||||
@addProjectStructureUpdates(project_id, userId, docUpdates, fileUpdates, version)
|
@addProjectStructureUpdates(project_id, userId, docUpdates, fileUpdates, version)
|
||||||
res.sendStatus 200
|
res.sendStatus 200
|
||||||
|
|
||||||
|
app.post "/project/:project_id/doc/:doc_id", (req, res, next) =>
|
||||||
|
res.sendStatus 204
|
||||||
|
|
||||||
app.post "/project/:project_id/doc/:doc_id/flush", (req, res, next) =>
|
app.post "/project/:project_id/doc/:doc_id/flush", (req, res, next) =>
|
||||||
res.sendStatus 204
|
res.sendStatus 204
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
ObjectId = require("mongojs").ObjectId
|
||||||
|
Path = require "path"
|
||||||
|
SandboxedModule = require "sandboxed-module"
|
||||||
|
assert = require "assert"
|
||||||
|
chai = require "chai"
|
||||||
|
sinon = require "sinon"
|
||||||
|
sinonChai = require "sinon-chai"
|
||||||
|
|
||||||
|
chai.use sinonChai
|
||||||
|
expect = chai.expect
|
||||||
|
|
||||||
|
modulePath = Path.join __dirname, "../../../../app/js/Features/Project/ProjectCollabratecDetailsHandler"
|
||||||
|
|
||||||
|
describe "ProjectCollabratecDetailsHandler", ->
|
||||||
|
beforeEach ->
|
||||||
|
@ProjectModel = {}
|
||||||
|
@ProjectCollabratecDetailsHandler = SandboxedModule.require modulePath, requires:
|
||||||
|
"../../models/Project": { Project: @ProjectModel }
|
||||||
|
@callback = sinon.stub()
|
||||||
|
|
||||||
|
describe "initializeCollabratecProject", ->
|
||||||
|
|
||||||
|
describe "when update succeeds", ->
|
||||||
|
beforeEach ->
|
||||||
|
@ProjectModel.update = sinon.stub().yields()
|
||||||
|
@ProjectCollabratecDetailsHandler.initializeCollabratecProject "project-id", "name", "user-id", "collabratec-document-id", "collabratec-private-group-id", @callback
|
||||||
|
|
||||||
|
it "should update project model", ->
|
||||||
|
update = $set: {
|
||||||
|
name: "name",
|
||||||
|
collabratecUsers: [ {
|
||||||
|
user_id: "user-id",
|
||||||
|
collabratec_document_id: "collabratec-document-id",
|
||||||
|
collabratec_privategroup_id: "collabratec-private-group-id"
|
||||||
|
} ]
|
||||||
|
}
|
||||||
|
expect(@ProjectModel.update).to.have.been.calledWith { _id: "project-id" }, update, @callback
|
||||||
|
|
||||||
|
describe "when update has error", ->
|
||||||
|
beforeEach ->
|
||||||
|
@ProjectModel.update = sinon.stub().yields("error")
|
||||||
|
@ProjectCollabratecDetailsHandler.initializeCollabratecProject "project-id", "name", "user-id", "collabratec-document-id", "collabratec-private-group-id", @callback
|
||||||
|
|
||||||
|
it "should callback with error", ->
|
||||||
|
expect(@callback).to.have.been.calledWith("error")
|
||||||
@@ -1,128 +1,66 @@
|
|||||||
should = require('chai').should()
|
|
||||||
SandboxedModule = require('sandboxed-module')
|
SandboxedModule = require('sandboxed-module')
|
||||||
assert = require('assert')
|
assert = require('assert')
|
||||||
path = require('path')
|
chai = require('chai')
|
||||||
sinon = require('sinon')
|
sinon = require('sinon')
|
||||||
|
sinonChai = require('sinon-chai')
|
||||||
|
|
||||||
|
chai.should()
|
||||||
|
chai.use(sinonChai)
|
||||||
|
expect = chai.expect
|
||||||
|
|
||||||
modulePath = '../../../../app/js/Features/Templates/TemplatesController'
|
modulePath = '../../../../app/js/Features/Templates/TemplatesController'
|
||||||
|
|
||||||
|
describe "TemplatesController", ->
|
||||||
describe 'TemplatesController', ->
|
|
||||||
|
|
||||||
@project_id = "213432"
|
|
||||||
|
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@request = sinon.stub()
|
@user_id = "user-id"
|
||||||
@request.returns {
|
@TemplatesController = SandboxedModule.require modulePath, requires:
|
||||||
pipe:->
|
"../../../js/Features/Authentication/AuthenticationController": @AuthenticationController = {
|
||||||
on:->
|
getLoggedInUserId: sinon.stub().returns(@user_id)
|
||||||
}
|
}
|
||||||
@fs = {
|
"./TemplatesManager": @TemplatesManager = {
|
||||||
unlink : sinon.stub()
|
createProjectFromV1Template: sinon.stub()
|
||||||
createWriteStream : sinon.stub().returns(on:(_, cb)->cb())
|
}
|
||||||
}
|
@next = sinon.stub()
|
||||||
@ProjectUploadManager = {createProjectFromZipArchive : sinon.stub().callsArgWith(3, null, {_id:@project_id})}
|
|
||||||
@dumpFolder = "dump/path"
|
|
||||||
@ProjectOptionsHandler = {
|
|
||||||
setCompiler:sinon.stub().callsArgWith(2)
|
|
||||||
setImageName:sinon.stub().callsArgWith(2)
|
|
||||||
setBrandVariationId:sinon.stub().callsArgWith(2)
|
|
||||||
}
|
|
||||||
@uuid = "1234"
|
|
||||||
@ProjectRootDocManager = {
|
|
||||||
setRootDocFromName: sinon.stub().callsArgWith(2)
|
|
||||||
}
|
|
||||||
@ProjectDetailsHandler =
|
|
||||||
getProjectDescription:sinon.stub()
|
|
||||||
fixProjectName: sinon.stub().returns(@templateName)
|
|
||||||
@Project =
|
|
||||||
update: sinon.stub().callsArgWith(3, null)
|
|
||||||
@controller = SandboxedModule.require modulePath, requires:
|
|
||||||
'../../../js/Features/Uploads/ProjectUploadManager':@ProjectUploadManager
|
|
||||||
'../../../js/Features/Project/ProjectOptionsHandler':@ProjectOptionsHandler
|
|
||||||
'../../../js/Features/Project/ProjectRootDocManager':@ProjectRootDocManager
|
|
||||||
'../../../js/Features/Project/ProjectDetailsHandler':@ProjectDetailsHandler
|
|
||||||
'../../../js/Features/Authentication/AuthenticationController': @AuthenticationController = {getLoggedInUserId: sinon.stub()}
|
|
||||||
'./TemplatesPublisher':@TemplatesPublisher
|
|
||||||
"logger-sharelatex":
|
|
||||||
log:->
|
|
||||||
err:->
|
|
||||||
"settings-sharelatex":
|
|
||||||
path:
|
|
||||||
dumpFolder:@dumpFolder
|
|
||||||
siteUrl: @siteUrl = "http://localhost:3000"
|
|
||||||
apis:
|
|
||||||
v1:
|
|
||||||
url: @v1Url="http://overleaf.com"
|
|
||||||
user: "sharelatex"
|
|
||||||
pass: "password"
|
|
||||||
overleaf:
|
|
||||||
host: @v1Url
|
|
||||||
"uuid":v4:=>@uuid
|
|
||||||
"request": @request
|
|
||||||
"fs":@fs
|
|
||||||
"../../../js/models/Project": {Project: @Project}
|
|
||||||
@zipUrl = "%2Ftemplates%2F52fb86a81ae1e566597a25f6%2Fv%2F4%2Fzip&templateName=Moderncv%20Banking&compiler=pdflatex"
|
|
||||||
@templateName = "project name here"
|
|
||||||
@user_id = "1234"
|
|
||||||
@req =
|
@req =
|
||||||
|
body:
|
||||||
|
brandVariationId: "brand-variation-id"
|
||||||
|
compiler: "compiler"
|
||||||
|
mainFile: "main-file"
|
||||||
|
templateId: "template-id"
|
||||||
|
templateName: "template-name"
|
||||||
|
templateVersionId: "template-version-id"
|
||||||
session:
|
session:
|
||||||
user: _id:@user_id
|
templateData: "template-data"
|
||||||
templateData:
|
user: _id: @user_id
|
||||||
zipUrl: @zipUrl
|
@res =
|
||||||
templateName: @templateName
|
redirect: sinon.stub()
|
||||||
@redirect = {}
|
|
||||||
@AuthenticationController.getLoggedInUserId.returns(@user_id)
|
|
||||||
|
|
||||||
describe 'v1Templates', ->
|
describe "createProjectFromV1Template", ->
|
||||||
|
|
||||||
it "should fetch zip from v1 based on template id", (done)->
|
describe "on success", ->
|
||||||
@templateVersionId = 15
|
beforeEach ->
|
||||||
@req.body = {templateVersionId: @templateVersionId}
|
@project =
|
||||||
|
_id: "project-id"
|
||||||
|
@TemplatesManager.createProjectFromV1Template.yields null, @project
|
||||||
|
@TemplatesController.createProjectFromV1Template @req, @res, @next
|
||||||
|
|
||||||
redirect = =>
|
it "should call TemplatesManager", ->
|
||||||
@request.calledWith("#{@v1Url}/api/v1/sharelatex/templates/#{@templateVersionId}").should.equal true
|
@TemplatesManager.createProjectFromV1Template.should.have.been.calledWithMatch "brand-variation-id", "compiler", "main-file", "template-id", "template-name", "template-version-id", "user-id"
|
||||||
done()
|
|
||||||
res = redirect:redirect
|
|
||||||
@controller.createProjectFromV1Template @req, res
|
|
||||||
|
|
||||||
it "should set project options based on payload data", (done)->
|
it "should redirect to project", ->
|
||||||
@compiler = "pdflatex"
|
@res.redirect.should.have.been.calledWith "/project/project-id"
|
||||||
@mainFile = "main.tex"
|
|
||||||
@templateVersionId = 15
|
|
||||||
@brandVariationId = "123"
|
|
||||||
|
|
||||||
@req.body =
|
it "should delete session", ->
|
||||||
templateVersionId: @templateVersionId
|
expect(@req.session.templateData).to.be.undefined
|
||||||
name: @templateName
|
|
||||||
compiler: @compiler
|
|
||||||
mainFile: @mainFile
|
|
||||||
brandVariationId: @brandVariationId
|
|
||||||
|
|
||||||
redirect = =>
|
describe "on error", ->
|
||||||
@ProjectOptionsHandler.setCompiler.calledWith(@project_id, @compiler).should.equal true
|
beforeEach ->
|
||||||
@ProjectOptionsHandler.setBrandVariationId.calledWith(@project_id, @brandVariationId).should.equal true
|
@TemplatesManager.createProjectFromV1Template.yields "error"
|
||||||
@ProjectRootDocManager.setRootDocFromName.calledWith(@project_id, @mainFile).should.equal true
|
@TemplatesController.createProjectFromV1Template @req, @res, @next
|
||||||
done()
|
|
||||||
res = redirect:redirect
|
|
||||||
@controller.createProjectFromV1Template @req, res
|
|
||||||
|
|
||||||
it "should only set project options which are defined in the payload", (done)->
|
it "should call next with error", ->
|
||||||
@compiler = "pdflatex"
|
@next.should.have.been.calledWith "error"
|
||||||
@templateVersionId = 15
|
|
||||||
@brandVariationId = "123"
|
|
||||||
|
|
||||||
@req.body =
|
|
||||||
templateVersionId: @templateVersionId
|
|
||||||
name: @templateName
|
|
||||||
compiler: @compiler
|
|
||||||
brandVariationId: @brandVariationId
|
|
||||||
|
|
||||||
redirect = =>
|
|
||||||
# Payload doesn't refine a main file, so `setRootDocFromName` should not be called
|
|
||||||
@ProjectOptionsHandler.setCompiler.calledWith(@project_id, @compiler).should.equal true
|
|
||||||
@ProjectOptionsHandler.setBrandVariationId.calledWith(@project_id, @brandVariationId).should.equal true
|
|
||||||
@ProjectRootDocManager.setRootDocFromName.called.should.equal false
|
|
||||||
done()
|
|
||||||
res = redirect:redirect
|
|
||||||
@controller.createProjectFromV1Template @req, res
|
|
||||||
|
|
||||||
|
it "should not redirect", ->
|
||||||
|
@res.redirect.called.should.equal false
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
SandboxedModule = require('sandboxed-module')
|
||||||
|
assert = require('assert')
|
||||||
|
chai = require('chai')
|
||||||
|
sinon = require('sinon')
|
||||||
|
sinonChai = require('sinon-chai')
|
||||||
|
|
||||||
|
should = require('chai').should()
|
||||||
|
chai.use(sinonChai)
|
||||||
|
|
||||||
|
modulePath = '../../../../app/js/Features/Templates/TemplatesManager'
|
||||||
|
|
||||||
|
describe 'TemplatesManager', ->
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
@project_id = "project-id"
|
||||||
|
@brandVariationId = "brand-variation-id"
|
||||||
|
@compiler = "pdflatex"
|
||||||
|
@mainFile = "main.tex"
|
||||||
|
@templateId = "template-id"
|
||||||
|
@templateName = "template name"
|
||||||
|
@templateVersionId = "template-version-id"
|
||||||
|
@user_id = "user-id"
|
||||||
|
@dumpPath = "#{@dumpFolder}/#{@uuid}"
|
||||||
|
@callback = sinon.stub()
|
||||||
|
@request = sinon.stub().returns {
|
||||||
|
pipe:->
|
||||||
|
on:->
|
||||||
|
response: statusCode: 200
|
||||||
|
}
|
||||||
|
@fs = {
|
||||||
|
unlink : sinon.stub()
|
||||||
|
createWriteStream : sinon.stub().returns(on: sinon.stub().yields())
|
||||||
|
}
|
||||||
|
@ProjectUploadManager = {createProjectFromZipArchive : sinon.stub().callsArgWith(3, null, {_id:@project_id})}
|
||||||
|
@dumpFolder = "dump/path"
|
||||||
|
@ProjectOptionsHandler = {
|
||||||
|
setCompiler:sinon.stub().callsArgWith(2)
|
||||||
|
setImageName:sinon.stub().callsArgWith(2)
|
||||||
|
setBrandVariationId:sinon.stub().callsArgWith(2)
|
||||||
|
}
|
||||||
|
@uuid = "1234"
|
||||||
|
@ProjectRootDocManager = {
|
||||||
|
setRootDocFromName: sinon.stub().callsArgWith(2)
|
||||||
|
}
|
||||||
|
@ProjectDetailsHandler =
|
||||||
|
getProjectDescription:sinon.stub()
|
||||||
|
fixProjectName: sinon.stub().returns(@templateName)
|
||||||
|
@Project =
|
||||||
|
update: sinon.stub().callsArgWith(3, null)
|
||||||
|
@TemplatesManager = SandboxedModule.require modulePath, requires:
|
||||||
|
'../../../js/Features/Uploads/ProjectUploadManager':@ProjectUploadManager
|
||||||
|
'../../../js/Features/Project/ProjectOptionsHandler':@ProjectOptionsHandler
|
||||||
|
'../../../js/Features/Project/ProjectRootDocManager':@ProjectRootDocManager
|
||||||
|
'../../../js/Features/Project/ProjectDetailsHandler':@ProjectDetailsHandler
|
||||||
|
'../../../js/Features/Authentication/AuthenticationController': @AuthenticationController = {getLoggedInUserId: sinon.stub()}
|
||||||
|
'./TemplatesPublisher':@TemplatesPublisher
|
||||||
|
"logger-sharelatex":
|
||||||
|
log:->
|
||||||
|
err:->
|
||||||
|
"settings-sharelatex":
|
||||||
|
path:
|
||||||
|
dumpFolder:@dumpFolder
|
||||||
|
siteUrl: @siteUrl = "http://localhost:3000"
|
||||||
|
apis:
|
||||||
|
v1:
|
||||||
|
url: @v1Url="http://overleaf.com"
|
||||||
|
user: "sharelatex"
|
||||||
|
pass: "password"
|
||||||
|
overleaf:
|
||||||
|
host: @v1Url
|
||||||
|
"uuid":v4:=>@uuid
|
||||||
|
"request": @request
|
||||||
|
"fs":@fs
|
||||||
|
"../../../js/models/Project": {Project: @Project}
|
||||||
|
@zipUrl = "%2Ftemplates%2F52fb86a81ae1e566597a25f6%2Fv%2F4%2Fzip&templateName=Moderncv%20Banking&compiler=pdflatex"
|
||||||
|
|
||||||
|
describe 'createProjectFromV1Template', ->
|
||||||
|
|
||||||
|
describe "when all options passed", ->
|
||||||
|
beforeEach ->
|
||||||
|
@TemplatesManager.createProjectFromV1Template @brandVariationId, @compiler, @mainFile, @templateId, @templateName, @templateVersionId, @user_id, @callback
|
||||||
|
|
||||||
|
it "should fetch zip from v1 based on template id", ->
|
||||||
|
@request.should.have.been.calledWith "#{@v1Url}/api/v1/sharelatex/templates/#{@templateVersionId}"
|
||||||
|
|
||||||
|
it "should save temporary file", ->
|
||||||
|
@fs.createWriteStream.should.have.been.calledWith @dumpPath
|
||||||
|
|
||||||
|
it "should create project", ->
|
||||||
|
@ProjectUploadManager.createProjectFromZipArchive.should.have.been.calledWithMatch @user_id, @templateName, @dumpPath
|
||||||
|
|
||||||
|
it "should unlink file", ->
|
||||||
|
@fs.unlink.should.have.been.calledWith @dumpPath
|
||||||
|
|
||||||
|
it "should set project options when passed", ->
|
||||||
|
@ProjectOptionsHandler.setCompiler.should.have.been.calledWithMatch @project_id, @compiler
|
||||||
|
@ProjectOptionsHandler.setImageName.should.have.been.calledWithMatch @project_id, "wl_texlive:2018.1"
|
||||||
|
@ProjectRootDocManager.setRootDocFromName.should.have.been.calledWithMatch @project_id, @mainFile
|
||||||
|
@ProjectOptionsHandler.setBrandVariationId.should.have.been.calledWithMatch @project_id, @brandVariationId
|
||||||
|
|
||||||
|
it "should update project", ->
|
||||||
|
@Project.update.should.have.been.calledWithMatch { _id: @project_id }, { fromV1TemplateId: @templateId, fromV1TemplateVersionId: @templateVersionId }
|
||||||
|
|
||||||
|
describe "when some options not set", ->
|
||||||
|
beforeEach ->
|
||||||
|
@TemplatesManager.createProjectFromV1Template null, null, null, @templateId, @templateName, @templateVersionId, @user_id, @callback
|
||||||
|
|
||||||
|
it "should not set missing project options", ->
|
||||||
|
@ProjectOptionsHandler.setCompiler.called.should.equal false
|
||||||
|
@ProjectRootDocManager.setRootDocFromName.called.should.equal false
|
||||||
|
@ProjectOptionsHandler.setBrandVariationId.called.should.equal false
|
||||||
Reference in New Issue
Block a user