|
|
@@ -1,28 +1,12 @@
|
|
|
-/* eslint-disable
|
|
|
- camelcase,
|
|
|
- handle-callback-err,
|
|
|
- max-len,
|
|
|
- no-unused-vars,
|
|
|
-*/
|
|
|
-// TODO: This file was created by bulk-decaffeinate.
|
|
|
-// Fix any style issues and re-enable lint.
|
|
|
-/*
|
|
|
- * decaffeinate suggestions:
|
|
|
- * DS102: Remove unnecessary code created because of implicit returns
|
|
|
- * DS207: Consider shorter variations of null checks
|
|
|
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
|
- */
|
|
|
-const async = require('async')
|
|
|
const { expect } = require('chai')
|
|
|
const _ = require('underscore')
|
|
|
const mkdirp = require('mkdirp')
|
|
|
+const { promisify } = require('util')
|
|
|
|
|
|
const Settings = require('settings-sharelatex')
|
|
|
-const MockFileStoreApi = require('./helpers/MockFileStoreApi')
|
|
|
-const request = require('./helpers/request')
|
|
|
-const User = require('./helpers/User')
|
|
|
-
|
|
|
-const MockClsiApi = require('./helpers/MockClsiApi')
|
|
|
+const User = require('./helpers/User').promises
|
|
|
+require('./helpers/MockFileStoreApi')
|
|
|
+require('./helpers/MockClsiApi')
|
|
|
|
|
|
const express = require('express')
|
|
|
const LinkedUrlProxy = express()
|
|
|
@@ -37,537 +21,336 @@ LinkedUrlProxy.get('/', (req, res, next) => {
|
|
|
})
|
|
|
|
|
|
describe('LinkedFiles', function() {
|
|
|
+ let projectOne, projectOneId, projectOneRootFolderId
|
|
|
+ let projectTwo, projectTwoId, projectTwoRootFolderId
|
|
|
+ let sourceDocName = 'test.txt'
|
|
|
+ let owner
|
|
|
+
|
|
|
before(function(done) {
|
|
|
- return LinkedUrlProxy.listen(6543, error => {
|
|
|
- if (error != null) {
|
|
|
- return done(error)
|
|
|
- }
|
|
|
- this.owner = new User()
|
|
|
- return this.owner.login(() => mkdirp(Settings.path.dumpFolder, done))
|
|
|
- })
|
|
|
+ LinkedUrlProxy.listen(6543, done)
|
|
|
+ })
|
|
|
+
|
|
|
+ beforeEach(async function() {
|
|
|
+ owner = new User()
|
|
|
+ await owner.login()
|
|
|
+ await promisify(mkdirp)(Settings.path.dumpFolder)
|
|
|
})
|
|
|
|
|
|
describe('creating a project linked file', function() {
|
|
|
- before(function(done) {
|
|
|
- this.source_doc_name = 'test.txt'
|
|
|
- return async.series(
|
|
|
- [
|
|
|
- cb => {
|
|
|
- return this.owner.createProject(
|
|
|
- 'plf-test-one',
|
|
|
- { template: 'blank' },
|
|
|
- (error, project_id) => {
|
|
|
- this.project_one_id = project_id
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
- cb => {
|
|
|
- return this.owner.getProject(
|
|
|
- this.project_one_id,
|
|
|
- (error, project) => {
|
|
|
- this.project_one = project
|
|
|
- this.project_one_root_folder_id = project.rootFolder[0]._id.toString()
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
- cb => {
|
|
|
- return this.owner.createProject(
|
|
|
- 'plf-test-two',
|
|
|
- { template: 'blank' },
|
|
|
- (error, project_id) => {
|
|
|
- this.project_two_id = project_id
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
- cb => {
|
|
|
- return this.owner.getProject(
|
|
|
- this.project_two_id,
|
|
|
- (error, project) => {
|
|
|
- this.project_two = project
|
|
|
- this.project_two_root_folder_id = project.rootFolder[0]._id.toString()
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
- cb => {
|
|
|
- return this.owner.createDocInProject(
|
|
|
- this.project_two_id,
|
|
|
- this.project_two_root_folder_id,
|
|
|
- this.source_doc_name,
|
|
|
- (error, doc_id) => {
|
|
|
- this.source_doc_id = doc_id
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
- cb => {
|
|
|
- return this.owner.createDocInProject(
|
|
|
- this.project_two_id,
|
|
|
- this.project_two_root_folder_id,
|
|
|
- 'some-harmless-doc.txt',
|
|
|
- (error, doc_id) => {
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- }
|
|
|
- ],
|
|
|
- done
|
|
|
- )
|
|
|
- })
|
|
|
+ beforeEach(async function() {
|
|
|
+ projectOneId = await owner.createProject('plf-test-one', {
|
|
|
+ template: 'blank'
|
|
|
+ })
|
|
|
+ projectOne = await owner.getProject(projectOneId)
|
|
|
+ projectOneRootFolderId = projectOne.rootFolder[0]._id.toString()
|
|
|
|
|
|
- it('should produce a list of the users projects', function(done) {
|
|
|
- return this.owner.request.get(
|
|
|
- {
|
|
|
- url: '/user/projects',
|
|
|
- json: true
|
|
|
- },
|
|
|
- (err, response, body) => {
|
|
|
- expect(err).to.not.exist
|
|
|
- expect(body).to.deep.equal({
|
|
|
- projects: [
|
|
|
- {
|
|
|
- _id: this.project_one_id,
|
|
|
- name: 'plf-test-one',
|
|
|
- accessLevel: 'owner'
|
|
|
- },
|
|
|
- {
|
|
|
- _id: this.project_two_id,
|
|
|
- name: 'plf-test-two',
|
|
|
- accessLevel: 'owner'
|
|
|
- }
|
|
|
- ]
|
|
|
- })
|
|
|
- return done()
|
|
|
- }
|
|
|
- )
|
|
|
- })
|
|
|
+ projectTwoId = await owner.createProject('plf-test-two', {
|
|
|
+ template: 'blank'
|
|
|
+ })
|
|
|
+ projectTwo = await owner.getProject(projectTwoId)
|
|
|
+ projectTwoRootFolderId = projectTwo.rootFolder[0]._id.toString()
|
|
|
|
|
|
- it('should produce a list of entities in the project', function(done) {
|
|
|
- return this.owner.request.get(
|
|
|
- {
|
|
|
- url: `/project/${this.project_two_id}/entities`,
|
|
|
- json: true
|
|
|
- },
|
|
|
- (err, response, body) => {
|
|
|
- expect(err).to.not.exist
|
|
|
- expect(body).to.deep.equal({
|
|
|
- project_id: this.project_two_id,
|
|
|
- entities: [
|
|
|
- { path: '/main.tex', type: 'doc' },
|
|
|
- { path: '/some-harmless-doc.txt', type: 'doc' },
|
|
|
- { path: '/test.txt', type: 'doc' }
|
|
|
- ]
|
|
|
- })
|
|
|
- return done()
|
|
|
- }
|
|
|
+ await owner.createDocInProject(
|
|
|
+ projectTwoId,
|
|
|
+ projectTwoRootFolderId,
|
|
|
+ sourceDocName
|
|
|
+ )
|
|
|
+ await owner.createDocInProject(
|
|
|
+ projectTwoId,
|
|
|
+ projectTwoRootFolderId,
|
|
|
+ 'some-harmless-doc.txt'
|
|
|
)
|
|
|
})
|
|
|
|
|
|
- it('should import a file from the source project', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_one_id}/linked_file`,
|
|
|
- json: {
|
|
|
- name: 'test-link.txt',
|
|
|
- parent_folder_id: this.project_one_root_folder_id,
|
|
|
- provider: 'project_file',
|
|
|
- data: {
|
|
|
- source_project_id: this.project_two_id,
|
|
|
- source_entity_path: `/${this.source_doc_name}`
|
|
|
- }
|
|
|
+ it('should produce a list of the users projects and their entities', async function() {
|
|
|
+ let { body } = await owner.doRequest('get', {
|
|
|
+ url: '/user/projects',
|
|
|
+ json: true
|
|
|
+ })
|
|
|
+
|
|
|
+ expect(body).to.deep.equal({
|
|
|
+ projects: [
|
|
|
+ {
|
|
|
+ _id: projectOneId,
|
|
|
+ name: 'plf-test-one',
|
|
|
+ accessLevel: 'owner'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ _id: projectTwoId,
|
|
|
+ name: 'plf-test-two',
|
|
|
+ accessLevel: 'owner'
|
|
|
}
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- expect(response.statusCode).to.equal(200)
|
|
|
- const { new_file_id } = body
|
|
|
- this.existing_file_id = new_file_id
|
|
|
- expect(new_file_id).to.exist
|
|
|
- return this.owner.getProject(
|
|
|
- this.project_one_id,
|
|
|
- (error, project) => {
|
|
|
- if (error != null) {
|
|
|
- return done(error)
|
|
|
- }
|
|
|
- const firstFile = project.rootFolder[0].fileRefs[0]
|
|
|
- expect(firstFile._id.toString()).to.equal(new_file_id.toString())
|
|
|
- expect(firstFile.linkedFileData).to.deep.equal({
|
|
|
- provider: 'project_file',
|
|
|
- source_project_id: this.project_two_id,
|
|
|
- source_entity_path: `/${this.source_doc_name}`
|
|
|
- })
|
|
|
- expect(firstFile.name).to.equal('test-link.txt')
|
|
|
- return done()
|
|
|
- }
|
|
|
- )
|
|
|
- }
|
|
|
- )
|
|
|
+ ]
|
|
|
+ })
|
|
|
+ ;({ body } = await owner.doRequest('get', {
|
|
|
+ url: `/project/${projectTwoId}/entities`,
|
|
|
+ json: true
|
|
|
+ }))
|
|
|
+ expect(body).to.deep.equal({
|
|
|
+ project_id: projectTwoId,
|
|
|
+ entities: [
|
|
|
+ { path: '/main.tex', type: 'doc' },
|
|
|
+ { path: '/some-harmless-doc.txt', type: 'doc' },
|
|
|
+ { path: '/test.txt', type: 'doc' }
|
|
|
+ ]
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
- it('should refresh the file', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_one_id}/linked_file/${
|
|
|
- this.existing_file_id
|
|
|
- }/refresh`,
|
|
|
- json: true
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- expect(response.statusCode).to.equal(200)
|
|
|
- const { new_file_id } = body
|
|
|
- expect(new_file_id).to.exist
|
|
|
- expect(new_file_id).to.not.equal(this.existing_file_id)
|
|
|
- this.refreshed_file_id = new_file_id
|
|
|
- return this.owner.getProject(
|
|
|
- this.project_one_id,
|
|
|
- (error, project) => {
|
|
|
- if (error != null) {
|
|
|
- return done(error)
|
|
|
- }
|
|
|
- const firstFile = project.rootFolder[0].fileRefs[0]
|
|
|
- expect(firstFile._id.toString()).to.equal(new_file_id.toString())
|
|
|
- expect(firstFile.name).to.equal('test-link.txt')
|
|
|
- return done()
|
|
|
- }
|
|
|
- )
|
|
|
+ it('should import a file and refresh it if there is no v1 id', async function() {
|
|
|
+ // import the file from the source project
|
|
|
+ let { response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file`,
|
|
|
+ json: {
|
|
|
+ name: 'test-link.txt',
|
|
|
+ parent_folder_id: projectOneRootFolderId,
|
|
|
+ provider: 'project_file',
|
|
|
+ data: {
|
|
|
+ source_project_id: projectTwoId,
|
|
|
+ source_entity_path: `/${sourceDocName}`
|
|
|
+ }
|
|
|
}
|
|
|
- )
|
|
|
- })
|
|
|
+ })
|
|
|
+ expect(response.statusCode).to.equal(200)
|
|
|
+ const existingFileId = body.new_file_id
|
|
|
+ expect(existingFileId).to.exist
|
|
|
+
|
|
|
+ let updatedProjectOne = await owner.getProject(projectOneId)
|
|
|
+
|
|
|
+ let firstFile = updatedProjectOne.rootFolder[0].fileRefs[0]
|
|
|
+ expect(firstFile._id.toString()).to.equal(existingFileId.toString())
|
|
|
+ expect(firstFile.linkedFileData).to.deep.equal({
|
|
|
+ provider: 'project_file',
|
|
|
+ source_project_id: projectTwoId,
|
|
|
+ source_entity_path: `/${sourceDocName}`
|
|
|
+ })
|
|
|
+ expect(firstFile.name).to.equal('test-link.txt')
|
|
|
+
|
|
|
+ // refresh the file
|
|
|
+ ;({ response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file/${existingFileId}/refresh`,
|
|
|
+ json: true
|
|
|
+ }))
|
|
|
+ expect(response.statusCode).to.equal(200)
|
|
|
+ const newFileId = body.new_file_id
|
|
|
+ expect(newFileId).to.exist
|
|
|
+ expect(newFileId).to.not.equal(existingFileId)
|
|
|
|
|
|
- it('should not allow to create a linked-file with v1 id', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_one_id}/linked_file`,
|
|
|
- json: {
|
|
|
- name: 'test-link-should-not-work.txt',
|
|
|
- parent_folder_id: this.project_one_root_folder_id,
|
|
|
- provider: 'project_file',
|
|
|
- data: {
|
|
|
- v1_source_doc_id: 1234,
|
|
|
- source_entity_path: `/${this.source_doc_name}`
|
|
|
- }
|
|
|
+ updatedProjectOne = await owner.getProject(projectOneId)
|
|
|
+ firstFile = updatedProjectOne.rootFolder[0].fileRefs[0]
|
|
|
+ expect(firstFile._id.toString()).to.equal(newFileId.toString())
|
|
|
+ expect(firstFile.name).to.equal('test-link.txt')
|
|
|
+
|
|
|
+ // should not work if there is a v1 id
|
|
|
+ ;({ response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file`,
|
|
|
+ json: {
|
|
|
+ name: 'test-link-should-not-work.txt',
|
|
|
+ parent_folder_id: projectOneRootFolderId,
|
|
|
+ provider: 'project_file',
|
|
|
+ data: {
|
|
|
+ v1_source_doc_id: 1234,
|
|
|
+ source_entity_path: `/${sourceDocName}`
|
|
|
}
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- expect(response.statusCode).to.equal(403)
|
|
|
- expect(body).to.equal('You do not have access to this project')
|
|
|
- return done()
|
|
|
}
|
|
|
- )
|
|
|
+ }))
|
|
|
+ expect(response.statusCode).to.equal(403)
|
|
|
+ expect(body).to.equal('You do not have access to this project')
|
|
|
})
|
|
|
})
|
|
|
|
|
|
describe('with a linked project_file from a v1 project that has not been imported', function() {
|
|
|
- before(function(done) {
|
|
|
- return async.series(
|
|
|
- [
|
|
|
- cb => {
|
|
|
- return this.owner.createProject(
|
|
|
- 'plf-v1-test-one',
|
|
|
- { template: 'blank' },
|
|
|
- (error, project_id) => {
|
|
|
- this.project_one_id = project_id
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
- cb => {
|
|
|
- return this.owner.getProject(
|
|
|
- this.project_one_id,
|
|
|
- (error, project) => {
|
|
|
- this.project_one = project
|
|
|
- this.project_one_root_folder_id = project.rootFolder[0]._id.toString()
|
|
|
- this.project_one.rootFolder[0].fileRefs.push({
|
|
|
- linkedFileData: {
|
|
|
- provider: 'project_file',
|
|
|
- v1_source_doc_id: 9999999, // We won't find this id in the database
|
|
|
- source_entity_path: 'example.jpeg'
|
|
|
- },
|
|
|
- _id: 'abcd',
|
|
|
- rev: 0,
|
|
|
- created: new Date(),
|
|
|
- name: 'example.jpeg'
|
|
|
- })
|
|
|
- return this.owner.saveProject(this.project_one, cb)
|
|
|
- }
|
|
|
- )
|
|
|
- }
|
|
|
- ],
|
|
|
- done
|
|
|
- )
|
|
|
+ beforeEach(async function() {
|
|
|
+ projectOneId = await owner.createProject('plf-v1-test-one', {
|
|
|
+ template: 'blank'
|
|
|
+ })
|
|
|
+ projectOne = await owner.getProject(projectOneId)
|
|
|
+ projectOneRootFolderId = projectOne.rootFolder[0]._id.toString()
|
|
|
+ projectOne.rootFolder[0].fileRefs.push({
|
|
|
+ linkedFileData: {
|
|
|
+ provider: 'project_file',
|
|
|
+ v1_source_doc_id: 9999999, // We won't find this id in the database
|
|
|
+ source_entity_path: 'example.jpeg'
|
|
|
+ },
|
|
|
+ _id: 'abcd',
|
|
|
+ rev: 0,
|
|
|
+ created: new Date(),
|
|
|
+ name: 'example.jpeg'
|
|
|
+ })
|
|
|
+ await owner.saveProject(projectOne)
|
|
|
})
|
|
|
|
|
|
- it('should refuse to refresh', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_one_id}/linked_file/abcd/refresh`,
|
|
|
- json: true
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- expect(response.statusCode).to.equal(409)
|
|
|
- expect(body).to.equal(
|
|
|
- 'Sorry, the source project is not yet imported to Overleaf v2. Please import it to Overleaf v2 to refresh this file'
|
|
|
- )
|
|
|
- return done()
|
|
|
- }
|
|
|
+ it('should refuse to refresh', async function() {
|
|
|
+ const { response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file/abcd/refresh`,
|
|
|
+ json: true
|
|
|
+ })
|
|
|
+ expect(response.statusCode).to.equal(409)
|
|
|
+ expect(body).to.equal(
|
|
|
+ 'Sorry, the source project is not yet imported to Overleaf v2. Please import it to Overleaf v2 to refresh this file'
|
|
|
)
|
|
|
})
|
|
|
})
|
|
|
|
|
|
describe('creating a URL based linked file', function() {
|
|
|
- before(function(done) {
|
|
|
- return this.owner.createProject(
|
|
|
- 'url-linked-files-project',
|
|
|
- { template: 'blank' },
|
|
|
- (error, project_id) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- this.project_id = project_id
|
|
|
- return this.owner.getProject(project_id, (error, project) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- this.project = project
|
|
|
- this.root_folder_id = project.rootFolder[0]._id.toString()
|
|
|
- return done()
|
|
|
- })
|
|
|
- }
|
|
|
- )
|
|
|
+ beforeEach(async function() {
|
|
|
+ projectOneId = await owner.createProject('url-linked-files-project', {
|
|
|
+ template: 'blank'
|
|
|
+ })
|
|
|
+ projectOne = await owner.getProject(projectOneId)
|
|
|
+ projectOneRootFolderId = projectOne.rootFolder[0]._id.toString()
|
|
|
})
|
|
|
|
|
|
- it('should download the URL and create a file with the contents and linkedFileData', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_id}/linked_file`,
|
|
|
- json: {
|
|
|
- provider: 'url',
|
|
|
- data: {
|
|
|
- url: 'http://example.com/foo'
|
|
|
- },
|
|
|
- parent_folder_id: this.root_folder_id,
|
|
|
- name: 'url-test-file-1'
|
|
|
- }
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- expect(response.statusCode).to.equal(200)
|
|
|
- return this.owner.getProject(this.project_id, (error, project) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- const file = project.rootFolder[0].fileRefs[0]
|
|
|
- expect(file.linkedFileData).to.deep.equal({
|
|
|
- provider: 'url',
|
|
|
- url: 'http://example.com/foo'
|
|
|
- })
|
|
|
- return this.owner.request.get(
|
|
|
- `/project/${this.project_id}/file/${file._id}`,
|
|
|
- (error, response, body) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- expect(response.statusCode).to.equal(200)
|
|
|
- expect(body).to.equal('foo foo foo')
|
|
|
- return done()
|
|
|
- }
|
|
|
- )
|
|
|
- })
|
|
|
+ it('should download, create and replace a file', async function() {
|
|
|
+ // downloading the initial file
|
|
|
+ let { response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file`,
|
|
|
+ json: {
|
|
|
+ provider: 'url',
|
|
|
+ data: {
|
|
|
+ url: 'http://example.com/foo'
|
|
|
+ },
|
|
|
+ parent_folder_id: projectOneRootFolderId,
|
|
|
+ name: 'url-test-file-1'
|
|
|
}
|
|
|
- )
|
|
|
- })
|
|
|
+ })
|
|
|
+ expect(response.statusCode).to.equal(200)
|
|
|
|
|
|
- it('should replace and update a URL based linked file', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_id}/linked_file`,
|
|
|
- json: {
|
|
|
- provider: 'url',
|
|
|
- data: {
|
|
|
- url: 'http://example.com/foo'
|
|
|
- },
|
|
|
- parent_folder_id: this.root_folder_id,
|
|
|
- name: 'url-test-file-2'
|
|
|
- }
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- expect(response.statusCode).to.equal(200)
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_id}/linked_file`,
|
|
|
- json: {
|
|
|
- provider: 'url',
|
|
|
- data: {
|
|
|
- url: 'http://example.com/bar'
|
|
|
- },
|
|
|
- parent_folder_id: this.root_folder_id,
|
|
|
- name: 'url-test-file-2'
|
|
|
- }
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- expect(response.statusCode).to.equal(200)
|
|
|
- return this.owner.getProject(
|
|
|
- this.project_id,
|
|
|
- (error, project) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- const file = project.rootFolder[0].fileRefs[1]
|
|
|
- expect(file.linkedFileData).to.deep.equal({
|
|
|
- provider: 'url',
|
|
|
- url: 'http://example.com/bar'
|
|
|
- })
|
|
|
- return this.owner.request.get(
|
|
|
- `/project/${this.project_id}/file/${file._id}`,
|
|
|
- (error, response, body) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- expect(response.statusCode).to.equal(200)
|
|
|
- expect(body).to.equal('bar bar bar')
|
|
|
- return done()
|
|
|
- }
|
|
|
- )
|
|
|
- }
|
|
|
- )
|
|
|
- }
|
|
|
- )
|
|
|
+ let updatedProject = await owner.getProject(projectOneId)
|
|
|
+ let file = updatedProject.rootFolder[0].fileRefs[0]
|
|
|
+ expect(file.linkedFileData).to.deep.equal({
|
|
|
+ provider: 'url',
|
|
|
+ url: 'http://example.com/foo'
|
|
|
+ })
|
|
|
+ ;({ response, body } = await owner.doRequest(
|
|
|
+ 'get',
|
|
|
+ `/project/${projectOneId}/file/${file._id}`
|
|
|
+ ))
|
|
|
+ expect(response.statusCode).to.equal(200)
|
|
|
+ expect(body).to.equal('foo foo foo')
|
|
|
+
|
|
|
+ // replacing the file
|
|
|
+ ;({ response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file`,
|
|
|
+ json: {
|
|
|
+ provider: 'url',
|
|
|
+ data: {
|
|
|
+ url: 'http://example.com/foo'
|
|
|
+ },
|
|
|
+ parent_folder_id: projectOneRootFolderId,
|
|
|
+ name: 'url-test-file-2'
|
|
|
}
|
|
|
- )
|
|
|
+ }))
|
|
|
+ expect(response.statusCode).to.equal(200)
|
|
|
+ ;({ response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file`,
|
|
|
+ json: {
|
|
|
+ provider: 'url',
|
|
|
+ data: {
|
|
|
+ url: 'http://example.com/bar'
|
|
|
+ },
|
|
|
+ parent_folder_id: projectOneRootFolderId,
|
|
|
+ name: 'url-test-file-2'
|
|
|
+ }
|
|
|
+ }))
|
|
|
+ expect(response.statusCode).to.equal(200)
|
|
|
+
|
|
|
+ updatedProject = await owner.getProject(projectOneId)
|
|
|
+ file = updatedProject.rootFolder[0].fileRefs[1]
|
|
|
+ expect(file.linkedFileData).to.deep.equal({
|
|
|
+ provider: 'url',
|
|
|
+ url: 'http://example.com/bar'
|
|
|
+ })
|
|
|
+ ;({ response, body } = await owner.doRequest(
|
|
|
+ 'get',
|
|
|
+ `/project/${projectOneId}/file/${file._id}`
|
|
|
+ ))
|
|
|
+ expect(response.statusCode).to.equal(200)
|
|
|
+ expect(body).to.equal('bar bar bar')
|
|
|
})
|
|
|
|
|
|
- it('should return an error if the URL does not succeed', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_id}/linked_file`,
|
|
|
- json: {
|
|
|
- provider: 'url',
|
|
|
- data: {
|
|
|
- url: 'http://example.com/does-not-exist'
|
|
|
- },
|
|
|
- parent_folder_id: this.root_folder_id,
|
|
|
- name: 'url-test-file-3'
|
|
|
- }
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- expect(response.statusCode).to.equal(422) // unprocessable
|
|
|
- expect(body).to.equal(
|
|
|
- 'Your URL could not be reached (404 status code). Please check it and try again.'
|
|
|
- )
|
|
|
- return done()
|
|
|
+ it("should return an error if the file can't be downloaded", async function() {
|
|
|
+ // download does not succeed
|
|
|
+ let { response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file`,
|
|
|
+ json: {
|
|
|
+ provider: 'url',
|
|
|
+ data: {
|
|
|
+ url: 'http://example.com/does-not-exist'
|
|
|
+ },
|
|
|
+ parent_folder_id: projectOneRootFolderId,
|
|
|
+ name: 'url-test-file-3'
|
|
|
}
|
|
|
+ })
|
|
|
+ expect(response.statusCode).to.equal(422) // unprocessable
|
|
|
+ expect(body).to.equal(
|
|
|
+ 'Your URL could not be reached (404 status code). Please check it and try again.'
|
|
|
)
|
|
|
- })
|
|
|
|
|
|
- it('should return an error if the URL is invalid', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_id}/linked_file`,
|
|
|
- json: {
|
|
|
- provider: 'url',
|
|
|
- data: {
|
|
|
- url: '!^$%'
|
|
|
- },
|
|
|
- parent_folder_id: this.root_folder_id,
|
|
|
- name: 'url-test-file-4'
|
|
|
- }
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- expect(response.statusCode).to.equal(422) // unprocessable
|
|
|
- expect(body).to.equal(
|
|
|
- 'Your URL is not valid. Please check it and try again.'
|
|
|
- )
|
|
|
- return done()
|
|
|
+ // url is invalid
|
|
|
+ ;({ response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file`,
|
|
|
+ json: {
|
|
|
+ provider: 'url',
|
|
|
+ data: {
|
|
|
+ url: '!^$%'
|
|
|
+ },
|
|
|
+ parent_folder_id: projectOneRootFolderId,
|
|
|
+ name: 'url-test-file-4'
|
|
|
}
|
|
|
+ }))
|
|
|
+ expect(response.statusCode).to.equal(422) // unprocessable
|
|
|
+ expect(body).to.equal(
|
|
|
+ 'Your URL is not valid. Please check it and try again.'
|
|
|
)
|
|
|
- })
|
|
|
|
|
|
- it('should return an error if the URL uses a non-http protocol', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_id}/linked_file`,
|
|
|
- json: {
|
|
|
- provider: 'url',
|
|
|
- data: {
|
|
|
- url: 'ftp://localhost'
|
|
|
- },
|
|
|
- parent_folder_id: this.root_folder_id,
|
|
|
- name: 'url-test-file-5'
|
|
|
- }
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- expect(response.statusCode).to.equal(422) // unprocessable
|
|
|
- expect(body).to.equal(
|
|
|
- 'Your URL is not valid. Please check it and try again.'
|
|
|
- )
|
|
|
- return done()
|
|
|
+ // URL is non-http
|
|
|
+ ;({ response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file`,
|
|
|
+ json: {
|
|
|
+ provider: 'url',
|
|
|
+ data: {
|
|
|
+ url: 'ftp://localhost'
|
|
|
+ },
|
|
|
+ parent_folder_id: projectOneRootFolderId,
|
|
|
+ name: 'url-test-file-5'
|
|
|
}
|
|
|
+ }))
|
|
|
+ expect(response.statusCode).to.equal(422) // unprocessable
|
|
|
+ expect(body).to.equal(
|
|
|
+ 'Your URL is not valid. Please check it and try again.'
|
|
|
)
|
|
|
})
|
|
|
|
|
|
- it('should accept a URL withuot a leading http://, and add it', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_id}/linked_file`,
|
|
|
- json: {
|
|
|
- provider: 'url',
|
|
|
- data: {
|
|
|
- url: 'example.com/foo'
|
|
|
- },
|
|
|
- parent_folder_id: this.root_folder_id,
|
|
|
- name: 'url-test-file-6'
|
|
|
- }
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- expect(response.statusCode).to.equal(200)
|
|
|
- return this.owner.getProject(this.project_id, (error, project) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- const file = _.find(
|
|
|
- project.rootFolder[0].fileRefs,
|
|
|
- file => file.name === 'url-test-file-6'
|
|
|
- )
|
|
|
- expect(file.linkedFileData).to.deep.equal({
|
|
|
- provider: 'url',
|
|
|
- url: 'http://example.com/foo'
|
|
|
- })
|
|
|
- return this.owner.request.get(
|
|
|
- `/project/${this.project_id}/file/${file._id}`,
|
|
|
- (error, response, body) => {
|
|
|
- if (error != null) {
|
|
|
- throw error
|
|
|
- }
|
|
|
- expect(response.statusCode).to.equal(200)
|
|
|
- expect(body).to.equal('foo foo foo')
|
|
|
- return done()
|
|
|
- }
|
|
|
- )
|
|
|
- })
|
|
|
+ it('should accept a URL withuot a leading http://, and add it', async function() {
|
|
|
+ let { response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file`,
|
|
|
+ json: {
|
|
|
+ provider: 'url',
|
|
|
+ data: {
|
|
|
+ url: 'example.com/foo'
|
|
|
+ },
|
|
|
+ parent_folder_id: projectOneRootFolderId,
|
|
|
+ name: 'url-test-file-6'
|
|
|
}
|
|
|
+ })
|
|
|
+ expect(response.statusCode).to.equal(200)
|
|
|
+
|
|
|
+ const updatedProject = await owner.getProject(projectOneId)
|
|
|
+
|
|
|
+ const file = _.find(
|
|
|
+ updatedProject.rootFolder[0].fileRefs,
|
|
|
+ file => file.name === 'url-test-file-6'
|
|
|
)
|
|
|
+ expect(file.linkedFileData).to.deep.equal({
|
|
|
+ provider: 'url',
|
|
|
+ url: 'http://example.com/foo'
|
|
|
+ })
|
|
|
+ ;({ response, body } = await owner.doRequest(
|
|
|
+ 'get',
|
|
|
+ `/project/${projectOneId}/file/${file._id}`
|
|
|
+ ))
|
|
|
+ expect(response.statusCode).to.equal(200)
|
|
|
+ expect(body).to.equal('foo foo foo')
|
|
|
})
|
|
|
})
|
|
|
|
|
|
@@ -575,178 +358,97 @@ describe('LinkedFiles', function() {
|
|
|
// (This will probably end up handled by the proxy)
|
|
|
|
|
|
describe('creating a linked output file', function() {
|
|
|
- before(function(done) {
|
|
|
- return async.series(
|
|
|
- [
|
|
|
- cb => {
|
|
|
- return this.owner.createProject(
|
|
|
- 'output-test-one',
|
|
|
- { template: 'blank' },
|
|
|
- (error, project_id) => {
|
|
|
- this.project_one_id = project_id
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
- cb => {
|
|
|
- return this.owner.getProject(
|
|
|
- this.project_one_id,
|
|
|
- (error, project) => {
|
|
|
- this.project_one = project
|
|
|
- this.project_one_root_folder_id = project.rootFolder[0]._id.toString()
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
- cb => {
|
|
|
- return this.owner.createProject(
|
|
|
- 'output-test-two',
|
|
|
- { template: 'blank' },
|
|
|
- (error, project_id) => {
|
|
|
- this.project_two_id = project_id
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
- cb => {
|
|
|
- return this.owner.getProject(
|
|
|
- this.project_two_id,
|
|
|
- (error, project) => {
|
|
|
- this.project_two = project
|
|
|
- this.project_two_root_folder_id = project.rootFolder[0]._id.toString()
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- }
|
|
|
- ],
|
|
|
- done
|
|
|
- )
|
|
|
+ beforeEach(async function() {
|
|
|
+ projectOneId = await owner.createProject('output-test-one', {
|
|
|
+ template: 'blank'
|
|
|
+ })
|
|
|
+ projectOne = await owner.getProject(projectOneId)
|
|
|
+
|
|
|
+ projectOneRootFolderId = projectOne.rootFolder[0]._id.toString()
|
|
|
+ projectTwoId = await owner.createProject('output-test-two', {
|
|
|
+ template: 'blank'
|
|
|
+ })
|
|
|
+ projectTwo = await owner.getProject(projectTwoId)
|
|
|
+ projectTwoRootFolderId = projectTwo.rootFolder[0]._id.toString()
|
|
|
})
|
|
|
|
|
|
- it('should import the project.pdf file from the source project', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_one_id}/linked_file`,
|
|
|
- json: {
|
|
|
- name: 'test.pdf',
|
|
|
- parent_folder_id: this.project_one_root_folder_id,
|
|
|
- provider: 'project_output_file',
|
|
|
- data: {
|
|
|
- source_project_id: this.project_two_id,
|
|
|
- source_output_file_path: 'project.pdf',
|
|
|
- build_id: '1234-abcd'
|
|
|
- }
|
|
|
+ it('should import the project.pdf file from the source project and refresh it', async function() {
|
|
|
+ // import the file
|
|
|
+ let { response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file`,
|
|
|
+ json: {
|
|
|
+ name: 'test.pdf',
|
|
|
+ parent_folder_id: projectOneRootFolderId,
|
|
|
+ provider: 'project_output_file',
|
|
|
+ data: {
|
|
|
+ source_project_id: projectTwoId,
|
|
|
+ source_output_file_path: 'project.pdf',
|
|
|
+ build_id: '1234-abcd'
|
|
|
}
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- const { new_file_id } = body
|
|
|
- this.existing_file_id = new_file_id
|
|
|
- expect(new_file_id).to.exist
|
|
|
- return this.owner.getProject(
|
|
|
- this.project_one_id,
|
|
|
- (error, project) => {
|
|
|
- if (error != null) {
|
|
|
- return done(error)
|
|
|
- }
|
|
|
- const firstFile = project.rootFolder[0].fileRefs[0]
|
|
|
- expect(firstFile._id.toString()).to.equal(new_file_id.toString())
|
|
|
- expect(firstFile.linkedFileData).to.deep.equal({
|
|
|
- provider: 'project_output_file',
|
|
|
- source_project_id: this.project_two_id,
|
|
|
- source_output_file_path: 'project.pdf',
|
|
|
- build_id: '1234-abcd'
|
|
|
- })
|
|
|
- expect(firstFile.name).to.equal('test.pdf')
|
|
|
- return done()
|
|
|
- }
|
|
|
- )
|
|
|
}
|
|
|
- )
|
|
|
- })
|
|
|
+ })
|
|
|
+ expect(response.statusCode).to.equal(200)
|
|
|
+ const existingFileId = body.new_file_id
|
|
|
+ expect(existingFileId).to.exist
|
|
|
|
|
|
- it('should refresh the file', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_one_id}/linked_file/${
|
|
|
- this.existing_file_id
|
|
|
- }/refresh`,
|
|
|
- json: true
|
|
|
- },
|
|
|
- (error, response, body) => {
|
|
|
- const { new_file_id } = body
|
|
|
- expect(new_file_id).to.exist
|
|
|
- expect(new_file_id).to.not.equal(this.existing_file_id)
|
|
|
- this.refreshed_file_id = new_file_id
|
|
|
- return this.owner.getProject(
|
|
|
- this.project_one_id,
|
|
|
- (error, project) => {
|
|
|
- if (error != null) {
|
|
|
- return done(error)
|
|
|
- }
|
|
|
- const firstFile = project.rootFolder[0].fileRefs[0]
|
|
|
- expect(firstFile._id.toString()).to.equal(new_file_id.toString())
|
|
|
- expect(firstFile.name).to.equal('test.pdf')
|
|
|
- return done()
|
|
|
- }
|
|
|
- )
|
|
|
- }
|
|
|
- )
|
|
|
+ const updatedProject = await owner.getProject(projectOneId)
|
|
|
+ const firstFile = updatedProject.rootFolder[0].fileRefs[0]
|
|
|
+ expect(firstFile._id.toString()).to.equal(existingFileId.toString())
|
|
|
+ expect(firstFile.linkedFileData).to.deep.equal({
|
|
|
+ provider: 'project_output_file',
|
|
|
+ source_project_id: projectTwoId,
|
|
|
+ source_output_file_path: 'project.pdf',
|
|
|
+ build_id: '1234-abcd'
|
|
|
+ })
|
|
|
+ expect(firstFile.name).to.equal('test.pdf')
|
|
|
+
|
|
|
+ // refresh the file
|
|
|
+ ;({ response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file/${existingFileId}/refresh`,
|
|
|
+ json: true
|
|
|
+ }))
|
|
|
+ expect(response.statusCode).to.equal(200)
|
|
|
+ const refreshedFileId = body.new_file_id
|
|
|
+ expect(refreshedFileId).to.exist
|
|
|
+ expect(refreshedFileId).to.not.equal(existingFileId)
|
|
|
+
|
|
|
+ const refreshedProject = await owner.getProject(projectOneId)
|
|
|
+ const refreshedFile = refreshedProject.rootFolder[0].fileRefs[0]
|
|
|
+ expect(refreshedFile._id.toString()).to.equal(refreshedFileId.toString())
|
|
|
+ expect(refreshedFile.name).to.equal('test.pdf')
|
|
|
})
|
|
|
})
|
|
|
|
|
|
describe('with a linked project_output_file from a v1 project that has not been imported', function() {
|
|
|
- before(function(done) {
|
|
|
- return async.series(
|
|
|
- [
|
|
|
- cb => {
|
|
|
- return this.owner.createProject(
|
|
|
- 'output-v1-test-one',
|
|
|
- { template: 'blank' },
|
|
|
- (error, project_id) => {
|
|
|
- this.project_one_id = project_id
|
|
|
- return cb(error)
|
|
|
- }
|
|
|
- )
|
|
|
- },
|
|
|
- cb => {
|
|
|
- return this.owner.getProject(
|
|
|
- this.project_one_id,
|
|
|
- (error, project) => {
|
|
|
- this.project_one = project
|
|
|
- this.project_one_root_folder_id = project.rootFolder[0]._id.toString()
|
|
|
- this.project_one.rootFolder[0].fileRefs.push({
|
|
|
- linkedFileData: {
|
|
|
- provider: 'project_output_file',
|
|
|
- v1_source_doc_id: 9999999, // We won't find this id in the database
|
|
|
- source_output_file_path: 'project.pdf'
|
|
|
- },
|
|
|
- _id: 'abcdef',
|
|
|
- rev: 0,
|
|
|
- created: new Date(),
|
|
|
- name: 'whatever.pdf'
|
|
|
- })
|
|
|
- return this.owner.saveProject(this.project_one, cb)
|
|
|
- }
|
|
|
- )
|
|
|
- }
|
|
|
- ],
|
|
|
- done
|
|
|
- )
|
|
|
- })
|
|
|
+ beforeEach(async function() {
|
|
|
+ projectOneId = await owner.createProject('output-v1-test-one', {
|
|
|
+ template: 'blank'
|
|
|
+ })
|
|
|
|
|
|
- it('should refuse to refresh', function(done) {
|
|
|
- return this.owner.request.post(
|
|
|
- {
|
|
|
- url: `/project/${this.project_one_id}/linked_file/abcdef/refresh`,
|
|
|
- json: true
|
|
|
+ projectOne = await owner.getProject(projectOneId)
|
|
|
+ projectOneRootFolderId = projectOne.rootFolder[0]._id.toString()
|
|
|
+ projectOne.rootFolder[0].fileRefs.push({
|
|
|
+ linkedFileData: {
|
|
|
+ provider: 'project_output_file',
|
|
|
+ v1_source_doc_id: 9999999, // We won't find this id in the database
|
|
|
+ source_output_file_path: 'project.pdf'
|
|
|
},
|
|
|
- (error, response, body) => {
|
|
|
- expect(response.statusCode).to.equal(409)
|
|
|
- expect(body).to.equal(
|
|
|
- 'Sorry, the source project is not yet imported to Overleaf v2. Please import it to Overleaf v2 to refresh this file'
|
|
|
- )
|
|
|
- return done()
|
|
|
- }
|
|
|
+ _id: 'abcdef',
|
|
|
+ rev: 0,
|
|
|
+ created: new Date(),
|
|
|
+ name: 'whatever.pdf'
|
|
|
+ })
|
|
|
+ await owner.saveProject(projectOne)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('should refuse to refresh', async function() {
|
|
|
+ const { response, body } = await owner.doRequest('post', {
|
|
|
+ url: `/project/${projectOneId}/linked_file/abcdef/refresh`,
|
|
|
+ json: true
|
|
|
+ })
|
|
|
+ expect(response.statusCode).to.equal(409)
|
|
|
+ expect(body).to.equal(
|
|
|
+ 'Sorry, the source project is not yet imported to Overleaf v2. Please import it to Overleaf v2 to refresh this file'
|
|
|
)
|
|
|
})
|
|
|
})
|