add in restore end point

This commit is contained in:
James Allen 2014-03-10 16:58:26 +00:00
parent 7eb8699b93
commit 83b2aa3082
10 changed files with 229 additions and 5 deletions

View file

@ -16,6 +16,8 @@ app.get "/project/:project_id/doc/:doc_id/diff", HttpController.getDiff
app.get "/project/:project_id/doc/:doc_id/updates", HttpController.getUpdates
app.post "/project/:project_id/doc/:doc_id/version/:version/restore", HttpController.restore
app.get "/status", (req, res, next) ->
res.send "track-changes is alive"

View file

@ -15,6 +15,23 @@ module.exports = DocumentUpdaterManager =
catch error
return callback(error)
callback null, body.lines.join("\n"), body.version
else
error = new Error("doc updater returned a non-success status code: #{res.statusCode}")
logger.error err: error, project_id:project_id, doc_id:doc_id, url: url, "error accessing doc updater"
callback error
setDocument: (project_id, doc_id, content, callback = (error) ->) ->
url = "#{Settings.apis.documentupdater.url}/project/#{project_id}/doc/#{doc_id}"
logger.log project_id:project_id, doc_id: doc_id, "setting doc in document updater"
request.post {
url: url
json:
lines: content.split("\n")
}, (error, res, body)->
if error?
return callback(error)
if res.statusCode >= 200 and res.statusCode < 300
callback null
else
error = new Error("doc updater returned a non-success status code: #{res.statusCode}")
logger.error err: error, project_id:project_id, doc_id:doc_id, url: url, "error accessing doc updater"

View file

@ -1,5 +1,6 @@
UpdatesManager = require "./UpdatesManager"
DiffManager = require "./DiffManager"
RestoreManager = require "./RestoreManager"
logger = require "logger-sharelatex"
module.exports = HttpController =
@ -45,3 +46,10 @@ module.exports = HttpController =
v: update.v
}
res.send JSON.stringify updates: formattedUpdates
restore: (req, res, next = (error) ->) ->
{doc_id, project_id, version} = req.params
version = parseInt(version, 10)
RestoreManager.restoreToBeforeVersion project_id, doc_id, version, (error) ->
return next(error) if error?
res.send 204

View file

@ -0,0 +1,12 @@
DocumentUpdaterManager = require "./DocumentUpdaterManager"
DiffManager = require "./DiffManager"
logger = require "logger-sharelatex"
module.exports = RestoreManager =
restoreToBeforeVersion: (project_id, doc_id, version, callback = (error) ->) ->
logger.log project_id: project_id, doc_id: doc_id, version: version, "restoring document"
DiffManager.getDocumentBeforeVersion project_id, doc_id, version, (error, content) ->
return callback(error) if error?
DocumentUpdaterManager.setDocument project_id, doc_id, content, (error) ->
return callback(error) if error?
callback()

View file

@ -0,0 +1,67 @@
sinon = require "sinon"
chai = require("chai")
chai.should()
expect = chai.expect
mongojs = require "../../../app/js/mongojs"
db = mongojs.db
ObjectId = mongojs.ObjectId
Settings = require "settings-sharelatex"
TrackChangesClient = require "./helpers/TrackChangesClient"
MockDocUpdaterApi = require "./helpers/MockDocUpdaterApi"
MockWebApi = require "./helpers/MockWebApi"
describe "Restoring a version", ->
before (done) ->
sinon.spy MockDocUpdaterApi, "setDoc"
@now = Date.now()
@user_id = ObjectId().toString()
@doc_id = ObjectId().toString()
@project_id = ObjectId().toString()
minutes = 60 * 1000
@updates = [{
op: [{ i: "one ", p: 0 }]
meta: { ts: @now - 6 * minutes, user_id: @user_id }
v: 3
}, {
op: [{ i: "two ", p: 4 }]
meta: { ts: @now - 4 * minutes, user_id: @user_id }
v: 4
}, {
op: [{ i: "three ", p: 8 }]
meta: { ts: @now - 2 * minutes, user_id: @user_id }
v: 5
}, {
op: [{ i: "four", p: 14 }]
meta: { ts: @now, user_id: @user_id }
v: 6
}]
@lines = ["one two three four"]
@restored_lines = ["one two "]
@beforeVersion = 5
MockWebApi.users[@user_id] = @user =
email: "user@sharelatex.com"
first_name: "Leo"
last_name: "Lion"
id: @user_id
MockDocUpdaterApi.docs[@doc_id] =
lines: @lines
version: 7
TrackChangesClient.pushRawUpdates @doc_id, @updates, (error) =>
throw error if error?
TrackChangesClient.restoreDoc @project_id, @doc_id, @beforeVersion, (error) =>
throw error if error?
done()
after () ->
MockDocUpdaterApi.setDoc.restore()
it "should set the doc in the doc updater", ->
MockDocUpdaterApi.setDoc
.calledWith(@project_id, @doc_id, @restored_lines)
.should.equal true

View file

@ -7,6 +7,11 @@ module.exports = MockDocUpdaterApi =
getDoc: (project_id, doc_id, callback = (error) ->) ->
callback null, @docs[doc_id]
setDoc: (project_id, doc_id, lines, callback = (error) ->) ->
@docs[doc_id] ||= {}
@docs[doc_id].lines = lines
callback()
run: () ->
app.get "/project/:project_id/doc/:doc_id", (req, res, next) =>
@getDoc req.params.project_id, req.params.doc_id, (error, doc) ->
@ -17,6 +22,13 @@ module.exports = MockDocUpdaterApi =
else
res.send JSON.stringify doc
app.post "/project/:project_id/doc/:doc_id", express.bodyParser(), (req, res, next) =>
@setDoc req.params.project_id, req.params.doc_id, req.body.lines, (errr, doc) ->
if error?
res.send 500
else
res.send 204
app.listen 3003, (error) ->
throw error if error?

View file

@ -28,4 +28,11 @@ module.exports = TrackChangesClient =
url: "http://localhost:3015/project/#{project_id}/doc/#{doc_id}/updates?to=#{options.to}&limit=#{options.limit}"
}, (error, response, body) =>
response.statusCode.should.equal 200
callback null, JSON.parse(body)
callback null, JSON.parse(body)
restoreDoc: (project_id, doc_id, version, callback = (error) ->) ->
request.post {
url: "http://localhost:3015/project/#{project_id}/doc/#{doc_id}/version/#{version}/restore"
}, (error, response, body) =>
response.statusCode.should.equal 204
callback null

View file

@ -46,6 +46,45 @@ describe "DocumentUpdaterManager", ->
@request.get = sinon.stub().callsArgWith(1, null, { statusCode: 500 }, "")
@DocumentUpdaterManager.getDocument @project_id, @doc_id, @callback
it "should return the callback with an error", ->
@callback
.calledWith(new Error("doc updater returned failure status code: 500"))
.should.equal true
describe "setDocument", ->
beforeEach ->
@content = "mock content"
describe "successfully", ->
beforeEach ->
@request.post = sinon.stub().callsArgWith(1, null, {statusCode: 200})
@DocumentUpdaterManager.setDocument @project_id, @doc_id, @content, @callback
it 'should set the document in the document updater', ->
url = "#{@settings.apis.documentupdater.url}/project/#{@project_id}/doc/#{@doc_id}"
@request.post
.calledWith({
url: url
json:
lines: @content.split("\n")
}).should.equal true
it "should call the callback", ->
@callback.calledWith(null).should.equal true
describe "when the document updater API returns an error", ->
beforeEach ->
@request.post = sinon.stub().callsArgWith(1, @error = new Error("something went wrong"), null, null)
@DocumentUpdaterManager.setDocument @project_id, @doc_id, @content, @callback
it "should return an error to the callback", ->
@callback.calledWith(@error).should.equal true
describe "when the document updater returns a failure error code", ->
beforeEach ->
@request.post = sinon.stub().callsArgWith(1, null, { statusCode: 500 }, "")
@DocumentUpdaterManager.setDocument @project_id, @doc_id, @content, @callback
it "should return the callback with an error", ->
@callback
.calledWith(new Error("doc updater returned failure status code: 500"))

View file

@ -11,9 +11,9 @@ describe "HttpController", ->
"logger-sharelatex": { log: sinon.stub() }
"./UpdatesManager": @UpdatesManager = {}
"./DiffManager": @DiffManager = {}
"./RestoreManager": @RestoreManager = {}
@doc_id = "doc-id-123"
@project_id = "project-id-123"
@version = 42
@next = sinon.stub()
describe "flushUpdatesWithLock", ->
@ -36,8 +36,8 @@ describe "HttpController", ->
describe "getDiff", ->
beforeEach ->
@from = Date.now() - 10000
@to = Date.now()
@from = 42
@to = 45
@req =
params:
doc_id: @doc_id
@ -61,7 +61,7 @@ describe "HttpController", ->
describe "getUpdates", ->
beforeEach ->
@to = Date.now()
@to = 42
@limit = 10
@req =
params:
@ -93,3 +93,25 @@ describe "HttpController", ->
v: @v
}
@res.send.calledWith(JSON.stringify(updates: updates)).should.equal true
describe "RestoreManager", ->
beforeEach ->
@version = "42"
@req =
params:
doc_id: @doc_id
project_id: @project_id
version: @version
@res =
send: sinon.stub()
@RestoreManager.restoreToBeforeVersion = sinon.stub().callsArg(3)
@HttpController.restore @req, @res, @next
it "should restore the document", ->
@RestoreManager.restoreToBeforeVersion
.calledWith(@project_id, @doc_id, parseInt(@version, 10))
.should.equal true
it "should return a success code", ->
@res.send.calledWith(204).should.equal true

View file

@ -0,0 +1,38 @@
sinon = require('sinon')
chai = require('chai')
should = chai.should()
expect = chai.expect
modulePath = "../../../../app/js/RestoreManager.js"
SandboxedModule = require('sandboxed-module')
describe "RestoreManager", ->
beforeEach ->
@RestoreManager = SandboxedModule.require modulePath, requires:
"logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() }
"./DocumentUpdaterManager": @DocumentUpdaterManager = {}
"./DiffManager": @DiffManager = {}
@callback = sinon.stub()
@project_id = "mock-project-id"
@doc_id = "mock-doc-id"
@version = 42
describe "restoreToBeforeVersion", ->
beforeEach ->
@content = "mock content"
@DocumentUpdaterManager.setDocument = sinon.stub().callsArg(3)
@DiffManager.getDocumentBeforeVersion = sinon.stub().callsArgWith(3, null, @content)
@RestoreManager.restoreToBeforeVersion @project_id, @doc_id, @version, @callback
it "should get the content before the requested version", ->
@DiffManager.getDocumentBeforeVersion
.calledWith(@project_id, @doc_id, @version)
.should.equal true
it "should set the document in the document updater", ->
@DocumentUpdaterManager.setDocument
.calledWith(@project_id, @doc_id, @content)
.should.equal true
it "should call the callback", ->
@callback.called.should.equal true