| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404 |
- const { expect } = require('chai')
- const mkdirp = require('mkdirp')
- const { ObjectId } = require('mongodb')
- 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 User = require('./helpers/User')
- const MockDocStoreApiClass = require('./mocks/MockDocstoreApi')
- const MockDocUpdaterApiClass = require('./mocks/MockDocUpdaterApi')
- let MockDocStoreApi, MockDocUpdaterApi
- before(function () {
- MockDocUpdaterApi = MockDocUpdaterApiClass.instance()
- MockDocStoreApi = MockDocStoreApiClass.instance()
- })
- 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
- ) {
- owner.uploadFileInProject(
- projectId,
- folderId,
- file,
- name,
- contentType,
- callback
- )
- }
- function uploadExampleFile(owner, projectId, folderId, callback) {
- owner.uploadExampleFileInProject(
- projectId,
- folderId,
- '1pixel.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.moveItemInProject(projectId, type, itemId, folderId, callback)
- }
- function renameItem(owner, projectId, type, itemId, name, callback) {
- owner.renameItemInProject(projectId, type, itemId, name, callback)
- }
- function deleteItem(owner, projectId, type, itemId, callback) {
- owner.deleteItemInProject(projectId, type, itemId, 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) {
- createExampleProject(owner, (err, projectId) => {
- exampleProjectId = projectId
- done(err)
- })
- })
- it('should version creating a doc and a file', function () {
- const { updates, version } = MockDocUpdaterApi.getProjectStructureUpdates(
- exampleProjectId
- )
- expect(updates.length).to.equal(3)
- for (const update of updates.slice(0, 2)) {
- expect(update.type).to.equal('add-doc')
- 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(updates[2].type).to.equal('add-file')
- expect(updates[2].userId).to.equal(owner._id)
- expect(updates[2].pathname).to.equal('/universe.jpg')
- expect(updates[2].url).to.be.a('string')
- expect(version).to.equal(3)
- })
- })
- describe('duplicating a project', function () {
- let dupProjectId
- beforeEach(function (done) {
- 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 and files created', function () {
- const { updates, version } = MockDocUpdaterApi.getProjectStructureUpdates(
- dupProjectId
- )
- expect(updates.length).to.equal(3)
- for (const update of updates.slice(0, 2)) {
- expect(update.type).to.equal('add-doc')
- 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(updates[2].type).to.equal('add-file')
- expect(updates[2].userId).to.equal(owner._id)
- expect(updates[2].pathname).to.equal('/universe.jpg')
- expect(updates[2].url).to.be.a('string')
- expect(version).to.equal(1)
- })
- })
- describe('adding a doc', function () {
- let exampleProjectId, oldVersion
- beforeEach(function (done) {
- createExampleProject(owner, (err, projectId) => {
- if (err) {
- return done(err)
- }
- exampleProjectId = projectId
- MockDocUpdaterApi.reset()
- 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 {
- updates,
- version: newVersion,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('add-doc')
- 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 and files created', function () {
- const { updates, version } = MockDocUpdaterApi.getProjectStructureUpdates(
- exampleProjectId
- )
- expect(updates.length).to.equal(2)
- expect(updates[0].type).to.equal('add-doc')
- expect(updates[0].userId).to.equal(owner._id)
- expect(updates[0].pathname).to.equal('/main.tex')
- expect(updates[0].docLines).to.equal('Test')
- expect(updates[1].type).to.equal('add-file')
- expect(updates[1].userId).to.equal(owner._id)
- expect(updates[1].pathname).to.equal('/1pixel.png')
- expect(updates[1].url).to.be.a('string')
- expect(version).to.equal(1)
- })
- })
- 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 updates
- beforeEach(function (done) {
- uploadExampleProject(owner, 'charsets/charsets.zip', (err, projectId) => {
- if (err) {
- return done(err)
- }
- updates = MockDocUpdaterApi.getProjectStructureUpdates(projectId)
- .updates
- done()
- })
- })
- it('should correctly parse windows-1252', function () {
- const update = _.find(
- updates,
- 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(
- updates,
- 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(
- updates,
- update => update.pathname === '/test-greek-utf16-le-bom.tex'
- )
- expect(update.docLines).to.contain(
- 'Η γρήγορη καστανή αλεπού πήδηξε χαλαρά πάνω από το σκυλί.'
- )
- })
- it('should correctly parse Greek utf8', function () {
- const update = _.find(
- updates,
- 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.reset()
- 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 { updates, version } = MockDocUpdaterApi.getProjectStructureUpdates(
- exampleProjectId
- )
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('add-file')
- 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.reset()
- uploadFile(
- owner,
- exampleProjectId,
- rootFolderId,
- '2pixel.png',
- '1pixel.png',
- 'image/png',
- () => {
- const {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(2)
- expect(updates[0].type).to.equal('rename-file')
- expect(updates[0].userId).to.equal(owner._id)
- expect(updates[0].pathname).to.equal('/1pixel.png')
- expect(updates[0].newPathname).to.equal('')
- expect(updates[1].type).to.equal('add-file')
- expect(updates[1].userId).to.equal(owner._id)
- expect(updates[1].pathname).to.equal('/1pixel.png')
- expect(updates[1].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.reset()
- done()
- })
- })
- })
- })
- })
- })
- it('should version moving a doc', function (done) {
- moveItem(
- owner,
- exampleProjectId,
- 'doc',
- exampleDocId,
- exampleFolderId,
- () => {
- const {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('rename-doc')
- 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 {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('rename-file')
- 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.reset()
- 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 {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(
- exampleProjectId
- )
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('rename-doc')
- 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.reset()
- 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 {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('rename-doc')
- 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 {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('rename-file')
- 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 {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(2)
- expect(updates[0].type).to.equal('rename-doc')
- expect(updates[0].userId).to.equal(owner._id)
- expect(updates[0].pathname).to.equal('/foo/new.tex')
- expect(updates[0].newPathname).to.equal('/giraffe/new.tex')
- expect(updates[1].type).to.equal('rename-file')
- expect(updates[1].userId).to.equal(owner._id)
- expect(updates[1].pathname).to.equal('/foo/1pixel.png')
- expect(updates[1].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.reset()
- 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 {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(2)
- expect(updates[0].type).to.equal('rename-doc')
- expect(updates[0].userId).to.equal(owner._id)
- expect(updates[0].pathname).to.equal('/foo/new.tex')
- expect(updates[0].newPathname).to.equal('')
- expect(updates[1].type).to.equal('rename-file')
- expect(updates[1].userId).to.equal(owner._id)
- expect(updates[1].pathname).to.equal('/foo/1pixel.png')
- expect(updates[1].newPathname).to.equal('')
- verifyVersionIncremented(exampleProjectId, oldVersion, version, 1, done)
- })
- })
- })
- describe('deleting docs', function () {
- beforeEach(function (done) {
- createExampleProject(owner, (err, projectId) => {
- if (err) {
- return done(err)
- }
- this.exampleProjectId = projectId
- createExampleFolder(owner, projectId, (err, folderId) => {
- if (err) {
- return done(err)
- }
- this.exampleFolderId = folderId
- createExampleDoc(owner, projectId, (err, docId) => {
- if (err) {
- return done(err)
- }
- this.exampleDocId = docId
- MockDocUpdaterApi.reset()
- ProjectGetter.getProject(
- this.exampleProjectId,
- (error, project) => {
- if (error) {
- throw error
- }
- this.project0 = project
- done()
- }
- )
- })
- })
- })
- })
- it('should pass the doc name to docstore', function (done) {
- deleteItem(
- owner,
- this.exampleProjectId,
- 'doc',
- this.exampleDocId,
- error => {
- if (error) return done(error)
- expect(
- MockDocStoreApi.getDeletedDocs(this.exampleProjectId)
- ).to.deep.equal([{ _id: this.exampleDocId, name: 'new.tex' }])
- done()
- }
- )
- })
- describe('when rootDoc_id matches doc being deleted', function () {
- beforeEach(function (done) {
- Project.updateOne(
- { _id: this.exampleProjectId },
- { $set: { rootDoc_id: this.exampleDocId } },
- done
- )
- })
- it('should clear rootDoc_id', function (done) {
- deleteItem(
- owner,
- this.exampleProjectId,
- '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.updateOne(
- { _id: this.exampleProjectId },
- { $set: { rootDoc_id: this.exampleRootDocId } },
- done
- )
- })
- it('should not clear rootDoc_id', function (done) {
- deleteItem(
- owner,
- this.exampleProjectId,
- '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.reset()
- 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 {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('add-doc')
- 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 {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('add-file')
- 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.reset()
- 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 {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(2)
- expect(updates[0].type).to.equal('rename-file')
- expect(updates[0].userId).to.equal(owner._id)
- expect(updates[0].pathname).to.equal('/1pixel.png')
- expect(updates[0].newPathname).to.equal('')
- expect(updates[1].type).to.equal('add-file')
- expect(updates[1].userId).to.equal(owner._id)
- expect(updates[1].pathname).to.equal('/1pixel.png')
- expect(updates[1].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 {
- updates,
- version,
- } = MockDocUpdaterApi.getProjectStructureUpdates(exampleProjectId)
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('rename-doc')
- 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.reset()
- 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 { updates } = MockDocUpdaterApi.getProjectStructureUpdates(
- exampleProjectId
- )
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('add-doc')
- 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 { updates } = MockDocUpdaterApi.getProjectStructureUpdates(
- exampleProjectId
- )
- expect(updates.length).to.equal(1)
- const update = updates[0]
- expect(update.type).to.equal('add-doc')
- 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()
- }
- )
- })
- })
- })
- })
|