From 80c58bb718dfb661c3a00bb721d34efe3a0c8c16 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 27 May 2014 12:56:23 +0100 Subject: [PATCH] Remove deprecated versioning code --- services/web/BackgroundJobsWorker.coffee | 2 - .../Features/Editor/EditorController.coffee | 3 - .../Editor/EditorUpdatesController.coffee | 5 - .../Project/ProjectCreationHandler.coffee | 4 +- .../Features/Project/ProjectDeleter.coffee | 1 - .../Project/ProjectEditorHandler.coffee | 1 - .../Features/Restore/RestoreController.coffee | 22 --- .../TpdsUpdateHandler.coffee | 11 +- .../AutomaticSnapshotManager.coffee | 50 ------ .../Features/Versioning/RedisKeys.coffee | 5 - .../Versioning/VersioningApiController.coffee | 31 ---- .../Versioning/VersioningApiHandler.coffee | 75 -------- services/web/app/coffee/models/Project.coffee | 1 - services/web/app/coffee/router.coffee | 29 --- .../Editor/EditorControllerTests.coffee | 5 - .../EditorUpdatesControllerTests.coffee | 11 -- .../ProjectCreationHandlerTests.coffee | 13 -- .../coffee/Project/ProjectDeleterTests.coffee | 3 - .../TpdsPollingBackgroundTasksTests.coffee | 1 - .../TpdsUpdateHandlerTests.coffee | 21 --- .../AutomaticSnapshotManagerTests.coffee | 135 -------------- .../VersioningApiControllerTests.coffee | 89 ---------- .../VersioningApiHandlerTests.coffee | 168 ------------------ 23 files changed, 5 insertions(+), 681 deletions(-) delete mode 100644 services/web/app/coffee/Features/Restore/RestoreController.coffee delete mode 100644 services/web/app/coffee/Features/Versioning/AutomaticSnapshotManager.coffee delete mode 100644 services/web/app/coffee/Features/Versioning/RedisKeys.coffee delete mode 100644 services/web/app/coffee/Features/Versioning/VersioningApiController.coffee delete mode 100644 services/web/app/coffee/Features/Versioning/VersioningApiHandler.coffee delete mode 100644 services/web/test/UnitTests/coffee/Versioning/AutomaticSnapshotManagerTests.coffee delete mode 100644 services/web/test/UnitTests/coffee/Versioning/VersioningApiControllerTests.coffee delete mode 100644 services/web/test/UnitTests/coffee/Versioning/VersioningApiHandlerTests.coffee diff --git a/services/web/BackgroundJobsWorker.coffee b/services/web/BackgroundJobsWorker.coffee index 47ec9a3d33..070c5ab4ad 100644 --- a/services/web/BackgroundJobsWorker.coffee +++ b/services/web/BackgroundJobsWorker.coffee @@ -1,7 +1,6 @@ settings = require('settings-sharelatex') SubscriptionBackgroundTasks = require("./app/js/Features/Subscription/SubscriptionBackgroundTasks") TpdsPollingBackgroundTasks = require("./app/js/Features/ThirdPartyDataStore/TpdsPollingBackgroundTasks") -AutomaticSnapshotManager = require("./app/js/Features/Versioning/AutomaticSnapshotManager") time = oneHour : 60 * 60 * 1000 @@ -24,4 +23,3 @@ runPeriodically = (funcToRun, periodLength)-> runPeriodically ((cb) -> SubscriptionBackgroundTasks.downgradeExpiredFreeTrials(cb)), time.oneHour runPeriodically ((cb) -> TpdsPollingBackgroundTasks.pollUsersWithDropbox(cb)), time.fifteenMinutes -runPeriodically ((cb) -> AutomaticSnapshotManager.takeAutomaticSnapshots(cb)), time.thirtySeconds diff --git a/services/web/app/coffee/Features/Editor/EditorController.coffee b/services/web/app/coffee/Features/Editor/EditorController.coffee index 0093fc0a52..99e28fd152 100644 --- a/services/web/app/coffee/Features/Editor/EditorController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorController.coffee @@ -11,8 +11,6 @@ CollaboratorsHandler = require("../Collaborators/CollaboratorsHandler") DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler') LimitationsManager = require("../Subscription/LimitationsManager") AuthorizationManager = require("../Security/AuthorizationManager") -AutomaticSnapshotManager = require("../Versioning/AutomaticSnapshotManager") -VersioningApiHandler = require("../Versioning/VersioningApiHandler") EditorRealTimeController = require("./EditorRealTimeController") TrackChangesManager = require("../TrackChanges/TrackChangesManager") settings = require('settings-sharelatex') @@ -56,7 +54,6 @@ module.exports = EditorController = client.set("connected_time", new Date()) client.set("signup_date", user.signUpDate) client.set("login_count", user.loginCount) - client.set("take_snapshots", project.existsInVersioningApi) AuthorizationManager.setPrivilegeLevelOnClient client, privilegeLevel callback null, ProjectEditorHandler.buildProjectModelView(project), privilegeLevel, EditorController.protocolVersion diff --git a/services/web/app/coffee/Features/Editor/EditorUpdatesController.coffee b/services/web/app/coffee/Features/Editor/EditorUpdatesController.coffee index 2e8748281f..4385123541 100644 --- a/services/web/app/coffee/Features/Editor/EditorUpdatesController.coffee +++ b/services/web/app/coffee/Features/Editor/EditorUpdatesController.coffee @@ -4,7 +4,6 @@ Settings = require 'settings-sharelatex' rclient = require("redis").createClient(Settings.redis.web.port, Settings.redis.web.host) rclient.auth(Settings.redis.web.password) DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler') -AutomaticSnapshotManager = require("../Versioning/AutomaticSnapshotManager") EditorRealTimeController = require("./EditorRealTimeController") module.exports = EditorUpdatesController = @@ -14,10 +13,6 @@ module.exports = EditorUpdatesController = client.get "user_id", (error, user_id) -> 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" DocumentUpdaterHandler.queueChange project_id, doc_id, update, (error) -> diff --git a/services/web/app/coffee/Features/Project/ProjectCreationHandler.coffee b/services/web/app/coffee/Features/Project/ProjectCreationHandler.coffee index 960c04ffd0..b7070786cb 100644 --- a/services/web/app/coffee/Features/Project/ProjectCreationHandler.coffee +++ b/services/web/app/coffee/Features/Project/ProjectCreationHandler.coffee @@ -5,7 +5,6 @@ Settings = require('settings-sharelatex') ObjectId = require('mongoose').Types.ObjectId Project = require('../../models/Project').Project Folder = require('../../models/Folder').Folder -VersioningApiHandler = require('../Versioning/VersioningApiHandler') ProjectEntityHandler = require('./ProjectEntityHandler') User = require('../../models/User').User fs = require('fs') @@ -26,8 +25,7 @@ module.exports = project.spellCheckLanguage = user.ace.spellCheckLanguage project.save (err)-> return callback(err) if err? - VersioningApiHandler.enableVersioning project._id, (err) -> - callback err, project + callback err, project createBasicProject : (owner_id, projectName, callback = (error, project) ->)-> self = @ diff --git a/services/web/app/coffee/Features/Project/ProjectDeleter.coffee b/services/web/app/coffee/Features/Project/ProjectDeleter.coffee index 41911d59b0..242e69f9e4 100644 --- a/services/web/app/coffee/Features/Project/ProjectDeleter.coffee +++ b/services/web/app/coffee/Features/Project/ProjectDeleter.coffee @@ -3,7 +3,6 @@ logger = require('logger-sharelatex') documentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandler') tagsHandler = require("../Tags/TagsHandler") async = require("async") -AutomaticSnapshotManager = require('../Versioning/AutomaticSnapshotManager') FileStoreHandler = require("../FileStore/FileStoreHandler") module.exports = diff --git a/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee b/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee index fe54138752..6c78a8e939 100644 --- a/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee +++ b/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee @@ -10,7 +10,6 @@ module.exports = ProjectEditorHandler = rootDoc_id : project.rootDoc_id rootFolder : [@buildFolderModelView project.rootFolder[0]] publicAccesLevel : project.publicAccesLevel - versioningVisible : !!project.existsInVersioningApi dropboxEnabled : !!project.existsInDropbox compiler : project.compiler description: project.description diff --git a/services/web/app/coffee/Features/Restore/RestoreController.coffee b/services/web/app/coffee/Features/Restore/RestoreController.coffee deleted file mode 100644 index 8a8f2cdb41..0000000000 --- a/services/web/app/coffee/Features/Restore/RestoreController.coffee +++ /dev/null @@ -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) \ No newline at end of file diff --git a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsUpdateHandler.coffee b/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsUpdateHandler.coffee index df47a055f6..76b802a5e3 100644 --- a/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsUpdateHandler.coffee +++ b/services/web/app/coffee/Features/ThirdPartyDataStore/TpdsUpdateHandler.coffee @@ -1,4 +1,3 @@ -versioningApiHandler = require('../Versioning/VersioningApiHandler') updateMerger = require('./UpdateMerger') logger = require('logger-sharelatex') projectLocator = require('../Project/ProjectLocator') @@ -23,9 +22,8 @@ module.exports = else cb err, project getOrCreateProject (err, project)-> - versioningApiHandler.takeSnapshot project._id, commitMessage, sl_req_id, -> - updateMerger.mergeUpdate project._id, path, updateRequest, sl_req_id, (err)-> - callback(err) + updateMerger.mergeUpdate project._id, path, updateRequest, sl_req_id, (err)-> + callback(err) deleteUpdate: (user_id, projectName, path, sl_req_id, callback)-> @@ -38,9 +36,8 @@ 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" return projectDeleter.markAsDeletedByExternalSource project._id, callback else - versioningApiHandler.takeSnapshot project._id, commitMessage, sl_req_id, -> - updateMerger.deleteUpdate project._id, path, sl_req_id, (err)-> - callback(err) + updateMerger.deleteUpdate project._id, path, sl_req_id, (err)-> + callback(err) _rootDocTimeoutLength : 30 * 1000 diff --git a/services/web/app/coffee/Features/Versioning/AutomaticSnapshotManager.coffee b/services/web/app/coffee/Features/Versioning/AutomaticSnapshotManager.coffee deleted file mode 100644 index 59df268969..0000000000 --- a/services/web/app/coffee/Features/Versioning/AutomaticSnapshotManager.coffee +++ /dev/null @@ -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() - diff --git a/services/web/app/coffee/Features/Versioning/RedisKeys.coffee b/services/web/app/coffee/Features/Versioning/RedisKeys.coffee deleted file mode 100644 index 9f34d86b6f..0000000000 --- a/services/web/app/coffee/Features/Versioning/RedisKeys.coffee +++ /dev/null @@ -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" diff --git a/services/web/app/coffee/Features/Versioning/VersioningApiController.coffee b/services/web/app/coffee/Features/Versioning/VersioningApiController.coffee deleted file mode 100644 index 480cb4fba0..0000000000 --- a/services/web/app/coffee/Features/Versioning/VersioningApiController.coffee +++ /dev/null @@ -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, "{}") diff --git a/services/web/app/coffee/Features/Versioning/VersioningApiHandler.coffee b/services/web/app/coffee/Features/Versioning/VersioningApiHandler.coffee deleted file mode 100644 index 5d390a6b14..0000000000 --- a/services/web/app/coffee/Features/Versioning/VersioningApiHandler.coffee +++ /dev/null @@ -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() - - - diff --git a/services/web/app/coffee/models/Project.coffee b/services/web/app/coffee/models/Project.coffee index 9fa2b11606..da9677b04d 100644 --- a/services/web/app/coffee/models/Project.coffee +++ b/services/web/app/coffee/models/Project.coffee @@ -25,7 +25,6 @@ ProjectSchema = new Schema publicAccesLevel : {type: String, default: 'private'} compiler : {type:String, default:'pdflatex'} spellCheckLanguage : {type:String, default:'en'} - existsInVersioningApi : {type: Boolean, default: false} deletedByExternalDataSource : {type: Boolean, default: false} useClsi2 : {type:Boolean, default: true} description : {type:String, default:''} diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index bc95f6fe19..1052f3cdae 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -6,7 +6,6 @@ InfoController = require('./Features/StaticPages/InfoController') SpellingController = require('./Features/Spelling/SpellingController') SecurityManager = require('./managers/SecurityManager') AuthorizationManager = require('./Features/Security/AuthorizationManager') -versioningController = require("./Features/Versioning/VersioningApiController") EditorController = require("./Features/Editor/EditorController") EditorUpdatesController = require("./Features/Editor/EditorUpdatesController") Settings = require('settings-sharelatex') @@ -33,7 +32,6 @@ ProjectDownloadsController = require "./Features/Downloads/ProjectDownloadsContr FileStoreController = require("./Features/FileStore/FileStoreController") TrackChangesController = require("./Features/TrackChanges/TrackChangesController") DropboxUserController = require("./Features/Dropbox/DropboxUserController") -RestoreController = require("./Features/Restore/RestoreController") PasswordResetRouter = require("./Features/PasswordReset/PasswordResetRouter") logger = require("logger-sharelatex") @@ -85,9 +83,6 @@ module.exports = class Router app.del '/user/newsletter/unsubscribe', AuthenticationController.requireLogin(), UserController.unsubscribe 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/completeRegistration', DropboxUserController.completeDropboxRegistration 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/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/doc/:doc_id/diff", 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('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/learn", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi @@ -327,10 +302,6 @@ module.exports = class Router CompileManager.compile project_id, user._id, opts, (error, status, 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)-> AuthorizationManager.ensureClientCanEditProject client, (error, project_id) => EditorController.getListOfDocPaths project_id, callback diff --git a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee index 755dc2e960..cccae79394 100644 --- a/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Editor/EditorControllerTests.coffee @@ -38,9 +38,6 @@ describe "EditorController", -> findPopulatedById: sinon.stub().callsArgWith(1, null, @project) @LimitationsManager = {} @AuthorizationManager = {} - @AutomaticSnapshotManager = {} - @VersioningApiHandler = - enableVersioning : sinon.stub().callsArg(1) @client = new MockClient() @settings = @@ -69,8 +66,6 @@ describe "EditorController", -> '../DocumentUpdater/DocumentUpdaterHandler' : @DocumentUpdaterHandler '../Subscription/LimitationsManager' : @LimitationsManager '../Security/AuthorizationManager' : @AuthorizationManager - "../Versioning/AutomaticSnapshotManager" : @AutomaticSnapshotManager - "../Versioning/VersioningApiHandler" : @VersioningApiHandler '../../models/Project' : Project: @Project "settings-sharelatex":@settings '../Dropbox/DropboxProjectLinker':@dropboxProjectLinker diff --git a/services/web/test/UnitTests/coffee/Editor/EditorUpdatesControllerTests.coffee b/services/web/test/UnitTests/coffee/Editor/EditorUpdatesControllerTests.coffee index 1d7f519168..befc9a2c0a 100644 --- a/services/web/test/UnitTests/coffee/Editor/EditorUpdatesControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Editor/EditorUpdatesControllerTests.coffee @@ -15,7 +15,6 @@ describe "EditorUpdatesController", -> "logger-sharelatex": @logger = { error: sinon.stub(), log: sinon.stub() } "./EditorRealTimeController" : @EditorRealTimeController = {} "../DocumentUpdater/DocumentUpdaterHandler" : @DocumentUpdaterHandler = {} - "../Versioning/AutomaticSnapshotManager" : @AutomaticSnapshotManager = {} "../../infrastructure/Metrics" : @metrics = { set: sinon.stub(), inc: sinon.stub() } "../../infrastructure/Server" : io: @io = {} "redis" : @@ -61,16 +60,6 @@ describe "EditorUpdatesController", -> it "should log an error", -> @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", -> beforeEach -> @client.id = "client-id" diff --git a/services/web/test/UnitTests/coffee/Project/ProjectCreationHandlerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectCreationHandlerTests.coffee index 891368c519..e9de417c02 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectCreationHandlerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectCreationHandlerTests.coffee @@ -16,7 +16,6 @@ describe 'ProjectCreationHandler', -> rootFolderId = "234adfa3r2afe" beforeEach -> - @versioningApiHandler={enableVersioning: sinon.stub().callsArg(1)} @ProjectModel = class Project constructor:(options = {})-> @._id = project_id @@ -47,7 +46,6 @@ describe 'ProjectCreationHandler', -> '../../models/User': User:@User '../../models/Project':{Project:@ProjectModel} '../../models/Folder':{Folder:@FolderModel} - '../Versioning/VersioningApiHandler':@versioningApiHandler './ProjectEntityHandler':@ProjectEntityHandler 'logger-sharelatex': {log:->} @@ -68,11 +66,6 @@ describe 'ProjectCreationHandler', -> (project.owner_ref + "").should.equal ownerId 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)-> @handler.createBlankProject ownerId, projectName, (err, project)-> project.spellCheckLanguage.should.equal "de" @@ -86,12 +79,6 @@ describe 'ProjectCreationHandler', -> it 'should return the error to the callback', -> 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', -> beforeEach -> @project = new @ProjectModel() diff --git a/services/web/test/UnitTests/coffee/Project/ProjectDeleterTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectDeleterTests.coffee index b9f7d9d09e..8963f0d2a2 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectDeleterTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectDeleterTests.coffee @@ -22,8 +22,6 @@ describe 'Project deleter', -> applyToAllFilesRecursivly: sinon.stub() @documentUpdaterHandler = flushProjectToMongoAndDelete:sinon.stub().callsArgWith(1) - @AutomaticSnapshotManager = - unmarkProjectAsUpdated:sinon.stub().callsArgWith(1) @editorController = notifyUsersProjectHasBeenDeletedOrRenamed : sinon.stub().callsArgWith(1) @TagsHandler = removeProjectFromAllTags: sinon.stub().callsArgWith(2) @@ -31,7 +29,6 @@ describe 'Project deleter', -> "../Editor/EditorController": @editorController '../../models/Project':{Project:@Project} '../DocumentUpdater/DocumentUpdaterHandler': @documentUpdaterHandler - '../Versioning/AutomaticSnapshotManager':@AutomaticSnapshotManager "../Tags/TagsHandler":@TagsHandler 'logger-sharelatex': log:-> diff --git a/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsPollingBackgroundTasksTests.coffee b/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsPollingBackgroundTasksTests.coffee index 4b509b5d41..83be12ff64 100644 --- a/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsPollingBackgroundTasksTests.coffee +++ b/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsPollingBackgroundTasksTests.coffee @@ -3,7 +3,6 @@ assert = require('assert') require('chai').should() sinon = require('sinon') modulePath = require('path').join __dirname, '../../../../app/js/Features/ThirdPartyDataStore/TpdsPollingBackgroundTasks.js' -redisKeys = require('../../../../app/js/Features/Versioning/RedisKeys') describe 'third party data store', -> beforeEach -> diff --git a/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsUpdateHandlerTests.coffee b/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsUpdateHandlerTests.coffee index 5a92c82d63..3a6e31809f 100644 --- a/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsUpdateHandlerTests.coffee +++ b/services/web/test/UnitTests/coffee/ThirdPartyDataStore/TpdsUpdateHandlerTests.coffee @@ -6,7 +6,6 @@ modulePath = require('path').join __dirname, '../../../../app/js/Features/ThirdP describe 'third party data store reciver :', -> beforeEach -> @requestQueuer = {} - @versioningApiHandler = {takeSnapshot:(_, message, sl_req_id, cb)->cb()} @updateMerger = deleteUpdate: (user_id, path, 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)} @rootDocManager = setRootDocAutomatically:sinon.stub() @handler = SandboxedModule.require modulePath, requires: - '../Versioning/VersioningApiHandler':@versioningApiHandler './UpdateMerger': @updateMerger './Editor/EditorController': @editorController '../Project/ProjectLocator': @projectLocator @@ -30,15 +28,6 @@ describe 'third party data store reciver :', -> @user_id = "dsad29jlkjas" 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)-> path = "/path/here" update = {} @@ -68,16 +57,6 @@ describe 'third party data store reciver :', -> 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)-> path = "/delete/this" update = {} diff --git a/services/web/test/UnitTests/coffee/Versioning/AutomaticSnapshotManagerTests.coffee b/services/web/test/UnitTests/coffee/Versioning/AutomaticSnapshotManagerTests.coffee deleted file mode 100644 index 96d768762b..0000000000 --- a/services/web/test/UnitTests/coffee/Versioning/AutomaticSnapshotManagerTests.coffee +++ /dev/null @@ -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 - diff --git a/services/web/test/UnitTests/coffee/Versioning/VersioningApiControllerTests.coffee b/services/web/test/UnitTests/coffee/Versioning/VersioningApiControllerTests.coffee deleted file mode 100644 index beea08de36..0000000000 --- a/services/web/test/UnitTests/coffee/Versioning/VersioningApiControllerTests.coffee +++ /dev/null @@ -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 diff --git a/services/web/test/UnitTests/coffee/Versioning/VersioningApiHandlerTests.coffee b/services/web/test/UnitTests/coffee/Versioning/VersioningApiHandlerTests.coffee deleted file mode 100644 index 25c4ab092c..0000000000 --- a/services/web/test/UnitTests/coffee/Versioning/VersioningApiHandlerTests.coffee +++ /dev/null @@ -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 -