mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
convert TpdsUpdateSender to async and cleanup
GitOrigin-RevId: a19830134a13a23775c604a05a7e093d00bbb2de
This commit is contained in:
parent
419100d167
commit
9c87ad9801
4 changed files with 349 additions and 463 deletions
|
@ -1194,13 +1194,18 @@ const ProjectEntityUpdateHandler = {
|
|||
project.overleaf &&
|
||||
project.overleaf.history &&
|
||||
project.overleaf.history.id
|
||||
TpdsUpdateSender.moveEntity({
|
||||
project_id: projectId,
|
||||
project_name: project.name,
|
||||
startPath,
|
||||
endPath,
|
||||
rev
|
||||
})
|
||||
// do not wait
|
||||
TpdsUpdateSender.promises
|
||||
.moveEntity({
|
||||
project_id: projectId,
|
||||
project_name: project.name,
|
||||
startPath,
|
||||
endPath,
|
||||
rev
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error({ err }, 'error sending tpds update')
|
||||
})
|
||||
DocumentUpdaterHandler.updateProjectStructure(
|
||||
projectId,
|
||||
projectHistoryId,
|
||||
|
@ -1243,13 +1248,18 @@ const ProjectEntityUpdateHandler = {
|
|||
project.overleaf &&
|
||||
project.overleaf.history &&
|
||||
project.overleaf.history.id
|
||||
TpdsUpdateSender.moveEntity({
|
||||
project_id: projectId,
|
||||
project_name: project.name,
|
||||
startPath,
|
||||
endPath,
|
||||
rev
|
||||
})
|
||||
// do not wait
|
||||
TpdsUpdateSender.promises
|
||||
.moveEntity({
|
||||
project_id: projectId,
|
||||
project_name: project.name,
|
||||
startPath,
|
||||
endPath,
|
||||
rev
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error({ err }, 'error sending tpds update')
|
||||
})
|
||||
DocumentUpdaterHandler.updateProjectStructure(
|
||||
projectId,
|
||||
projectHistoryId,
|
||||
|
|
|
@ -1,306 +1,187 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
handle-callback-err,
|
||||
max-len,
|
||||
no-irregular-whitespace,
|
||||
no-unused-vars,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
let tpdsUrl
|
||||
const settings = require('settings-sharelatex')
|
||||
const _ = require('lodash')
|
||||
const { callbackify } = require('util')
|
||||
const logger = require('logger-sharelatex')
|
||||
const path = require('path')
|
||||
const ProjectGetter = require('../Project/ProjectGetter')
|
||||
const keys = require('../../infrastructure/Keys')
|
||||
const metrics = require('metrics-sharelatex')
|
||||
const request = require('request')
|
||||
const path = require('path')
|
||||
const request = require('request-promise-native')
|
||||
const settings = require('settings-sharelatex')
|
||||
|
||||
const CollaboratorsGetter = require('../Collaborators/CollaboratorsGetter')
|
||||
const { promisifyAll } = require('../../util/promises')
|
||||
.promises
|
||||
|
||||
const buildPath = function(user_id, project_name, filePath) {
|
||||
let projectPath = path.join(project_name, '/', filePath)
|
||||
projectPath = encodeURIComponent(projectPath)
|
||||
const fullPath = path.join('/user/', `${user_id}`, '/entity/', projectPath)
|
||||
return fullPath
|
||||
const tpdsUrl = _.get(settings, ['apis', 'thirdPartyDataStore', 'url'])
|
||||
|
||||
async function addDoc(options) {
|
||||
metrics.inc('tpds.add-doc')
|
||||
|
||||
options.streamOrigin =
|
||||
settings.apis.docstore.pubUrl +
|
||||
path.join(
|
||||
`/project/${options.project_id}`,
|
||||
`/doc/${options.doc_id}`,
|
||||
'/raw'
|
||||
)
|
||||
|
||||
return addEntity(options)
|
||||
}
|
||||
|
||||
const tpdsworkerEnabled = () =>
|
||||
(settings.apis.tpdsworker != null
|
||||
? settings.apis.tpdsworker.url
|
||||
: undefined) != null
|
||||
if (!tpdsworkerEnabled()) {
|
||||
logger.log('tpdsworker is not enabled, request will not be sent to it')
|
||||
async function addEntity(options) {
|
||||
const projectUserIds = await getProjectUsersIds(options.project_id)
|
||||
if (!projectUserIds.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const job = {
|
||||
method: 'post',
|
||||
headers: {
|
||||
sl_entity_rev: options.rev,
|
||||
sl_project_id: options.project_id,
|
||||
sl_all_user_ids: JSON.stringify(projectUserIds)
|
||||
},
|
||||
uri: buildTpdsUrl(projectUserIds[0], options.project_name, options.path),
|
||||
title: 'addFile',
|
||||
streamOrigin: options.streamOrigin
|
||||
}
|
||||
|
||||
return enqueue(options.project_id, 'pipeStreamFrom', job)
|
||||
}
|
||||
|
||||
if (settings.apis.thirdPartyDataStore.linode_url != null) {
|
||||
tpdsUrl = settings.apis.thirdPartyDataStore.linode_url
|
||||
} else {
|
||||
tpdsUrl = settings.apis.thirdPartyDataStore.url
|
||||
async function addFile(options) {
|
||||
metrics.inc('tpds.add-file')
|
||||
|
||||
options.streamOrigin =
|
||||
settings.apis.filestore.url +
|
||||
path.join(`/project/${options.project_id}`, `/file/${options.file_id}`)
|
||||
|
||||
return addEntity(options)
|
||||
}
|
||||
|
||||
function buildMovePaths(options) {
|
||||
if (options.newProjectName) {
|
||||
return {
|
||||
startPath: path.join('/', options.project_name, '/'),
|
||||
endPath: path.join('/', options.newProjectName, '/')
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
startPath: path.join('/', options.project_name, '/', options.startPath),
|
||||
endPath: path.join('/', options.project_name, '/', options.endPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildTpdsUrl(userId, projectName, filePath) {
|
||||
const projectPath = encodeURIComponent(path.join(projectName, '/', filePath))
|
||||
return `${tpdsUrl}/user/${userId}/entity/${projectPath}`
|
||||
}
|
||||
|
||||
async function deleteEntity(options) {
|
||||
metrics.inc('tpds.delete-entity')
|
||||
|
||||
const projectUserIds = await getProjectUsersIds(options.project_id)
|
||||
if (!projectUserIds.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const job = {
|
||||
method: 'delete',
|
||||
headers: {
|
||||
sl_project_id: options.project_id,
|
||||
sl_all_user_ids: JSON.stringify(projectUserIds)
|
||||
},
|
||||
uri: buildTpdsUrl(projectUserIds[0], options.project_name, options.path),
|
||||
title: 'deleteEntity',
|
||||
sl_all_user_ids: JSON.stringify(projectUserIds)
|
||||
}
|
||||
|
||||
return enqueue(options.project_id, 'standardHttpRequest', job)
|
||||
}
|
||||
|
||||
async function enqueue(group, method, job) {
|
||||
const tpdsWorkerUrl = _.get(settings, ['apis', 'tpdsworker', 'url'])
|
||||
// silently do nothing if worker url is not in settings
|
||||
if (!tpdsWorkerUrl) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
return request({
|
||||
uri: `${tpdsWorkerUrl}/enqueue/web_to_tpds_http_requests`,
|
||||
json: { group, job, method },
|
||||
method: 'post',
|
||||
timeout: 5 * 1000
|
||||
})
|
||||
} catch (err) {
|
||||
// log error and continue
|
||||
logger.error({ err, group, job, method }, 'error enqueueing tpdsworker job')
|
||||
}
|
||||
}
|
||||
|
||||
async function getProjectUsersIds(projectId) {
|
||||
// get list of all user ids with access to project. project owner
|
||||
// will always be the first entry in the list.
|
||||
// TODO: filter this list to only return users with dropbox linked
|
||||
return CollaboratorsGetter.getInvitedMemberIds(projectId)
|
||||
}
|
||||
|
||||
async function moveEntity(options) {
|
||||
metrics.inc('tpds.move-entity')
|
||||
|
||||
const projectUserIds = await getProjectUsersIds(options.project_id)
|
||||
if (!projectUserIds.length) {
|
||||
return
|
||||
}
|
||||
const { endPath, startPath } = buildMovePaths(options)
|
||||
|
||||
const job = {
|
||||
method: 'put',
|
||||
title: 'moveEntity',
|
||||
uri: `${tpdsUrl}/user/${projectUserIds[0]}/entity`,
|
||||
headers: {
|
||||
sl_project_id: options.project_id,
|
||||
sl_entity_rev: options.rev,
|
||||
sl_all_user_ids: JSON.stringify(projectUserIds)
|
||||
},
|
||||
json: {
|
||||
user_id: projectUserIds[0],
|
||||
endPath,
|
||||
startPath
|
||||
}
|
||||
}
|
||||
|
||||
return enqueue(options.project_id, 'standardHttpRequest', job)
|
||||
}
|
||||
|
||||
async function pollDropboxForUser(userId) {
|
||||
metrics.inc('tpds.poll-dropbox')
|
||||
|
||||
const job = {
|
||||
method: 'post',
|
||||
uri: `${tpdsUrl}/user/poll`,
|
||||
json: {
|
||||
user_ids: [userId]
|
||||
}
|
||||
}
|
||||
|
||||
return enqueue(`poll-dropbox:${userId}`, 'standardHttpRequest', job)
|
||||
}
|
||||
|
||||
const TpdsUpdateSender = {
|
||||
_enqueue(group, method, job, callback) {
|
||||
if (!tpdsworkerEnabled()) {
|
||||
return callback()
|
||||
}
|
||||
const opts = {
|
||||
uri: `${settings.apis.tpdsworker.url}/enqueue/web_to_tpds_http_requests`,
|
||||
json: {
|
||||
group,
|
||||
method,
|
||||
job
|
||||
},
|
||||
method: 'post',
|
||||
timeout: 5 * 1000
|
||||
}
|
||||
return request(opts, function(err) {
|
||||
if (err != null) {
|
||||
logger.err(
|
||||
{ err },
|
||||
'error queuing something in the tpdsworker, continuing anyway'
|
||||
)
|
||||
return callback()
|
||||
} else {
|
||||
return callback()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
_addEntity(options, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err) {}
|
||||
}
|
||||
return getProjectsUsersIds(options.project_id, function(
|
||||
err,
|
||||
user_id,
|
||||
allUserIds
|
||||
) {
|
||||
if (err != null) {
|
||||
logger.warn({ err, options }, 'error getting projects user ids')
|
||||
return callback(err)
|
||||
}
|
||||
logger.log(
|
||||
{
|
||||
project_id: options.project_id,
|
||||
user_id,
|
||||
path: options.path,
|
||||
uri: options.uri,
|
||||
rev: options.rev
|
||||
},
|
||||
'sending file to third party data store'
|
||||
)
|
||||
const postOptions = {
|
||||
method: 'post',
|
||||
headers: {
|
||||
sl_entity_rev: options.rev,
|
||||
sl_project_id: options.project_id,
|
||||
sl_all_user_ids: JSON.stringify(allUserIds)
|
||||
},
|
||||
uri: `${tpdsUrl}${buildPath(
|
||||
user_id,
|
||||
options.project_name,
|
||||
options.path
|
||||
)}`,
|
||||
title: 'addFile',
|
||||
streamOrigin: options.streamOrigin
|
||||
}
|
||||
return TpdsUpdateSender._enqueue(
|
||||
options.project_id,
|
||||
'pipeStreamFrom',
|
||||
postOptions,
|
||||
function(err) {
|
||||
if (err != null) {
|
||||
logger.warn(
|
||||
{
|
||||
err,
|
||||
project_id: options.project_id,
|
||||
user_id,
|
||||
path: options.path,
|
||||
uri: options.uri,
|
||||
rev: options.rev
|
||||
},
|
||||
'error sending file to third party data store queued up for processing'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
logger.log(
|
||||
{
|
||||
project_id: options.project_id,
|
||||
user_id,
|
||||
path: options.path,
|
||||
uri: options.uri,
|
||||
rev: options.rev
|
||||
},
|
||||
'sending file to third party data store queued up for processing'
|
||||
)
|
||||
return callback(err)
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
|
||||
addFile(options, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err) {}
|
||||
}
|
||||
metrics.inc('tpds.add-file')
|
||||
options.streamOrigin =
|
||||
(settings.apis.filestore.linode_url || settings.apis.filestore.url) +
|
||||
path.join(`/project/${options.project_id}/file/`, `${options.file_id}`)
|
||||
return this._addEntity(options, callback)
|
||||
},
|
||||
|
||||
addDoc(options, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err) {}
|
||||
}
|
||||
metrics.inc('tpds.add-doc')
|
||||
options.streamOrigin =
|
||||
(settings.apis.docstore.linode_url || settings.apis.docstore.pubUrl) +
|
||||
path.join(`/project/${options.project_id}/doc/`, `${options.doc_id}/raw`)
|
||||
return this._addEntity(options, callback)
|
||||
},
|
||||
moveEntity(options, callback) {
|
||||
let endPath, startPath
|
||||
if (callback == null) {
|
||||
callback = function(err) {}
|
||||
}
|
||||
metrics.inc('tpds.move-entity')
|
||||
if (options.newProjectName != null) {
|
||||
startPath = path.join(`/${options.project_name}/`)
|
||||
endPath = path.join(`/${options.newProjectName}/`)
|
||||
} else {
|
||||
startPath = mergeProjectNameAndPath(
|
||||
options.project_name,
|
||||
options.startPath
|
||||
)
|
||||
endPath = mergeProjectNameAndPath(options.project_name, options.endPath)
|
||||
}
|
||||
return getProjectsUsersIds(options.project_id, function(
|
||||
err,
|
||||
user_id,
|
||||
allUserIds
|
||||
) {
|
||||
const moveOptions = {
|
||||
method: 'put',
|
||||
title: 'moveEntity',
|
||||
uri: `${tpdsUrl}/user/${user_id}/entity`,
|
||||
headers: {
|
||||
sl_project_id: options.project_id,
|
||||
sl_entity_rev: options.rev,
|
||||
sl_all_user_ids: JSON.stringify(allUserIds)
|
||||
},
|
||||
json: {
|
||||
user_id,
|
||||
endPath,
|
||||
startPath
|
||||
}
|
||||
}
|
||||
return TpdsUpdateSender._enqueue(
|
||||
options.project_id,
|
||||
'standardHttpRequest',
|
||||
moveOptions,
|
||||
callback
|
||||
)
|
||||
})
|
||||
},
|
||||
|
||||
deleteEntity(options, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err) {}
|
||||
}
|
||||
metrics.inc('tpds.delete-entity')
|
||||
return getProjectsUsersIds(options.project_id, function(
|
||||
err,
|
||||
user_id,
|
||||
allUserIds
|
||||
) {
|
||||
const deleteOptions = {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
sl_project_id: options.project_id,
|
||||
sl_all_user_ids: JSON.stringify(allUserIds)
|
||||
},
|
||||
uri: `${tpdsUrl}${buildPath(
|
||||
user_id,
|
||||
options.project_name,
|
||||
options.path
|
||||
)}`,
|
||||
title: 'deleteEntity',
|
||||
sl_all_user_ids: JSON.stringify(allUserIds)
|
||||
}
|
||||
return TpdsUpdateSender._enqueue(
|
||||
options.project_id,
|
||||
'standardHttpRequest',
|
||||
deleteOptions,
|
||||
callback
|
||||
)
|
||||
})
|
||||
},
|
||||
|
||||
pollDropboxForUser(user_id, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err) {}
|
||||
}
|
||||
metrics.inc('tpds.poll-dropbox')
|
||||
const options = {
|
||||
method: 'POST',
|
||||
uri: `${tpdsUrl}/user/poll`,
|
||||
json: {
|
||||
user_ids: [user_id]
|
||||
}
|
||||
}
|
||||
return TpdsUpdateSender._enqueue(
|
||||
`poll-dropbox:${user_id}`,
|
||||
'standardHttpRequest',
|
||||
options,
|
||||
callback
|
||||
)
|
||||
addDoc: callbackify(addDoc),
|
||||
addEntity: callbackify(addEntity),
|
||||
addFile: callbackify(addFile),
|
||||
deleteEntity: callbackify(deleteEntity),
|
||||
enqueue: callbackify(enqueue),
|
||||
moveEntity: callbackify(moveEntity),
|
||||
pollDropboxForUser: callbackify(pollDropboxForUser),
|
||||
promises: {
|
||||
addDoc,
|
||||
addEntity,
|
||||
addFile,
|
||||
deleteEntity,
|
||||
enqueue,
|
||||
moveEntity,
|
||||
pollDropboxForUser
|
||||
}
|
||||
}
|
||||
|
||||
var getProjectsUsersIds = function(project_id, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err, owner_id, allUserIds) {}
|
||||
}
|
||||
return ProjectGetter.getProject(
|
||||
project_id,
|
||||
{ _id: true, owner_ref: true },
|
||||
function(err, project) {
|
||||
if (err != null) {
|
||||
return callback(err)
|
||||
}
|
||||
return CollaboratorsGetter.getInvitedMemberIds(project_id, function(
|
||||
err,
|
||||
member_ids
|
||||
) {
|
||||
if (err != null) {
|
||||
return callback(err)
|
||||
}
|
||||
return callback(
|
||||
err,
|
||||
project != null ? project.owner_ref : undefined,
|
||||
member_ids
|
||||
)
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var mergeProjectNameAndPath = function(project_name, path) {
|
||||
if (path.indexOf('/') === 0) {
|
||||
path = path.substring(1)
|
||||
}
|
||||
const fullPath = `/${project_name}/${path}`
|
||||
return fullPath
|
||||
}
|
||||
|
||||
TpdsUpdateSender.promises = promisifyAll(TpdsUpdateSender)
|
||||
module.exports = TpdsUpdateSender
|
||||
|
|
|
@ -133,7 +133,10 @@ describe('ProjectEntityUpdateHandler', function() {
|
|||
addFile: sinon.stub().yields(),
|
||||
addDoc: sinon.stub(),
|
||||
deleteEntity: sinon.stub().yields(),
|
||||
moveEntity: sinon.stub()
|
||||
moveEntity: sinon.stub(),
|
||||
promises: {
|
||||
moveEntity: sinon.stub().resolves()
|
||||
}
|
||||
}
|
||||
this.FileStoreHandler = {
|
||||
copyFile: sinon.stub(),
|
||||
|
@ -1672,7 +1675,7 @@ describe('ProjectEntityUpdateHandler', function() {
|
|||
})
|
||||
|
||||
it('notifies tpds', function() {
|
||||
this.TpdsUpdateSender.moveEntity
|
||||
this.TpdsUpdateSender.promises.moveEntity
|
||||
.calledWith({
|
||||
project_id: projectId,
|
||||
project_name: this.project_name,
|
||||
|
@ -1731,7 +1734,7 @@ describe('ProjectEntityUpdateHandler', function() {
|
|||
})
|
||||
|
||||
it('notifies tpds', function() {
|
||||
this.TpdsUpdateSender.moveEntity
|
||||
this.TpdsUpdateSender.promises.moveEntity
|
||||
.calledWith({
|
||||
project_id: projectId,
|
||||
project_name: this.project_name,
|
||||
|
|
|
@ -1,31 +1,20 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
handle-callback-err,
|
||||
max-len,
|
||||
no-return-assign,
|
||||
no-unused-vars,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
const SandboxedModule = require('sandboxed-module')
|
||||
const assert = require('assert')
|
||||
require('chai').should()
|
||||
const modulePath = require('path').join(
|
||||
const chai = require('chai')
|
||||
const path = require('path')
|
||||
const sinon = require('sinon')
|
||||
|
||||
chai.should()
|
||||
|
||||
const modulePath = path.join(
|
||||
__dirname,
|
||||
'../../../../app/src/Features/ThirdPartyDataStore/TpdsUpdateSender.js'
|
||||
)
|
||||
const sinon = require('sinon')
|
||||
const ath = require('path')
|
||||
const project_id = 'project_id_here'
|
||||
const user_id = 'user_id_here'
|
||||
const read_only_ref_1 = 'read_only_ref_1_id_here'
|
||||
const collaberator_ref_1 = 'collaberator_ref_1_here'
|
||||
const project_name = 'project_name_here'
|
||||
|
||||
const projectId = 'project_id_here'
|
||||
const userId = 'user_id_here'
|
||||
const readOnlyRef = 'read_only_ref_1_id_here'
|
||||
const collaberatorRef = 'collaberator_ref_1_here'
|
||||
const projectName = 'project_name_here'
|
||||
|
||||
const thirdPartyDataStoreApiUrl = 'http://third-party-json-store.herokuapp.com'
|
||||
const httpUsername = 'user'
|
||||
|
@ -37,16 +26,14 @@ const filestoreUrl = 'filestore.sharelatex.com'
|
|||
describe('TpdsUpdateSender', function() {
|
||||
beforeEach(function() {
|
||||
this.requestQueuer = function(queue, meth, opts, callback) {}
|
||||
const project = { owner_ref: user_id }
|
||||
const member_ids = [collaberator_ref_1, read_only_ref_1, user_id]
|
||||
const memberIds = [userId, collaberatorRef, readOnlyRef]
|
||||
this.CollaboratorsGetter = {
|
||||
getInvitedMemberIds: sinon.stub().yields(null, member_ids)
|
||||
}
|
||||
this.ProjectGetter = {
|
||||
getProject: sinon.stub().callsArgWith(2, null, project)
|
||||
promises: {
|
||||
getInvitedMemberIds: sinon.stub().resolves(memberIds)
|
||||
}
|
||||
}
|
||||
this.docstoreUrl = 'docstore.sharelatex.env'
|
||||
this.request = sinon.stub().returns({ pipe() {} })
|
||||
this.request = sinon.stub().resolves()
|
||||
this.settings = {
|
||||
siteUrl,
|
||||
httpAuthSiteUrl,
|
||||
|
@ -60,182 +47,187 @@ describe('TpdsUpdateSender', function() {
|
|||
}
|
||||
}
|
||||
}
|
||||
return (this.updateSender = SandboxedModule.require(modulePath, {
|
||||
this.updateSender = SandboxedModule.require(modulePath, {
|
||||
globals: {
|
||||
console: console
|
||||
},
|
||||
requires: {
|
||||
'settings-sharelatex': this.settings,
|
||||
'logger-sharelatex': { log() {} },
|
||||
'../Project/ProjectGetter': this.ProjectGetter,
|
||||
request: this.request,
|
||||
'request-promise-native': this.request,
|
||||
'../Collaborators/CollaboratorsGetter': this.CollaboratorsGetter,
|
||||
'metrics-sharelatex': {
|
||||
inc() {}
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
describe('_enqueue', function() {
|
||||
it('should not call request if there is no tpdsworker url', function(done) {
|
||||
return this.updateSender._enqueue(null, null, null, err => {
|
||||
this.request.called.should.equal(false)
|
||||
return done()
|
||||
})
|
||||
describe('enqueue', function() {
|
||||
it('should not call request if there is no tpdsworker url', async function() {
|
||||
await this.updateSender.promises.enqueue(null, null, null)
|
||||
this.request.should.not.have.been.called
|
||||
})
|
||||
|
||||
it('should post the message to the tpdsworker', function(done) {
|
||||
it('should post the message to the tpdsworker', async function() {
|
||||
this.settings.apis.tpdsworker = { url: 'www.tpdsworker.env' }
|
||||
const group = 'myproject'
|
||||
const method = 'somemethod'
|
||||
const job = 'do something'
|
||||
this.request.callsArgWith(1)
|
||||
return this.updateSender._enqueue(group, method, job, err => {
|
||||
const args = this.request.args[0][0]
|
||||
args.json.group.should.equal(group)
|
||||
args.json.job.should.equal(job)
|
||||
args.json.method.should.equal(method)
|
||||
args.uri.should.equal(
|
||||
'www.tpdsworker.env/enqueue/web_to_tpds_http_requests'
|
||||
)
|
||||
return done()
|
||||
})
|
||||
await this.updateSender.promises.enqueue(group, method, job)
|
||||
const args = this.request.firstCall.args[0]
|
||||
args.json.group.should.equal(group)
|
||||
args.json.job.should.equal(job)
|
||||
args.json.method.should.equal(method)
|
||||
args.uri.should.equal(
|
||||
'www.tpdsworker.env/enqueue/web_to_tpds_http_requests'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('sending updates', function() {
|
||||
it('queues a post the file with user and file id', function(done) {
|
||||
const file_id = '4545345'
|
||||
beforeEach(function() {
|
||||
this.settings.apis.tpdsworker = { url: 'www.tpdsworker.env' }
|
||||
})
|
||||
|
||||
it('queues a post the file with user and file id', async function() {
|
||||
const fileId = '4545345'
|
||||
const path = '/some/path/here.jpg'
|
||||
this.updateSender._enqueue = function(uid, method, job, callback) {
|
||||
uid.should.equal(project_id)
|
||||
job.method.should.equal('post')
|
||||
job.streamOrigin.should.equal(
|
||||
`${filestoreUrl}/project/${project_id}/file/${file_id}`
|
||||
)
|
||||
const expectedUrl = `${thirdPartyDataStoreApiUrl}/user/${user_id}/entity/${encodeURIComponent(
|
||||
project_name
|
||||
)}${encodeURIComponent(path)}`
|
||||
job.uri.should.equal(expectedUrl)
|
||||
job.headers.sl_all_user_ids.should.eql(
|
||||
JSON.stringify([collaberator_ref_1, read_only_ref_1, user_id])
|
||||
)
|
||||
return done()
|
||||
}
|
||||
return this.updateSender.addFile(
|
||||
{ project_id, file_id, path, project_name },
|
||||
() => {}
|
||||
|
||||
await this.updateSender.promises.addFile({
|
||||
project_id: projectId,
|
||||
file_id: fileId,
|
||||
path,
|
||||
project_name: projectName
|
||||
})
|
||||
|
||||
const { group, job, method } = this.request.firstCall.args[0].json
|
||||
group.should.equal(projectId)
|
||||
method.should.equal('pipeStreamFrom')
|
||||
job.method.should.equal('post')
|
||||
job.streamOrigin.should.equal(
|
||||
`${filestoreUrl}/project/${projectId}/file/${fileId}`
|
||||
)
|
||||
const expectedUrl = `${thirdPartyDataStoreApiUrl}/user/${userId}/entity/${encodeURIComponent(
|
||||
projectName
|
||||
)}${encodeURIComponent(path)}`
|
||||
job.uri.should.equal(expectedUrl)
|
||||
job.headers.sl_all_user_ids.should.equal(
|
||||
JSON.stringify([userId, collaberatorRef, readOnlyRef])
|
||||
)
|
||||
})
|
||||
|
||||
it('post doc with stream origin of docstore', function(done) {
|
||||
const doc_id = '4545345'
|
||||
it('post doc with stream origin of docstore', async function() {
|
||||
const docId = '4545345'
|
||||
const path = '/some/path/here.tex'
|
||||
const lines = ['line1', 'line2', 'line3']
|
||||
|
||||
this.updateSender._enqueue = (uid, method, job, callback) => {
|
||||
uid.should.equal(project_id)
|
||||
job.method.should.equal('post')
|
||||
const expectedUrl = `${thirdPartyDataStoreApiUrl}/user/${user_id}/entity/${encodeURIComponent(
|
||||
project_name
|
||||
)}${encodeURIComponent(path)}`
|
||||
job.uri.should.equal(expectedUrl)
|
||||
job.streamOrigin.should.equal(
|
||||
`${this.docstoreUrl}/project/${project_id}/doc/${doc_id}/raw`
|
||||
)
|
||||
job.headers.sl_all_user_ids.should.eql(
|
||||
JSON.stringify([collaberator_ref_1, read_only_ref_1, user_id])
|
||||
)
|
||||
return done()
|
||||
}
|
||||
return this.updateSender.addDoc({
|
||||
project_id,
|
||||
doc_id,
|
||||
await this.updateSender.promises.addDoc({
|
||||
project_id: projectId,
|
||||
doc_id: docId,
|
||||
path,
|
||||
docLines: lines,
|
||||
project_name
|
||||
project_name: projectName
|
||||
})
|
||||
|
||||
const { group, job, method } = this.request.firstCall.args[0].json
|
||||
|
||||
group.should.equal(projectId)
|
||||
method.should.equal('pipeStreamFrom')
|
||||
job.method.should.equal('post')
|
||||
const expectedUrl = `${thirdPartyDataStoreApiUrl}/user/${userId}/entity/${encodeURIComponent(
|
||||
projectName
|
||||
)}${encodeURIComponent(path)}`
|
||||
job.uri.should.equal(expectedUrl)
|
||||
job.streamOrigin.should.equal(
|
||||
`${this.docstoreUrl}/project/${projectId}/doc/${docId}/raw`
|
||||
)
|
||||
job.headers.sl_all_user_ids.should.eql(
|
||||
JSON.stringify([userId, collaberatorRef, readOnlyRef])
|
||||
)
|
||||
})
|
||||
|
||||
it('deleting entity', function(done) {
|
||||
it('deleting entity', async function() {
|
||||
const path = '/path/here/t.tex'
|
||||
this.updateSender._enqueue = function(uid, method, job, callback) {
|
||||
uid.should.equal(project_id)
|
||||
job.method.should.equal('DELETE')
|
||||
const expectedUrl = `${thirdPartyDataStoreApiUrl}/user/${user_id}/entity/${encodeURIComponent(
|
||||
project_name
|
||||
)}${encodeURIComponent(path)}`
|
||||
job.headers.sl_all_user_ids.should.eql(
|
||||
JSON.stringify([collaberator_ref_1, read_only_ref_1, user_id])
|
||||
)
|
||||
job.uri.should.equal(expectedUrl)
|
||||
return done()
|
||||
}
|
||||
return this.updateSender.deleteEntity({ project_id, path, project_name })
|
||||
|
||||
await this.updateSender.promises.deleteEntity({
|
||||
project_id: projectId,
|
||||
path,
|
||||
project_name: projectName
|
||||
})
|
||||
|
||||
const { group, job, method } = this.request.firstCall.args[0].json
|
||||
|
||||
group.should.equal(projectId)
|
||||
method.should.equal('standardHttpRequest')
|
||||
job.method.should.equal('delete')
|
||||
const expectedUrl = `${thirdPartyDataStoreApiUrl}/user/${userId}/entity/${encodeURIComponent(
|
||||
projectName
|
||||
)}${encodeURIComponent(path)}`
|
||||
job.headers.sl_all_user_ids.should.eql(
|
||||
JSON.stringify([userId, collaberatorRef, readOnlyRef])
|
||||
)
|
||||
job.uri.should.equal(expectedUrl)
|
||||
})
|
||||
|
||||
it('moving entity', function(done) {
|
||||
it('moving entity', async function() {
|
||||
const startPath = 'staring/here/file.tex'
|
||||
const endPath = 'ending/here/file.tex'
|
||||
this.updateSender._enqueue = function(uid, method, job, callback) {
|
||||
uid.should.equal(project_id)
|
||||
job.method.should.equal('put')
|
||||
job.uri.should.equal(
|
||||
`${thirdPartyDataStoreApiUrl}/user/${user_id}/entity`
|
||||
)
|
||||
job.json.startPath.should.equal(`/${project_name}/${startPath}`)
|
||||
job.json.endPath.should.equal(`/${project_name}/${endPath}`)
|
||||
job.headers.sl_all_user_ids.should.eql(
|
||||
JSON.stringify([collaberator_ref_1, read_only_ref_1, user_id])
|
||||
)
|
||||
return done()
|
||||
}
|
||||
return this.updateSender.moveEntity({
|
||||
project_id,
|
||||
|
||||
await this.updateSender.promises.moveEntity({
|
||||
project_id: projectId,
|
||||
startPath,
|
||||
endPath,
|
||||
project_name
|
||||
project_name: projectName
|
||||
})
|
||||
|
||||
const { group, job, method } = this.request.firstCall.args[0].json
|
||||
|
||||
group.should.equal(projectId)
|
||||
method.should.equal('standardHttpRequest')
|
||||
job.method.should.equal('put')
|
||||
job.uri.should.equal(`${thirdPartyDataStoreApiUrl}/user/${userId}/entity`)
|
||||
job.json.startPath.should.equal(`/${projectName}/${startPath}`)
|
||||
job.json.endPath.should.equal(`/${projectName}/${endPath}`)
|
||||
job.headers.sl_all_user_ids.should.eql(
|
||||
JSON.stringify([userId, collaberatorRef, readOnlyRef])
|
||||
)
|
||||
})
|
||||
|
||||
it('should be able to rename a project using the move entity func', function(done) {
|
||||
it('should be able to rename a project using the move entity func', async function() {
|
||||
const oldProjectName = '/oldProjectName/'
|
||||
const newProjectName = '/newProjectName/'
|
||||
this.updateSender._enqueue = function(uid, method, job, callback) {
|
||||
uid.should.equal(project_id)
|
||||
job.method.should.equal('put')
|
||||
job.uri.should.equal(
|
||||
`${thirdPartyDataStoreApiUrl}/user/${user_id}/entity`
|
||||
)
|
||||
job.json.startPath.should.equal(oldProjectName)
|
||||
job.json.endPath.should.equal(newProjectName)
|
||||
job.headers.sl_all_user_ids.should.eql(
|
||||
JSON.stringify([collaberator_ref_1, read_only_ref_1, user_id])
|
||||
)
|
||||
return done()
|
||||
}
|
||||
return this.updateSender.moveEntity({
|
||||
project_id,
|
||||
|
||||
await this.updateSender.promises.moveEntity({
|
||||
project_id: projectId,
|
||||
project_name: oldProjectName,
|
||||
newProjectName
|
||||
})
|
||||
|
||||
const { group, job, method } = this.request.firstCall.args[0].json
|
||||
|
||||
group.should.equal(projectId)
|
||||
method.should.equal('standardHttpRequest')
|
||||
job.method.should.equal('put')
|
||||
job.uri.should.equal(`${thirdPartyDataStoreApiUrl}/user/${userId}/entity`)
|
||||
job.json.startPath.should.equal(oldProjectName)
|
||||
job.json.endPath.should.equal(newProjectName)
|
||||
job.headers.sl_all_user_ids.should.eql(
|
||||
JSON.stringify([userId, collaberatorRef, readOnlyRef])
|
||||
)
|
||||
})
|
||||
|
||||
it('pollDropboxForUser', function(done) {
|
||||
this.updateSender._enqueue = sinon.stub().callsArg(3)
|
||||
return this.updateSender.pollDropboxForUser(user_id, error => {
|
||||
this.updateSender._enqueue
|
||||
.calledWith(`poll-dropbox:${user_id}`, 'standardHttpRequest', {
|
||||
method: 'POST',
|
||||
uri: `${thirdPartyDataStoreApiUrl}/user/poll`,
|
||||
json: {
|
||||
user_ids: [user_id]
|
||||
}
|
||||
})
|
||||
.should.equal(true)
|
||||
return done()
|
||||
})
|
||||
it('pollDropboxForUser', async function() {
|
||||
await this.updateSender.promises.pollDropboxForUser(userId)
|
||||
|
||||
const { group, job, method } = this.request.firstCall.args[0].json
|
||||
|
||||
group.should.equal(`poll-dropbox:${userId}`)
|
||||
method.should.equal('standardHttpRequest')
|
||||
|
||||
job.method.should.equal('post')
|
||||
job.uri.should.equal(`${thirdPartyDataStoreApiUrl}/user/poll`)
|
||||
job.json.user_ids[0].should.equal(userId)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue