mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-02 05:41:33 +02:00
Implement restore end point with acceptance tests
This commit is contained in:
@@ -3,6 +3,8 @@ Path = require 'path'
|
||||
FileWriter = require '../../infrastructure/FileWriter'
|
||||
FileSystemImportManager = require '../Uploads/FileSystemImportManager'
|
||||
ProjectLocator = require '../Project/ProjectLocator'
|
||||
Errors = require '../Errors/Errors'
|
||||
moment = require 'moment'
|
||||
|
||||
module.exports = RestoreManager =
|
||||
restoreFile: (user_id, project_id, version, pathname, callback = (error) ->) ->
|
||||
@@ -12,18 +14,41 @@ module.exports = RestoreManager =
|
||||
dirname = Path.dirname(pathname)
|
||||
if dirname == '.' # no directory
|
||||
dirname = ''
|
||||
ProjectLocator.findElementByPath {project_id, path: dirname}, (error, element, type) ->
|
||||
RestoreManager._findFolderOrRootFolderId project_id, dirname, (error, parent_folder_id) ->
|
||||
return callback(error) if error?
|
||||
# We're going to try to recover the file into the folder it was in previously,
|
||||
# but this is historical, so the folder may not exist anymore. Fallback to the
|
||||
# root folder if not (parent_folder_id == null will default to this)
|
||||
if type == 'folder' and element?
|
||||
parent_folder_id = element._id
|
||||
RestoreManager._addEntityWithUniqueName user_id, project_id, parent_folder_id, basename, fsPath, callback
|
||||
|
||||
_findFolderOrRootFolderId: (project_id, dirname, callback = (error, folder_id) ->) ->
|
||||
# We're going to try to recover the file into the folder it was in previously,
|
||||
# but this is historical, so the folder may not exist anymore. Fallback to the
|
||||
# root folder if not (folder_id == null)
|
||||
ProjectLocator.findElementByPath {project_id, path: dirname}, (error, element, type) ->
|
||||
if error? and not error instanceof Errors.NotFoundError
|
||||
return callback(error)
|
||||
if type == 'folder' and element?
|
||||
return callback(null, element._id)
|
||||
else
|
||||
return callback(null, null)
|
||||
|
||||
_addEntityWithUniqueName: (user_id, project_id, parent_folder_id, basename, fsPath, callback = (error) ->) ->
|
||||
FileSystemImportManager.addEntity user_id, project_id, parent_folder_id, basename, fsPath, false, (error, entity) ->
|
||||
if error?
|
||||
console.log "ERROR", error, error instanceof Errors.InvalidNameError
|
||||
if error instanceof Errors.InvalidNameError
|
||||
# likely a duplicate name, so try with a prefix
|
||||
date = moment(new Date()).format('Do MMM YY H:mm:ss')
|
||||
# Move extension to the end so the file type is preserved
|
||||
extension = Path.extname(basename)
|
||||
basename = Path.basename(basename, extension)
|
||||
basename = "#{basename} (Restored on #{date})"
|
||||
if extension != ''
|
||||
basename = "#{basename}#{extension}"
|
||||
FileSystemImportManager.addEntity user_id, project_id, parent_folder_id, basename, fsPath, false, callback
|
||||
else
|
||||
parent_folder_id = null
|
||||
# TODO if we get a name conflict error from here, then retry with a timestamp appended
|
||||
FileSystemImportManager.addEntity user_id, project_id, parent_folder_id, basename, fsPath, false, callback
|
||||
callback(error)
|
||||
else
|
||||
callback()
|
||||
|
||||
_writeFileVersionToDisk: (project_id, version, pathname, callback = (error, fsPath) ->) ->
|
||||
url = "#{Settings.apis.project_history.url}/project/#{project_id}/version/#{version}/#{pathname}"
|
||||
url = "#{Settings.apis.project_history.url}/project/#{project_id}/version/#{version}/#{encodeURIComponent(pathname)}"
|
||||
FileWriter.writeUrlToDisk project_id, url, callback
|
||||
@@ -21,7 +21,7 @@ describe "LinkedFiles", ->
|
||||
before (done) ->
|
||||
LinkedUrlProxy.listen 6543, (error) =>
|
||||
return done(error) if error?
|
||||
@owner = new User()
|
||||
@owner = new User()
|
||||
@owner.login done
|
||||
|
||||
describe "creating a URL based linked file", ->
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
async = require "async"
|
||||
expect = require("chai").expect
|
||||
_ = require 'underscore'
|
||||
|
||||
ProjectGetter = require "../../../app/js/Features/Project/ProjectGetter.js"
|
||||
|
||||
User = require "./helpers/User"
|
||||
MockProjectHistoryApi = require "./helpers/MockProjectHistoryApi"
|
||||
MockDocstoreApi = require "./helpers/MockDocstoreApi"
|
||||
MockFileStoreApi = require "./helpers/MockFileStoreApi"
|
||||
|
||||
describe "RestoringFiles", ->
|
||||
before (done) ->
|
||||
@@ -30,7 +32,7 @@ describe "RestoringFiles", ->
|
||||
expect(response.statusCode).to.equal 204
|
||||
done()
|
||||
|
||||
it "should have created a doc", ->
|
||||
it "should have created a doc", (done) ->
|
||||
@owner.getProject @project_id, (error, project) =>
|
||||
throw error if error?
|
||||
doc = _.find project.rootFolder[0].docs, (doc) ->
|
||||
@@ -42,10 +44,111 @@ describe "RestoringFiles", ->
|
||||
done()
|
||||
|
||||
describe "restoring a binary file", ->
|
||||
it "should have created a file"
|
||||
beforeEach (done) ->
|
||||
MockProjectHistoryApi.addOldFile(@project_id, 42, "image.png", "Mock image.png content")
|
||||
@owner.request {
|
||||
method: "POST",
|
||||
url: "/project/#{@project_id}/restore_file",
|
||||
json:
|
||||
pathname: "image.png"
|
||||
version: 42
|
||||
}, (error, response, body) ->
|
||||
throw error if error?
|
||||
expect(response.statusCode).to.equal 204
|
||||
done()
|
||||
|
||||
it "should have created a file", (done) ->
|
||||
@owner.getProject @project_id, (error, project) =>
|
||||
throw error if error?
|
||||
file = _.find project.rootFolder[0].fileRefs, (file) ->
|
||||
file.name == 'image.png'
|
||||
file = MockFileStoreApi.files[@project_id][file._id]
|
||||
expect(file.content).to.equal "Mock image.png content"
|
||||
done()
|
||||
|
||||
describe "restoring to a directory that exists", ->
|
||||
beforeEach (done) ->
|
||||
MockProjectHistoryApi.addOldFile(@project_id, 42, "foldername/foo2.tex", "hello world, this is foo-2.tex!")
|
||||
@owner.request.post {
|
||||
uri: "project/#{@project_id}/folder",
|
||||
json:
|
||||
name: 'foldername'
|
||||
}, (error, response, body) =>
|
||||
throw error if error?
|
||||
expect(response.statusCode).to.equal 200
|
||||
@owner.request {
|
||||
method: "POST",
|
||||
url: "/project/#{@project_id}/restore_file",
|
||||
json:
|
||||
pathname: "foldername/foo2.tex"
|
||||
version: 42
|
||||
}, (error, response, body) ->
|
||||
throw error if error?
|
||||
expect(response.statusCode).to.equal 204
|
||||
done()
|
||||
|
||||
it "should have created the doc in the named folder", (done) ->
|
||||
@owner.getProject @project_id, (error, project) =>
|
||||
throw error if error?
|
||||
folder = _.find project.rootFolder[0].folders, (folder) ->
|
||||
folder.name == 'foldername'
|
||||
doc = _.find folder.docs, (doc) ->
|
||||
doc.name == 'foo2.tex'
|
||||
doc = MockDocstoreApi.docs[@project_id][doc._id]
|
||||
expect(doc.lines).to.deep.equal [
|
||||
"hello world, this is foo-2.tex!"
|
||||
]
|
||||
done()
|
||||
|
||||
describe "restoring to a directory that no longer exists", ->
|
||||
it "should have created the file in the root folder"
|
||||
beforeEach (done) ->
|
||||
MockProjectHistoryApi.addOldFile(@project_id, 42, "nothere/foo3.tex", "hello world, this is foo-3.tex!")
|
||||
@owner.request {
|
||||
method: "POST",
|
||||
url: "/project/#{@project_id}/restore_file",
|
||||
json:
|
||||
pathname: "nothere/foo3.tex"
|
||||
version: 42
|
||||
}, (error, response, body) ->
|
||||
throw error if error?
|
||||
expect(response.statusCode).to.equal 204
|
||||
done()
|
||||
|
||||
it "should have created the doc in the root folder", (done) ->
|
||||
@owner.getProject @project_id, (error, project) =>
|
||||
throw error if error?
|
||||
doc = _.find project.rootFolder[0].docs, (doc) ->
|
||||
doc.name == 'foo3.tex'
|
||||
doc = MockDocstoreApi.docs[@project_id][doc._id]
|
||||
expect(doc.lines).to.deep.equal [
|
||||
"hello world, this is foo-3.tex!"
|
||||
]
|
||||
done()
|
||||
|
||||
describe "restoring to a filename that already exists", ->
|
||||
it "should have created the file with a timestamp appended"
|
||||
it "should have created the file with a timestamp appended", ->
|
||||
beforeEach (done) ->
|
||||
MockProjectHistoryApi.addOldFile(@project_id, 42, "main.tex", "hello world, this is main.tex!")
|
||||
@owner.request {
|
||||
method: "POST",
|
||||
url: "/project/#{@project_id}/restore_file",
|
||||
json:
|
||||
pathname: "main.tex"
|
||||
version: 42
|
||||
}, (error, response, body) ->
|
||||
throw error if error?
|
||||
expect(response.statusCode).to.equal 204
|
||||
done()
|
||||
|
||||
it "should have created the doc in the root folder", (done) ->
|
||||
@owner.getProject @project_id, (error, project) =>
|
||||
throw error if error?
|
||||
doc = _.find project.rootFolder[0].docs, (doc) ->
|
||||
doc.name.match(/main \(Restored on/)
|
||||
expect(doc).to.exist
|
||||
doc = MockDocstoreApi.docs[@project_id][doc._id]
|
||||
expect(doc.lines).to.deep.equal [
|
||||
"hello world, this is main.tex!"
|
||||
]
|
||||
done()
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ module.exports = MockProjectHistoryApi =
|
||||
app.get "/project/:project_id/version/:version/:pathname", (req, res, next) =>
|
||||
{project_id, version, pathname} = req.params
|
||||
key = "#{project_id}:#{version}:#{pathname}"
|
||||
console.log key, @oldFiles, @oldFiles[key]
|
||||
if @oldFiles[key]?
|
||||
res.send @oldFiles[key]
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user