overleaf/services/track-changes/test/acceptance/coffee/ArchivingUpdatesTests.js

181 lines
No EOL
5.8 KiB
JavaScript

/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS103: Rewrite code to no longer use __guard__
* DS202: Simplify dynamic range loops
* 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 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);
}
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();
this.minutes = 60 * 1000;
this.hours = 60 * this.minutes;
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");
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 = 0 <= end; 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, function(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);
});
});
});
describe("archiving a doc's updates", function() {
before(function(done) {
TrackChangesClient.pushDocHistory(this.project_id, this.doc_id, function(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}}, function(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)}, function(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) }, function(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) }, function(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 describe("unarchiving a doc's updates", function() {
before(function(done) {
TrackChangesClient.pullDocHistory(this.project_id, this.doc_id, function(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) }, function(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;
}