| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453 |
- const { expect } = require('chai')
- const mkdirp = require('mkdirp')
- const { ObjectId } = require('mongojs')
- const Path = require('path')
- const fs = require('fs')
- const Settings = require('settings-sharelatex')
- const _ = require('underscore')
- const { Project } = require('../../../app/src/models/Project')
- const ProjectGetter = require('../../../app/src/Features/Project/ProjectGetter.js')
- const MockDocUpdaterApi = require('./helpers/MockDocUpdaterApi')
- require('./helpers/MockFileStoreApi')
- require('./helpers/MockProjectHistoryApi')
- const User = require('./helpers/User')
- describe('ProjectStructureChanges', function() {
- let owner
- beforeEach(function(done) {
- owner = new User()
- owner.login(done)
- })
- function createExampleProject(owner, callback) {
- owner.createProject(
- 'example-project',
- { template: 'example' },
- (error, projectId) => {
- if (error) {
- return callback(error)
- }
- ProjectGetter.getProject(projectId, (error, project) => {
- if (error) {
- return callback(error)
- }
- const rootFolderId = project.rootFolder[0]._id.toString()
- callback(null, projectId, rootFolderId)
- })
- }
- )
- }
- function createExampleDoc(owner, projectId, callback) {
- ProjectGetter.getProject(projectId, (error, project) => {
- if (error) {
- return callback(error)
- }
- owner.request.post(
- {
- uri: `project/${projectId}/doc`,
- json: {
- name: 'new.tex',
- parent_folder_id: project.rootFolder[0]._id
- }
- },
- (error, res, body) => {
- if (error) {
- return callback(error)
- }
- if (res.statusCode < 200 || res.statusCode >= 300) {
- return callback(new Error(`failed to add doc ${res.statusCode}`))
- }
- callback(null, body._id)
- }
- )
- })
- }
- function createExampleFolder(owner, projectId, callback) {
- owner.request.post(
- {
- uri: `project/${projectId}/folder`,
- json: {
- name: 'foo'
- }
- },
- (error, res, body) => {
- if (error) {
- return callback(error)
- }
- if (res.statusCode < 200 || res.statusCode >= 300) {
- return callback(new Error(`failed to add doc ${res.statusCode}`))
- }
- callback(null, body._id)
- }
- )
- }
- function uploadFile(
- owner,
- projectId,
- folderId,
- file,
- name,
- contentType,
- callback
- ) {
- const imageFile = fs.createReadStream(
- Path.resolve(Path.join(__dirname, '..', 'files', file))
- )
- owner.request.post(
- {
- uri: `project/${projectId}/upload`,
- qs: {
- folder_id: folderId
- },
- formData: {
- qqfile: {
- value: imageFile,
- options: {
- filename: name,
- contentType: contentType
- }
- }
- }
- },
- (error, res, body) => {
- if (error) {
- return callback(error)
- }
- if (res.statusCode < 200 || res.statusCode >= 300) {
- return callback(new Error(`failed to upload file ${res.statusCode}`))
- }
- callback(null, JSON.parse(body).entity_id)
- }
- )
- }
- function uploadExampleFile(owner, projectId, folderId, callback) {
- uploadFile(
- owner,
- projectId,
- folderId,
- '1pixel.png',
- '1pixel.png',
- 'image/png',
- callback
- )
- }
- function uploadExampleProject(owner, zipFilename, options, callback) {
- if (typeof options === 'function') {
- callback = options
- options = {}
- }
- const zipFile = fs.createReadStream(
- Path.resolve(Path.join(__dirname, '..', 'files', zipFilename))
- )
- owner.request.post(
- {
- uri: 'project/new/upload',
- formData: {
- qqfile: zipFile
- }
- },
- (error, res, body) => {
- if (error) {
- return callback(error)
- }
- if (
- !options.allowBadStatus &&
- (res.statusCode < 200 || res.statusCode >= 300)
- ) {
- return new Error(`failed to upload project ${res.statusCode}`)
- }
- callback(null, JSON.parse(body).project_id, res)
- }
- )
- }
- function moveItem(owner, projectId, type, itemId, folderId, callback) {
- owner.request.post(
- {
- uri: `project/${projectId}/${type}/${itemId}/move`,
- json: {
- folder_id: folderId
- }
- },
- (error, res) => {
- if (error) {
- return callback(error)
- }
- if (res.statusCode < 200 || res.statusCode >= 300) {
- return callback(new Error(`failed to move ${type} ${res.statusCode}`))
- }
- callback()
- }
- )
- }
- function renameItem(owner, projectId, type, itemId, name, callback) {
- owner.request.post(
- {
- uri: `project/${projectId}/${type}/${itemId}/rename`,
- json: {
- name: name
- }
- },
- (error, res) => {
- if (error) {
- return callback(error)
- }
- if (res.statusCode < 200 || res.statusCode >= 300) {
- return callback(
- new Error(`failed to rename ${type} ${res.statusCode}`)
- )
- }
- callback()
- }
- )
- }
- function deleteItem(owner, projectId, type, itemId, callback) {
- owner.request.delete(
- {
- uri: `project/${projectId}/${type}/${itemId}`
- },
- (error, res) => {
- if (error) {
- return callback(error)
- }
- if (res.statusCode < 200 || res.statusCode >= 300) {
- return callback(
- new Error(`failed to delete folder ${res.statusCode}`)
- )
- }
- callback()
- }
- )
- }
- function verifyVersionIncremented(
- projectId,
- oldVersion,
- updateVersion,
- increment,
- callback
- ) {
- expect(updateVersion).to.equal(oldVersion + increment)
- ProjectGetter.getProject(projectId, (error, newProject) => {
- if (error) {
- return callback(error)
- }
- expect(newProject.version).to.equal(updateVersion)
- callback()
- })
- }
- describe('creating a project from the example template', function() {
- let exampleProjectId
- beforeEach(function(done) {
- MockDocUpdaterApi.clearProjectStructureUpdates()
- createExampleProject(owner, (err, projectId) => {
- exampleProjectId = projectId
- done(err)
- })
- })
- it('should version creating a doc', function() {
- const {
- docUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(2)
- _.each(updates, update => {
- expect(update.userId).to.equal(owner._id)
- expect(update.docLines).to.be.a('string')
- })
- expect(_.where(updates, { pathname: '/main.tex' }).length).to.equal(1)
- expect(_.where(updates, { pathname: '/references.bib' }).length).to.equal(
- 1
- )
- expect(version).to.equal(3)
- })
- it('should version creating a file', function() {
- const {
- fileUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/universe.jpg')
- expect(update.url).to.be.a('string')
- expect(version).to.equal(3)
- })
- })
- describe('duplicating a project', function() {
- let dupProjectId
- beforeEach(function(done) {
- MockDocUpdaterApi.clearProjectStructureUpdates()
- createExampleProject(owner, (err, projectId) => {
- if (err) {
- return done(err)
- }
- owner.request.post(
- {
- uri: `/Project/${projectId}/clone`,
- json: {
- projectName: 'new.tex'
- }
- },
- (error, res, body) => {
- if (error) {
- throw error
- }
- if (res.statusCode < 200 || res.statusCode >= 300) {
- throw new Error(`failed to clone project ${res.statusCode}`)
- }
- dupProjectId = body.project_id
- done()
- }
- )
- })
- })
- it('should version the docs created', function() {
- const {
- docUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(dupProjectId)
- expect(updates.length).to.equal(2)
- _.each(updates, update => {
- expect(update.userId).to.equal(owner._id)
- expect(update.docLines).to.be.a('string')
- })
- expect(_.where(updates, { pathname: '/main.tex' }).length).to.equal(1)
- expect(_.where(updates, { pathname: '/references.bib' }).length).to.equal(
- 1
- )
- expect(version).to.equal(3)
- })
- it('should version the files created', function() {
- const {
- fileUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(dupProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/universe.jpg')
- expect(update.url).to.be.a('string')
- expect(version).to.equal(3)
- })
- })
- describe('adding a doc', function() {
- let exampleProjectId, oldVersion
- beforeEach(function(done) {
- createExampleProject(owner, (err, projectId) => {
- if (err) {
- return done(err)
- }
- exampleProjectId = projectId
- MockDocUpdaterApi.clearProjectStructureUpdates()
- ProjectGetter.getProject(projectId, (error, project) => {
- if (error) {
- return done(error)
- }
- oldVersion = project.version
- createExampleDoc(owner, projectId, done)
- })
- })
- })
- it('should version the doc added', function(done) {
- const {
- docUpdates: updates,
- version: newVersion
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/new.tex')
- expect(update.docLines).to.be.a('string')
- verifyVersionIncremented(
- exampleProjectId,
- oldVersion,
- newVersion,
- 1,
- done
- )
- })
- })
- describe('uploading a project', function() {
- let exampleProjectId
- beforeEach(function(done) {
- uploadExampleProject(owner, 'test_project.zip', (err, projectId) => {
- if (err) {
- return done(err)
- }
- exampleProjectId = projectId
- done()
- })
- })
- it('should version the docs created', function() {
- const {
- docUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/main.tex')
- expect(update.docLines).to.equal('Test')
- expect(version).to.equal(2)
- })
- it('should version the files created', function() {
- const {
- fileUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/1pixel.png')
- expect(update.url).to.be.a('string')
- expect(version).to.equal(2)
- })
- })
- describe('uploading a project with a name', function() {
- let exampleProjectId
- const testProjectName = 'wombat'
- beforeEach(function(done) {
- uploadExampleProject(
- owner,
- 'test_project_with_name.zip',
- (err, projectId) => {
- if (err) {
- return done(err)
- }
- exampleProjectId = projectId
- done()
- }
- )
- })
- it('should set the project name from the zip contents', function(done) {
- ProjectGetter.getProject(exampleProjectId, (error, project) => {
- expect(error).not.to.exist
- expect(project.name).to.equal(testProjectName)
- done()
- })
- })
- })
- describe('uploading a project with an invalid name', function() {
- let exampleProjectId
- const testProjectMatch = /^bad[^\\]+name$/
- beforeEach(function(done) {
- uploadExampleProject(
- owner,
- 'test_project_with_invalid_name.zip',
- (error, projectId) => {
- if (error) {
- return done(error)
- }
- exampleProjectId = projectId
- done()
- }
- )
- })
- it('should set the project name from the zip contents', function(done) {
- ProjectGetter.getProject(exampleProjectId, (error, project) => {
- expect(error).not.to.exist
- expect(project.name).to.match(testProjectMatch)
- done()
- })
- })
- })
- describe('uploading an empty zipfile', function() {
- let res
- beforeEach(function(done) {
- uploadExampleProject(
- owner,
- 'test_project_empty.zip',
- { allowBadStatus: true },
- (err, projectId, response) => {
- if (err) {
- return done(err)
- }
- res = response
- done()
- }
- )
- })
- it('should fail with 422 error', function() {
- expect(res.statusCode).to.equal(422)
- })
- })
- describe('uploading a zipfile containing only empty directories', function() {
- let res
- beforeEach(function(done) {
- uploadExampleProject(
- owner,
- 'test_project_with_empty_folder.zip',
- { allowBadStatus: true },
- (err, projectId, response) => {
- if (err) {
- return done(err)
- }
- res = response
- done()
- }
- )
- })
- it('should fail with 422 error', function() {
- expect(res.statusCode).to.equal(422)
- })
- })
- describe('uploading a project with a shared top-level folder', function() {
- let exampleProjectId
- beforeEach(function(done) {
- uploadExampleProject(
- owner,
- 'test_project_with_shared_top_level_folder.zip',
- (err, projectId) => {
- if (err) {
- return done(err)
- }
- exampleProjectId = projectId
- done()
- }
- )
- })
- it('should not create the top-level folder', function(done) {
- ProjectGetter.getProject(exampleProjectId, (error, project) => {
- expect(error).not.to.exist
- expect(project.rootFolder[0].folders.length).to.equal(0)
- expect(project.rootFolder[0].docs.length).to.equal(2)
- done()
- })
- })
- })
- describe('uploading a project with backslashes in the path names', function() {
- let exampleProjectId
- beforeEach(function(done) {
- uploadExampleProject(
- owner,
- 'test_project_with_backslash_in_filename.zip',
- (err, projectId) => {
- if (err) {
- return done(err)
- }
- exampleProjectId = projectId
- done()
- }
- )
- })
- it('should treat the backslash as a directory separator', function(done) {
- ProjectGetter.getProject(exampleProjectId, (error, project) => {
- expect(error).not.to.exist
- expect(project.rootFolder[0].folders[0].name).to.equal('styles')
- expect(project.rootFolder[0].folders[0].docs[0].name).to.equal('ao.sty')
- done()
- })
- })
- })
- describe('uploading a project with files in different encodings', function() {
- let docUpdates
- beforeEach(function(done) {
- uploadExampleProject(owner, 'charsets/charsets.zip', (err, projectId) => {
- if (err) {
- return done(err)
- }
- docUpdates = MockDocUpdaterApi.getProjectStructureUpdates(projectId)
- .docUpdates
- done()
- })
- })
- it('should correctly parse windows-1252', function() {
- const update = _.find(
- docUpdates,
- update => update.pathname === '/test-german-windows-1252.tex'
- )
- expect(update.docLines).to.contain(
- 'Der schnelle braune Fuchs sprang träge über den Hund.'
- )
- })
- it('should correctly parse German utf8', function() {
- const update = _.find(
- docUpdates,
- update => update.pathname === '/test-german-utf8x.tex'
- )
- expect(update.docLines).to.contain(
- 'Der schnelle braune Fuchs sprang träge über den Hund.'
- )
- })
- it('should correctly parse little-endian utf16', function() {
- const update = _.find(
- docUpdates,
- update => update.pathname === '/test-greek-utf16-le-bom.tex'
- )
- expect(update.docLines).to.contain(
- 'Η γρήγορη καστανή αλεπού πήδηξε χαλαρά πάνω από το σκυλί.'
- )
- })
- it('should correctly parse Greek utf8', function() {
- const update = _.find(
- docUpdates,
- update => update.pathname === '/test-greek-utf8x.tex'
- )
- expect(update.docLines).to.contain(
- 'Η γρήγορη καστανή αλεπού πήδηξε χαλαρά πάνω από το σκυλί.'
- )
- })
- })
- describe('uploading a file', function() {
- let exampleProjectId, oldVersion, rootFolderId
- beforeEach(function(done) {
- createExampleProject(owner, (err, projectId, folderId) => {
- if (err) {
- return done(err)
- }
- exampleProjectId = projectId
- rootFolderId = folderId
- MockDocUpdaterApi.clearProjectStructureUpdates()
- ProjectGetter.getProject(projectId, (error, project) => {
- if (error) {
- throw error
- }
- oldVersion = project.version
- uploadExampleFile(owner, projectId, rootFolderId, done)
- })
- })
- })
- it('should version a newly uploaded file', function(done) {
- const {
- fileUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/1pixel.png')
- expect(update.url).to.be.a('string')
- // one file upload
- verifyVersionIncremented(exampleProjectId, oldVersion, version, 1, done)
- })
- it('should version a replacement file', function(done) {
- MockDocUpdaterApi.clearProjectStructureUpdates()
- uploadFile(
- owner,
- exampleProjectId,
- rootFolderId,
- '2pixel.png',
- '1pixel.png',
- 'image/png',
- () => {
- const {
- fileUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(2)
- let update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/1pixel.png')
- update = updates[1]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/1pixel.png')
- expect(update.url).to.be.a('string')
- // two file uploads
- verifyVersionIncremented(
- exampleProjectId,
- oldVersion,
- version,
- 2,
- done
- )
- }
- )
- })
- })
- describe('moving entities', function() {
- let exampleProjectId,
- oldVersion,
- exampleDocId,
- exampleFileId,
- exampleFolderId
- beforeEach(function(done) {
- createExampleProject(owner, (err, projectId, rootFolderId) => {
- if (err) {
- return done(err)
- }
- exampleProjectId = projectId
- createExampleDoc(owner, projectId, (err, docId) => {
- if (err) {
- return done(err)
- }
- exampleDocId = docId
- uploadExampleFile(owner, projectId, rootFolderId, (err, fileId) => {
- if (err) {
- return done(err)
- }
- exampleFileId = fileId
- createExampleFolder(owner, projectId, (err, folderId) => {
- if (err) {
- return done(err)
- }
- exampleFolderId = folderId
- ProjectGetter.getProject(projectId, (error, project) => {
- if (error) {
- throw error
- }
- oldVersion = project.version
- MockDocUpdaterApi.clearProjectStructureUpdates()
- done()
- })
- })
- })
- })
- })
- })
- it('should version moving a doc', function(done) {
- moveItem(
- owner,
- exampleProjectId,
- 'doc',
- exampleDocId,
- exampleFolderId,
- () => {
- const {
- docUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/new.tex')
- expect(update.newPathname).to.equal('/foo/new.tex')
- // 2, because it's a delete and then add
- verifyVersionIncremented(
- exampleProjectId,
- oldVersion,
- version,
- 2,
- done
- )
- }
- )
- })
- it('should version moving a file', function(done) {
- moveItem(
- owner,
- exampleProjectId,
- 'file',
- exampleFileId,
- exampleFolderId,
- () => {
- const {
- fileUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/1pixel.png')
- expect(update.newPathname).to.equal('/foo/1pixel.png')
- // 2, because it's a delete and then add
- verifyVersionIncremented(
- exampleProjectId,
- oldVersion,
- version,
- 2,
- done
- )
- }
- )
- })
- it('should version moving a folder', function(done) {
- moveItem(
- owner,
- exampleProjectId,
- 'doc',
- exampleDocId,
- exampleFolderId,
- () => {
- MockDocUpdaterApi.clearProjectStructureUpdates()
- owner.request.post(
- {
- uri: `project/${exampleProjectId}/folder`,
- json: {
- name: 'bar'
- }
- },
- (error, res, body) => {
- if (error) {
- throw error
- }
- const newFolderId = body._id
- moveItem(
- owner,
- exampleProjectId,
- 'folder',
- exampleFolderId,
- newFolderId,
- () => {
- const {
- docUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(
- exampleProjectId
- )
- expect(updates.length).to.equal(1)
- let update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/foo/new.tex')
- expect(update.newPathname).to.equal('/bar/foo/new.tex')
- // 5, because it's two file moves plus a folder
- verifyVersionIncremented(
- exampleProjectId,
- oldVersion,
- version,
- 5,
- done
- )
- }
- )
- }
- )
- }
- )
- })
- })
- describe('renaming entities', function() {
- let exampleProjectId,
- exampleDocId,
- exampleFileId,
- exampleFolderId,
- oldVersion
- beforeEach(function(done) {
- createExampleProject(owner, (err, projectId, rootFolderId) => {
- if (err) {
- return done(err)
- }
- exampleProjectId = projectId
- createExampleDoc(owner, projectId, (err, docId) => {
- if (err) {
- return done(err)
- }
- exampleDocId = docId
- uploadExampleFile(owner, projectId, rootFolderId, (err, fileId) => {
- if (err) {
- return done(err)
- }
- exampleFileId = fileId
- createExampleFolder(owner, projectId, (err, folderId) => {
- if (err) {
- return done(err)
- }
- exampleFolderId = folderId
- moveItem(owner, projectId, 'doc', docId, folderId, () => {
- moveItem(owner, projectId, 'file', fileId, folderId, () => {
- MockDocUpdaterApi.clearProjectStructureUpdates()
- ProjectGetter.getProject(
- exampleProjectId,
- (error, project) => {
- if (error) {
- throw error
- }
- oldVersion = project.version
- done()
- }
- )
- })
- })
- })
- })
- })
- })
- })
- it('should version renaming a doc', function(done) {
- renameItem(
- owner,
- exampleProjectId,
- 'Doc',
- exampleDocId,
- 'wombat.tex',
- () => {
- const {
- docUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/foo/new.tex')
- expect(update.newPathname).to.equal('/foo/wombat.tex')
- verifyVersionIncremented(
- exampleProjectId,
- oldVersion,
- version,
- 1,
- done
- )
- }
- )
- })
- it('should version renaming a file', function(done) {
- renameItem(
- owner,
- exampleProjectId,
- 'file',
- exampleFileId,
- 'potato.png',
- () => {
- const {
- fileUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/foo/1pixel.png')
- expect(update.newPathname).to.equal('/foo/potato.png')
- verifyVersionIncremented(
- exampleProjectId,
- oldVersion,
- version,
- 1,
- done
- )
- }
- )
- })
- it('should version renaming a folder', function(done) {
- renameItem(
- owner,
- exampleProjectId,
- 'folder',
- exampleFolderId,
- 'giraffe',
- () => {
- const {
- docUpdates,
- fileUpdates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(docUpdates.length).to.equal(1)
- const docUpdate = docUpdates[0]
- expect(docUpdate.userId).to.equal(owner._id)
- expect(docUpdate.pathname).to.equal('/foo/new.tex')
- expect(docUpdate.newPathname).to.equal('/giraffe/new.tex')
- expect(fileUpdates.length).to.equal(1)
- const fileUpdate = fileUpdates[0]
- expect(fileUpdate.userId).to.equal(owner._id)
- expect(fileUpdate.pathname).to.equal('/foo/1pixel.png')
- expect(fileUpdate.newPathname).to.equal('/giraffe/1pixel.png')
- verifyVersionIncremented(
- exampleProjectId,
- oldVersion,
- version,
- 1,
- done
- )
- }
- )
- })
- })
- describe('deleting entities', function() {
- let exampleProjectId, oldVersion, exampleFolderId
- beforeEach(function(done) {
- createExampleProject(owner, (err, projectId) => {
- if (err) {
- return done(err)
- }
- exampleProjectId = projectId
- createExampleFolder(owner, exampleProjectId, (err, folderId) => {
- if (err) {
- return done(err)
- }
- exampleFolderId = folderId
- createExampleDoc(owner, projectId, (err, docId) => {
- if (err) {
- return done(err)
- }
- uploadExampleFile(owner, projectId, folderId, (err, fileId) => {
- if (err) {
- return done(err)
- }
- moveItem(owner, projectId, 'doc', docId, folderId, () => {
- moveItem(owner, projectId, 'file', fileId, folderId, () => {
- MockDocUpdaterApi.clearProjectStructureUpdates()
- ProjectGetter.getProject(
- exampleProjectId,
- (error, project) => {
- if (error) {
- throw error
- }
- oldVersion = project.version
- done()
- }
- )
- })
- })
- })
- })
- })
- })
- })
- it('should version deleting a folder', function(done) {
- deleteItem(owner, exampleProjectId, 'folder', exampleFolderId, () => {
- const {
- docUpdates,
- fileUpdates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(docUpdates.length).to.equal(1)
- const docUpdate = docUpdates[0]
- expect(docUpdate.userId).to.equal(owner._id)
- expect(docUpdate.pathname).to.equal('/foo/new.tex')
- expect(docUpdate.newPathname).to.equal('')
- expect(fileUpdates.length).to.equal(1)
- const fileUpdate = fileUpdates[0]
- expect(fileUpdate.userId).to.equal(owner._id)
- expect(fileUpdate.pathname).to.equal('/foo/1pixel.png')
- expect(fileUpdate.newPathname).to.equal('')
- verifyVersionIncremented(exampleProjectId, oldVersion, version, 1, done)
- })
- })
- })
- describe('deleting docs', function() {
- beforeEach(function(done) {
- createExampleProject(this, () => {
- createExampleFolder(this, () => {
- createExampleDoc(this, () => {
- MockDocUpdaterApi.clearProjectStructureUpdates()
- ProjectGetter.getProject(
- this.exampleProjectId,
- (error, project) => {
- if (error) {
- throw error
- }
- this.project0 = project
- done()
- }
- )
- })
- })
- })
- })
- describe('when rootDoc_id matches doc being deleted', function() {
- beforeEach(function(done) {
- Project.update(
- { _id: this.exampleProjectId },
- { $set: { rootDoc_id: this.exampleDocId } },
- done
- )
- })
- it('should clear rootDoc_id', function(done) {
- deleteItem(this, 'doc', this.exampleDocId, () => {
- ProjectGetter.getProject(this.exampleProjectId, (error, project) => {
- if (error) {
- throw error
- }
- expect(project.rootDoc_id).to.be.undefined
- done()
- })
- })
- })
- })
- describe('when rootDoc_id does not match doc being deleted', function() {
- beforeEach(function(done) {
- this.exampleRootDocId = new ObjectId()
- Project.update(
- { _id: this.exampleProjectId },
- { $set: { rootDoc_id: this.exampleRootDocId } },
- done
- )
- })
- it('should not clear rootDoc_id', function(done) {
- deleteItem(this, 'doc', this.exampleDocId, () => {
- ProjectGetter.getProject(this.exampleProjectId, (error, project) => {
- if (error) {
- throw error
- }
- expect(project.rootDoc_id.toString()).to.equal(
- this.exampleRootDocId.toString()
- )
- done()
- })
- })
- })
- })
- })
- describe('tpds', function() {
- let projectName, exampleProjectId, oldVersion, rootFolderId
- beforeEach(function(done) {
- projectName = `tpds-project-${new ObjectId().toString()}`
- owner.createProject(projectName, (error, projectId) => {
- if (error) {
- throw error
- }
- exampleProjectId = projectId
- mkdirp(Settings.path.dumpFolder, () => {
- ProjectGetter.getProject(exampleProjectId, (error, project) => {
- if (error) {
- throw error
- }
- MockDocUpdaterApi.clearProjectStructureUpdates()
- rootFolderId = project.rootFolder[0]._id.toString()
- oldVersion = project.version
- done()
- })
- })
- })
- })
- it('should version adding a doc', function(done) {
- const texFile = fs.createReadStream(
- Path.resolve(Path.join(__dirname, '..', 'files', 'test.tex'))
- )
- const req = owner.request.post({
- uri: `/user/${owner._id}/update/${projectName}/test.tex`,
- auth: {
- user: _.keys(Settings.httpAuthUsers)[0],
- pass: _.values(Settings.httpAuthUsers)[0],
- sendImmediately: true
- }
- })
- texFile.on('error', err => {
- throw err
- })
- req.on('error', err => {
- throw err
- })
- req.on('response', res => {
- if (res.statusCode < 200 || res.statusCode >= 300) {
- throw new Error(`failed to upload file ${res.statusCode}`)
- }
- const {
- docUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/test.tex')
- expect(update.docLines).to.equal('Test')
- verifyVersionIncremented(exampleProjectId, oldVersion, version, 1, done)
- })
- texFile.pipe(req)
- })
- it('should version adding a new file', function(done) {
- const imageFile = fs.createReadStream(
- Path.resolve(Path.join(__dirname, '..', 'files', '1pixel.png'))
- )
- const req = owner.request.post({
- uri: `/user/${owner._id}/update/${projectName}/1pixel.png`,
- auth: {
- user: _.keys(Settings.httpAuthUsers)[0],
- pass: _.values(Settings.httpAuthUsers)[0],
- sendImmediately: true
- }
- })
- imageFile.on('error', err => {
- throw err
- })
- req.on('error', err => {
- throw err
- })
- req.on('response', res => {
- if (res.statusCode < 200 || res.statusCode >= 300) {
- throw new Error(`failed to upload file ${res.statusCode}`)
- }
- const {
- fileUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/1pixel.png')
- expect(update.url).to.be.a('string')
- verifyVersionIncremented(exampleProjectId, oldVersion, version, 1, done)
- })
- imageFile.pipe(req)
- })
- describe('when there are files in the project', function() {
- beforeEach(function(done) {
- uploadExampleFile(owner, exampleProjectId, rootFolderId, () => {
- createExampleDoc(owner, exampleProjectId, () => {
- ProjectGetter.getProject(exampleProjectId, (error, project) => {
- if (error) {
- throw error
- }
- MockDocUpdaterApi.clearProjectStructureUpdates()
- oldVersion = project.version
- done()
- })
- })
- })
- })
- it('should version replacing a file', function(done) {
- const imageFile = fs.createReadStream(
- Path.resolve(Path.join(__dirname, '..', 'files', '2pixel.png'))
- )
- const req = owner.request.post({
- uri: `/user/${owner._id}/update/${projectName}/1pixel.png`,
- auth: {
- user: _.keys(Settings.httpAuthUsers)[0],
- pass: _.values(Settings.httpAuthUsers)[0],
- sendImmediately: true
- }
- })
- imageFile.on('error', err => {
- throw err
- })
- req.on('error', err => {
- throw err
- })
- req.on('response', res => {
- if (res.statusCode < 200 || res.statusCode >= 300) {
- throw new Error(`failed to upload file ${res.statusCode}`)
- }
- const {
- fileUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(2)
- let update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/1pixel.png')
- // expect(update.url).to.be.a('string');
- update = updates[1]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/1pixel.png')
- expect(update.url).to.be.a('string')
- verifyVersionIncremented(
- exampleProjectId,
- oldVersion,
- version,
- 1,
- done
- )
- })
- imageFile.pipe(req)
- })
- it('should version deleting a doc', function(done) {
- owner.request.delete(
- {
- uri: `/user/${owner._id}/update/${projectName}/new.tex`,
- auth: {
- user: _.keys(Settings.httpAuthUsers)[0],
- pass: _.values(Settings.httpAuthUsers)[0],
- sendImmediately: true
- }
- },
- (error, res) => {
- if (error) {
- throw error
- }
- if (res.statusCode < 200 || res.statusCode >= 300) {
- throw new Error(`failed to delete doc ${res.statusCode}`)
- }
- const {
- docUpdates: updates,
- version
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.userId).to.equal(owner._id)
- expect(update.pathname).to.equal('/new.tex')
- expect(update.newPathname).to.equal('')
- verifyVersionIncremented(
- exampleProjectId,
- oldVersion,
- version,
- 1,
- done
- )
- }
- )
- })
- })
- })
- describe('uploading a document', function() {
- let exampleProjectId, rootFolderId
- beforeEach(function(done) {
- createExampleProject(owner, (err, projectId, folderId) => {
- if (err) {
- return done(err)
- }
- exampleProjectId = projectId
- rootFolderId = folderId
- MockDocUpdaterApi.clearProjectStructureUpdates()
- done()
- })
- })
- describe('with an unusual character set', function() {
- it('should correctly handle utf16-le data', function(done) {
- uploadFile(
- owner,
- exampleProjectId,
- rootFolderId,
- 'charsets/test-greek-utf16-le-bom.tex',
- 'test-greek-utf16-le-bom.tex',
- 'text/x-tex',
- () => {
- const {
- docUpdates: updates
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.pathname).to.equal('/test-greek-utf16-le-bom.tex')
- expect(update.docLines).to.contain(
- 'Η γρήγορη καστανή αλεπού πήδηξε χαλαρά πάνω από το σκυλί.'
- )
- done()
- }
- )
- })
- it('should correctly handle windows1252/iso-8859-1/latin1 data', function(done) {
- uploadFile(
- owner,
- exampleProjectId,
- rootFolderId,
- 'charsets/test-german-windows-1252.tex',
- 'test-german-windows-1252.tex',
- 'text/x-tex',
- () => {
- const {
- docUpdates: updates
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.pathname).to.equal('/test-german-windows-1252.tex')
- expect(update.docLines).to.contain(
- 'Der schnelle braune Fuchs sprang träge über den Hund.'
- )
- done()
- }
- )
- })
- })
- })
- })
|