mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
added inactive and reactivate project logic
This commit is contained in:
parent
04d3e527d6
commit
a0142d4415
10 changed files with 303 additions and 2 deletions
|
@ -67,3 +67,31 @@ module.exports = DocstoreManager =
|
|||
error = new Error("docstore api responded with non-success code: #{res.statusCode}")
|
||||
logger.error err: error, project_id: project_id, doc_id: doc_id, "error updating doc in docstore"
|
||||
callback(error)
|
||||
|
||||
archiveProject: (project_id, callback)->
|
||||
url = "#{settings.apis.docstore.url}/project/#{project_id}/archive"
|
||||
logger.log project_id:project_id, "archiving project in docstore"
|
||||
request.post url, (err, res, docs) ->
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, "error archving project in docstore"
|
||||
return callback(err)
|
||||
if 200 <= res.statusCode < 300
|
||||
callback()
|
||||
else
|
||||
error = new Error("docstore api responded with non-success code: #{res.statusCode}")
|
||||
logger.err err: error, project_id: project_id, "error archiving project in docstore"
|
||||
return callback(error)
|
||||
|
||||
unarchiveProject: (project_id, callback)->
|
||||
url = "#{settings.apis.docstore.url}/project/#{project_id}/unarchive"
|
||||
logger.log project_id:project_id, "unarchiving project in docstore"
|
||||
request.post url, (err, res, docs) ->
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, "error unarchiving project in docstore"
|
||||
return callback(err)
|
||||
if 200 <= res.statusCode < 300
|
||||
callback()
|
||||
else
|
||||
error = new Error("docstore api responded with non-success code: #{res.statusCode}")
|
||||
logger.err err: error, project_id: project_id, "error unarchiving project in docstore"
|
||||
return callback(error)
|
|
@ -0,0 +1,11 @@
|
|||
InactiveProjectManager = require("./InactiveProjectManager")
|
||||
|
||||
module.exports =
|
||||
|
||||
deactivateOldProjects: (req, res)->
|
||||
InactiveProjectManager.deactivateOldProjects 10, (err)->
|
||||
if err?
|
||||
res.sendStatus(500)
|
||||
else
|
||||
res.sendStatus(200)
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
async = require("async")
|
||||
_ = require("lodash")
|
||||
logger = require("logger-sharelatex")
|
||||
DocstoreManager = require("../Docstore/DocstoreManager")
|
||||
ProjectGetter = require("../Project/ProjectGetter")
|
||||
ProjectUpdateHandler = require("../Project/ProjectUpdateHandler")
|
||||
Project = require("../../models/Project").Project
|
||||
|
||||
MILISECONDS_IN_DAY = 86400000
|
||||
module.exports = InactiveProjectManager =
|
||||
|
||||
reactivateProjectIfRequired: (project_id, callback)->
|
||||
ProjectGetter.getProject project_id, {inactive:true}, (err, project)->
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, "error getting project"
|
||||
return callback(err)
|
||||
logger.log project_id:project_id, inactive:project.inactive, "seeing if need to reactivate project"
|
||||
|
||||
if !project.inactive
|
||||
return callback()
|
||||
|
||||
DocstoreManager.unarchiveProject project_id, (err)->
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, "error reactivating project in docstore"
|
||||
return callback(err)
|
||||
ProjectUpdateHandler.markAsActive project_id, callback
|
||||
|
||||
deactivateOldProjects: (limit, callback)->
|
||||
|
||||
sixMonthsAgo = new Date() - (MILISECONDS_IN_DAY * 1)
|
||||
Project.find()
|
||||
.where("lastOpened").lt(sixMonthsAgo)
|
||||
.where("inactive").ne(true)
|
||||
.select("_id")
|
||||
.limit(limit)
|
||||
.exec (err, projects)->
|
||||
if err?
|
||||
logger.err err:err, "could not get projects for deactivating"
|
||||
jobs = _.map projects, (project)->
|
||||
return (cb)->
|
||||
InactiveProjectManager.deactivateProject project._id, cb
|
||||
logger.log numberOfProjects:projects?.length, "deactivating projects"
|
||||
async.series jobs, callback
|
||||
|
||||
|
||||
deactivateProject: (project_id, callback)->
|
||||
logger.log project_id:project_id, "deactivating inactive project"
|
||||
DocstoreManager.archiveProject project_id, (err)->
|
||||
if err?
|
||||
logger.err err:err, project_id:project_id, "error deactivating project in docstore"
|
||||
return callback(err)
|
||||
ProjectUpdateHandler.markAsInactive project_id, callback
|
||||
|
|
@ -14,6 +14,8 @@ _ = require("underscore")
|
|||
Settings = require("settings-sharelatex")
|
||||
SecurityManager = require("../../managers/SecurityManager")
|
||||
fs = require "fs"
|
||||
InactiveProjectManager = require("../InactiveData/InactiveProjectManager")
|
||||
ProjectUpdateHandler = require("./ProjectUpdateHandler")
|
||||
|
||||
module.exports = ProjectController =
|
||||
|
||||
|
@ -189,6 +191,10 @@ module.exports = ProjectController =
|
|||
if user_id == 'openUser'
|
||||
return cb()
|
||||
SubscriptionLocator.getUsersSubscription user_id, cb
|
||||
activate: (cb)->
|
||||
InactiveProjectManager.reactivateProjectIfRequired project_id, cb
|
||||
markOpened: (cb)->
|
||||
ProjectUpdateHandler.markOpened project_id, cb
|
||||
}, (err, results)->
|
||||
if err?
|
||||
logger.err err:err, "error getting details for project page"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
Project = require('../../models/Project').Project
|
||||
logger = require('logger-sharelatex')
|
||||
Project = require("../../models/Project").Project
|
||||
|
||||
module.exports =
|
||||
markAsUpdated : (project_id, callback)->
|
||||
|
@ -8,3 +9,24 @@ module.exports =
|
|||
Project.update conditions, update, {}, (err)->
|
||||
if callback?
|
||||
callback()
|
||||
|
||||
markAsOpened : (project_id, callback)->
|
||||
conditions = {_id:project_id}
|
||||
update = {lastOpened:Date.now()}
|
||||
Project.update conditions, update, {}, (err)->
|
||||
if callback?
|
||||
callback()
|
||||
|
||||
markAsInactive: (project_id, callback)->
|
||||
conditions = {_id:project_id}
|
||||
update = {inactive:true}
|
||||
Project.update conditions, update, {}, (err)->
|
||||
if callback?
|
||||
callback()
|
||||
|
||||
markAsActive: (project_id, callback)->
|
||||
conditions = {_id:project_id}
|
||||
update = { $unset: { inactive: true }}
|
||||
Project.update conditions, update, {}, (err)->
|
||||
if callback?
|
||||
callback()
|
|
@ -17,6 +17,8 @@ DeletedDocSchema = new Schema
|
|||
ProjectSchema = new Schema
|
||||
name : {type:String, default:'new project'}
|
||||
lastUpdated : {type:Date, default: () -> new Date()}
|
||||
lastOpened : {type:Date}
|
||||
inactive : { type: Boolean }
|
||||
owner_ref : {type:ObjectId, ref:'User'}
|
||||
collaberator_refs : [ type:ObjectId, ref:'User' ]
|
||||
readOnly_refs : [ type:ObjectId, ref:'User' ]
|
||||
|
|
|
@ -13,7 +13,7 @@ describe "DocstoreManager", ->
|
|||
apis:
|
||||
docstore:
|
||||
url: "docstore.sharelatex.com"
|
||||
"logger-sharelatex": @logger = {log: sinon.stub(), error: sinon.stub()}
|
||||
"logger-sharelatex": @logger = {log: sinon.stub(), error: sinon.stub(), err:->}
|
||||
|
||||
@requestDefaults.calledWith(jar: false).should.equal true
|
||||
|
||||
|
@ -179,3 +179,42 @@ describe "DocstoreManager", ->
|
|||
project_id: @project_id
|
||||
}, "error getting all docs from docstore")
|
||||
.should.equal true
|
||||
|
||||
|
||||
describe "archiveProject", ->
|
||||
describe "with a successful response code", ->
|
||||
beforeEach ->
|
||||
@request.post = sinon.stub().callsArgWith(1, null, statusCode: 204)
|
||||
@DocstoreManager.archiveProject @project_id, @callback
|
||||
|
||||
it "should call the callback", ->
|
||||
@callback.called.should.equal true
|
||||
|
||||
describe "with a failed response code", ->
|
||||
beforeEach ->
|
||||
@request.post = sinon.stub().callsArgWith(1, null, statusCode: 500)
|
||||
@DocstoreManager.archiveProject @project_id, @callback
|
||||
|
||||
it "should call the callback with an error", ->
|
||||
@callback.calledWith(new Error("docstore api responded with non-success code: 500")).should.equal true
|
||||
|
||||
|
||||
|
||||
describe "unarchiveProject", ->
|
||||
describe "with a successful response code", ->
|
||||
beforeEach ->
|
||||
@request.post = sinon.stub().callsArgWith(1, null, statusCode: 204)
|
||||
@DocstoreManager.unarchiveProject @project_id, @callback
|
||||
|
||||
it "should call the callback", ->
|
||||
@callback.called.should.equal true
|
||||
|
||||
describe "with a failed response code", ->
|
||||
beforeEach ->
|
||||
@request.post = sinon.stub().callsArgWith(1, null, statusCode: 500)
|
||||
@DocstoreManager.unarchiveProject @project_id, @callback
|
||||
|
||||
it "should call the callback with an error", ->
|
||||
@callback.calledWith(new Error("docstore api responded with non-success code: 500")).should.equal true
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
should = require('chai').should()
|
||||
SandboxedModule = require('sandboxed-module')
|
||||
assert = require('assert')
|
||||
path = require('path')
|
||||
sinon = require('sinon')
|
||||
modulePath = path.join __dirname, "../../../../app/js/Features/InactiveData/InactiveProjectManager"
|
||||
expect = require("chai").expect
|
||||
|
||||
describe "InactiveProjectManager", ->
|
||||
|
||||
beforeEach ->
|
||||
|
||||
@settings = {}
|
||||
@DocstoreManager =
|
||||
unarchiveProject:sinon.stub()
|
||||
@ProjectUpdateHandler =
|
||||
markAsActive:sinon.stub()
|
||||
markAsInactive:sinon.stub()
|
||||
@ProjectGetter =
|
||||
getProject:sinon.stub()
|
||||
@InactiveProjectManager = SandboxedModule.require modulePath, requires:
|
||||
"settings-sharelatex":@settings
|
||||
"logger-sharelatex":
|
||||
log:->
|
||||
err:->
|
||||
"../Docstore/DocstoreManager":@DocstoreManager
|
||||
"../Project/ProjectUpdateHandler":@ProjectUpdateHandler
|
||||
"../Project/ProjectGetter":@ProjectGetter
|
||||
|
||||
@project_id = "1234"
|
||||
|
||||
describe "reactivateProjectIfRequired", ->
|
||||
|
||||
beforeEach ->
|
||||
@project = {inactive:true}
|
||||
@ProjectGetter.getProject.callsArgWith(2, null, @project)
|
||||
@ProjectUpdateHandler.markAsActive.callsArgWith(1)
|
||||
|
||||
it "should call unarchiveProject", (done)->
|
||||
@DocstoreManager.unarchiveProject.callsArgWith(1)
|
||||
@InactiveProjectManager.reactivateProjectIfRequired @project_id, (err)=>
|
||||
@DocstoreManager.unarchiveProject.calledWith(@project_id).should.equal true
|
||||
@ProjectUpdateHandler.markAsActive.calledWith(@project_id).should.equal true
|
||||
done()
|
||||
|
||||
it "should not mark project as active if error with unarchinging", (done)->
|
||||
@DocstoreManager.unarchiveProject.callsArgWith(1, "error")
|
||||
@InactiveProjectManager.reactivateProjectIfRequired @project_id, (err)=>
|
||||
err.should.equal "error"
|
||||
@DocstoreManager.unarchiveProject.calledWith(@project_id).should.equal true
|
||||
@ProjectUpdateHandler.markAsActive.calledWith(@project_id).should.equal false
|
||||
done()
|
||||
|
||||
|
||||
it "should not call unarchiveProject if it is not inactive", (done)->
|
||||
delete @project.inactive
|
||||
@DocstoreManager.unarchiveProject.callsArgWith(1)
|
||||
@InactiveProjectManager.reactivateProjectIfRequired @project_id, (err)=>
|
||||
@DocstoreManager.unarchiveProject.calledWith(@project_id).should.equal false
|
||||
@ProjectUpdateHandler.markAsActive.calledWith(@project_id).should.equal false
|
||||
done()
|
||||
|
||||
|
||||
describe "deactivateProject", ->
|
||||
|
||||
beforeEach ->
|
||||
|
||||
it "should call unarchiveProject and markAsInactive", (done)->
|
||||
@DocstoreManager.unarchiveProject.callsArgWith(1)
|
||||
@ProjectUpdateHandler.markAsInactive.callsArgWith(1)
|
||||
|
||||
@InactiveProjectManager.deactivateProject @project_id, (err)->
|
||||
@DocstoreManager.unarchiveProject.calledWith(@project_id).should.equal true
|
||||
@ProjectUpdateHandler.markAsInactive.callsArgWith(@project_id).should.equal true
|
||||
done()
|
||||
|
||||
it "should not call markAsInactive if there was a problem unarchiving", (done)->
|
||||
@DocstoreManager.unarchiveProject.callsArgWith(1, "errorrr")
|
||||
@ProjectUpdateHandler.markAsInactive.callsArgWith(1)
|
||||
|
||||
@InactiveProjectManager.deactivateProject @project_id, (err)->
|
||||
err.should.equal "errorrr"
|
||||
@DocstoreManager.unarchiveProject.calledWith(@project_id).should.equal true
|
||||
@ProjectUpdateHandler.markAsInactive.callsArgWith(@project_id).should.equal false
|
||||
done()
|
|
@ -42,6 +42,10 @@ describe "ProjectController", ->
|
|||
userCanAccessProject:sinon.stub()
|
||||
@EditorController =
|
||||
renameProject:sinon.stub()
|
||||
@InactiveProjectManager =
|
||||
reactivateProjectIfRequired:sinon.stub()
|
||||
@ProjectUpdateHandler =
|
||||
markOpened: sinon.stub()
|
||||
@ProjectController = SandboxedModule.require modulePath, requires:
|
||||
"settings-sharelatex":@settings
|
||||
"logger-sharelatex":
|
||||
|
@ -57,6 +61,8 @@ describe "ProjectController", ->
|
|||
'../../models/Project': Project:@ProjectModel
|
||||
"../../models/User":User:@UserModel
|
||||
"../../managers/SecurityManager":@SecurityManager
|
||||
"../InactiveData/InactiveProjectManager":@InactiveProjectManager
|
||||
"./ProjectUpdateHandler":@ProjectUpdateHandler
|
||||
|
||||
@user =
|
||||
_id:"!£123213kjljkl"
|
||||
|
@ -282,6 +288,9 @@ describe "ProjectController", ->
|
|||
@SubscriptionLocator.getUsersSubscription.callsArgWith(1, null, {})
|
||||
@SecurityManager.userCanAccessProject.callsArgWith 2, true, "owner"
|
||||
@ProjectDeleter.unmarkAsDeletedByExternalSource = sinon.stub()
|
||||
@InactiveProjectManager.reactivateProjectIfRequired.callsArgWith(1)
|
||||
@ProjectUpdateHandler.markOpened.callsArgWith(1)
|
||||
|
||||
|
||||
it "should render the project/editor page", (done)->
|
||||
@res.render = (pageName, opts)=>
|
||||
|
@ -321,3 +330,16 @@ describe "ProjectController", ->
|
|||
resCode.should.equal 401
|
||||
done()
|
||||
@ProjectController.loadEditor @req, @res
|
||||
|
||||
it "should reactivateProjectIfRequired", (done)->
|
||||
@res.render = (pageName, opts)=>
|
||||
@InactiveProjectManager.reactivateProjectIfRequired.calledWith(@project_id).should.equal true
|
||||
done()
|
||||
@ProjectController.loadEditor @req, @res
|
||||
|
||||
it "should mark project as opened", (done)->
|
||||
@res.render = (pageName, opts)=>
|
||||
@ProjectUpdateHandler.markOpened.calledWith(@project_id).should.equal true
|
||||
done()
|
||||
@ProjectController.loadEditor @req, @res
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ chai = require('chai').should()
|
|||
modulePath = "../../../../app/js/Features/Project/ProjectUpdateHandler.js"
|
||||
SandboxedModule = require('sandboxed-module')
|
||||
|
||||
describe 'updating a project', ->
|
||||
describe 'ProjectUpdateHandler', ->
|
||||
|
||||
|
||||
beforeEach ->
|
||||
|
@ -22,3 +22,36 @@ describe 'updating a project', ->
|
|||
now = Date.now()+""
|
||||
date.substring(0,5).should.equal now.substring(0,5)
|
||||
done()
|
||||
|
||||
describe "markAsOpened", ->
|
||||
|
||||
it 'should send an update to mongo', (done)->
|
||||
project_id = "project_id"
|
||||
@handler.markAsOpened project_id, (err)=>
|
||||
args = @ProjectModel.update.args[0]
|
||||
args[0]._id.should.equal project_id
|
||||
date = args[1].lastOpened+""
|
||||
now = Date.now()+""
|
||||
date.substring(0,5).should.equal now.substring(0,5)
|
||||
done()
|
||||
|
||||
describe "markAsInactive", ->
|
||||
|
||||
it 'should send an update to mongo', (done)->
|
||||
project_id = "project_id"
|
||||
@handler.markAsInactive project_id, (err)=>
|
||||
args = @ProjectModel.update.args[0]
|
||||
args[0]._id.should.equal project_id
|
||||
args[1].inactive.should.equal true
|
||||
done()
|
||||
|
||||
describe "markAsActive", ->
|
||||
it 'should send an update to mongo', (done)->
|
||||
project_id = "project_id"
|
||||
@handler.markAsActive project_id, (err)=>
|
||||
args = @ProjectModel.update.args[0]
|
||||
args[0]._id.should.equal project_id
|
||||
args[1]["$unset"].inactive.should.equal true
|
||||
done()
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue