| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- /* eslint-disable
- camelcase,
- no-return-assign,
- no-unused-vars,
- */
- // TODO: This file was created by bulk-decaffeinate.
- // Fix any style issues and re-enable lint.
- /*
- * decaffeinate suggestions:
- * DS102: Remove unnecessary code created because of implicit returns
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
- */
- const sinon = require('sinon')
- const { expect } = require('chai')
- const modulePath = '../../../../app/js/DiffManager.js'
- const SandboxedModule = require('sandboxed-module')
- describe('DiffManager', function () {
- beforeEach(function () {
- this.DiffManager = SandboxedModule.require(modulePath, {
- requires: {
- './UpdatesManager': (this.UpdatesManager = {}),
- './DocumentUpdaterManager': (this.DocumentUpdaterManager = {}),
- './DiffGenerator': (this.DiffGenerator = {}),
- },
- })
- this.callback = sinon.stub()
- this.from = new Date()
- this.to = new Date(Date.now() + 10000)
- this.project_id = 'mock-project-id'
- return (this.doc_id = 'mock-doc-id')
- })
- describe('getLatestDocAndUpdates', function () {
- beforeEach(function () {
- this.content = 'hello world'
- this.version = 42
- this.updates = ['mock-update-1', 'mock-update-2']
- this.DocumentUpdaterManager.getDocument = sinon
- .stub()
- .callsArgWith(2, null, this.content, this.version)
- return (this.UpdatesManager.getDocUpdatesWithUserInfo = sinon
- .stub()
- .callsArgWith(3, null, this.updates))
- })
- describe('with a fromVersion', function () {
- beforeEach(function () {
- return this.DiffManager.getLatestDocAndUpdates(
- this.project_id,
- this.doc_id,
- this.from,
- this.callback
- )
- })
- it('should get the latest version of the doc', function () {
- return this.DocumentUpdaterManager.getDocument
- .calledWith(this.project_id, this.doc_id)
- .should.equal(true)
- })
- it('should get the latest updates', function () {
- return this.UpdatesManager.getDocUpdatesWithUserInfo
- .calledWith(this.project_id, this.doc_id, { from: this.from })
- .should.equal(true)
- })
- return it('should call the callback with the content, version and updates', function () {
- return this.callback
- .calledWith(null, this.content, this.version, this.updates)
- .should.equal(true)
- })
- })
- return describe('with no fromVersion', function () {
- beforeEach(function () {
- return this.DiffManager.getLatestDocAndUpdates(
- this.project_id,
- this.doc_id,
- null,
- this.callback
- )
- })
- it('should get the latest version of the doc', function () {
- return this.DocumentUpdaterManager.getDocument
- .calledWith(this.project_id, this.doc_id)
- .should.equal(true)
- })
- it('should not get the latest updates', function () {
- return this.UpdatesManager.getDocUpdatesWithUserInfo.called.should.equal(
- false
- )
- })
- return it('should call the callback with the content, version and blank updates', function () {
- return this.callback
- .calledWith(null, this.content, this.version, [])
- .should.equal(true)
- })
- })
- })
- describe('getDiff', function () {
- beforeEach(function () {
- this.content = 'hello world'
- // Op versions are the version they were applied to, so doc is always one version
- // ahead.s
- this.version = 43
- this.updates = [
- {
- op: 'mock-4',
- v: 42,
- meta: { start_ts: new Date(this.to.getTime() + 20) },
- },
- {
- op: 'mock-3',
- v: 41,
- meta: { start_ts: new Date(this.to.getTime() + 10) },
- },
- {
- op: 'mock-2',
- v: 40,
- meta: { start_ts: new Date(this.to.getTime() - 10) },
- },
- {
- op: 'mock-1',
- v: 39,
- meta: { start_ts: new Date(this.to.getTime() - 20) },
- },
- ]
- this.fromVersion = 39
- this.toVersion = 40
- this.diffed_updates = this.updates.slice(2)
- this.rewound_content = 'rewound-content'
- return (this.diff = [{ u: 'mock-diff' }])
- })
- describe('with matching versions', function () {
- beforeEach(function () {
- this.DiffManager.getDocumentBeforeVersion = sinon
- .stub()
- .callsArgWith(3, null, this.rewound_content, this.updates)
- this.DiffGenerator.buildDiff = sinon.stub().returns(this.diff)
- return this.DiffManager.getDiff(
- this.project_id,
- this.doc_id,
- this.fromVersion,
- this.toVersion,
- this.callback
- )
- })
- it('should get the latest doc and version with all recent updates', function () {
- return this.DiffManager.getDocumentBeforeVersion
- .calledWith(this.project_id, this.doc_id, this.fromVersion)
- .should.equal(true)
- })
- it('should generate the diff', function () {
- return this.DiffGenerator.buildDiff
- .calledWith(
- this.rewound_content,
- this.diffed_updates.slice().reverse()
- )
- .should.equal(true)
- })
- return it('should call the callback with the diff', function () {
- return this.callback.calledWith(null, this.diff).should.equal(true)
- })
- })
- describe('when the updates are inconsistent', function () {
- beforeEach(function () {
- this.DiffManager.getLatestDocAndUpdates = sinon
- .stub()
- .callsArgWith(3, null, this.content, this.version, this.updates)
- this.DiffGenerator.buildDiff = sinon
- .stub()
- .throws((this.error = new Error('inconsistent!')))
- this.DiffGenerator.rewindUpdates = sinon.stub()
- this.DiffManager.getDiff(
- this.project_id,
- this.doc_id,
- this.fromVersion,
- this.toVersion,
- this.callback
- )
- })
- it('should call the callback with an error', function () {
- this.callback.calledWith(sinon.match(Error)).should.equal(true)
- const errorObj = this.callback.args[0][0]
- expect(errorObj.message).to.include('inconsistent!')
- })
- })
- })
- describe('getDocumentBeforeVersion', function () {
- beforeEach(function () {
- this.DiffManager._tryGetDocumentBeforeVersion = sinon.stub()
- this.document = 'mock-documents'
- return (this.rewound_updates = 'mock-rewound-updates')
- })
- describe('succesfully', function () {
- beforeEach(function () {
- this.DiffManager._tryGetDocumentBeforeVersion.yields(
- null,
- this.document,
- this.rewound_updates
- )
- return this.DiffManager.getDocumentBeforeVersion(
- this.project_id,
- this.doc_id,
- this.version,
- this.callback
- )
- })
- it('should call _tryGetDocumentBeforeVersion', function () {
- return this.DiffManager._tryGetDocumentBeforeVersion
- .calledWith(this.project_id, this.doc_id, this.version)
- .should.equal(true)
- })
- return it('should call the callback with the response', function () {
- return this.callback
- .calledWith(null, this.document, this.rewound_updates)
- .should.equal(true)
- })
- })
- describe('with a retry needed', function () {
- beforeEach(function () {
- let retried = false
- this.DiffManager._tryGetDocumentBeforeVersion = (
- project_id,
- doc_id,
- version,
- callback
- ) => {
- if (!retried) {
- retried = true
- const error = new Error()
- error.retry = true
- return callback(error)
- } else {
- return callback(null, this.document, this.rewound_updates)
- }
- }
- sinon.spy(this.DiffManager, '_tryGetDocumentBeforeVersion')
- return this.DiffManager.getDocumentBeforeVersion(
- this.project_id,
- this.doc_id,
- this.version,
- this.callback
- )
- })
- it('should call _tryGetDocumentBeforeVersion twice', function () {
- return this.DiffManager._tryGetDocumentBeforeVersion.calledTwice.should.equal(
- true
- )
- })
- return it('should call the callback with the response', function () {
- return this.callback
- .calledWith(null, this.document, this.rewound_updates)
- .should.equal(true)
- })
- })
- describe('with a non-retriable error', function () {
- beforeEach(function () {
- this.error = new Error('oops')
- this.DiffManager._tryGetDocumentBeforeVersion.yields(this.error)
- return this.DiffManager.getDocumentBeforeVersion(
- this.project_id,
- this.doc_id,
- this.version,
- this.callback
- )
- })
- it('should call _tryGetDocumentBeforeVersion once', function () {
- return this.DiffManager._tryGetDocumentBeforeVersion.calledOnce.should.equal(
- true
- )
- })
- return it('should call the callback with the error', function () {
- return this.callback.calledWith(this.error).should.equal(true)
- })
- })
- return describe('when retry limit is matched', function () {
- beforeEach(function () {
- this.error = new Error('oops')
- this.error.retry = true
- this.DiffManager._tryGetDocumentBeforeVersion.yields(this.error)
- return this.DiffManager.getDocumentBeforeVersion(
- this.project_id,
- this.doc_id,
- this.version,
- this.callback
- )
- })
- it('should call _tryGetDocumentBeforeVersion three times (max retries)', function () {
- return this.DiffManager._tryGetDocumentBeforeVersion.calledThrice.should.equal(
- true
- )
- })
- return it('should call the callback with the error', function () {
- return this.callback.calledWith(this.error).should.equal(true)
- })
- })
- })
- return describe('_tryGetDocumentBeforeVersion', function () {
- beforeEach(function () {
- this.content = 'hello world'
- // Op versions are the version they were applied to, so doc is always one version
- // ahead.s
- this.version = 43
- this.updates = [
- {
- op: 'mock-4',
- v: 42,
- meta: { start_ts: new Date(this.to.getTime() + 20) },
- },
- {
- op: 'mock-3',
- v: 41,
- meta: { start_ts: new Date(this.to.getTime() + 10) },
- },
- {
- op: 'mock-2',
- v: 40,
- meta: { start_ts: new Date(this.to.getTime() - 10) },
- },
- {
- op: 'mock-1',
- v: 39,
- meta: { start_ts: new Date(this.to.getTime() - 20) },
- },
- ]
- this.fromVersion = 39
- this.rewound_content = 'rewound-content'
- return (this.diff = [{ u: 'mock-diff' }])
- })
- describe('with matching versions', function () {
- beforeEach(function () {
- this.DiffManager.getLatestDocAndUpdates = sinon
- .stub()
- .callsArgWith(3, null, this.content, this.version, this.updates)
- this.DiffGenerator.rewindUpdates = sinon.spy((content, updates) => {
- // the rewindUpdates method reverses the 'updates' array
- updates.reverse()
- return this.rewound_content
- })
- this.rewindUpdatesWithArgs = this.DiffGenerator.rewindUpdates.withArgs(
- this.content,
- this.updates.slice().reverse()
- )
- return this.DiffManager._tryGetDocumentBeforeVersion(
- this.project_id,
- this.doc_id,
- this.fromVersion,
- this.callback
- )
- })
- it('should get the latest doc and version with all recent updates', function () {
- return this.DiffManager.getLatestDocAndUpdates
- .calledWith(this.project_id, this.doc_id, this.fromVersion)
- .should.equal(true)
- })
- it('should rewind the diff', function () {
- return sinon.assert.calledOnce(this.rewindUpdatesWithArgs)
- })
- return it('should call the callback with the rewound document and updates', function () {
- return this.callback
- .calledWith(null, this.rewound_content, this.updates)
- .should.equal(true)
- })
- })
- describe('with mismatching versions', function () {
- beforeEach(function () {
- this.version = 50
- this.updates = [
- { op: 'mock-1', v: 40 },
- { op: 'mock-1', v: 39 },
- ]
- this.DiffManager.getLatestDocAndUpdates = sinon
- .stub()
- .callsArgWith(3, null, this.content, this.version, this.updates)
- return this.DiffManager._tryGetDocumentBeforeVersion(
- this.project_id,
- this.doc_id,
- this.fromVersion,
- this.callback
- )
- })
- return it('should call the callback with an error with retry = true set', function () {
- this.callback.calledOnce.should.equal(true)
- const error = this.callback.args[0][0]
- return expect(error.retry).to.equal(true)
- })
- })
- return describe('when the updates are inconsistent', function () {
- beforeEach(function () {
- this.DiffManager.getLatestDocAndUpdates = sinon
- .stub()
- .callsArgWith(3, null, this.content, this.version, this.updates)
- this.DiffGenerator.rewindUpdates = sinon
- .stub()
- .throws((this.error = new Error('inconsistent!')))
- return this.DiffManager.getDocumentBeforeVersion(
- this.project_id,
- this.doc_id,
- this.fromVersion,
- this.callback
- )
- })
- return it('should call the callback with an error', function () {
- return this.callback.calledWith(this.error).should.equal(true)
- })
- })
- })
- })
|