Remove deprecated versioning code

This commit is contained in:
James Allen 2014-05-27 12:56:23 +01:00
parent c1afbc66d9
commit 80c58bb718
23 changed files with 5 additions and 681 deletions

View file

@ -1,7 +1,6 @@
settings = require('settings-sharelatex') settings = require('settings-sharelatex')
SubscriptionBackgroundTasks = require("./app/js/Features/Subscription/SubscriptionBackgroundTasks") SubscriptionBackgroundTasks = require("./app/js/Features/Subscription/SubscriptionBackgroundTasks")
TpdsPollingBackgroundTasks = require("./app/js/Features/ThirdPartyDataStore/TpdsPollingBackgroundTasks") TpdsPollingBackgroundTasks = require("./app/js/Features/ThirdPartyDataStore/TpdsPollingBackgroundTasks")
AutomaticSnapshotManager = require("./app/js/Features/Versioning/AutomaticSnapshotManager")
time = time =
oneHour : 60 * 60 * 1000 oneHour : 60 * 60 * 1000
@ -24,4 +23,3 @@ runPeriodically = (funcToRun, periodLength)->
runPeriodically ((cb) -> SubscriptionBackgroundTasks.downgradeExpiredFreeTrials(cb)), time.oneHour runPeriodically ((cb) -> SubscriptionBackgroundTasks.downgradeExpiredFreeTrials(cb)), time.oneHour
runPeriodically ((cb) -> TpdsPollingBackgroundTasks.pollUsersWithDropbox(cb)), time.fifteenMinutes runPeriodically ((cb) -> TpdsPollingBackgroundTasks.pollUsersWithDropbox(cb)), time.fifteenMinutes
runPeriodically ((cb) -> AutomaticSnapshotManager.takeAutomaticSnapshots(cb)), time.thirtySeconds

View file

@ -11,8 +11,6 @@ CollaboratorsHandler = require("../Collaborators/CollaboratorsHandler")
DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler') DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
LimitationsManager = require("../Subscription/LimitationsManager") LimitationsManager = require("../Subscription/LimitationsManager")
AuthorizationManager = require("../Security/AuthorizationManager") AuthorizationManager = require("../Security/AuthorizationManager")
AutomaticSnapshotManager = require("../Versioning/AutomaticSnapshotManager")
VersioningApiHandler = require("../Versioning/VersioningApiHandler")
EditorRealTimeController = require("./EditorRealTimeController") EditorRealTimeController = require("./EditorRealTimeController")
TrackChangesManager = require("../TrackChanges/TrackChangesManager") TrackChangesManager = require("../TrackChanges/TrackChangesManager")
settings = require('settings-sharelatex') settings = require('settings-sharelatex')
@ -56,7 +54,6 @@ module.exports = EditorController =
client.set("connected_time", new Date()) client.set("connected_time", new Date())
client.set("signup_date", user.signUpDate) client.set("signup_date", user.signUpDate)
client.set("login_count", user.loginCount) client.set("login_count", user.loginCount)
client.set("take_snapshots", project.existsInVersioningApi)
AuthorizationManager.setPrivilegeLevelOnClient client, privilegeLevel AuthorizationManager.setPrivilegeLevelOnClient client, privilegeLevel
callback null, ProjectEditorHandler.buildProjectModelView(project), privilegeLevel, EditorController.protocolVersion callback null, ProjectEditorHandler.buildProjectModelView(project), privilegeLevel, EditorController.protocolVersion

View file

@ -4,7 +4,6 @@ Settings = require 'settings-sharelatex'
rclient = require("redis").createClient(Settings.redis.web.port, Settings.redis.web.host) rclient = require("redis").createClient(Settings.redis.web.port, Settings.redis.web.host)
rclient.auth(Settings.redis.web.password) rclient.auth(Settings.redis.web.password)
DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler') DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
AutomaticSnapshotManager = require("../Versioning/AutomaticSnapshotManager")
EditorRealTimeController = require("./EditorRealTimeController") EditorRealTimeController = require("./EditorRealTimeController")
module.exports = EditorUpdatesController = module.exports = EditorUpdatesController =
@ -14,10 +13,6 @@ module.exports = EditorUpdatesController =
client.get "user_id", (error, user_id) -> client.get "user_id", (error, user_id) ->
metrics.set "editor.active-users", user_id, 0.3 metrics.set "editor.active-users", user_id, 0.3
client.get "take_snapshots", (error, takeSnapshot) ->
if takeSnapshot
AutomaticSnapshotManager.markProjectAsUpdated(project_id)
logger.log doc_id: doc_id, project_id: project_id, client_id: update.meta?.source, version: update.v, "sending update to doc updater" logger.log doc_id: doc_id, project_id: project_id, client_id: update.meta?.source, version: update.v, "sending update to doc updater"
DocumentUpdaterHandler.queueChange project_id, doc_id, update, (error) -> DocumentUpdaterHandler.queueChange project_id, doc_id, update, (error) ->

View file

@ -5,7 +5,6 @@ Settings = require('settings-sharelatex')
ObjectId = require('mongoose').Types.ObjectId ObjectId = require('mongoose').Types.ObjectId
Project = require('../../models/Project').Project Project = require('../../models/Project').Project
Folder = require('../../models/Folder').Folder Folder = require('../../models/Folder').Folder
VersioningApiHandler = require('../Versioning/VersioningApiHandler')
ProjectEntityHandler = require('./ProjectEntityHandler') ProjectEntityHandler = require('./ProjectEntityHandler')
User = require('../../models/User').User User = require('../../models/User').User
fs = require('fs') fs = require('fs')
@ -26,7 +25,6 @@ module.exports =
project.spellCheckLanguage = user.ace.spellCheckLanguage project.spellCheckLanguage = user.ace.spellCheckLanguage
project.save (err)-> project.save (err)->
return callback(err) if err? return callback(err) if err?
VersioningApiHandler.enableVersioning project._id, (err) ->
callback err, project callback err, project
createBasicProject : (owner_id, projectName, callback = (error, project) ->)-> createBasicProject : (owner_id, projectName, callback = (error, project) ->)->

View file

@ -3,7 +3,6 @@ logger = require('logger-sharelatex')
documentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler') documentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler')
tagsHandler = require("../Tags/TagsHandler") tagsHandler = require("../Tags/TagsHandler")
async = require("async") async = require("async")
AutomaticSnapshotManager = require('../Versioning/AutomaticSnapshotManager')
FileStoreHandler = require("../FileStore/FileStoreHandler") FileStoreHandler = require("../FileStore/FileStoreHandler")
module.exports = module.exports =

View file

@ -10,7 +10,6 @@ module.exports = ProjectEditorHandler =
rootDoc_id : project.rootDoc_id rootDoc_id : project.rootDoc_id
rootFolder : [@buildFolderModelView project.rootFolder[0]] rootFolder : [@buildFolderModelView project.rootFolder[0]]
publicAccesLevel : project.publicAccesLevel publicAccesLevel : project.publicAccesLevel
versioningVisible : !!project.existsInVersioningApi
dropboxEnabled : !!project.existsInDropbox dropboxEnabled : !!project.existsInDropbox
compiler : project.compiler compiler : project.compiler
description: project.description description: project.description

View file

@ -1,22 +0,0 @@
Settings = require "settings-sharelatex"
mongojs = require "mongojs"
logger = require("logger-sharelatex")
if Settings.mongo.restoreUrl?
logger.log "restore url defined, talking to old db"
db = mongojs.connect(Settings.mongo.restoreUrl, ["projects", "users"])
else
logger.log "restore not not defined, continuing as normal"
db = {}
ObjectId = mongojs.ObjectId
VersioningApiHandler = require "../Versioning/VersioningApiHandler"
module.exports = RestoreController =
restore: (req, res, next = (error) ->) ->
user_id = req.session.user._id
db.projects.find { owner_ref: ObjectId(user_id) }, { _id: 1, name: 1 }, (error, projects) ->
return next(error) if error?
res.render 'restore', projects: projects, title: "Restore projects"
getZip: (req, res, next = (error) ->) ->
project_id = req.params.Project_id
VersioningApiHandler.proxyToVersioningApi(req, res)

View file

@ -1,4 +1,3 @@
versioningApiHandler = require('../Versioning/VersioningApiHandler')
updateMerger = require('./UpdateMerger') updateMerger = require('./UpdateMerger')
logger = require('logger-sharelatex') logger = require('logger-sharelatex')
projectLocator = require('../Project/ProjectLocator') projectLocator = require('../Project/ProjectLocator')
@ -23,7 +22,6 @@ module.exports =
else else
cb err, project cb err, project
getOrCreateProject (err, project)-> getOrCreateProject (err, project)->
versioningApiHandler.takeSnapshot project._id, commitMessage, sl_req_id, ->
updateMerger.mergeUpdate project._id, path, updateRequest, sl_req_id, (err)-> updateMerger.mergeUpdate project._id, path, updateRequest, sl_req_id, (err)->
callback(err) callback(err)
@ -38,7 +36,6 @@ module.exports =
logger.log user_id:user_id, filePath:path, projectName:projectName, project_id:project._id, "project found for delete update, path is root so marking project as deleted" logger.log user_id:user_id, filePath:path, projectName:projectName, project_id:project._id, "project found for delete update, path is root so marking project as deleted"
return projectDeleter.markAsDeletedByExternalSource project._id, callback return projectDeleter.markAsDeletedByExternalSource project._id, callback
else else
versioningApiHandler.takeSnapshot project._id, commitMessage, sl_req_id, ->
updateMerger.deleteUpdate project._id, path, sl_req_id, (err)-> updateMerger.deleteUpdate project._id, path, sl_req_id, (err)->
callback(err) callback(err)

View file

@ -1,50 +0,0 @@
Keys = require("./RedisKeys")
Settings = require "settings-sharelatex"
redis = require('redis')
rclient = redis.createClient(Settings.redis.web.port, Settings.redis.web.host)
rclient.auth(Settings.redis.web.password)
VersioningApiHandler = require('../../Features/Versioning/VersioningApiHandler')
async = require('async')
metrics = require('../../infrastructure/Metrics')
logger = require('logger-sharelatex')
module.exports = AutomaticSnapshotManager =
markProjectAsUpdated: (project_id, callback = (error) ->) ->
rclient.set Keys.buildLastUpdatedKey(project_id), Date.now(), (error) ->
return callback(error) if error?
rclient.sadd Keys.projectsToSnapshotKey, project_id, (error) ->
return callback(error) if error?
callback()
unmarkProjectAsUpdated: (project_id, callback = (err)->)->
rclient.del Keys.buildLastUpdatedKey(project_id), Date.now(), (error) ->
return callback(error) if error?
rclient.srem Keys.projectsToSnapshotKey, project_id, (error) ->
return callback(error) if error?
callback()
takeAutomaticSnapshots: (callback = (error) ->) ->
rclient.smembers Keys.projectsToSnapshotKey, (error, project_ids) =>
logger.log project_ids:project_ids, "taking automatic snapshots"
metrics.gauge "versioning.projectsToSnapshot", project_ids.length
return callback(error) if error?
methods = []
for project_id in project_ids
do (project_id) =>
methods.push((callback) => @takeSnapshotIfRequired(project_id, callback))
async.series methods, callback
takeSnapshotIfRequired: (project_id, callback = (error) ->) ->
rclient.get Keys.buildLastUpdatedKey(project_id), (error, lastUpdated) ->
return callback(error) if error?
if lastUpdated? and lastUpdated < Date.now() - Settings.automaticSnapshots.waitTimeAfterLastEdit
VersioningApiHandler.takeSnapshot(project_id, "Automatic snapshot", callback)
else
rclient.get Keys.buildLastSnapshotKey(project_id), (error, lastSnapshot) ->
return callback(error) if error?
if !lastSnapshot? or lastSnapshot < Date.now() - Settings.automaticSnapshots.maxTimeBetweenSnapshots
VersioningApiHandler.takeSnapshot(project_id, "Automatic snapshot", callback)
else
callback()

View file

@ -1,5 +0,0 @@
module.exports =
buildLastUpdatedKey: (project_id) -> "project_last_updated:#{project_id}"
buildLastSnapshotKey: (project_id) -> "project_last_snapshot:#{project_id}"
projectsToSnapshotKey: "projects_to_snapshot"
usersToPollTpdsForUpdates: "users_with_active_projects"

View file

@ -1,31 +0,0 @@
versioningApiHandler = require './VersioningApiHandler'
metrics = require('../../infrastructure/Metrics')
module.exports =
enableVersioning: (project_id, callback)->
metrics.inc "versioning.enableVersioning"
versioningApiHandler.enableVersioning project_id, callback
listVersions : (req, res) ->
metrics.inc "versioning.listVersions"
versioningApiHandler.proxyToVersioningApi(req, res)
getVersion : (req, res) ->
metrics.inc "versioning.getVersion"
versioningApiHandler.proxyToVersioningApi(req, res)
getVersionFile : (req, res) ->
metrics.inc "versioning.getVersionFile"
versioningApiHandler.proxyToVersioningApi(req, res)
takeSnapshot: (req, res, next) ->
metrics.inc "versioning.takeSnapshot"
if req.body? and req.body.message? and req.body.message.length > 0
message = req.body.message
else
message = "Manual snapshot"
versioningApiHandler.takeSnapshot req.params.Project_id, message, (error) ->
if error?
next(error)
else
res.send(200, "{}")

View file

@ -1,75 +0,0 @@
settings = require('settings-sharelatex')
logger = require('logger-sharelatex')
Project = require('../../models/Project').Project
request = require('request')
DocumentUpdaterHandler = require('../../Features/DocumentUpdater/DocumentUpdaterHandler')
redis = require('redis')
rclient = redis.createClient(settings.redis.web.port, settings.redis.web.host)
rclient.auth(settings.redis.web.password)
Keys = require("./RedisKeys")
ProjectEntityHandler = require('../../Features/Project/ProjectEntityHandler')
metrics = require('../../infrastructure/Metrics')
keys = require('../../infrastructure/Keys')
queue = require('fairy').connect(settings.redis.fairy).queue(keys.queue.web_to_tpds_http_requests)
slReqIdHelper = require('soa-req-id')
headers =
Authorization : "Basic " + new Buffer("#{settings.apis.versioning.username}:#{settings.apis.versioning.password}").toString("base64")
module.exports =
enableVersioning: (project_or_id, callback = (err)->)->
Project.getProject project_or_id, 'existsInVersioningApi', (error, project)=>
return callback error if error?
return callback new Error("project_id:#{project_id} does not exist") if !project?
project_id = project._id
if project.existsInVersioningApi
logger.log project_id: project_id, "versioning already enabled"
return callback()
logger.log project_id: project_id, "enabling versioning in versioning API"
@createProject project_id, (error) ->
return callback error if error?
logger.log project_id: project_id, "enabling versioning in Mongo"
project.existsInVersioningApi = true
update = existsInVersioningApi : true
conditions = _id:project_id
Project.update conditions, update, {}, ->
ProjectEntityHandler.flushProjectToThirdPartyDataStore project_id, (err) ->
callback(err)
proxyToVersioningApi : (req, res) ->
metrics.inc "versioning.proxy"
options =
url : settings.apis.versioning.url + req.url
headers : headers
logger.log url: req.url, "proxying to versioning api"
getReq = request.get(options)
getReq.pipe(res)
getReq.on "error", (error) ->
logger.error err: error, "versioning API error"
res.send 500
createProject : (project_id, callback) ->
url = "#{settings.apis.versioning.url}/project/#{project_id}"
options = {method:"post", url:url, headers:headers, title:"createVersioningProject"}
queue.enqueue project_id, "standardHttpRequest", options, callback
takeSnapshot: (project_id, message, sl_req_id, callback = (error) ->)->
{callback, sl_req_id} = slReqIdHelper.getCallbackAndReqId(callback, sl_req_id)
logger.log project_id: project_id, sl_req_id: sl_req_id, "taking snapshot of project"
# This isn't critical so we can do it async
rclient.set Keys.buildLastSnapshotKey(project_id), Date.now(), () ->
rclient.srem Keys.projectsToSnapshotKey, project_id, () ->
DocumentUpdaterHandler.flushProjectToMongo project_id, sl_req_id, (err) ->
return callback(err) if err?
url = "#{settings.apis.versioning.url}/project/#{project_id}/version"
json = version:{message:message}
options = {method:"post", json:json, url:url, headers:headers, title:"takeVersioningSnapshot"}
queue.enqueue project_id, "standardHttpRequest", options, ->
logger.log options:options, project_id, "take snapshot enqueued"
callback()

View file

@ -25,7 +25,6 @@ ProjectSchema = new Schema
publicAccesLevel : {type: String, default: 'private'} publicAccesLevel : {type: String, default: 'private'}
compiler : {type:String, default:'pdflatex'} compiler : {type:String, default:'pdflatex'}
spellCheckLanguage : {type:String, default:'en'} spellCheckLanguage : {type:String, default:'en'}
existsInVersioningApi : {type: Boolean, default: false}
deletedByExternalDataSource : {type: Boolean, default: false} deletedByExternalDataSource : {type: Boolean, default: false}
useClsi2 : {type:Boolean, default: true} useClsi2 : {type:Boolean, default: true}
description : {type:String, default:''} description : {type:String, default:''}

View file

@ -6,7 +6,6 @@ InfoController = require('./Features/StaticPages/InfoController')
SpellingController = require('./Features/Spelling/SpellingController') SpellingController = require('./Features/Spelling/SpellingController')
SecurityManager = require('./managers/SecurityManager') SecurityManager = require('./managers/SecurityManager')
AuthorizationManager = require('./Features/Security/AuthorizationManager') AuthorizationManager = require('./Features/Security/AuthorizationManager')
versioningController = require("./Features/Versioning/VersioningApiController")
EditorController = require("./Features/Editor/EditorController") EditorController = require("./Features/Editor/EditorController")
EditorUpdatesController = require("./Features/Editor/EditorUpdatesController") EditorUpdatesController = require("./Features/Editor/EditorUpdatesController")
Settings = require('settings-sharelatex') Settings = require('settings-sharelatex')
@ -33,7 +32,6 @@ ProjectDownloadsController = require "./Features/Downloads/ProjectDownloadsContr
FileStoreController = require("./Features/FileStore/FileStoreController") FileStoreController = require("./Features/FileStore/FileStoreController")
TrackChangesController = require("./Features/TrackChanges/TrackChangesController") TrackChangesController = require("./Features/TrackChanges/TrackChangesController")
DropboxUserController = require("./Features/Dropbox/DropboxUserController") DropboxUserController = require("./Features/Dropbox/DropboxUserController")
RestoreController = require("./Features/Restore/RestoreController")
PasswordResetRouter = require("./Features/PasswordReset/PasswordResetRouter") PasswordResetRouter = require("./Features/PasswordReset/PasswordResetRouter")
logger = require("logger-sharelatex") logger = require("logger-sharelatex")
@ -85,9 +83,6 @@ module.exports = class Router
app.del '/user/newsletter/unsubscribe', AuthenticationController.requireLogin(), UserController.unsubscribe app.del '/user/newsletter/unsubscribe', AuthenticationController.requireLogin(), UserController.unsubscribe
app.del '/user', AuthenticationController.requireLogin(), UserController.deleteUser app.del '/user', AuthenticationController.requireLogin(), UserController.deleteUser
app.get "/restore", AuthenticationController.requireLogin(), RestoreController.restore
app.get "/project/:Project_id/zip", SecurityManager.requestCanAccessProject, RestoreController.getZip
app.get '/dropbox/beginAuth', DropboxUserController.redirectUserToDropboxAuth app.get '/dropbox/beginAuth', DropboxUserController.redirectUserToDropboxAuth
app.get '/dropbox/completeRegistration', DropboxUserController.completeDropboxRegistration app.get '/dropbox/completeRegistration', DropboxUserController.completeDropboxRegistration
app.get '/dropbox/unlink', DropboxUserController.unlinkDropbox app.get '/dropbox/unlink', DropboxUserController.unlinkDropbox
@ -124,12 +119,6 @@ module.exports = class Router
app.post '/project/:Project_id/rename', SecurityManager.requestIsOwner, ProjectController.renameProject app.post '/project/:Project_id/rename', SecurityManager.requestIsOwner, ProjectController.renameProject
app.post '/Project/:Project_id/snapshot', SecurityManager.requestCanModifyProject, versioningController.takeSnapshot
app.get '/Project/:Project_id/version', SecurityManager.requestCanAccessProject, versioningController.listVersions
app.get '/Project/:Project_id/version/:Version_id', SecurityManager.requestCanAccessProject, versioningController.getVersion
app.get '/Project/:Project_id/version', SecurityManager.requestCanAccessProject, versioningController.listVersions
app.get '/Project/:Project_id/version/:Version_id', SecurityManager.requestCanAccessProject, versioningController.getVersion
app.get "/project/:Project_id/updates", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi app.get "/project/:Project_id/updates", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
app.get "/project/:Project_id/doc/:doc_id/diff", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi app.get "/project/:Project_id/doc/:doc_id/diff", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
app.post "/project/:Project_id/doc/:doc_id/version/:version_id/restore", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi app.post "/project/:Project_id/doc/:doc_id/version/:version_id/restore", SecurityManager.requestCanAccessProject, TrackChangesController.proxyToTrackChangesApi
@ -158,20 +147,6 @@ module.exports = class Router
app.ignoreCsrf('post', '/user/:user_id/update/*') app.ignoreCsrf('post', '/user/:user_id/update/*')
app.ignoreCsrf('delete', '/user/:user_id/update/*') app.ignoreCsrf('delete', '/user/:user_id/update/*')
app.get '/enableversioning/:Project_id', (req, res)->
versioningController.enableVersioning req.params.Project_id, -> res.send()
app.get /^\/project\/([^\/]*)\/version\/([^\/]*)\/file\/(.*)$/,
((req, res, next) ->
params =
"Project_id": req.params[0]
"Version_id": req.params[1]
"File_id": req.params[2]
req.params = params
next()
),
SecurityManager.requestCanAccessProject, versioningController.getVersionFile
app.post "/spelling/check", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi app.post "/spelling/check", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi
app.post "/spelling/learn", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi app.post "/spelling/learn", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi
@ -327,10 +302,6 @@ module.exports = class Router
CompileManager.compile project_id, user._id, opts, (error, status, outputFiles) -> CompileManager.compile project_id, user._id, opts, (error, status, outputFiles) ->
return callback error, status == "success", outputFiles return callback error, status == "success", outputFiles
client.on 'enableversioningController', (callback)->
AuthorizationManager.ensureClientCanEditProject client, (error, project_id) =>
versioningController.enableVersioning project_id, callback
client.on 'getRootDocumentsList', (callback)-> client.on 'getRootDocumentsList', (callback)->
AuthorizationManager.ensureClientCanEditProject client, (error, project_id) => AuthorizationManager.ensureClientCanEditProject client, (error, project_id) =>
EditorController.getListOfDocPaths project_id, callback EditorController.getListOfDocPaths project_id, callback

View file

@ -38,9 +38,6 @@ describe "EditorController", ->
findPopulatedById: sinon.stub().callsArgWith(1, null, @project) findPopulatedById: sinon.stub().callsArgWith(1, null, @project)
@LimitationsManager = {} @LimitationsManager = {}
@AuthorizationManager = {} @AuthorizationManager = {}
@AutomaticSnapshotManager = {}
@VersioningApiHandler =
enableVersioning : sinon.stub().callsArg(1)
@client = new MockClient() @client = new MockClient()
@settings = @settings =
@ -69,8 +66,6 @@ describe "EditorController", ->
'../DocumentUpdater/DocumentUpdaterHandler' : @DocumentUpdaterHandler '../DocumentUpdater/DocumentUpdaterHandler' : @DocumentUpdaterHandler
'../Subscription/LimitationsManager' : @LimitationsManager '../Subscription/LimitationsManager' : @LimitationsManager
'../Security/AuthorizationManager' : @AuthorizationManager '../Security/AuthorizationManager' : @AuthorizationManager
"../Versioning/AutomaticSnapshotManager" : @AutomaticSnapshotManager
"../Versioning/VersioningApiHandler" : @VersioningApiHandler
'../../models/Project' : Project: @Project '../../models/Project' : Project: @Project
"settings-sharelatex":@settings "settings-sharelatex":@settings
'../Dropbox/DropboxProjectLinker':@dropboxProjectLinker '../Dropbox/DropboxProjectLinker':@dropboxProjectLinker

View file

@ -15,7 +15,6 @@ describe "EditorUpdatesController", ->
"logger-sharelatex": @logger = { error: sinon.stub(), log: sinon.stub() } "logger-sharelatex": @logger = { error: sinon.stub(), log: sinon.stub() }
"./EditorRealTimeController" : @EditorRealTimeController = {} "./EditorRealTimeController" : @EditorRealTimeController = {}
"../DocumentUpdater/DocumentUpdaterHandler" : @DocumentUpdaterHandler = {} "../DocumentUpdater/DocumentUpdaterHandler" : @DocumentUpdaterHandler = {}
"../Versioning/AutomaticSnapshotManager" : @AutomaticSnapshotManager = {}
"../../infrastructure/Metrics" : @metrics = { set: sinon.stub(), inc: sinon.stub() } "../../infrastructure/Metrics" : @metrics = { set: sinon.stub(), inc: sinon.stub() }
"../../infrastructure/Server" : io: @io = {} "../../infrastructure/Server" : io: @io = {}
"redis" : "redis" :
@ -61,16 +60,6 @@ describe "EditorUpdatesController", ->
it "should log an error", -> it "should log an error", ->
@logger.error.called.should.equal true @logger.error.called.should.equal true
describe "when client.take_snapshot is true", ->
beforeEach ->
@client.set("take_snapshots", true)
@AutomaticSnapshotManager.markProjectAsUpdated = sinon.stub()
@EditorUpdatesController._applyUpdate(@client, @project_id, @doc_id, @update)
it "should call AutomaticSnapshotManager.markProjectAsUpdated", ->
@AutomaticSnapshotManager.markProjectAsUpdated.calledWith(@project_id)
.should.equal true
describe "applyOtUpdate", -> describe "applyOtUpdate", ->
beforeEach -> beforeEach ->
@client.id = "client-id" @client.id = "client-id"

View file

@ -16,7 +16,6 @@ describe 'ProjectCreationHandler', ->
rootFolderId = "234adfa3r2afe" rootFolderId = "234adfa3r2afe"
beforeEach -> beforeEach ->
@versioningApiHandler={enableVersioning: sinon.stub().callsArg(1)}
@ProjectModel = class Project @ProjectModel = class Project
constructor:(options = {})-> constructor:(options = {})->
@._id = project_id @._id = project_id
@ -47,7 +46,6 @@ describe 'ProjectCreationHandler', ->
'../../models/User': User:@User '../../models/User': User:@User
'../../models/Project':{Project:@ProjectModel} '../../models/Project':{Project:@ProjectModel}
'../../models/Folder':{Folder:@FolderModel} '../../models/Folder':{Folder:@FolderModel}
'../Versioning/VersioningApiHandler':@versioningApiHandler
'./ProjectEntityHandler':@ProjectEntityHandler './ProjectEntityHandler':@ProjectEntityHandler
'logger-sharelatex': {log:->} 'logger-sharelatex': {log:->}
@ -68,11 +66,6 @@ describe 'ProjectCreationHandler', ->
(project.owner_ref + "").should.equal ownerId (project.owner_ref + "").should.equal ownerId
done() done()
it 'should enable versioning', (done)->
@handler.createBlankProject ownerId, projectName, =>
@versioningApiHandler.enableVersioning.calledWith(project_id).should.equal true
done()
it "should set the language from the user", (done)-> it "should set the language from the user", (done)->
@handler.createBlankProject ownerId, projectName, (err, project)-> @handler.createBlankProject ownerId, projectName, (err, project)->
project.spellCheckLanguage.should.equal "de" project.spellCheckLanguage.should.equal "de"
@ -86,12 +79,6 @@ describe 'ProjectCreationHandler', ->
it 'should return the error to the callback', -> it 'should return the error to the callback', ->
should.exist @callback.args[0][0] should.exist @callback.args[0][0]
it 'enables versioning', (done)->
@versioningApiHandler.enableVersioning = (enbleVersioningProjectId, callback)->
project_id.should.equal enbleVersioningProjectId
done()
@handler.createBlankProject ownerId, projectName, ->
describe 'Creating a basic project', -> describe 'Creating a basic project', ->
beforeEach -> beforeEach ->
@project = new @ProjectModel() @project = new @ProjectModel()

View file

@ -22,8 +22,6 @@ describe 'Project deleter', ->
applyToAllFilesRecursivly: sinon.stub() applyToAllFilesRecursivly: sinon.stub()
@documentUpdaterHandler = @documentUpdaterHandler =
flushProjectToMongoAndDelete:sinon.stub().callsArgWith(1) flushProjectToMongoAndDelete:sinon.stub().callsArgWith(1)
@AutomaticSnapshotManager =
unmarkProjectAsUpdated:sinon.stub().callsArgWith(1)
@editorController = notifyUsersProjectHasBeenDeletedOrRenamed : sinon.stub().callsArgWith(1) @editorController = notifyUsersProjectHasBeenDeletedOrRenamed : sinon.stub().callsArgWith(1)
@TagsHandler = @TagsHandler =
removeProjectFromAllTags: sinon.stub().callsArgWith(2) removeProjectFromAllTags: sinon.stub().callsArgWith(2)
@ -31,7 +29,6 @@ describe 'Project deleter', ->
"../Editor/EditorController": @editorController "../Editor/EditorController": @editorController
'../../models/Project':{Project:@Project} '../../models/Project':{Project:@Project}
'../DocumentUpdater/DocumentUpdaterHandler': @documentUpdaterHandler '../DocumentUpdater/DocumentUpdaterHandler': @documentUpdaterHandler
'../Versioning/AutomaticSnapshotManager':@AutomaticSnapshotManager
"../Tags/TagsHandler":@TagsHandler "../Tags/TagsHandler":@TagsHandler
'logger-sharelatex': 'logger-sharelatex':
log:-> log:->

View file

@ -3,7 +3,6 @@ assert = require('assert')
require('chai').should() require('chai').should()
sinon = require('sinon') sinon = require('sinon')
modulePath = require('path').join __dirname, '../../../../app/js/Features/ThirdPartyDataStore/TpdsPollingBackgroundTasks.js' modulePath = require('path').join __dirname, '../../../../app/js/Features/ThirdPartyDataStore/TpdsPollingBackgroundTasks.js'
redisKeys = require('../../../../app/js/Features/Versioning/RedisKeys')
describe 'third party data store', -> describe 'third party data store', ->
beforeEach -> beforeEach ->

View file

@ -6,7 +6,6 @@ modulePath = require('path').join __dirname, '../../../../app/js/Features/ThirdP
describe 'third party data store reciver :', -> describe 'third party data store reciver :', ->
beforeEach -> beforeEach ->
@requestQueuer = {} @requestQueuer = {}
@versioningApiHandler = {takeSnapshot:(_, message, sl_req_id, cb)->cb()}
@updateMerger = @updateMerger =
deleteUpdate: (user_id, path, sl_req_id, cb)->cb() deleteUpdate: (user_id, path, sl_req_id, cb)->cb()
mergeUpdate:(user_id, path, update, sl_req_id, cb)->cb() mergeUpdate:(user_id, path, update, sl_req_id, cb)->cb()
@ -19,7 +18,6 @@ describe 'third party data store reciver :', ->
@projectDeleter = {markAsDeletedByExternalSource:sinon.stub().callsArgWith(1)} @projectDeleter = {markAsDeletedByExternalSource:sinon.stub().callsArgWith(1)}
@rootDocManager = setRootDocAutomatically:sinon.stub() @rootDocManager = setRootDocAutomatically:sinon.stub()
@handler = SandboxedModule.require modulePath, requires: @handler = SandboxedModule.require modulePath, requires:
'../Versioning/VersioningApiHandler':@versioningApiHandler
'./UpdateMerger': @updateMerger './UpdateMerger': @updateMerger
'./Editor/EditorController': @editorController './Editor/EditorController': @editorController
'../Project/ProjectLocator': @projectLocator '../Project/ProjectLocator': @projectLocator
@ -30,15 +28,6 @@ describe 'third party data store reciver :', ->
@user_id = "dsad29jlkjas" @user_id = "dsad29jlkjas"
describe 'getting an update', -> describe 'getting an update', ->
it 'should call versioning api to take snapshot for backup reasons', (done)->
update = {}
@versioningApiHandler.takeSnapshot = sinon.stub().callsArg(3)
@handler.newUpdate @user_id, @project.name, "",update, "", =>
@versioningApiHandler.takeSnapshot.calledWith(@project_id).should.equal true
@projectCreationHandler.createBlankProject.called.should.equal false
done()
it 'should send the update to the update merger', (done)-> it 'should send the update to the update merger', (done)->
path = "/path/here" path = "/path/here"
update = {} update = {}
@ -68,16 +57,6 @@ describe 'third party data store reciver :', ->
describe 'getting a delete :', -> describe 'getting a delete :', ->
it 'should call versioning api to take snapshot for backup reasons', (done)->
update = {}
@versioningApiHandler.takeSnapshot = sinon.stub()
@versioningApiHandler.takeSnapshot.callsArg(3)
@handler.deleteUpdate @user_id,@project.name, "", "", =>
@projectDeleter.markAsDeletedByExternalSource.calledWith(@project._id).should.equal false
@versioningApiHandler.takeSnapshot.calledWith(@project_id).should.equal true
done()
it 'should call deleteEntity in the collaberation manager', (done)-> it 'should call deleteEntity in the collaberation manager', (done)->
path = "/delete/this" path = "/delete/this"
update = {} update = {}

View file

@ -1,135 +0,0 @@
should = require('chai').should()
sinon = require('sinon')
SandboxedModule = require('sandboxed-module')
assert = require('assert')
path = require("path")
modulePath = path.join __dirname, '../../../../app/js/Features/Versioning/AutomaticSnapshotManager'
tk = require 'timekeeper'
Settings = require "settings-sharelatex"
describe 'AutomaticSnapshotManager', ->
beforeEach ->
tk.freeze(Date.now())
@project_id = "project-id-1234"
@callback = sinon.stub()
@rclient =
auth:->
del: sinon.stub().callsArg(2)
srem: sinon.stub().callsArg(2)
sadd: sinon.stub().callsArg(2)
set: sinon.stub().callsArg(2)
@VersioningApiHandler =
takeSnapshot: sinon.stub().callsArg(2)
@AutomaticSnapshotManager = SandboxedModule.require modulePath,
requires:
'redis' : createClient: () => @rclient
'../../Features/Versioning/VersioningApiHandler' : @VersioningApiHandler
globals:
Date: Date
afterEach -> tk.reset()
describe "markProjectAsUpdated", ->
beforeEach ->
@AutomaticSnapshotManager.markProjectAsUpdated(@project_id, @callback)
it "should update the project's last updated date", ->
@rclient.set.calledWith("project_last_updated:#{@project_id}", Date.now())
it "should add the project to the set needing processing", ->
@rclient.sadd.calledWith("projects_to_snapshot", @project_id)
it "should call the callback", ->
@callback.calledWith().should.equal true
describe "takeSnapshotIfRequired", ->
beforeEach ->
@lastUpdated = Date.now() - Settings.automaticSnapshots.waitTimeAfterLastEdit + 1
@lastSnapshot = Date.now() - Settings.automaticSnapshots.maxTimeBetweenSnapshots + 1
@rclient.get = (key, callback) =>
if key == "project_last_updated:#{@project_id}"
callback(null, @lastUpdated)
else if key == "project_last_snapshot:#{@project_id}"
callback(null, @lastSnapshot)
else
throw new Error("unexpected key: #{key}")
describe "when updated longer than waitTimeAfterLastEdit ago", ->
beforeEach ->
@lastUpdated = Date.now() - Settings.automaticSnapshots.waitTimeAfterLastEdit - 1
@AutomaticSnapshotManager.takeSnapshotIfRequired(@project_id, @callback)
it "should take a snapshot", ->
@VersioningApiHandler.takeSnapshot.calledWith(@project_id, "Automatic snapshot")
.should.equal true
it "should return the callback", ->
@callback.calledWithExactly().should.equal true
describe "when last snapshot longer then maxTimeBetweenSnapshots ago", ->
beforeEach ->
@lastSnapshot = Date.now() - Settings.automaticSnapshots.maxTimeBetweenSnapshots - 1
@AutomaticSnapshotManager.takeSnapshotIfRequired(@project_id, @callback)
it "should take a snapshot", ->
@VersioningApiHandler.takeSnapshot.calledWith(@project_id, "Automatic snapshot")
.should.equal true
it "should return the callback", ->
@callback.calledWithExactly().should.equal true
describe "when no snapshot has been taken", ->
beforeEach ->
@lastSnapshot = null
@AutomaticSnapshotManager.takeSnapshotIfRequired(@project_id, @callback)
it "should take a snapshot", ->
@VersioningApiHandler.takeSnapshot.calledWith(@project_id, "Automatic snapshot")
.should.equal true
it "should return the callback", ->
@callback.calledWithExactly().should.equal true
describe "when no snapshot is needed", ->
beforeEach ->
@AutomaticSnapshotManager.takeSnapshotIfRequired(@project_id, @callback)
it "should take a snapshot", ->
@VersioningApiHandler.takeSnapshot.called.should.equal false
it "should return the callback", ->
@callback.calledWithExactly().should.equal true
describe "takeAutomaticSnapshots", ->
beforeEach ->
@project_ids = ["project-1", "project-2", "project-3"]
@rclient.smembers = (key, callback) =>
if key == "projects_to_snapshot"
callback(null, @project_ids)
else
throw new Error("unexpected key: #{key}")
sinon.stub(@AutomaticSnapshotManager, "takeSnapshotIfRequired").callsArgWith(1, null)
@AutomaticSnapshotManager.takeAutomaticSnapshots @callback
afterEach ->
@AutomaticSnapshotManager.takeSnapshotIfRequired.restore()
it "should call the callback", ->
@callback.calledWith(undefined).should.equal true
describe "removing project from marked set", ->
beforeEach ->
@AutomaticSnapshotManager.markProjectAsUpdated @project_id, =>
@AutomaticSnapshotManager.unmarkProjectAsUpdated @project_id, @callback
it "should update the project's last updated date", ->
@rclient.del.calledWith("project_last_updated:#{@project_id}", Date.now())
it "should add the project to the set needing processing", ->
@rclient.srem.calledWith("projects_to_snapshot", @project_id)
it "should call the callback", ->
@callback.calledWith().should.equal true

View file

@ -1,89 +0,0 @@
spies = require('chai-spies')
chai = require('chai').use(spies)
sinon = require('sinon')
should = chai.should()
modulePath = "../../../../app/js/Features/Versioning/VersioningApiController"
SandboxedModule = require('sandboxed-module')
MockRequest = require "../helpers/MockRequest"
MockResponse = require "../helpers/MockResponse"
describe "VersioningApiController", ->
beforeEach ->
@handler = {}
@controller = SandboxedModule.require modulePath, requires:
'./VersioningApiHandler':@handler
@req = new MockRequest()
@res = new MockResponse()
describe "takeSnapshot", ->
beforeEach ->
@error = null
@handler.takeSnapshot = (project_id, message, callback) =>
callback(@error)
sinon.spy @handler, "takeSnapshot"
@req.params = Project_id: "project_id"
describe "successfully", ->
beforeEach ->
@error = null
@req.body = message: "hello world"
@controller.takeSnapshot(@req, @res)
it "should call VersioningApiHandler.takeSnapshot", ->
@handler.takeSnapshot.calledWith(
"project_id", @req.body.message
).should.equal true
it "should return a successful response", ->
@res.returned.should.equal true
@res.success.should.equal true
@res.body.should.equal "{}"
describe "without message", ->
beforeEach ->
@error = null
@controller.takeSnapshot(@req, @res)
it "should use a default message", ->
@handler.takeSnapshot.calledWith(
"project_id", "Manual snapshot"
).should.equal true
describe "with errors", ->
beforeEach ->
@error = new Error("Oops")
@next = sinon.stub()
@controller.takeSnapshot(@req, @res, @next)
it "should call next() with the error", ->
@res.returned.should.equal false
@next.called.should.equal true
it 'enable versioning in the handler', (done)->
project_id = "1234"
@handler.enableVersioning = (sentProjectId, callback)->
sentProjectId.should.equal project_id
callback null
@controller.enableVersioning project_id, ->
done()
it 'proxys list versions', (done)->
shouldProxy @controller.listVersions, @handler, done
it 'proxys get version', (done)->
shouldProxy @controller.getVersion, @handler, done
it 'proxys get verion file', (done)->
shouldProxy @controller.getVersionFile, @handler, done
shouldProxy = (fun, handler, callback)->
req = {"stuf":"here"}
res = {"other":"stuff"}
handler.proxyToVersioningApi = (proxyReq, proxyRes)->
proxyReq.should.deep.equal req
proxyRes.should.deep.equal res
callback()
fun req, res

View file

@ -1,168 +0,0 @@
assert = require('chai').assert
chai = require('chai')
should = chai.should()
sinon = require("sinon")
modulePath = "../../../../app/js/Features/Versioning/VersioningApiHandler"
SandboxedModule = require('sandboxed-module')
tk = require 'timekeeper'
describe "VersioningApiHandler", ->
beforeEach ->
tk.freeze(Date.now())
@fakeHttp ={}
@requestQueuer = {}
@thirdParyDataStoreManager = {}
@documentUpdaterHandler =
flushProjectToMongo : (project_id, sl_req_id, callback) -> callback()
@projectEntityHandler = {}
@ProjectModel =
getProject : (project_id, fields, callback)=>
callback(null, @project)
@rclient =
auth:->
srem: sinon.stub().callsArg(2)
set: sinon.stub().callsArg(2)
@settings =
apis:
versioning:
snapshotwaitInMs:100
url: "http://localhost:4000"
username:"username"
password:"password"
redis:
web: {}
fairy: {}
@versioningApi = SandboxedModule.require modulePath,
requires:
'../../models/Project':{Project:@ProjectModel}
'../../Features/DocumentUpdater/DocumentUpdaterHandler' : @documentUpdaterHandler
'../../Features/Project/ProjectEntityHandler' : @projectEntityHandler
'fairy':{connect:=>{queue:=>@requestQueuer}}
'request': @fakeHttp
'settings-sharelatex' : @settings
'logger-sharelatex':
log:->
err:->
'redis' : createClient: () => @rclient
globals:
Date: Date
@project = _id:"123456", existsInVersioningApi : false
@callback = sinon.stub()
afterEach -> tk.reset()
it 'should create project in versioning api using request queuer', (done)->
@requestQueuer.enqueue = (project_id, method, options, callback)=>
project_id.should.equal @project._id
method.should.equal "standardHttpRequest"
options.method.should.equal "post"
options.url.should.equal("#{@settings.apis.versioning.url}/project/#{@project._id}")
done()
@versioningApi.createProject(@project._id)
describe "takeSnapshot", ->
beforeEach ->
@message = "finished chapter"
@requestQueuer.enqueue = (project_id, method, options, callback) -> callback()
sinon.spy @requestQueuer, "enqueue"
sinon.spy @documentUpdaterHandler, "flushProjectToMongo"
@versioningApi.takeSnapshot(@project._id, @message)
afterEach ->
@documentUpdaterHandler.flushProjectToMongo.restore()
it 'should flush the document to the third party datastore', ->
@documentUpdaterHandler.flushProjectToMongo.calledWith(@project._id).should.equal true
@documentUpdaterHandler.flushProjectToMongo.calledBefore(@requestQueuer.enqueue)
it 'should queue a request for the versioning api', ->
@requestQueuer.enqueue.calledWith(@project._id, "standardHttpRequest").should.equal true
options = @requestQueuer.enqueue.args[0][2]
options.method.should.equal "post"
options.url.should.equal("#{@settings.apis.versioning.url}/project/#{@project._id}/version")
assert.deepEqual options.json, {version: {message: @message}}
it "should remove the project from the set needing snapshotting", ->
@rclient.srem.calledWith("projects_to_snapshot", @project._id).should.equal true
it "should set the project's last snapshot date", ->
@rclient.set.calledWith("project_last_snapshot:#{@project._id}", Date.now()).should.equal true
it 'proxyToVersioningApi pipes to url passed', (done)->
res = {some:"stuff"}
req = url : "/somewhere"
@fakeHttp.get = (options)=>
options.url.should.equal("#{@settings.apis.versioning.url}#{req.url}")
return {
pipe:(pipedResponse)->
pipedResponse.should.deep.equal res
done()
on: () ->
}
@versioningApi.proxyToVersioningApi req, res
describe "enableVersioning", ->
beforeEach ->
@projectEntityHandler.flushProjectToThirdPartyDataStore = sinon.stub().callsArg(1)
@versioningApi.createProject = sinon.stub().callsArg(1)
@ProjectModel.update = sinon.stub().callsArg(3)
describe "successfully", ->
beforeEach ->
@versioningApi.enableVersioning @project._id, ->
it "should flush the project to the TPDS", ->
@projectEntityHandler.flushProjectToThirdPartyDataStore.calledWith(@project._id)
.should.equal true
it "should create the project in the versioning api", ->
@versioningApi.createProject.calledWith(@project._id)
.should.equal true
it "should set the existsInVersioningApi flag to true", ->
@ProjectModel.update.calledWith({_id: @project._id}, {existsInVersioningApi: true})
.should.equal true
describe "with a non existant project id", ->
beforeEach ->
@ProjectModel.getProject = (project_id, fields, callback)->
callback null, null
@versioningApi.enableVersioning @project._id, @callback
it "should return an error", ->
should.exist @callback.args[0][0]
it "should not try to enable versioning", ->
@projectEntityHandler.flushProjectToThirdPartyDataStore.called.should.equal false
@versioningApi.createProject.called.should.equal false
@ProjectModel.update.called.should.equal false
describe "when versioning API request fails", ->
beforeEach ->
@versioningApi.createProject = sinon.stub().callsArgWith(1, new Error("something went wrong"))
@versioningApi.enableVersioning @project._id, @callback
it "should return an error", ->
should.exist @callback.args[0][0]
it "should not try to flush the project or save the change", ->
@projectEntityHandler.flushProjectToThirdPartyDataStore.called.should.equal false
@ProjectModel.update.called.should.equal false
describe "when the project already has versioning enabled", ->
beforeEach ->
@project.existsInVersioningApi = true
@versioningApi.enableVersioning @project._id, @callback
it "should not return an error", ->
@callback.calledWithExactly().should.equal true
it "should not try to enable versioning again", ->
@projectEntityHandler.flushProjectToThirdPartyDataStore.called.should.equal false
@versioningApi.createProject.called.should.equal false
@ProjectModel.update.called.should.equal false