diff --git a/services/track-changes/test/acceptance/js/AppendingUpdatesTests.js b/services/track-changes/test/acceptance/js/AppendingUpdatesTests.js index e2cda7f6e9..c20703d71f 100644 --- a/services/track-changes/test/acceptance/js/AppendingUpdatesTests.js +++ b/services/track-changes/test/acceptance/js/AppendingUpdatesTests.js @@ -10,384 +10,581 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -chai.should(); -const { expect } = chai; -const mongojs = require("../../../app/js/mongojs"); -const { ObjectId } = mongojs; -const Settings = require("settings-sharelatex"); -const request = require("request"); -const rclient = require("redis").createClient(Settings.redis.history); // Only works locally for now +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { expect } = chai +const mongojs = require('../../../app/js/mongojs') +const { ObjectId } = mongojs +const Settings = require('settings-sharelatex') +const request = require('request') +const rclient = require('redis').createClient(Settings.redis.history) // Only works locally for now -const TrackChangesApp = require("./helpers/TrackChangesApp"); -const TrackChangesClient = require("./helpers/TrackChangesClient"); -const MockWebApi = require("./helpers/MockWebApi"); +const TrackChangesApp = require('./helpers/TrackChangesApp') +const TrackChangesClient = require('./helpers/TrackChangesClient') +const MockWebApi = require('./helpers/MockWebApi') -describe("Appending doc ops to the history", function() { - before(function(done) { return TrackChangesApp.ensureRunning(done); }); +describe('Appending doc ops to the history', function() { + before(function(done) { + return TrackChangesApp.ensureRunning(done) + }) - describe("when the history does not exist yet", function() { - before(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); - MockWebApi.projects[this.project_id] = {features: {versioning: false}}; - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ i: "f", p: 3 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 3 - }, { - op: [{ i: "o", p: 4 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 4 - }, { - op: [{ i: "o", p: 5 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 5 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushAndGetCompressedUpdates(this.project_id, this.doc_id, (error, updates) => { - this.updates = updates; - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + describe('when the history does not exist yet', function() { + before(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() + MockWebApi.projects[this.project_id] = { features: { versioning: false } } + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [{ i: 'f', p: 3 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 3 + }, + { + op: [{ i: 'o', p: 4 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 4 + }, + { + op: [{ i: 'o', p: 5 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 5 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushAndGetCompressedUpdates( + this.project_id, + this.doc_id, + (error, updates) => { + this.updates = updates + if (error != null) { + throw error + } + return done() + } + ) + } + ) + return null + }) - it("should insert the compressed op into mongo", function() { - return expect(this.updates[0].pack[0].op).to.deep.equal([{ - p: 3, i: "foo" - }]); - }); + it('should insert the compressed op into mongo', function() { + return expect(this.updates[0].pack[0].op).to.deep.equal([ + { + p: 3, + i: 'foo' + } + ]) + }) - it("should insert the correct version number into mongo", function() { - return expect(this.updates[0].v).to.equal(5); - }); + it('should insert the correct version number into mongo', function() { + return expect(this.updates[0].v).to.equal(5) + }) - it("should store the doc id", function() { - return expect(this.updates[0].doc_id.toString()).to.equal(this.doc_id); - }); + it('should store the doc id', function() { + return expect(this.updates[0].doc_id.toString()).to.equal(this.doc_id) + }) - it("should store the project id", function() { - return expect(this.updates[0].project_id.toString()).to.equal(this.project_id); - }); + it('should store the project id', function() { + return expect(this.updates[0].project_id.toString()).to.equal( + this.project_id + ) + }) - return it("should clear the doc from the DocsWithHistoryOps set", function(done) { - rclient.sismember(`DocsWithHistoryOps:${this.project_id}`, this.doc_id, (error, member) => { - member.should.equal(0); - return done(); - }); - return null; - }); - }); + return it('should clear the doc from the DocsWithHistoryOps set', function(done) { + rclient.sismember( + `DocsWithHistoryOps:${this.project_id}`, + this.doc_id, + (error, member) => { + member.should.equal(0) + return done() + } + ) + return null + }) + }) - describe("when the history has already been started", function() { - beforeEach(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); - MockWebApi.projects[this.project_id] = {features: {versioning: false}}; - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ i: "f", p: 3 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 3 - }, { - op: [{ i: "o", p: 4 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 4 - }, { - op: [{ i: "o", p: 5 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 5 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushAndGetCompressedUpdates(this.project_id, this.doc_id, (error, updates) => { - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + describe('when the history has already been started', function() { + beforeEach(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() + MockWebApi.projects[this.project_id] = { features: { versioning: false } } + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [{ i: 'f', p: 3 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 3 + }, + { + op: [{ i: 'o', p: 4 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 4 + }, + { + op: [{ i: 'o', p: 5 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 5 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushAndGetCompressedUpdates( + this.project_id, + this.doc_id, + (error, updates) => { + if (error != null) { + throw error + } + return done() + } + ) + } + ) + return null + }) - describe("when the updates are recent and from the same user", function() { - beforeEach(function(done) { - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ i: "b", p: 6 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 6 - }, { - op: [{ i: "a", p: 7 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 7 - }, { - op: [{ i: "r", p: 8 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 8 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushAndGetCompressedUpdates(this.project_id, this.doc_id, (error, updates) => { - this.updates = updates; - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + describe('when the updates are recent and from the same user', function() { + beforeEach(function(done) { + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [{ i: 'b', p: 6 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 6 + }, + { + op: [{ i: 'a', p: 7 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 7 + }, + { + op: [{ i: 'r', p: 8 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 8 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushAndGetCompressedUpdates( + this.project_id, + this.doc_id, + (error, updates) => { + this.updates = updates + if (error != null) { + throw error + } + return done() + } + ) + } + ) + return null + }) - it("should combine all the updates into one pack", function() { - return expect(this.updates[0].pack[1].op).to.deep.equal([{ - p: 6, i: "bar" - }]); - }); + it('should combine all the updates into one pack', function() { + return expect(this.updates[0].pack[1].op).to.deep.equal([ + { + p: 6, + i: 'bar' + } + ]) + }) - return it("should insert the correct version number into mongo", function() { - return expect(this.updates[0].v_end).to.equal(8); - }); - }); + return it('should insert the correct version number into mongo', function() { + return expect(this.updates[0].v_end).to.equal(8) + }) + }) + return describe('when the updates are far apart', function() { + beforeEach(function(done) { + const oneDay = 24 * 60 * 60 * 1000 + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [{ i: 'b', p: 6 }], + meta: { ts: Date.now() + oneDay, user_id: this.user_id }, + v: 6 + }, + { + op: [{ i: 'a', p: 7 }], + meta: { ts: Date.now() + oneDay, user_id: this.user_id }, + v: 7 + }, + { + op: [{ i: 'r', p: 8 }], + meta: { ts: Date.now() + oneDay, user_id: this.user_id }, + v: 8 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushAndGetCompressedUpdates( + this.project_id, + this.doc_id, + (error, updates) => { + this.updates = updates + if (error != null) { + throw error + } + return done() + } + ) + } + ) + return null + }) - return describe("when the updates are far apart", function() { - beforeEach(function(done) { - const oneDay = 24 * 60 * 60 * 1000; - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ i: "b", p: 6 }], - meta: { ts: Date.now() + oneDay, user_id: this.user_id }, - v: 6 - }, { - op: [{ i: "a", p: 7 }], - meta: { ts: Date.now() + oneDay, user_id: this.user_id }, - v: 7 - }, { - op: [{ i: "r", p: 8 }], - meta: { ts: Date.now() + oneDay, user_id: this.user_id }, - v: 8 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushAndGetCompressedUpdates(this.project_id, this.doc_id, (error, updates) => { - this.updates = updates; - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + return it('should combine the updates into one pack', function() { + expect(this.updates[0].pack[0].op).to.deep.equal([ + { + p: 3, + i: 'foo' + } + ]) + return expect(this.updates[0].pack[1].op).to.deep.equal([ + { + p: 6, + i: 'bar' + } + ]) + }) + }) + }) - return it("should combine the updates into one pack", function() { - expect(this.updates[0].pack[0].op).to.deep.equal([{ - p: 3, i: "foo" - }]); - return expect(this.updates[0].pack[1].op).to.deep.equal([{ - p: 6, i: "bar" - }]); - }); - }); -}); + describe('when the updates need processing in batches', function() { + before(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() + MockWebApi.projects[this.project_id] = { features: { versioning: false } } + const updates = [] + this.expectedOp = [{ p: 0, i: '' }] + for (let i = 0; i <= 250; i++) { + updates.push({ + op: [{ i: 'a', p: 0 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: i + }) + this.expectedOp[0].i = `a${this.expectedOp[0].i}` + } - describe("when the updates need processing in batches", function() { - before(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); - MockWebApi.projects[this.project_id] = {features: {versioning: false}}; - const updates = []; - this.expectedOp = [{ p:0, i: "" }]; - for (let i = 0; i <= 250; i++) { - updates.push({ - op: [{i: "a", p: 0}], - meta: { ts: Date.now(), user_id: this.user_id }, - v: i - }); - this.expectedOp[0].i = `a${this.expectedOp[0].i}`; - } + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + updates, + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushAndGetCompressedUpdates( + this.project_id, + this.doc_id, + (error, updates1) => { + this.updates = updates1 + if (error != null) { + throw error + } + return done() + } + ) + } + ) + return null + }) - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, updates, error => { - if (error != null) { throw error; } - return TrackChangesClient.flushAndGetCompressedUpdates(this.project_id, this.doc_id, (error, updates1) => { - this.updates = updates1; - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + it('should concat the compressed op into mongo', function() { + return expect(this.updates[0].pack.length).to.deep.equal(3) + }) // batch size is 100 - it("should concat the compressed op into mongo", function() { - return expect(this.updates[0].pack.length).to.deep.equal(3); - }); // batch size is 100 + return it('should insert the correct version number into mongo', function() { + return expect(this.updates[0].v_end).to.equal(250) + }) + }) - return it("should insert the correct version number into mongo", function() { - return expect(this.updates[0].v_end).to.equal(250); - }); - }); + describe('when there are multiple ops in each update', function() { + before(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() + MockWebApi.projects[this.project_id] = { features: { versioning: false } } + const oneDay = 24 * 60 * 60 * 1000 + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [ + { i: 'f', p: 3 }, + { i: 'o', p: 4 }, + { i: 'o', p: 5 } + ], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 3 + }, + { + op: [ + { i: 'b', p: 6 }, + { i: 'a', p: 7 }, + { i: 'r', p: 8 } + ], + meta: { ts: Date.now() + oneDay, user_id: this.user_id }, + v: 4 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushAndGetCompressedUpdates( + this.project_id, + this.doc_id, + (error, updates) => { + this.updates = updates + if (error != null) { + throw error + } + return done() + } + ) + } + ) + return null + }) + it('should insert the compressed ops into mongo', function() { + expect(this.updates[0].pack[0].op).to.deep.equal([ + { + p: 3, + i: 'foo' + } + ]) + return expect(this.updates[0].pack[1].op).to.deep.equal([ + { + p: 6, + i: 'bar' + } + ]) + }) - describe("when there are multiple ops in each update", function() { - before(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); - MockWebApi.projects[this.project_id] = {features: {versioning: false}}; - const oneDay = 24 * 60 * 60 * 1000; - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ i: "f", p: 3 }, { i: "o", p: 4 }, { i: "o", p: 5 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 3 - }, { - op: [{ i: "b", p: 6 }, { i: "a", p: 7 }, { i: "r", p: 8 }], - meta: { ts: Date.now() + oneDay, user_id: this.user_id }, - v: 4 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushAndGetCompressedUpdates(this.project_id, this.doc_id, (error, updates) => { - this.updates = updates; - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + return it('should insert the correct version numbers into mongo', function() { + expect(this.updates[0].pack[0].v).to.equal(3) + return expect(this.updates[0].pack[1].v).to.equal(4) + }) + }) - it("should insert the compressed ops into mongo", function() { - expect(this.updates[0].pack[0].op).to.deep.equal([{ - p: 3, i: "foo" - }]); - return expect(this.updates[0].pack[1].op).to.deep.equal([{ - p: 6, i: "bar" - }]); - }); + describe('when there is a no-op update', function() { + before(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() + MockWebApi.projects[this.project_id] = { features: { versioning: false } } + const oneDay = 24 * 60 * 60 * 1000 + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 3 + }, + { + op: [{ i: 'foo', p: 3 }], + meta: { ts: Date.now() + oneDay, user_id: this.user_id }, + v: 4 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushAndGetCompressedUpdates( + this.project_id, + this.doc_id, + (error, updates) => { + this.updates = updates + if (error != null) { + throw error + } + return done() + } + ) + } + ) + return null + }) - return it("should insert the correct version numbers into mongo", function() { - expect(this.updates[0].pack[0].v).to.equal(3); - return expect(this.updates[0].pack[1].v).to.equal(4); - }); - }); + it('should insert the compressed no-op into mongo', function() { + return expect(this.updates[0].pack[0].op).to.deep.equal([]) + }) - describe("when there is a no-op update", function() { - before(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); - MockWebApi.projects[this.project_id] = {features: {versioning: false}}; - const oneDay = 24 * 60 * 60 * 1000; - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 3 - }, { - op: [{ i: "foo", p: 3 }], - meta: { ts: Date.now() + oneDay, user_id: this.user_id }, - v: 4 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushAndGetCompressedUpdates(this.project_id, this.doc_id, (error, updates) => { - this.updates = updates; - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + it('should insert the compressed next update into mongo', function() { + return expect(this.updates[0].pack[1].op).to.deep.equal([ + { + p: 3, + i: 'foo' + } + ]) + }) - it("should insert the compressed no-op into mongo", function() { - return expect(this.updates[0].pack[0].op).to.deep.equal([]); - }); + return it('should insert the correct version numbers into mongo', function() { + expect(this.updates[0].pack[0].v).to.equal(3) + return expect(this.updates[0].pack[1].v).to.equal(4) + }) + }) + describe('when there is a comment update', function() { + before(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() + MockWebApi.projects[this.project_id] = { features: { versioning: false } } + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [ + { c: 'foo', p: 3 }, + { d: 'bar', p: 6 } + ], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 3 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushAndGetCompressedUpdates( + this.project_id, + this.doc_id, + (error, updates) => { + this.updates = updates + if (error != null) { + throw error + } + return done() + } + ) + } + ) + return null + }) - it("should insert the compressed next update into mongo", function() { - return expect(this.updates[0].pack[1].op).to.deep.equal([{ - p: 3, i: "foo" - }]); - }); + it('should ignore the comment op', function() { + return expect(this.updates[0].pack[0].op).to.deep.equal([ + { d: 'bar', p: 6 } + ]) + }) - return it("should insert the correct version numbers into mongo", function() { - expect(this.updates[0].pack[0].v).to.equal(3); - return expect(this.updates[0].pack[1].v).to.equal(4); - }); - }); + return it('should insert the correct version numbers into mongo', function() { + return expect(this.updates[0].pack[0].v).to.equal(3) + }) + }) - describe("when there is a comment update", function() { - before(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); - MockWebApi.projects[this.project_id] = {features: {versioning: false}}; - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ c: "foo", p: 3 }, {d: "bar", p: 6}], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 3 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushAndGetCompressedUpdates(this.project_id, this.doc_id, (error, updates) => { - this.updates = updates; - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + describe('when the project has versioning enabled', function() { + before(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() + MockWebApi.projects[this.project_id] = { features: { versioning: true } } - it("should ignore the comment op", function() { - return expect(this.updates[0].pack[0].op).to.deep.equal([{d: "bar", p: 6}]); - }); + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [{ i: 'f', p: 3 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 3 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushAndGetCompressedUpdates( + this.project_id, + this.doc_id, + (error, updates) => { + this.updates = updates + if (error != null) { + throw error + } + return done() + } + ) + } + ) + return null + }) - return it("should insert the correct version numbers into mongo", function() { - return expect(this.updates[0].pack[0].v).to.equal(3); - }); - }); + return it('should not add a expiresAt entry in the update in mongo', function() { + return expect(this.updates[0].expiresAt).to.be.undefined + }) + }) - describe("when the project has versioning enabled", function() { - before(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); - MockWebApi.projects[this.project_id] = {features: {versioning: true}}; + return describe('when the project does not have versioning enabled', function() { + before(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() + MockWebApi.projects[this.project_id] = { features: { versioning: false } } - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ i: "f", p: 3 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 3 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushAndGetCompressedUpdates(this.project_id, this.doc_id, (error, updates) => { - this.updates = updates; - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [{ i: 'f', p: 3 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 3 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushAndGetCompressedUpdates( + this.project_id, + this.doc_id, + (error, updates) => { + this.updates = updates + if (error != null) { + throw error + } + return done() + } + ) + } + ) + return null + }) - return it("should not add a expiresAt entry in the update in mongo", function() { - return expect(this.updates[0].expiresAt).to.be.undefined; - }); - }); - - return describe("when the project does not have versioning enabled", function() { - before(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); - MockWebApi.projects[this.project_id] = {features: {versioning: false}}; - - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ i: "f", p: 3 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 3 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushAndGetCompressedUpdates(this.project_id, this.doc_id, (error, updates) => { - this.updates = updates; - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); - - return it("should add a expiresAt entry in the update in mongo", function() { - return expect(this.updates[0].expiresAt).to.exist; - }); - }); -}); + return it('should add a expiresAt entry in the update in mongo', function() { + return expect(this.updates[0].expiresAt).to.exist + }) + }) +}) diff --git a/services/track-changes/test/acceptance/js/ArchivingUpdatesTests.js b/services/track-changes/test/acceptance/js/ArchivingUpdatesTests.js index ceee1767ce..d66ed60940 100644 --- a/services/track-changes/test/acceptance/js/ArchivingUpdatesTests.js +++ b/services/track-changes/test/acceptance/js/ArchivingUpdatesTests.js @@ -14,176 +14,260 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -chai.should(); -const { expect } = chai; -const mongojs = require("../../../app/js/mongojs"); -const { db } = mongojs; -const { ObjectId } = mongojs; -const Settings = require("settings-sharelatex"); -const request = require("request"); -const rclient = require("redis").createClient(Settings.redis.history); // Only works locally for now +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { expect } = chai +const mongojs = require('../../../app/js/mongojs') +const { db } = mongojs +const { ObjectId } = mongojs +const Settings = require('settings-sharelatex') +const request = require('request') +const rclient = require('redis').createClient(Settings.redis.history) // Only works locally for now -const TrackChangesApp = require("./helpers/TrackChangesApp"); -const TrackChangesClient = require("./helpers/TrackChangesClient"); -const MockDocStoreApi = require("./helpers/MockDocStoreApi"); -const MockWebApi = require("./helpers/MockWebApi"); +const TrackChangesApp = require('./helpers/TrackChangesApp') +const TrackChangesClient = require('./helpers/TrackChangesClient') +const MockDocStoreApi = require('./helpers/MockDocStoreApi') +const MockWebApi = require('./helpers/MockWebApi') -describe("Archiving updates", function() { - before(function(done) { - if (__guard__(__guard__(Settings != null ? Settings.trackchanges : undefined, x1 => x1.s3), x => x.key.length) < 1) { - const message = new Error("s3 keys not setup, this test setup will fail"); - return done(message); - } +describe('Archiving updates', function() { + before(function(done) { + if ( + __guard__( + __guard__( + Settings != null ? Settings.trackchanges : undefined, + x1 => x1.s3 + ), + x => x.key.length + ) < 1 + ) { + const message = new Error('s3 keys not setup, this test setup will fail') + return done(message) + } - return TrackChangesClient.waitForS3(done); - }); + return TrackChangesClient.waitForS3(done) + }) - before(function(done) { - this.now = Date.now(); - this.to = this.now; - this.user_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.project_id = ObjectId().toString(); + before(function(done) { + this.now = Date.now() + this.to = this.now + this.user_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.project_id = ObjectId().toString() - this.minutes = 60 * 1000; - this.hours = 60 * this.minutes; + this.minutes = 60 * 1000 + this.hours = 60 * this.minutes - MockWebApi.projects[this.project_id] = { - features: { - versioning: true - } - }; - sinon.spy(MockWebApi, "getProjectDetails"); + MockWebApi.projects[this.project_id] = { + features: { + versioning: true + } + } + sinon.spy(MockWebApi, 'getProjectDetails') - MockWebApi.users[this.user_id] = (this.user = { - email: "user@sharelatex.com", - first_name: "Leo", - last_name: "Lion", - id: this.user_id - }); - sinon.spy(MockWebApi, "getUserInfo"); + MockWebApi.users[this.user_id] = this.user = { + email: 'user@sharelatex.com', + first_name: 'Leo', + last_name: 'Lion', + id: this.user_id + } + sinon.spy(MockWebApi, 'getUserInfo') - MockDocStoreApi.docs[this.doc_id] = (this.doc = { - _id: this.doc_id, - project_id: this.project_id - }); - sinon.spy(MockDocStoreApi, "getAllDoc"); + MockDocStoreApi.docs[this.doc_id] = this.doc = { + _id: this.doc_id, + project_id: this.project_id + } + sinon.spy(MockDocStoreApi, 'getAllDoc') - this.updates = []; - for (let i = 0, end = 512+10, asc = end >= 0; asc ? i <= end : i >= end; asc ? i++ : i--) { - this.updates.push({ - op: [{ i: "a", p: 0 }], - meta: { ts: this.now + ((i-2048) * this.hours), user_id: this.user_id }, - v: (2 * i) + 1 - }); - this.updates.push({ - op: [{ i: "b", p: 0 }], - meta: { ts: this.now + ((i-2048) * this.hours) + (10*this.minutes), user_id: this.user_id }, - v: (2 * i) + 2 - }); - } - TrackChangesApp.ensureRunning(() => { - return TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, this.updates, error => { - if (error != null) { throw error; } - return TrackChangesClient.flushDoc(this.project_id, this.doc_id, (error) => { - if (error != null) { throw error; } - return done(); - }); - }); - }); - return null; - }); + this.updates = [] + for ( + let i = 0, end = 512 + 10, asc = end >= 0; + asc ? i <= end : i >= end; + asc ? i++ : i-- + ) { + this.updates.push({ + op: [{ i: 'a', p: 0 }], + meta: { ts: this.now + (i - 2048) * this.hours, user_id: this.user_id }, + v: 2 * i + 1 + }) + this.updates.push({ + op: [{ i: 'b', p: 0 }], + meta: { + ts: this.now + (i - 2048) * this.hours + 10 * this.minutes, + user_id: this.user_id + }, + v: 2 * i + 2 + }) + } + TrackChangesApp.ensureRunning(() => { + return TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + this.updates, + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushDoc( + this.project_id, + this.doc_id, + error => { + if (error != null) { + throw error + } + return done() + } + ) + } + ) + }) + return null + }) - after(function(done) { - MockWebApi.getUserInfo.restore(); - return db.docHistory.remove({project_id: ObjectId(this.project_id)}, () => { - return db.docHistoryIndex.remove({project_id: ObjectId(this.project_id)}, () => { - return TrackChangesClient.removeS3Doc(this.project_id, this.doc_id, done); - }); - }); - }); + after(function(done) { + MockWebApi.getUserInfo.restore() + return db.docHistory.remove( + { project_id: ObjectId(this.project_id) }, + () => { + return db.docHistoryIndex.remove( + { project_id: ObjectId(this.project_id) }, + () => { + return TrackChangesClient.removeS3Doc( + this.project_id, + this.doc_id, + done + ) + } + ) + } + ) + }) - describe("archiving a doc's updates", function() { - before(function(done) { - TrackChangesClient.pushDocHistory(this.project_id, this.doc_id, (error) => { - if (error != null) { throw error; } - return done(); - }); - return null; - }); + describe("archiving a doc's updates", function() { + before(function(done) { + TrackChangesClient.pushDocHistory(this.project_id, this.doc_id, error => { + if (error != null) { + throw error + } + return done() + }) + return null + }) - it("should have one cached pack", function(done) { - return db.docHistory.count({ doc_id: ObjectId(this.doc_id), expiresAt:{$exists:true}}, (error, count) => { - if (error != null) { throw error; } - count.should.equal(1); - return done(); - }); - }); + it('should have one cached pack', function(done) { + return db.docHistory.count( + { doc_id: ObjectId(this.doc_id), expiresAt: { $exists: true } }, + (error, count) => { + if (error != null) { + throw error + } + count.should.equal(1) + return done() + } + ) + }) - it("should have one remaining pack after cache is expired", function(done) { - return db.docHistory.remove({ - doc_id: ObjectId(this.doc_id), - expiresAt:{$exists:true} - }, (err, result) => { - if (typeof error !== 'undefined' && error !== null) { throw error; } - return db.docHistory.count({ doc_id: ObjectId(this.doc_id)}, (error, count) => { - if (error != null) { throw error; } - count.should.equal(1); - return done(); - }); - }); - }); + it('should have one remaining pack after cache is expired', function(done) { + return db.docHistory.remove( + { + doc_id: ObjectId(this.doc_id), + expiresAt: { $exists: true } + }, + (err, result) => { + if (typeof error !== 'undefined' && error !== null) { + throw error + } + return db.docHistory.count( + { doc_id: ObjectId(this.doc_id) }, + (error, count) => { + if (error != null) { + throw error + } + count.should.equal(1) + return done() + } + ) + } + ) + }) - it("should have a docHistoryIndex entry marked as inS3", function(done) { - return db.docHistoryIndex.findOne({ _id: ObjectId(this.doc_id) }, (error, index) => { - if (error != null) { throw error; } - index.packs[0].inS3.should.equal(true); - return done(); - }); - }); + it('should have a docHistoryIndex entry marked as inS3', function(done) { + return db.docHistoryIndex.findOne( + { _id: ObjectId(this.doc_id) }, + (error, index) => { + if (error != null) { + throw error + } + index.packs[0].inS3.should.equal(true) + return done() + } + ) + }) - it("should have a docHistoryIndex entry with the last version", function(done) { - return db.docHistoryIndex.findOne({ _id: ObjectId(this.doc_id) }, (error, index) => { - if (error != null) { throw error; } - index.packs[0].v_end.should.equal(1024); - return done(); - }); - }); + it('should have a docHistoryIndex entry with the last version', function(done) { + return db.docHistoryIndex.findOne( + { _id: ObjectId(this.doc_id) }, + (error, index) => { + if (error != null) { + throw error + } + index.packs[0].v_end.should.equal(1024) + return done() + } + ) + }) - return it("should store 1024 doc changes in S3 in one pack", function(done) { - return db.docHistoryIndex.findOne({ _id: ObjectId(this.doc_id) }, (error, index) => { - if (error != null) { throw error; } - const pack_id = index.packs[0]._id; - return TrackChangesClient.getS3Doc(this.project_id, this.doc_id, pack_id, (error, doc) => { - doc.n.should.equal(1024); - doc.pack.length.should.equal(1024); - return done(); - }); - }); - }); - }); + return it('should store 1024 doc changes in S3 in one pack', function(done) { + return db.docHistoryIndex.findOne( + { _id: ObjectId(this.doc_id) }, + (error, index) => { + if (error != null) { + throw error + } + const pack_id = index.packs[0]._id + return TrackChangesClient.getS3Doc( + this.project_id, + this.doc_id, + pack_id, + (error, doc) => { + doc.n.should.equal(1024) + doc.pack.length.should.equal(1024) + return done() + } + ) + } + ) + }) + }) - return describe("unarchiving a doc's updates", function() { - before(function(done) { - TrackChangesClient.pullDocHistory(this.project_id, this.doc_id, (error) => { - if (error != null) { throw error; } - return done(); - }); - return null; - }); + return describe("unarchiving a doc's updates", function() { + before(function(done) { + TrackChangesClient.pullDocHistory(this.project_id, this.doc_id, error => { + if (error != null) { + throw error + } + return done() + }) + return null + }) - return it("should restore both packs", function(done) { - return db.docHistory.count({ doc_id: ObjectId(this.doc_id) }, (error, count) => { - if (error != null) { throw error; } - count.should.equal(2); - return done(); - }); - }); - }); -}); + return it('should restore both packs', function(done) { + return db.docHistory.count( + { doc_id: ObjectId(this.doc_id) }, + (error, count) => { + if (error != null) { + throw error + } + count.should.equal(2) + return done() + } + ) + }) + }) +}) function __guard__(value, transform) { - return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined; -} \ No newline at end of file + return typeof value !== 'undefined' && value !== null + ? transform(value) + : undefined +} diff --git a/services/track-changes/test/acceptance/js/FlushingUpdatesTests.js b/services/track-changes/test/acceptance/js/FlushingUpdatesTests.js index bc7a6b886a..9eaf86e85e 100644 --- a/services/track-changes/test/acceptance/js/FlushingUpdatesTests.js +++ b/services/track-changes/test/acceptance/js/FlushingUpdatesTests.js @@ -10,188 +10,267 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -chai.should(); -const { expect } = chai; -const mongojs = require("../../../app/js/mongojs"); -const { ObjectId } = mongojs; -const Settings = require("settings-sharelatex"); -const request = require("request"); -const rclient = require("redis").createClient(Settings.redis.history); // Only works locally for now +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { expect } = chai +const mongojs = require('../../../app/js/mongojs') +const { ObjectId } = mongojs +const Settings = require('settings-sharelatex') +const request = require('request') +const rclient = require('redis').createClient(Settings.redis.history) // Only works locally for now -const TrackChangesApp = require("./helpers/TrackChangesApp"); -const TrackChangesClient = require("./helpers/TrackChangesClient"); -const MockWebApi = require("./helpers/MockWebApi"); +const TrackChangesApp = require('./helpers/TrackChangesApp') +const TrackChangesClient = require('./helpers/TrackChangesClient') +const MockWebApi = require('./helpers/MockWebApi') -describe("Flushing updates", function() { - before(function(done) { return TrackChangesApp.ensureRunning(done); }); +describe('Flushing updates', function() { + before(function(done) { + return TrackChangesApp.ensureRunning(done) + }) - describe("flushing a doc's updates", function() { - before(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); - MockWebApi.projects[this.project_id] = {features: {versioning: true}}; + describe("flushing a doc's updates", function() { + before(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() + MockWebApi.projects[this.project_id] = { features: { versioning: true } } - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ i: "f", p: 3 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 3 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushDoc(this.project_id, this.doc_id, (error) => { - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [{ i: 'f', p: 3 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 3 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushDoc( + this.project_id, + this.doc_id, + error => { + if (error != null) { + throw error + } + return done() + } + ) + } + ) + return null + }) - return it("should flush the op into mongo", function(done) { - TrackChangesClient.getCompressedUpdates(this.doc_id, (error, updates) => { - expect(updates[0].pack[0].op).to.deep.equal([{ - p: 3, i: "f" - }]); - return done(); - }); - return null; - }); - }); + return it('should flush the op into mongo', function(done) { + TrackChangesClient.getCompressedUpdates(this.doc_id, (error, updates) => { + expect(updates[0].pack[0].op).to.deep.equal([ + { + p: 3, + i: 'f' + } + ]) + return done() + }) + return null + }) + }) - return describe("flushing a project's updates", function() { - describe("with versioning enabled", function() { - before(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); + return describe("flushing a project's updates", function() { + describe('with versioning enabled', function() { + before(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() - this.weeks = 7 * 24 * 60 * 60 * 1000; + this.weeks = 7 * 24 * 60 * 60 * 1000 - MockWebApi.projects[this.project_id] = { - features: { - versioning: true - } - }; + MockWebApi.projects[this.project_id] = { + features: { + versioning: true + } + } - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ i: "g", p: 2 }], - meta: { ts: Date.now() - (2 * this.weeks), user_id: this.user_id }, - v: 2 - }, { - op: [{ i: "f", p: 3 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 3 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushProject(this.project_id, (error) => { - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [{ i: 'g', p: 2 }], + meta: { ts: Date.now() - 2 * this.weeks, user_id: this.user_id }, + v: 2 + }, + { + op: [{ i: 'f', p: 3 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 3 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushProject(this.project_id, error => { + if (error != null) { + throw error + } + return done() + }) + } + ) + return null + }) - it("should not mark the updates for deletion", function(done) { - TrackChangesClient.getCompressedUpdates(this.doc_id, (error, updates) => { - expect(updates[0].expiresAt).to.not.exist; - return done(); - }); - return null; - }); + it('should not mark the updates for deletion', function(done) { + TrackChangesClient.getCompressedUpdates( + this.doc_id, + (error, updates) => { + expect(updates[0].expiresAt).to.not.exist + return done() + } + ) + return null + }) - return it("should preserve history forever", function(done) { - TrackChangesClient.getProjectMetaData(this.project_id, (error, project) => { - expect(project.preserveHistory).to.equal(true); - return done(); - }); - return null; - }); - }); + return it('should preserve history forever', function(done) { + TrackChangesClient.getProjectMetaData( + this.project_id, + (error, project) => { + expect(project.preserveHistory).to.equal(true) + return done() + } + ) + return null + }) + }) - describe("without versioning enabled", function() { - before(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); + describe('without versioning enabled', function() { + before(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() - this.weeks = 7 * 24 * 60 * 60 * 1000; + this.weeks = 7 * 24 * 60 * 60 * 1000 - MockWebApi.projects[this.project_id] = { - features: { - versioning: false - } - }; + MockWebApi.projects[this.project_id] = { + features: { + versioning: false + } + } - TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ i: "g", p: 2 }], - meta: { ts: Date.now() - (2 * this.weeks), user_id: this.user_id }, - v: 2 - }, { - op: [{ i: "f", p: 3 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 3 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushProject(this.project_id, (error) => { - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [{ i: 'g', p: 2 }], + meta: { ts: Date.now() - 2 * this.weeks, user_id: this.user_id }, + v: 2 + }, + { + op: [{ i: 'f', p: 3 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 3 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushProject(this.project_id, error => { + if (error != null) { + throw error + } + return done() + }) + } + ) + return null + }) - return it("should mark the updates for deletion", function(done) { - TrackChangesClient.getCompressedUpdates(this.doc_id, (error, updates) => { - expect(updates[0].expiresAt).to.exist; - return done(); - }); - return null; - }); - }); + return it('should mark the updates for deletion', function(done) { + TrackChangesClient.getCompressedUpdates( + this.doc_id, + (error, updates) => { + expect(updates[0].expiresAt).to.exist + return done() + } + ) + return null + }) + }) - return describe("without versioning enabled but with preserveHistory set to true", function() { - before(function(done) { - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.user_id = ObjectId().toString(); + return describe('without versioning enabled but with preserveHistory set to true', function() { + before(function(done) { + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.user_id = ObjectId().toString() - this.weeks = 7 * 24 * 60 * 60 * 1000; + this.weeks = 7 * 24 * 60 * 60 * 1000 - MockWebApi.projects[this.project_id] = { - features: { - versioning: false - } - }; + MockWebApi.projects[this.project_id] = { + features: { + versioning: false + } + } - TrackChangesClient.setPreserveHistoryForProject(this.project_id, error => { - if (error != null) { throw error; } - return TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, [{ - op: [{ i: "g", p: 2 }], - meta: { ts: Date.now() - (2 * this.weeks), user_id: this.user_id }, - v: 2 - }, { - op: [{ i: "f", p: 3 }], - meta: { ts: Date.now(), user_id: this.user_id }, - v: 3 - }], error => { - if (error != null) { throw error; } - return TrackChangesClient.flushProject(this.project_id, (error) => { - if (error != null) { throw error; } - return done(); - }); - }); - }); - return null; - }); + TrackChangesClient.setPreserveHistoryForProject( + this.project_id, + error => { + if (error != null) { + throw error + } + return TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + [ + { + op: [{ i: 'g', p: 2 }], + meta: { + ts: Date.now() - 2 * this.weeks, + user_id: this.user_id + }, + v: 2 + }, + { + op: [{ i: 'f', p: 3 }], + meta: { ts: Date.now(), user_id: this.user_id }, + v: 3 + } + ], + error => { + if (error != null) { + throw error + } + return TrackChangesClient.flushProject( + this.project_id, + error => { + if (error != null) { + throw error + } + return done() + } + ) + } + ) + } + ) + return null + }) - return it("should not mark the updates for deletion", function(done) { - TrackChangesClient.getCompressedUpdates(this.doc_id, (error, updates) => { - expect(updates[0].expiresAt).to.not.exist; - return done(); - }); - return null; - }); - }); - }); -}); + return it('should not mark the updates for deletion', function(done) { + TrackChangesClient.getCompressedUpdates( + this.doc_id, + (error, updates) => { + expect(updates[0].expiresAt).to.not.exist + return done() + } + ) + return null + }) + }) + }) +}) diff --git a/services/track-changes/test/acceptance/js/GettingADiffTests.js b/services/track-changes/test/acceptance/js/GettingADiffTests.js index 7dd63698ea..871258b30d 100644 --- a/services/track-changes/test/acceptance/js/GettingADiffTests.js +++ b/services/track-changes/test/acceptance/js/GettingADiffTests.js @@ -9,97 +9,123 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -chai.should(); -const { expect } = chai; -const mongojs = require("../../../app/js/mongojs"); -const { db } = mongojs; -const { ObjectId } = mongojs; -const Settings = require("settings-sharelatex"); +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { expect } = chai +const mongojs = require('../../../app/js/mongojs') +const { db } = mongojs +const { ObjectId } = mongojs +const Settings = require('settings-sharelatex') -const TrackChangesApp = require("./helpers/TrackChangesApp"); -const TrackChangesClient = require("./helpers/TrackChangesClient"); -const MockDocUpdaterApi = require("./helpers/MockDocUpdaterApi"); -const MockWebApi = require("./helpers/MockWebApi"); +const TrackChangesApp = require('./helpers/TrackChangesApp') +const TrackChangesClient = require('./helpers/TrackChangesClient') +const MockDocUpdaterApi = require('./helpers/MockDocUpdaterApi') +const MockWebApi = require('./helpers/MockWebApi') -describe("Getting a diff", function() { +describe('Getting a diff', function() { + beforeEach(function(done) { + sinon.spy(MockDocUpdaterApi, 'getDoc') - beforeEach(function(done) { - sinon.spy(MockDocUpdaterApi, "getDoc"); + this.now = Date.now() + this.from = this.now - 100000000 + this.to = this.now + this.user_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.project_id = ObjectId().toString() + MockWebApi.projects[this.project_id] = { features: { versioning: true } } - this.now = Date.now(); - this.from = this.now - 100000000; - this.to = this.now; - this.user_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.project_id = ObjectId().toString(); - MockWebApi.projects[this.project_id] = {features: {versioning: true}}; + MockWebApi.users[this.user_id] = this.user = { + email: 'user@sharelatex.com', + first_name: 'Leo', + last_name: 'Lion', + id: this.user_id + } + sinon.spy(MockWebApi, 'getUserInfo') - MockWebApi.users[this.user_id] = (this.user = { - email: "user@sharelatex.com", - first_name: "Leo", - last_name: "Lion", - id: this.user_id - }); - sinon.spy(MockWebApi, "getUserInfo"); + const twoMinutes = 2 * 60 * 1000 - const twoMinutes = 2 * 60 * 1000; + this.updates = [ + { + op: [{ i: 'one ', p: 0 }], + meta: { ts: this.from - twoMinutes, user_id: this.user_id }, + v: 3 + }, + { + op: [{ i: 'two ', p: 4 }], + meta: { ts: this.from + twoMinutes, user_id: this.user_id }, + v: (this.fromVersion = 4) + }, + { + op: [{ i: 'three ', p: 8 }], + meta: { ts: this.to - twoMinutes, user_id: this.user_id }, + v: (this.toVersion = 5) + }, + { + op: [{ i: 'four', p: 14 }], + meta: { ts: this.to + twoMinutes, user_id: this.user_id }, + v: 6 + } + ] + this.lines = ['one two three four'] + this.expected_diff = [ + { u: 'one ' }, + { + i: 'two three ', + meta: { + start_ts: this.from + twoMinutes, + end_ts: this.to - twoMinutes, + user: this.user + } + } + ] - this.updates = [{ - op: [{ i: "one ", p: 0 }], - meta: { ts: this.from - twoMinutes, user_id: this.user_id }, - v: 3 - }, { - op: [{ i: "two ", p: 4 }], - meta: { ts: this.from + twoMinutes, user_id: this.user_id }, - v: (this.fromVersion = 4) - }, { - op: [{ i: "three ", p: 8 }], - meta: { ts: this.to - twoMinutes, user_id: this.user_id }, - v: (this.toVersion = 5) - }, { - op: [{ i: "four", p: 14 }], - meta: { ts: this.to + twoMinutes, user_id: this.user_id }, - v: 6 - }]; - this.lines = ["one two three four"]; - this.expected_diff = [ - { u: "one " }, - { i: "two three ", meta: { start_ts: this.from + twoMinutes, end_ts: this.to - twoMinutes, user: this.user } } - ]; + MockDocUpdaterApi.docs[this.doc_id] = { + lines: this.lines, + version: 7 + } + TrackChangesApp.ensureRunning(() => { + return TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + this.updates, + error => { + if (error != null) { + throw error + } + return TrackChangesClient.getDiff( + this.project_id, + this.doc_id, + this.fromVersion, + this.toVersion, + (error, diff) => { + if (error != null) { + throw error + } + this.diff = diff.diff + return done() + } + ) + } + ) + }) + return null + }) - MockDocUpdaterApi.docs[this.doc_id] = { - lines: this.lines, - version: 7 - }; - TrackChangesApp.ensureRunning(() => { - return TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, this.updates, error => { - if (error != null) { throw error; } - return TrackChangesClient.getDiff(this.project_id, this.doc_id, this.fromVersion, this.toVersion, (error, diff) => { - if (error != null) { throw error; } - this.diff = diff.diff; - return done(); - }); - }); - }); - return null; - }); + afterEach(function() { + MockDocUpdaterApi.getDoc.restore() + MockWebApi.getUserInfo.restore() + return null + }) - afterEach(function() { - MockDocUpdaterApi.getDoc.restore(); - MockWebApi.getUserInfo.restore(); - return null; - }); + it('should return the diff', function() { + return expect(this.diff).to.deep.equal(this.expected_diff) + }) - it("should return the diff", function() { - return expect(this.diff).to.deep.equal(this.expected_diff); - }); - - return it("should get the doc from the doc updater", function() { - MockDocUpdaterApi.getDoc - .calledWith(this.project_id, this.doc_id) - .should.equal(true); - return null; - }); -}); + return it('should get the doc from the doc updater', function() { + MockDocUpdaterApi.getDoc + .calledWith(this.project_id, this.doc_id) + .should.equal(true) + return null + }) +}) diff --git a/services/track-changes/test/acceptance/js/GettingUpdatesTests.js b/services/track-changes/test/acceptance/js/GettingUpdatesTests.js index 299ba96afd..d9cd43f1f8 100644 --- a/services/track-changes/test/acceptance/js/GettingUpdatesTests.js +++ b/services/track-changes/test/acceptance/js/GettingUpdatesTests.js @@ -10,154 +10,181 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -chai.should(); -const { expect } = chai; -const mongojs = require("../../../app/js/mongojs"); -const { db } = mongojs; -const { ObjectId } = mongojs; -const Settings = require("settings-sharelatex"); +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { expect } = chai +const mongojs = require('../../../app/js/mongojs') +const { db } = mongojs +const { ObjectId } = mongojs +const Settings = require('settings-sharelatex') -const TrackChangesApp = require("./helpers/TrackChangesApp"); -const TrackChangesClient = require("./helpers/TrackChangesClient"); -const MockWebApi = require("./helpers/MockWebApi"); +const TrackChangesApp = require('./helpers/TrackChangesApp') +const TrackChangesClient = require('./helpers/TrackChangesClient') +const MockWebApi = require('./helpers/MockWebApi') -describe("Getting updates", function() { - before(function(done) { - this.now = Date.now(); - this.to = this.now; - this.user_id = ObjectId().toString(); - this.deleted_user_id = 'deleted_user'; - this.doc_id = ObjectId().toString(); - this.project_id = ObjectId().toString(); +describe('Getting updates', function() { + before(function(done) { + this.now = Date.now() + this.to = this.now + this.user_id = ObjectId().toString() + this.deleted_user_id = 'deleted_user' + this.doc_id = ObjectId().toString() + this.project_id = ObjectId().toString() - this.minutes = 60 * 1000; - this.hours = 60 * this.minutes; + this.minutes = 60 * 1000 + this.hours = 60 * this.minutes - MockWebApi.projects[this.project_id] = { - features: { - versioning: true - } - }; + MockWebApi.projects[this.project_id] = { + features: { + versioning: true + } + } - MockWebApi.users[this.user_id] = (this.user = { - email: "user@sharelatex.com", - first_name: "Leo", - last_name: "Lion", - id: this.user_id - }); - sinon.spy(MockWebApi, "getUserInfo"); + MockWebApi.users[this.user_id] = this.user = { + email: 'user@sharelatex.com', + first_name: 'Leo', + last_name: 'Lion', + id: this.user_id + } + sinon.spy(MockWebApi, 'getUserInfo') - this.updates = []; - for (let i = 0; i <= 9; i++) { - this.updates.push({ - op: [{ i: "a", p: 0 }], - meta: { ts: this.now - ((9 - i) * this.hours) - (2 * this.minutes), user_id: this.user_id }, - v: (2 * i) + 1 - }); - this.updates.push({ - op: [{ i: "b", p: 0 }], - meta: { ts: this.now - ((9 - i) * this.hours), user_id: this.user_id }, - v: (2 * i) + 2 - }); - } - this.updates[0].meta.user_id = this.deleted_user_id; + this.updates = [] + for (let i = 0; i <= 9; i++) { + this.updates.push({ + op: [{ i: 'a', p: 0 }], + meta: { + ts: this.now - (9 - i) * this.hours - 2 * this.minutes, + user_id: this.user_id + }, + v: 2 * i + 1 + }) + this.updates.push({ + op: [{ i: 'b', p: 0 }], + meta: { ts: this.now - (9 - i) * this.hours, user_id: this.user_id }, + v: 2 * i + 2 + }) + } + this.updates[0].meta.user_id = this.deleted_user_id - TrackChangesApp.ensureRunning(() => { - return TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, this.updates, error => { - if (error != null) { throw error; } - return done(); - }); - }); - return null; - }); + TrackChangesApp.ensureRunning(() => { + return TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + this.updates, + error => { + if (error != null) { + throw error + } + return done() + } + ) + }) + return null + }) - ({ - after() { - MockWebApi.getUserInfo.restore(); - return null; - } - }); + ;({ + after() { + MockWebApi.getUserInfo.restore() + return null + } + }) - describe("getting updates up to the limit", function() { - before(function(done) { - TrackChangesClient.getUpdates(this.project_id, { before: this.to + 1, min_count: 3 }, (error, body) => { - if (error != null) { throw error; } - this.updates = body.updates; - return done(); - }); - return null; - }); + describe('getting updates up to the limit', function() { + before(function(done) { + TrackChangesClient.getUpdates( + this.project_id, + { before: this.to + 1, min_count: 3 }, + (error, body) => { + if (error != null) { + throw error + } + this.updates = body.updates + return done() + } + ) + return null + }) - it("should fetch the user details from the web api", function() { - return MockWebApi.getUserInfo - .calledWith(this.user_id) - .should.equal(true); - }); + it('should fetch the user details from the web api', function() { + return MockWebApi.getUserInfo.calledWith(this.user_id).should.equal(true) + }) - return it("should return at least the min_count number of summarized updates", function() { - const docs1 = {}; - docs1[this.doc_id] = {toV: 20, fromV: 19}; - const docs2 = {}; - docs2[this.doc_id] = {toV: 18, fromV: 17}; - const docs3 = {}; - docs3[this.doc_id] = {toV: 16, fromV: 15}; - return expect(this.updates.slice(0,3)).to.deep.equal([{ - docs: docs1, - meta: { - start_ts: this.to - (2 * this.minutes), - end_ts: this.to, - users: [this.user] - } - }, { - docs: docs2, - meta: { - start_ts: this.to - (1 * this.hours) - (2 * this.minutes), - end_ts: this.to - (1 * this.hours), - users: [this.user] - } - }, { - docs: docs3, - meta: { - start_ts: this.to - (2 * this.hours) - (2 * this.minutes), - end_ts: this.to - (2 * this.hours), - users: [this.user] - } - }]); - }); -}); + return it('should return at least the min_count number of summarized updates', function() { + const docs1 = {} + docs1[this.doc_id] = { toV: 20, fromV: 19 } + const docs2 = {} + docs2[this.doc_id] = { toV: 18, fromV: 17 } + const docs3 = {} + docs3[this.doc_id] = { toV: 16, fromV: 15 } + return expect(this.updates.slice(0, 3)).to.deep.equal([ + { + docs: docs1, + meta: { + start_ts: this.to - 2 * this.minutes, + end_ts: this.to, + users: [this.user] + } + }, + { + docs: docs2, + meta: { + start_ts: this.to - 1 * this.hours - 2 * this.minutes, + end_ts: this.to - 1 * this.hours, + users: [this.user] + } + }, + { + docs: docs3, + meta: { + start_ts: this.to - 2 * this.hours - 2 * this.minutes, + end_ts: this.to - 2 * this.hours, + users: [this.user] + } + } + ]) + }) + }) - return describe("getting updates beyond the end of the database", function() { - before(function(done) { - TrackChangesClient.getUpdates(this.project_id, { before: (this.to - (8 * this.hours)) + 1, min_count: 30 }, (error, body) => { - if (error != null) { throw error; } - this.updates = body.updates; - return done(); - }); - return null; - }); + return describe('getting updates beyond the end of the database', function() { + before(function(done) { + TrackChangesClient.getUpdates( + this.project_id, + { before: this.to - 8 * this.hours + 1, min_count: 30 }, + (error, body) => { + if (error != null) { + throw error + } + this.updates = body.updates + return done() + } + ) + return null + }) - return it("should return as many updates as it can", function() { - const docs1 = {}; - docs1[this.doc_id] = {toV: 4, fromV: 3}; - const docs2 = {}; - docs2[this.doc_id] = {toV: 2, fromV: 1}; - return expect(this.updates).to.deep.equal([{ - docs: docs1, - meta: { - start_ts: this.to - (8 * this.hours) - (2 * this.minutes), - end_ts: this.to - (8 * this.hours), - users: [this.user] - } - }, { - docs: docs2, - meta: { - start_ts: this.to - (9 * this.hours) - (2 * this.minutes), - end_ts: this.to - (9 * this.hours), - users: [this.user, null] - } - }]); - }); -}); -}); + return it('should return as many updates as it can', function() { + const docs1 = {} + docs1[this.doc_id] = { toV: 4, fromV: 3 } + const docs2 = {} + docs2[this.doc_id] = { toV: 2, fromV: 1 } + return expect(this.updates).to.deep.equal([ + { + docs: docs1, + meta: { + start_ts: this.to - 8 * this.hours - 2 * this.minutes, + end_ts: this.to - 8 * this.hours, + users: [this.user] + } + }, + { + docs: docs2, + meta: { + start_ts: this.to - 9 * this.hours - 2 * this.minutes, + end_ts: this.to - 9 * this.hours, + users: [this.user, null] + } + } + ]) + }) + }) +}) diff --git a/services/track-changes/test/acceptance/js/LockManagerTests.js b/services/track-changes/test/acceptance/js/LockManagerTests.js index 19e0a13914..ad5352ae44 100644 --- a/services/track-changes/test/acceptance/js/LockManagerTests.js +++ b/services/track-changes/test/acceptance/js/LockManagerTests.js @@ -9,52 +9,58 @@ * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -chai.should(); -const { expect } = chai; -const mongojs = require("../../../app/js/mongojs"); -const { ObjectId } = mongojs; -const Settings = require("settings-sharelatex"); -const LockManager = require("../../../app/js/LockManager"); -const rclient = require("redis").createClient(Settings.redis.history); // Only works locally for now -const TrackChangesApp = require("./helpers/TrackChangesApp"); +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { expect } = chai +const mongojs = require('../../../app/js/mongojs') +const { ObjectId } = mongojs +const Settings = require('settings-sharelatex') +const LockManager = require('../../../app/js/LockManager') +const rclient = require('redis').createClient(Settings.redis.history) // Only works locally for now +const TrackChangesApp = require('./helpers/TrackChangesApp') -describe("Locking document", function() { +describe('Locking document', function() { + before(function(done) { + TrackChangesApp.ensureRunning(done) + return null + }) - before(function(done){ - TrackChangesApp.ensureRunning(done); - return null; - }); - - return describe("when the lock has expired in redis", function() { - before(function(done) { - LockManager.LOCK_TTL = 1; // second - LockManager.runWithLock("doc123", releaseA => { - // we create a lock A and allow it to expire in redis - return setTimeout(() => - // now we create a new lock B and try to release A - LockManager.runWithLock("doc123", releaseB => { - return releaseA(); - } // try to release lock A to see if it wipes out lock B - , (error) => {}) - - // we never release lock B so nothing should happen here - , 1500); - } // enough time to wait until the lock has expired - , error => - // we get here after trying to release lock A - done() - ); - return null; - }); + return describe('when the lock has expired in redis', function() { + before(function(done) { + LockManager.LOCK_TTL = 1 // second + LockManager.runWithLock( + 'doc123', + releaseA => { + // we create a lock A and allow it to expire in redis + return setTimeout( + () => + // now we create a new lock B and try to release A + LockManager.runWithLock( + 'doc123', + releaseB => { + return releaseA() + }, // try to release lock A to see if it wipes out lock B + error => {} + ), - return it("the new lock should not be removed by the expired locker", function(done) { - LockManager.checkLock("doc123", (err, isFree) => { - expect(isFree).to.equal(false); - return done(); - }); - return null; - }); - }); -}); + // we never release lock B so nothing should happen here + 1500 + ) + }, // enough time to wait until the lock has expired + error => + // we get here after trying to release lock A + done() + ) + return null + }) + + return it('the new lock should not be removed by the expired locker', function(done) { + LockManager.checkLock('doc123', (err, isFree) => { + expect(isFree).to.equal(false) + return done() + }) + return null + }) + }) +}) diff --git a/services/track-changes/test/acceptance/js/RestoringVersions.js b/services/track-changes/test/acceptance/js/RestoringVersions.js index 3c03848a8b..bfa55e8ba2 100644 --- a/services/track-changes/test/acceptance/js/RestoringVersions.js +++ b/services/track-changes/test/acceptance/js/RestoringVersions.js @@ -9,86 +9,112 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -chai.should(); -const { expect } = chai; -const mongojs = require("../../../app/js/mongojs"); -const { db } = mongojs; -const { ObjectId } = mongojs; -const Settings = require("settings-sharelatex"); +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { expect } = chai +const mongojs = require('../../../app/js/mongojs') +const { db } = mongojs +const { ObjectId } = mongojs +const Settings = require('settings-sharelatex') -const TrackChangesApp = require("./helpers/TrackChangesApp"); -const TrackChangesClient = require("./helpers/TrackChangesClient"); -const MockDocUpdaterApi = require("./helpers/MockDocUpdaterApi"); -const MockWebApi = require("./helpers/MockWebApi"); +const TrackChangesApp = require('./helpers/TrackChangesApp') +const TrackChangesClient = require('./helpers/TrackChangesClient') +const MockDocUpdaterApi = require('./helpers/MockDocUpdaterApi') +const MockWebApi = require('./helpers/MockWebApi') -describe("Restoring a version", function() { - before(function(done) { - sinon.spy(MockDocUpdaterApi, "setDoc"); +describe('Restoring a version', function() { + before(function(done) { + sinon.spy(MockDocUpdaterApi, 'setDoc') - this.now = Date.now(); - this.user_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.project_id = ObjectId().toString(); - MockWebApi.projects[this.project_id] = {features: {versioning: true}}; - - const minutes = 60 * 1000; + this.now = Date.now() + this.user_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.project_id = ObjectId().toString() + MockWebApi.projects[this.project_id] = { features: { versioning: true } } - this.updates = [{ - op: [{ i: "one ", p: 0 }], - meta: { ts: this.now - (6 * minutes), user_id: this.user_id }, - v: 3 - }, { - op: [{ i: "two ", p: 4 }], - meta: { ts: this.now - (4 * minutes), user_id: this.user_id }, - v: 4 - }, { - op: [{ i: "three ", p: 8 }], - meta: { ts: this.now - (2 * minutes), user_id: this.user_id }, - v: 5 - }, { - op: [{ i: "four", p: 14 }], - meta: { ts: this.now, user_id: this.user_id }, - v: 6 - }]; - this.lines = ["one two three four"]; - this.restored_lines = ["one two "]; - this.beforeVersion = 5; + const minutes = 60 * 1000 - MockWebApi.users[this.user_id] = (this.user = { - email: "user@sharelatex.com", - first_name: "Leo", - last_name: "Lion", - id: this.user_id - }); + this.updates = [ + { + op: [{ i: 'one ', p: 0 }], + meta: { ts: this.now - 6 * minutes, user_id: this.user_id }, + v: 3 + }, + { + op: [{ i: 'two ', p: 4 }], + meta: { ts: this.now - 4 * minutes, user_id: this.user_id }, + v: 4 + }, + { + op: [{ i: 'three ', p: 8 }], + meta: { ts: this.now - 2 * minutes, user_id: this.user_id }, + v: 5 + }, + { + op: [{ i: 'four', p: 14 }], + meta: { ts: this.now, user_id: this.user_id }, + v: 6 + } + ] + this.lines = ['one two three four'] + this.restored_lines = ['one two '] + this.beforeVersion = 5 - MockDocUpdaterApi.docs[this.doc_id] = { - lines: this.lines, - version: 7 - }; + MockWebApi.users[this.user_id] = this.user = { + email: 'user@sharelatex.com', + first_name: 'Leo', + last_name: 'Lion', + id: this.user_id + } - TrackChangesApp.ensureRunning(() => { - return TrackChangesClient.pushRawUpdates(this.project_id, this.doc_id, this.updates, error => { - if (error != null) { throw error; } - return TrackChangesClient.restoreDoc(this.project_id, this.doc_id, this.beforeVersion, this.user_id, error => { - if (error != null) { throw error; } - return done(); - }); - }); - }); - return null; - }); + MockDocUpdaterApi.docs[this.doc_id] = { + lines: this.lines, + version: 7 + } - after(function() { - MockDocUpdaterApi.setDoc.restore(); - return null; - }); + TrackChangesApp.ensureRunning(() => { + return TrackChangesClient.pushRawUpdates( + this.project_id, + this.doc_id, + this.updates, + error => { + if (error != null) { + throw error + } + return TrackChangesClient.restoreDoc( + this.project_id, + this.doc_id, + this.beforeVersion, + this.user_id, + error => { + if (error != null) { + throw error + } + return done() + } + ) + } + ) + }) + return null + }) - return it("should set the doc in the doc updater", function() { - MockDocUpdaterApi.setDoc - .calledWith(this.project_id, this.doc_id, this.restored_lines, this.user_id, true) - .should.equal(true); - return null; - }); -}); + after(function() { + MockDocUpdaterApi.setDoc.restore() + return null + }) + + return it('should set the doc in the doc updater', function() { + MockDocUpdaterApi.setDoc + .calledWith( + this.project_id, + this.doc_id, + this.restored_lines, + this.user_id, + true + ) + .should.equal(true) + return null + }) +}) diff --git a/services/track-changes/test/acceptance/js/helpers/MockDocStoreApi.js b/services/track-changes/test/acceptance/js/helpers/MockDocStoreApi.js index c55260a007..8ebaf68081 100644 --- a/services/track-changes/test/acceptance/js/helpers/MockDocStoreApi.js +++ b/services/track-changes/test/acceptance/js/helpers/MockDocStoreApi.js @@ -10,40 +10,45 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let MockDocUpdaterApi; -const express = require("express"); -const app = express(); +let MockDocUpdaterApi +const express = require('express') +const app = express() -module.exports = (MockDocUpdaterApi = { - docs: {}, +module.exports = MockDocUpdaterApi = { + docs: {}, - getAllDoc(project_id, callback) { - if (callback == null) { callback = function(error) {}; } - return callback(null, this.docs); - }, + getAllDoc(project_id, callback) { + if (callback == null) { + callback = function(error) {} + } + return callback(null, this.docs) + }, - run() { - app.get("/project/:project_id/doc", (req, res, next) => { - return this.getAllDoc(req.params.project_id, (error, docs) => { - if (error != null) { - res.send(500); - } - if ((docs == null)) { - return res.send(404); - } else { - return res.send(JSON.stringify(docs)); - } - }); - }); + run() { + app.get('/project/:project_id/doc', (req, res, next) => { + return this.getAllDoc(req.params.project_id, (error, docs) => { + if (error != null) { + res.send(500) + } + if (docs == null) { + return res.send(404) + } else { + return res.send(JSON.stringify(docs)) + } + }) + }) - return app.listen(3016, (error) => { - if (error != null) { throw error; } - }).on("error", (error) => { - console.error("error starting MockDocStoreApi:", error.message); - return process.exit(1); - }); - } -}); - -MockDocUpdaterApi.run(); + return app + .listen(3016, error => { + if (error != null) { + throw error + } + }) + .on('error', error => { + console.error('error starting MockDocStoreApi:', error.message) + return process.exit(1) + }) + } +} +MockDocUpdaterApi.run() diff --git a/services/track-changes/test/acceptance/js/helpers/MockDocUpdaterApi.js b/services/track-changes/test/acceptance/js/helpers/MockDocUpdaterApi.js index 8ba6f2c6b2..38a4136d9f 100644 --- a/services/track-changes/test/acceptance/js/helpers/MockDocUpdaterApi.js +++ b/services/track-changes/test/acceptance/js/helpers/MockDocUpdaterApi.js @@ -11,58 +11,81 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let MockDocUpdaterApi; -const express = require("express"); -const app = express(); +let MockDocUpdaterApi +const express = require('express') +const app = express() -module.exports = (MockDocUpdaterApi = { - docs: {}, +module.exports = MockDocUpdaterApi = { + docs: {}, - getDoc(project_id, doc_id, callback) { - if (callback == null) { callback = function(error) {}; } - return callback(null, this.docs[doc_id]); - }, + getDoc(project_id, doc_id, callback) { + if (callback == null) { + callback = function(error) {} + } + return callback(null, this.docs[doc_id]) + }, - setDoc(project_id, doc_id, lines, user_id, undoing, callback) { - if (callback == null) { callback = function(error) {}; } - if (!this.docs[doc_id]) { this.docs[doc_id] = {}; } - this.docs[doc_id].lines = lines; - return callback(); - }, + setDoc(project_id, doc_id, lines, user_id, undoing, callback) { + if (callback == null) { + callback = function(error) {} + } + if (!this.docs[doc_id]) { + this.docs[doc_id] = {} + } + this.docs[doc_id].lines = lines + return callback() + }, - run() { - app.get("/project/:project_id/doc/:doc_id", (req, res, next) => { - return this.getDoc(req.params.project_id, req.params.doc_id, (error, doc) => { - if (error != null) { - res.send(500); - } - if ((doc == null)) { - return res.send(404); - } else { - return res.send(JSON.stringify(doc)); - } - }); - }); + run() { + app.get('/project/:project_id/doc/:doc_id', (req, res, next) => { + return this.getDoc( + req.params.project_id, + req.params.doc_id, + (error, doc) => { + if (error != null) { + res.send(500) + } + if (doc == null) { + return res.send(404) + } else { + return res.send(JSON.stringify(doc)) + } + } + ) + }) - app.post("/project/:project_id/doc/:doc_id", express.bodyParser(), (req, res, next) => { - return this.setDoc(req.params.project_id, req.params.doc_id, req.body.lines, req.body.user_id, req.body.undoing, (errr, doc) => { - if (typeof error !== 'undefined' && error !== null) { - return res.send(500); - } else { - return res.send(204); - } - }); - }); + app.post( + '/project/:project_id/doc/:doc_id', + express.bodyParser(), + (req, res, next) => { + return this.setDoc( + req.params.project_id, + req.params.doc_id, + req.body.lines, + req.body.user_id, + req.body.undoing, + (errr, doc) => { + if (typeof error !== 'undefined' && error !== null) { + return res.send(500) + } else { + return res.send(204) + } + } + ) + } + ) - return app.listen(3003, (error) => { - if (error != null) { throw error; } - }).on("error", (error) => { - console.error("error starting MockDocUpdaterApi:", error.message); - return process.exit(1); - }); - } -}); - - -MockDocUpdaterApi.run(); + return app + .listen(3003, error => { + if (error != null) { + throw error + } + }) + .on('error', error => { + console.error('error starting MockDocUpdaterApi:', error.message) + return process.exit(1) + }) + } +} +MockDocUpdaterApi.run() diff --git a/services/track-changes/test/acceptance/js/helpers/MockWebApi.js b/services/track-changes/test/acceptance/js/helpers/MockWebApi.js index cf1350f97d..ebf1b05e18 100644 --- a/services/track-changes/test/acceptance/js/helpers/MockWebApi.js +++ b/services/track-changes/test/acceptance/js/helpers/MockWebApi.js @@ -10,60 +10,67 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let MockWebApi; -const express = require("express"); -const app = express(); +let MockWebApi +const express = require('express') +const app = express() -module.exports = (MockWebApi = { - users: {}, +module.exports = MockWebApi = { + users: {}, - projects: {}, + projects: {}, - getUserInfo(user_id, callback) { - if (callback == null) { callback = function(error) {}; } - return callback(null, this.users[user_id] || null); - }, + getUserInfo(user_id, callback) { + if (callback == null) { + callback = function(error) {} + } + return callback(null, this.users[user_id] || null) + }, - getProjectDetails(project_id, callback) { - if (callback == null) { callback = function(error, project) {}; } - return callback(null, this.projects[project_id]); - }, + getProjectDetails(project_id, callback) { + if (callback == null) { + callback = function(error, project) {} + } + return callback(null, this.projects[project_id]) + }, - run() { - app.get("/user/:user_id/personal_info", (req, res, next) => { - return this.getUserInfo(req.params.user_id, (error, user) => { - if (error != null) { - res.send(500); - } - if ((user == null)) { - return res.send(404); - } else { - return res.send(JSON.stringify(user)); - } - }); - }); + run() { + app.get('/user/:user_id/personal_info', (req, res, next) => { + return this.getUserInfo(req.params.user_id, (error, user) => { + if (error != null) { + res.send(500) + } + if (user == null) { + return res.send(404) + } else { + return res.send(JSON.stringify(user)) + } + }) + }) - app.get("/project/:project_id/details", (req, res, next) => { - return this.getProjectDetails(req.params.project_id, (error, project) => { - if (error != null) { - res.send(500); - } - if ((project == null)) { - return res.send(404); - } else { - return res.send(JSON.stringify(project)); - } - }); - }); + app.get('/project/:project_id/details', (req, res, next) => { + return this.getProjectDetails(req.params.project_id, (error, project) => { + if (error != null) { + res.send(500) + } + if (project == null) { + return res.send(404) + } else { + return res.send(JSON.stringify(project)) + } + }) + }) - return app.listen(3000, (error) => { - if (error != null) { throw error; } - }).on("error", (error) => { - console.error("error starting MockWebApiServer:", error.message); - return process.exit(1); - }); - } -}); - -MockWebApi.run(); + return app + .listen(3000, error => { + if (error != null) { + throw error + } + }) + .on('error', error => { + console.error('error starting MockWebApiServer:', error.message) + return process.exit(1) + }) + } +} +MockWebApi.run() diff --git a/services/track-changes/test/acceptance/js/helpers/TrackChangesApp.js b/services/track-changes/test/acceptance/js/helpers/TrackChangesApp.js index 464961c689..1ce662548e 100644 --- a/services/track-changes/test/acceptance/js/helpers/TrackChangesApp.js +++ b/services/track-changes/test/acceptance/js/helpers/TrackChangesApp.js @@ -12,40 +12,55 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const app = require('../../../../app'); -require("logger-sharelatex"); -const logger = require("logger-sharelatex"); -const Settings = require("settings-sharelatex"); +const app = require('../../../../app') +require('logger-sharelatex') +const logger = require('logger-sharelatex') +const Settings = require('settings-sharelatex') module.exports = { - running: false, - initing: false, - callbacks: [], - ensureRunning(callback) { - if (callback == null) { callback = function(error) {}; } - if (this.running) { - return callback(); - } else if (this.initing) { - return this.callbacks.push(callback); - } else { - this.initing = true; - this.callbacks.push(callback); - return app.listen(__guard__(Settings.internal != null ? Settings.internal.trackchanges : undefined, x => x.port), "localhost", error => { - if (error != null) { throw error; } - this.running = true; - logger.log("track changes running in dev mode"); + running: false, + initing: false, + callbacks: [], + ensureRunning(callback) { + if (callback == null) { + callback = function(error) {} + } + if (this.running) { + return callback() + } else if (this.initing) { + return this.callbacks.push(callback) + } else { + this.initing = true + this.callbacks.push(callback) + return app.listen( + __guard__( + Settings.internal != null + ? Settings.internal.trackchanges + : undefined, + x => x.port + ), + 'localhost', + error => { + if (error != null) { + throw error + } + this.running = true + logger.log('track changes running in dev mode') - return (() => { - const result = []; - for (callback of Array.from(this.callbacks)) { - result.push(callback()); - } - return result; - })(); - }); - } - } -}; + return (() => { + const result = [] + for (callback of Array.from(this.callbacks)) { + result.push(callback()) + } + return result + })() + } + ) + } + } +} function __guard__(value, transform) { - return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined; -} \ No newline at end of file + return typeof value !== 'undefined' && value !== null + ? transform(value) + : undefined +} diff --git a/services/track-changes/test/acceptance/js/helpers/TrackChangesClient.js b/services/track-changes/test/acceptance/js/helpers/TrackChangesClient.js index df66425a49..d49980976b 100644 --- a/services/track-changes/test/acceptance/js/helpers/TrackChangesClient.js +++ b/services/track-changes/test/acceptance/js/helpers/TrackChangesClient.js @@ -12,198 +12,277 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let TrackChangesClient; -const async = require('async'); -const zlib = require('zlib'); -const request = require("request"); -const Settings = require("settings-sharelatex"); -const rclient = require("redis-sharelatex").createClient(Settings.redis.history); // Only works locally for now -const Keys = Settings.redis.history.key_schema; -const {db, ObjectId} = require("../../../../app/js/mongojs"); +let TrackChangesClient +const async = require('async') +const zlib = require('zlib') +const request = require('request') +const Settings = require('settings-sharelatex') +const rclient = require('redis-sharelatex').createClient(Settings.redis.history) // Only works locally for now +const Keys = Settings.redis.history.key_schema +const { db, ObjectId } = require('../../../../app/js/mongojs') -const aws = require("aws-sdk"); +const aws = require('aws-sdk') const s3 = new aws.S3({ - accessKeyId: Settings.trackchanges.s3.key, - secretAccessKey: Settings.trackchanges.s3.secret, - endpoint: Settings.trackchanges.s3.endpoint, - s3ForcePathStyle: Settings.trackchanges.s3.pathStyle -}); -const S3_BUCKET = Settings.trackchanges.stores.doc_history; + accessKeyId: Settings.trackchanges.s3.key, + secretAccessKey: Settings.trackchanges.s3.secret, + endpoint: Settings.trackchanges.s3.endpoint, + s3ForcePathStyle: Settings.trackchanges.s3.pathStyle +}) +const S3_BUCKET = Settings.trackchanges.stores.doc_history -module.exports = (TrackChangesClient = { - flushAndGetCompressedUpdates(project_id, doc_id, callback) { - if (callback == null) { callback = function(error, updates) {}; } - return TrackChangesClient.flushDoc(project_id, doc_id, (error) => { - if (error != null) { return callback(error); } - return TrackChangesClient.getCompressedUpdates(doc_id, callback); - }); - }, +module.exports = TrackChangesClient = { + flushAndGetCompressedUpdates(project_id, doc_id, callback) { + if (callback == null) { + callback = function(error, updates) {} + } + return TrackChangesClient.flushDoc(project_id, doc_id, error => { + if (error != null) { + return callback(error) + } + return TrackChangesClient.getCompressedUpdates(doc_id, callback) + }) + }, - flushDoc(project_id, doc_id, callback) { - if (callback == null) { callback = function(error) {}; } - return request.post({ - url: `http://localhost:3015/project/${project_id}/doc/${doc_id}/flush` - }, (error, response, body) => { - response.statusCode.should.equal(204); - return callback(error); - }); - }, + flushDoc(project_id, doc_id, callback) { + if (callback == null) { + callback = function(error) {} + } + return request.post( + { + url: `http://localhost:3015/project/${project_id}/doc/${doc_id}/flush` + }, + (error, response, body) => { + response.statusCode.should.equal(204) + return callback(error) + } + ) + }, - flushProject(project_id, callback) { - if (callback == null) { callback = function(error) {}; } - return request.post({ - url: `http://localhost:3015/project/${project_id}/flush` - }, (error, response, body) => { - response.statusCode.should.equal(204); - return callback(error); - }); - }, + flushProject(project_id, callback) { + if (callback == null) { + callback = function(error) {} + } + return request.post( + { + url: `http://localhost:3015/project/${project_id}/flush` + }, + (error, response, body) => { + response.statusCode.should.equal(204) + return callback(error) + } + ) + }, - getCompressedUpdates(doc_id, callback) { - if (callback == null) { callback = function(error, updates) {}; } - return db.docHistory - .find({doc_id: ObjectId(doc_id)}) - .sort({"meta.end_ts": 1}) - .toArray(callback); - }, + getCompressedUpdates(doc_id, callback) { + if (callback == null) { + callback = function(error, updates) {} + } + return db.docHistory + .find({ doc_id: ObjectId(doc_id) }) + .sort({ 'meta.end_ts': 1 }) + .toArray(callback) + }, - getProjectMetaData(project_id, callback) { - if (callback == null) { callback = function(error, updates) {}; } - return db.projectHistoryMetaData - .find({ - project_id: ObjectId(project_id) - }, - (error, projects) => callback(error, projects[0])); - }, + getProjectMetaData(project_id, callback) { + if (callback == null) { + callback = function(error, updates) {} + } + return db.projectHistoryMetaData.find( + { + project_id: ObjectId(project_id) + }, + (error, projects) => callback(error, projects[0]) + ) + }, - setPreserveHistoryForProject(project_id, callback) { - if (callback == null) { callback = function(error) {}; } - return db.projectHistoryMetaData.update({ - project_id: ObjectId(project_id) - }, { - $set: { preserveHistory: true } - }, { - upsert: true - }, callback); - }, + setPreserveHistoryForProject(project_id, callback) { + if (callback == null) { + callback = function(error) {} + } + return db.projectHistoryMetaData.update( + { + project_id: ObjectId(project_id) + }, + { + $set: { preserveHistory: true } + }, + { + upsert: true + }, + callback + ) + }, - pushRawUpdates(project_id, doc_id, updates, callback) { - if (callback == null) { callback = function(error) {}; } - return rclient.sadd(Keys.docsWithHistoryOps({project_id}), doc_id, (error) => { - if (error != null) { return callback(error); } - return rclient.rpush(Keys.uncompressedHistoryOps({doc_id}), ...Array.from(((Array.from(updates).map((u) => JSON.stringify(u))))), callback); - }); - }, + pushRawUpdates(project_id, doc_id, updates, callback) { + if (callback == null) { + callback = function(error) {} + } + return rclient.sadd( + Keys.docsWithHistoryOps({ project_id }), + doc_id, + error => { + if (error != null) { + return callback(error) + } + return rclient.rpush( + Keys.uncompressedHistoryOps({ doc_id }), + ...Array.from(Array.from(updates).map(u => JSON.stringify(u))), + callback + ) + } + ) + }, - getDiff(project_id, doc_id, from, to, callback) { - if (callback == null) { callback = function(error, diff) {}; } - return request.get({ - url: `http://localhost:3015/project/${project_id}/doc/${doc_id}/diff?from=${from}&to=${to}` - }, (error, response, body) => { - response.statusCode.should.equal(200); - return callback(null, JSON.parse(body)); - }); - }, + getDiff(project_id, doc_id, from, to, callback) { + if (callback == null) { + callback = function(error, diff) {} + } + return request.get( + { + url: `http://localhost:3015/project/${project_id}/doc/${doc_id}/diff?from=${from}&to=${to}` + }, + (error, response, body) => { + response.statusCode.should.equal(200) + return callback(null, JSON.parse(body)) + } + ) + }, - getUpdates(project_id, options, callback) { - if (callback == null) { callback = function(error, body) {}; } - return request.get({ - url: `http://localhost:3015/project/${project_id}/updates?before=${options.before}&min_count=${options.min_count}` - }, (error, response, body) => { - response.statusCode.should.equal(200); - return callback(null, JSON.parse(body)); - }); - }, + getUpdates(project_id, options, callback) { + if (callback == null) { + callback = function(error, body) {} + } + return request.get( + { + url: `http://localhost:3015/project/${project_id}/updates?before=${options.before}&min_count=${options.min_count}` + }, + (error, response, body) => { + response.statusCode.should.equal(200) + return callback(null, JSON.parse(body)) + } + ) + }, - restoreDoc(project_id, doc_id, version, user_id, callback) { - if (callback == null) { callback = function(error) {}; } - return request.post({ - url: `http://localhost:3015/project/${project_id}/doc/${doc_id}/version/${version}/restore`, - headers: { - "X-User-Id": user_id - } - }, (error, response, body) => { - response.statusCode.should.equal(204); - return callback(null); - }); - }, + restoreDoc(project_id, doc_id, version, user_id, callback) { + if (callback == null) { + callback = function(error) {} + } + return request.post( + { + url: `http://localhost:3015/project/${project_id}/doc/${doc_id}/version/${version}/restore`, + headers: { + 'X-User-Id': user_id + } + }, + (error, response, body) => { + response.statusCode.should.equal(204) + return callback(null) + } + ) + }, - pushDocHistory(project_id, doc_id, callback) { - if (callback == null) { callback = function(error) {}; } - return request.post({ - url: `http://localhost:3015/project/${project_id}/doc/${doc_id}/push` - }, (error, response, body) => { - response.statusCode.should.equal(204); - return callback(error); - }); - }, + pushDocHistory(project_id, doc_id, callback) { + if (callback == null) { + callback = function(error) {} + } + return request.post( + { + url: `http://localhost:3015/project/${project_id}/doc/${doc_id}/push` + }, + (error, response, body) => { + response.statusCode.should.equal(204) + return callback(error) + } + ) + }, - pullDocHistory(project_id, doc_id, callback) { - if (callback == null) { callback = function(error) {}; } - return request.post({ - url: `http://localhost:3015/project/${project_id}/doc/${doc_id}/pull` - }, (error, response, body) => { - response.statusCode.should.equal(204); - return callback(error); - }); - }, + pullDocHistory(project_id, doc_id, callback) { + if (callback == null) { + callback = function(error) {} + } + return request.post( + { + url: `http://localhost:3015/project/${project_id}/doc/${doc_id}/pull` + }, + (error, response, body) => { + response.statusCode.should.equal(204) + return callback(error) + } + ) + }, - waitForS3(done, retries) { - if (retries == null) { retries = 42; } - if (!Settings.trackchanges.s3.endpoint) { - return done(); - } + waitForS3(done, retries) { + if (retries == null) { + retries = 42 + } + if (!Settings.trackchanges.s3.endpoint) { + return done() + } - return request.get(`${Settings.trackchanges.s3.endpoint}/`, (err, res) => { - if (res && (res.statusCode < 500)) { - return done(); - } + return request.get(`${Settings.trackchanges.s3.endpoint}/`, (err, res) => { + if (res && res.statusCode < 500) { + return done() + } - if (retries === 0) { - return done(err || new Error(`s3 returned ${res.statusCode}`)); - } + if (retries === 0) { + return done(err || new Error(`s3 returned ${res.statusCode}`)) + } - return setTimeout(() => TrackChangesClient.waitForS3(done, --retries) - , 1000); - }); - }, + return setTimeout( + () => TrackChangesClient.waitForS3(done, --retries), + 1000 + ) + }) + }, - getS3Doc(project_id, doc_id, pack_id, callback) { - if (callback == null) { callback = function(error, body) {}; } - const params = { - Bucket: S3_BUCKET, - Key: `${project_id}/changes-${doc_id}/pack-${pack_id}` - }; + getS3Doc(project_id, doc_id, pack_id, callback) { + if (callback == null) { + callback = function(error, body) {} + } + const params = { + Bucket: S3_BUCKET, + Key: `${project_id}/changes-${doc_id}/pack-${pack_id}` + } - return s3.getObject(params, (error, data) => { - if (error != null) { return callback(error); } - const body = data.Body; - if ((body == null)) { return callback(new Error("empty response from s3")); } - return zlib.gunzip(body, (err, result) => { - if (err != null) { return callback(err); } - return callback(null, JSON.parse(result.toString())); - }); - }); - }, + return s3.getObject(params, (error, data) => { + if (error != null) { + return callback(error) + } + const body = data.Body + if (body == null) { + return callback(new Error('empty response from s3')) + } + return zlib.gunzip(body, (err, result) => { + if (err != null) { + return callback(err) + } + return callback(null, JSON.parse(result.toString())) + }) + }) + }, - removeS3Doc(project_id, doc_id, callback) { - if (callback == null) { callback = function(error, res, body) {}; } - let params = { - Bucket: S3_BUCKET, - Prefix: `${project_id}/changes-${doc_id}` - }; + removeS3Doc(project_id, doc_id, callback) { + if (callback == null) { + callback = function(error, res, body) {} + } + let params = { + Bucket: S3_BUCKET, + Prefix: `${project_id}/changes-${doc_id}` + } - return s3.listObjects(params, (error, data) => { - if (error != null) { return callback(error); } + return s3.listObjects(params, (error, data) => { + if (error != null) { + return callback(error) + } - params = { - Bucket: S3_BUCKET, - Delete: { - Objects: data.Contents.map(s3object => ({Key: s3object.Key})) - } - }; + params = { + Bucket: S3_BUCKET, + Delete: { + Objects: data.Contents.map(s3object => ({ Key: s3object.Key })) + } + } - return s3.deleteObjects(params, callback); - }); - } -}); + return s3.deleteObjects(params, callback) + }) + } +}