mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
815 lines
25 KiB
JavaScript
815 lines
25 KiB
JavaScript
/* eslint-disable
|
|
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
|
|
* DS206: Consider reworking classes to avoid initClass
|
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
*/
|
|
const sinon = require('sinon');
|
|
const chai = require('chai');
|
|
const should = chai.should();
|
|
const modulePath = "../../../../app/js/HttpController.js";
|
|
const SandboxedModule = require('sandboxed-module');
|
|
const Errors = require("../../../../app/js/Errors.js");
|
|
|
|
describe("HttpController", function() {
|
|
beforeEach(function() {
|
|
let Timer;
|
|
this.HttpController = SandboxedModule.require(modulePath, { requires: {
|
|
"./DocumentManager": (this.DocumentManager = {}),
|
|
"./HistoryManager": (this.HistoryManager =
|
|
{flushProjectChangesAsync: sinon.stub()}),
|
|
"./ProjectManager": (this.ProjectManager = {}),
|
|
"logger-sharelatex" : (this.logger = { log: sinon.stub() }),
|
|
"./ProjectFlusher": {flushAllProjects() {}},
|
|
"./DeleteQueueManager": (this.DeleteQueueManager = {}),
|
|
"./Metrics": (this.Metrics = {}),
|
|
"./Errors" : Errors
|
|
}
|
|
}
|
|
);
|
|
this.Metrics.Timer = (Timer = (function() {
|
|
Timer = class Timer {
|
|
static initClass() {
|
|
this.prototype.done = sinon.stub();
|
|
}
|
|
};
|
|
Timer.initClass();
|
|
return Timer;
|
|
})());
|
|
this.project_id = "project-id-123";
|
|
this.doc_id = "doc-id-123";
|
|
this.next = sinon.stub();
|
|
return this.res = {
|
|
send: sinon.stub(),
|
|
sendStatus: sinon.stub(),
|
|
json: sinon.stub()
|
|
};
|
|
});
|
|
|
|
describe("getDoc", function() {
|
|
beforeEach(function() {
|
|
this.lines = ["one", "two", "three"];
|
|
this.ops = ["mock-op-1", "mock-op-2"];
|
|
this.version = 42;
|
|
this.fromVersion = 42;
|
|
this.ranges = { changes: "mock", comments: "mock" };
|
|
this.pathname = '/a/b/c';
|
|
return this.req = {
|
|
params: {
|
|
project_id: this.project_id,
|
|
doc_id: this.doc_id
|
|
}
|
|
};
|
|
});
|
|
|
|
describe("when the document exists and no recent ops are requested", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.getDocAndRecentOpsWithLock = sinon.stub().callsArgWith(3, null, this.lines, this.version, [], this.ranges, this.pathname);
|
|
return this.HttpController.getDoc(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should get the doc", function() {
|
|
return this.DocumentManager.getDocAndRecentOpsWithLock
|
|
.calledWith(this.project_id, this.doc_id, -1)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should return the doc as JSON", function() {
|
|
return this.res.json
|
|
.calledWith({
|
|
id: this.doc_id,
|
|
lines: this.lines,
|
|
version: this.version,
|
|
ops: [],
|
|
ranges: this.ranges,
|
|
pathname: this.pathname
|
|
})
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should log the request", function() {
|
|
return this.logger.log
|
|
.calledWith({doc_id: this.doc_id, project_id: this.project_id}, "getting doc via http")
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should time the request", function() {
|
|
return this.Metrics.Timer.prototype.done.called.should.equal(true);
|
|
});
|
|
});
|
|
|
|
describe("when recent ops are requested", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.getDocAndRecentOpsWithLock = sinon.stub().callsArgWith(3, null, this.lines, this.version, this.ops, this.ranges, this.pathname);
|
|
this.req.query = {fromVersion: `${this.fromVersion}`};
|
|
return this.HttpController.getDoc(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should get the doc", function() {
|
|
return this.DocumentManager.getDocAndRecentOpsWithLock
|
|
.calledWith(this.project_id, this.doc_id, this.fromVersion)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should return the doc as JSON", function() {
|
|
return this.res.json
|
|
.calledWith({
|
|
id: this.doc_id,
|
|
lines: this.lines,
|
|
version: this.version,
|
|
ops: this.ops,
|
|
ranges: this.ranges,
|
|
pathname: this.pathname
|
|
})
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should log the request", function() {
|
|
return this.logger.log
|
|
.calledWith({doc_id: this.doc_id, project_id: this.project_id}, "getting doc via http")
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should time the request", function() {
|
|
return this.Metrics.Timer.prototype.done.called.should.equal(true);
|
|
});
|
|
});
|
|
|
|
describe("when the document does not exist", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.getDocAndRecentOpsWithLock = sinon.stub().callsArgWith(3, null, null, null);
|
|
return this.HttpController.getDoc(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should call next with NotFoundError", function() {
|
|
return this.next
|
|
.calledWith(new Errors.NotFoundError("not found"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
|
|
return describe("when an errors occurs", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.getDocAndRecentOpsWithLock = sinon.stub().callsArgWith(3, new Error("oops"), null, null);
|
|
return this.HttpController.getDoc(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should call next with the error", function() {
|
|
return this.next
|
|
.calledWith(new Error("oops"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("setDoc", function() {
|
|
beforeEach(function() {
|
|
this.lines = ["one", "two", "three"];
|
|
this.source = "dropbox";
|
|
this.user_id = "user-id-123";
|
|
return this.req = {
|
|
headers: {},
|
|
params: {
|
|
project_id: this.project_id,
|
|
doc_id: this.doc_id
|
|
},
|
|
body: {
|
|
lines: this.lines,
|
|
source: this.source,
|
|
user_id: this.user_id,
|
|
undoing: (this.undoing = true)
|
|
}
|
|
};
|
|
});
|
|
|
|
describe("successfully", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.setDocWithLock = sinon.stub().callsArgWith(6);
|
|
return this.HttpController.setDoc(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should set the doc", function() {
|
|
return this.DocumentManager.setDocWithLock
|
|
.calledWith(this.project_id, this.doc_id, this.lines, this.source, this.user_id, this.undoing)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should return a successful No Content response", function() {
|
|
return this.res.sendStatus
|
|
.calledWith(204)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should log the request", function() {
|
|
return this.logger.log
|
|
.calledWith({doc_id: this.doc_id, project_id: this.project_id, lines: this.lines, source: this.source, user_id: this.user_id, undoing: this.undoing}, "setting doc via http")
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should time the request", function() {
|
|
return this.Metrics.Timer.prototype.done.called.should.equal(true);
|
|
});
|
|
});
|
|
|
|
describe("when an errors occurs", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.setDocWithLock = sinon.stub().callsArgWith(6, new Error("oops"));
|
|
return this.HttpController.setDoc(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should call next with the error", function() {
|
|
return this.next
|
|
.calledWith(new Error("oops"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
|
|
return describe("when the payload is too large", function() {
|
|
beforeEach(function() {
|
|
const lines = [];
|
|
for (let _ = 0; _ <= 200000; _++) {
|
|
lines.push("test test test");
|
|
}
|
|
this.req.body.lines = lines;
|
|
this.DocumentManager.setDocWithLock = sinon.stub().callsArgWith(6);
|
|
return this.HttpController.setDoc(this.req, this.res, this.next);
|
|
});
|
|
|
|
it('should send back a 406 response', function() {
|
|
return this.res.sendStatus.calledWith(406).should.equal(true);
|
|
});
|
|
|
|
return it('should not call setDocWithLock', function() {
|
|
return this.DocumentManager.setDocWithLock.callCount.should.equal(0);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("flushProject", function() {
|
|
beforeEach(function() {
|
|
return this.req = {
|
|
params: {
|
|
project_id: this.project_id
|
|
}
|
|
};
|
|
});
|
|
|
|
describe("successfully", function() {
|
|
beforeEach(function() {
|
|
this.ProjectManager.flushProjectWithLocks = sinon.stub().callsArgWith(1);
|
|
return this.HttpController.flushProject(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should flush the project", function() {
|
|
return this.ProjectManager.flushProjectWithLocks
|
|
.calledWith(this.project_id)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should return a successful No Content response", function() {
|
|
return this.res.sendStatus
|
|
.calledWith(204)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should log the request", function() {
|
|
return this.logger.log
|
|
.calledWith({project_id: this.project_id}, "flushing project via http")
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should time the request", function() {
|
|
return this.Metrics.Timer.prototype.done.called.should.equal(true);
|
|
});
|
|
});
|
|
|
|
return describe("when an errors occurs", function() {
|
|
beforeEach(function() {
|
|
this.ProjectManager.flushProjectWithLocks = sinon.stub().callsArgWith(1, new Error("oops"));
|
|
return this.HttpController.flushProject(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should call next with the error", function() {
|
|
return this.next
|
|
.calledWith(new Error("oops"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("flushDocIfLoaded", function() {
|
|
beforeEach(function() {
|
|
this.lines = ["one", "two", "three"];
|
|
this.version = 42;
|
|
return this.req = {
|
|
params: {
|
|
project_id: this.project_id,
|
|
doc_id: this.doc_id
|
|
}
|
|
};
|
|
});
|
|
|
|
describe("successfully", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.flushDocIfLoadedWithLock = sinon.stub().callsArgWith(2);
|
|
return this.HttpController.flushDocIfLoaded(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should flush the doc", function() {
|
|
return this.DocumentManager.flushDocIfLoadedWithLock
|
|
.calledWith(this.project_id, this.doc_id)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should return a successful No Content response", function() {
|
|
return this.res.sendStatus
|
|
.calledWith(204)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should log the request", function() {
|
|
return this.logger.log
|
|
.calledWith({doc_id: this.doc_id, project_id: this.project_id}, "flushing doc via http")
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should time the request", function() {
|
|
return this.Metrics.Timer.prototype.done.called.should.equal(true);
|
|
});
|
|
});
|
|
|
|
return describe("when an errors occurs", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.flushDocIfLoadedWithLock = sinon.stub().callsArgWith(2, new Error("oops"));
|
|
return this.HttpController.flushDocIfLoaded(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should call next with the error", function() {
|
|
return this.next
|
|
.calledWith(new Error("oops"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("deleteDoc", function() {
|
|
beforeEach(function() {
|
|
return this.req = {
|
|
params: {
|
|
project_id: this.project_id,
|
|
doc_id: this.doc_id
|
|
},
|
|
query: {}
|
|
};});
|
|
|
|
describe("successfully", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.flushAndDeleteDocWithLock = sinon.stub().callsArgWith(3);
|
|
return this.HttpController.deleteDoc(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should flush and delete the doc", function() {
|
|
return this.DocumentManager.flushAndDeleteDocWithLock
|
|
.calledWith(this.project_id, this.doc_id, { ignoreFlushErrors: false })
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should flush project history", function() {
|
|
return this.HistoryManager.flushProjectChangesAsync
|
|
.calledWithExactly(this.project_id)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should return a successful No Content response", function() {
|
|
return this.res.sendStatus
|
|
.calledWith(204)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should log the request", function() {
|
|
return this.logger.log
|
|
.calledWith({doc_id: this.doc_id, project_id: this.project_id}, "deleting doc via http")
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should time the request", function() {
|
|
return this.Metrics.Timer.prototype.done.called.should.equal(true);
|
|
});
|
|
});
|
|
|
|
describe("ignoring errors", function() {
|
|
beforeEach(function() {
|
|
this.req.query.ignore_flush_errors = 'true';
|
|
this.DocumentManager.flushAndDeleteDocWithLock = sinon.stub().yields();
|
|
return this.HttpController.deleteDoc(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should delete the doc", function() {
|
|
return this.DocumentManager.flushAndDeleteDocWithLock
|
|
.calledWith(this.project_id, this.doc_id, { ignoreFlushErrors: true })
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should return a successful No Content response", function() {
|
|
return this.res.sendStatus.calledWith(204).should.equal(true);
|
|
});
|
|
});
|
|
|
|
return describe("when an errors occurs", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.flushAndDeleteDocWithLock = sinon.stub().callsArgWith(3, new Error("oops"));
|
|
return this.HttpController.deleteDoc(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should flush project history", function() {
|
|
return this.HistoryManager.flushProjectChangesAsync
|
|
.calledWithExactly(this.project_id)
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should call next with the error", function() {
|
|
return this.next
|
|
.calledWith(new Error("oops"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("deleteProject", function() {
|
|
beforeEach(function() {
|
|
return this.req = {
|
|
params: {
|
|
project_id: this.project_id
|
|
}
|
|
};
|
|
});
|
|
|
|
describe("successfully", function() {
|
|
beforeEach(function() {
|
|
this.ProjectManager.flushAndDeleteProjectWithLocks = sinon.stub().callsArgWith(2);
|
|
return this.HttpController.deleteProject(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should delete the project", function() {
|
|
return this.ProjectManager.flushAndDeleteProjectWithLocks
|
|
.calledWith(this.project_id)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should return a successful No Content response", function() {
|
|
return this.res.sendStatus
|
|
.calledWith(204)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should log the request", function() {
|
|
return this.logger.log
|
|
.calledWith({project_id: this.project_id}, "deleting project via http")
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should time the request", function() {
|
|
return this.Metrics.Timer.prototype.done.called.should.equal(true);
|
|
});
|
|
});
|
|
|
|
describe("with the background=true option from realtime", function() {
|
|
beforeEach(function() {
|
|
this.ProjectManager.queueFlushAndDeleteProject = sinon.stub().callsArgWith(1);
|
|
this.req.query = {background:true, shutdown:true};
|
|
return this.HttpController.deleteProject(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should queue the flush and delete", function() {
|
|
return this.ProjectManager.queueFlushAndDeleteProject
|
|
.calledWith(this.project_id)
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
|
|
return describe("when an errors occurs", function() {
|
|
beforeEach(function() {
|
|
this.ProjectManager.flushAndDeleteProjectWithLocks = sinon.stub().callsArgWith(2, new Error("oops"));
|
|
return this.HttpController.deleteProject(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should call next with the error", function() {
|
|
return this.next
|
|
.calledWith(new Error("oops"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("acceptChanges", function() {
|
|
beforeEach(function() {
|
|
return this.req = {
|
|
params: {
|
|
project_id: this.project_id,
|
|
doc_id: this.doc_id,
|
|
change_id: (this.change_id = "mock-change-od-1")
|
|
}
|
|
};
|
|
});
|
|
|
|
describe("successfully with a single change", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.acceptChangesWithLock = sinon.stub().callsArgWith(3);
|
|
return this.HttpController.acceptChanges(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should accept the change", function() {
|
|
return this.DocumentManager.acceptChangesWithLock
|
|
.calledWith(this.project_id, this.doc_id, [ this.change_id ])
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should return a successful No Content response", function() {
|
|
return this.res.sendStatus
|
|
.calledWith(204)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should log the request", function() {
|
|
return this.logger.log
|
|
.calledWith({project_id: this.project_id, doc_id: this.doc_id}, "accepting 1 changes via http")
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should time the request", function() {
|
|
return this.Metrics.Timer.prototype.done.called.should.equal(true);
|
|
});
|
|
});
|
|
|
|
describe("succesfully with with multiple changes", function() {
|
|
beforeEach(function() {
|
|
this.change_ids = [ "mock-change-od-1", "mock-change-od-2", "mock-change-od-3", "mock-change-od-4" ];
|
|
this.req.body =
|
|
{change_ids: this.change_ids};
|
|
this.DocumentManager.acceptChangesWithLock = sinon.stub().callsArgWith(3);
|
|
return this.HttpController.acceptChanges(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should accept the changes in the body payload", function() {
|
|
return this.DocumentManager.acceptChangesWithLock
|
|
.calledWith(this.project_id, this.doc_id, this.change_ids)
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should log the request with the correct number of changes", function() {
|
|
return this.logger.log
|
|
.calledWith({project_id: this.project_id, doc_id: this.doc_id}, `accepting ${ this.change_ids.length } changes via http`)
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
|
|
return describe("when an errors occurs", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.acceptChangesWithLock = sinon.stub().callsArgWith(3, new Error("oops"));
|
|
return this.HttpController.acceptChanges(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should call next with the error", function() {
|
|
return this.next
|
|
.calledWith(new Error("oops"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("deleteComment", function() {
|
|
beforeEach(function() {
|
|
return this.req = {
|
|
params: {
|
|
project_id: this.project_id,
|
|
doc_id: this.doc_id,
|
|
comment_id: (this.comment_id = "mock-comment-id")
|
|
}
|
|
};
|
|
});
|
|
|
|
describe("successfully", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.deleteCommentWithLock = sinon.stub().callsArgWith(3);
|
|
return this.HttpController.deleteComment(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should accept the change", function() {
|
|
return this.DocumentManager.deleteCommentWithLock
|
|
.calledWith(this.project_id, this.doc_id, this.comment_id)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should return a successful No Content response", function() {
|
|
return this.res.sendStatus
|
|
.calledWith(204)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should log the request", function() {
|
|
return this.logger.log
|
|
.calledWith({project_id: this.project_id, doc_id: this.doc_id, comment_id: this.comment_id}, "deleting comment via http")
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should time the request", function() {
|
|
return this.Metrics.Timer.prototype.done.called.should.equal(true);
|
|
});
|
|
});
|
|
|
|
return describe("when an errors occurs", function() {
|
|
beforeEach(function() {
|
|
this.DocumentManager.deleteCommentWithLock = sinon.stub().callsArgWith(3, new Error("oops"));
|
|
return this.HttpController.deleteComment(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should call next with the error", function() {
|
|
return this.next
|
|
.calledWith(new Error("oops"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("getProjectDocsAndFlushIfOld", function() {
|
|
beforeEach(function() {
|
|
this.state = "01234567890abcdef";
|
|
this.docs = [{_id: "1234", lines: "hello", v: 23}, {_id: "4567", lines: "world", v: 45}];
|
|
return this.req = {
|
|
params: {
|
|
project_id: this.project_id
|
|
},
|
|
query: {
|
|
state: this.state
|
|
}
|
|
};
|
|
});
|
|
|
|
describe("successfully", function() {
|
|
beforeEach(function() {
|
|
this.ProjectManager.getProjectDocsAndFlushIfOld = sinon.stub().callsArgWith(3,null, this.docs);
|
|
return this.HttpController.getProjectDocsAndFlushIfOld(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should get docs from the project manager", function() {
|
|
return this.ProjectManager.getProjectDocsAndFlushIfOld
|
|
.calledWith(this.project_id, this.state, {})
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should return a successful response", function() {
|
|
return this.res.send
|
|
.calledWith(this.docs)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should log the request", function() {
|
|
return this.logger.log
|
|
.calledWith({project_id: this.project_id, exclude: []}, "getting docs via http")
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should log the response", function() {
|
|
return this.logger.log
|
|
.calledWith({project_id: this.project_id, result: ["1234:23", "4567:45"]}, "got docs via http")
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should time the request", function() {
|
|
return this.Metrics.Timer.prototype.done.called.should.equal(true);
|
|
});
|
|
});
|
|
|
|
describe("when there is a conflict", function() {
|
|
beforeEach(function() {
|
|
this.ProjectManager.getProjectDocsAndFlushIfOld = sinon.stub().callsArgWith(3, new Errors.ProjectStateChangedError("project state changed"));
|
|
return this.HttpController.getProjectDocsAndFlushIfOld(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should return an HTTP 409 Conflict response", function() {
|
|
return this.res.sendStatus
|
|
.calledWith(409)
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
|
|
return describe("when an error occurs", function() {
|
|
beforeEach(function() {
|
|
this.ProjectManager.getProjectDocsAndFlushIfOld = sinon.stub().callsArgWith(3, new Error("oops"));
|
|
return this.HttpController.getProjectDocsAndFlushIfOld(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should call next with the error", function() {
|
|
return this.next
|
|
.calledWith(new Error("oops"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("updateProject", function() {
|
|
beforeEach(function() {
|
|
this.projectHistoryId = "history-id-123";
|
|
this.userId = "user-id-123";
|
|
this.docUpdates = sinon.stub();
|
|
this.fileUpdates = sinon.stub();
|
|
this.version = 1234567;
|
|
return this.req = {
|
|
body: {projectHistoryId: this.projectHistoryId, userId: this.userId, docUpdates: this.docUpdates, fileUpdates: this.fileUpdates, version: this.version},
|
|
params: {
|
|
project_id: this.project_id
|
|
}
|
|
};
|
|
});
|
|
|
|
describe("successfully", function() {
|
|
beforeEach(function() {
|
|
this.ProjectManager.updateProjectWithLocks = sinon.stub().callsArgWith(6);
|
|
return this.HttpController.updateProject(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should accept the change", function() {
|
|
return this.ProjectManager.updateProjectWithLocks
|
|
.calledWith(this.project_id, this.projectHistoryId, this.userId, this.docUpdates, this.fileUpdates, this.version)
|
|
.should.equal(true);
|
|
});
|
|
|
|
it("should return a successful No Content response", function() {
|
|
return this.res.sendStatus
|
|
.calledWith(204)
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should time the request", function() {
|
|
return this.Metrics.Timer.prototype.done.called.should.equal(true);
|
|
});
|
|
});
|
|
|
|
return describe("when an errors occurs", function() {
|
|
beforeEach(function() {
|
|
this.ProjectManager.updateProjectWithLocks = sinon.stub().callsArgWith(6, new Error("oops"));
|
|
return this.HttpController.updateProject(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should call next with the error", function() {
|
|
return this.next
|
|
.calledWith(new Error("oops"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
return describe("resyncProjectHistory", function() {
|
|
beforeEach(function() {
|
|
this.projectHistoryId = "history-id-123";
|
|
this.docs = sinon.stub();
|
|
this.files = sinon.stub();
|
|
this.fileUpdates = sinon.stub();
|
|
return this.req = {
|
|
body:
|
|
{projectHistoryId: this.projectHistoryId, docs: this.docs, files: this.files},
|
|
params: {
|
|
project_id: this.project_id
|
|
}
|
|
};
|
|
});
|
|
|
|
describe("successfully", function() {
|
|
beforeEach(function() {
|
|
this.HistoryManager.resyncProjectHistory = sinon.stub().callsArgWith(4);
|
|
return this.HttpController.resyncProjectHistory(this.req, this.res, this.next);
|
|
});
|
|
|
|
it("should accept the change", function() {
|
|
return this.HistoryManager.resyncProjectHistory
|
|
.calledWith(this.project_id, this.projectHistoryId, this.docs, this.files)
|
|
.should.equal(true);
|
|
});
|
|
|
|
return it("should return a successful No Content response", function() {
|
|
return this.res.sendStatus
|
|
.calledWith(204)
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
|
|
return describe("when an errors occurs", function() {
|
|
beforeEach(function() {
|
|
this.HistoryManager.resyncProjectHistory = sinon.stub().callsArgWith(4, new Error("oops"));
|
|
return this.HttpController.resyncProjectHistory(this.req, this.res, this.next);
|
|
});
|
|
|
|
return it("should call next with the error", function() {
|
|
return this.next
|
|
.calledWith(new Error("oops"))
|
|
.should.equal(true);
|
|
});
|
|
});
|
|
});
|
|
});
|