piskel/test/js/service/BackupServiceTest.js

282 lines
10 KiB
JavaScript
Raw Normal View History

2017-06-17 23:38:39 +03:00
describe('BackupService test', function () {
// Some helper const.
var ONE_SECOND = 1000;
var ONE_MINUTE = 60 * ONE_SECOND;
var mockBackupDatabase;
var mockPiskel;
var mockPiskelController;
// Globals used in stubs
var stubValues = {
snapshotDate: null,
serializedPiskel: null
};
// Main test object.
var backupService;
beforeEach(function () {
// Create mocks.
mockBackupDatabase = {
// Test property
_sessions: {},
init: function () {},
getSnapshotsBySessionId: function (sessionId) {
// Default implementation that looks up in _sessions or returns an
// empty array.
return Promise.resolve(this._sessions[sessionId] || []);
},
updateSnapshot: function () { return Promise.resolve(); },
createSnapshot: function () { return Promise.resolve(); },
deleteSnapshot: function () { return Promise.resolve(); },
getSessions: function () { return Promise.resolve([]); },
deleteSnapshotsForSession: function () { return Promise.resolve(); },
findLastSnapshot: function () { return Promise.resolve(null); }
};
mockPiskel = {
_descriptor: {},
_hash: null,
getDescriptor: function () { return this._descriptor; },
getHash: function () { return this._hash; },
};
mockPiskelController = {
getPiskel: function () { return mockPiskel; },
setPiskel: function () {}
};
spyOn(pskl.utils.serialization.Serializer, 'serialize').and.callFake(function () {
return stubValues.serializedPiskel;
});
// Create test backup service with mocks.
backupService = new pskl.service.BackupService(
mockPiskelController,
mockBackupDatabase
);
// Override the currentDate_ internal helper in order to set
// custom snapshot dates.
backupService.currentDate_ = function () {
return snapshotDate;
}
});
var createSnapshotObject = function (session_id, name, description, date, serialized) {
return {
session_id: session_id,
name: name,
description: description,
date: date,
serialized: serialized
};
};
var preparePiskelMocks = function (session_id, name, description, hash, serialized) {
2017-06-19 00:24:15 +03:00
// Update the session id.
pskl.app.sessionId = session_id;
// Update the piskel mock.
2017-06-17 23:38:39 +03:00
mockPiskel._descriptor.name = name;
mockPiskel._descriptor.description = description;
mockPiskel._hash = hash;
stubValues.serializedPiskel = serialized;
};
it('calls create to backup', function (done) {
preparePiskelMocks(1, 'piskel_name', 'piskel_desc', 'piskel_hash', 'serialized');
// Set snashot date.
snapshotDate = 5;
// No snapshots currently saved.
spyOn(mockBackupDatabase, 'createSnapshot').and.callThrough();
backupService.backup().then(function () {
expect(mockBackupDatabase.createSnapshot).toHaveBeenCalled();
var snapshot = mockBackupDatabase.createSnapshot.calls.mostRecent().args[0]
expect(snapshot.session_id).toEqual(1);
expect(snapshot.name).toEqual('piskel_name');
expect(snapshot.description).toEqual('piskel_desc');
expect(snapshot.date).toEqual(5);
expect(snapshot.serialized).toEqual('serialized');
done();
});
});
it('does not call update to backup if the hash did not change', function (done) {
var session = 1;
var date1 = 0;
var date2 = ONE_MINUTE;
var snapshot1 = createSnapshotObject(1, 'piskel_name1', 'piskel_desc1', date1, 'serialized1');
preparePiskelMocks(session, 'piskel_name1', 'piskel_desc1', 'hash', 'serialized1');
snapshotDate = date1;
// Prepare spies.
spyOn(mockBackupDatabase, 'updateSnapshot').and.callThrough();
spyOn(mockBackupDatabase, 'createSnapshot').and.callThrough();
backupService.backup().then(function () {
// The snapshot should have been created using "createSnapshot".
expect(mockBackupDatabase.createSnapshot).toHaveBeenCalled();
expect(mockBackupDatabase.updateSnapshot.calls.any()).toBe(false);
// Prepare snapshot1 to be returned in the list of already existing sessions.
mockBackupDatabase._sessions[session] = [snapshot1];
preparePiskelMocks(session, 'piskel_name2', 'piskel_desc2', 'hash', 'serialized2');
snapshotDate = date2;
backupService.backup().then(function () {
// Check that createSnapshot was not called again and updateSnapshot either.
expect(mockBackupDatabase.createSnapshot.calls.count()).toEqual(1);
expect(mockBackupDatabase.updateSnapshot.calls.count()).toEqual(0);
done();
});
});
});
it('calls update to backup if there is an existing & recent snapshot', function (done) {
var session = 1;
var date1 = 0;
var date2 = ONE_MINUTE;
var snapshot1 = createSnapshotObject(1, 'piskel_name1', 'piskel_desc1', date1, 'serialized1');
preparePiskelMocks(session, 'piskel_name1', 'piskel_desc1', 'piskel_hash1', 'serialized1');
snapshotDate = date1;
// Prepare spies.
spyOn(mockBackupDatabase, 'updateSnapshot').and.callThrough();
spyOn(mockBackupDatabase, 'createSnapshot').and.callThrough();
backupService.backup().then(function () {
// The snapshot should have been created using "createSnapshot".
expect(mockBackupDatabase.createSnapshot).toHaveBeenCalled();
// Prepare snapshot1 to be returned in the list of already existing sessions.
mockBackupDatabase._sessions[session] = [snapshot1];
preparePiskelMocks(session, 'piskel_name2', 'piskel_desc2', 'piskel_hash2', 'serialized2');
snapshotDate = date2;
backupService.backup().then(function () {
// Check that createSnapshot was not called again.
expect(mockBackupDatabase.createSnapshot.calls.count()).toEqual(1);
// Check that updateSnapshot was called with the expected arguments.
expect(mockBackupDatabase.updateSnapshot).toHaveBeenCalled();
var snapshot = mockBackupDatabase.updateSnapshot.calls.mostRecent().args[0]
expect(snapshot.session_id).toEqual(session);
expect(snapshot.name).toEqual('piskel_name2');
expect(snapshot.description).toEqual('piskel_desc2');
expect(snapshot.date).toEqual(date2);
expect(snapshot.serialized).toEqual('serialized2');
done();
});
});
});
it('creates a new snapshot if the time difference is big enough', function (done) {
var session = 1;
var date1 = 0;
var date2 = 6 * ONE_MINUTE;
var snapshot1 = createSnapshotObject(1, 'piskel_name1', 'piskel_desc1', date1, 'serialized1');
preparePiskelMocks(session, 'piskel_name1', 'piskel_desc1', 'piskel_hash1', 'serialized1');
snapshotDate = date1;
// Prepare spies.
spyOn(mockBackupDatabase, 'updateSnapshot').and.callThrough();
spyOn(mockBackupDatabase, 'createSnapshot').and.callThrough();
backupService.backup().then(function () {
// The snapshot should have been created using "createSnapshot".
expect(mockBackupDatabase.createSnapshot).toHaveBeenCalled();
// Prepare snapshot1 to be returned in the list of already existing sessions.
mockBackupDatabase._sessions[session] = [snapshot1];
preparePiskelMocks(session, 'piskel_name2', 'piskel_desc2', 'piskel_hash2', 'serialized2');
snapshotDate = date2;
backupService.backup().then(function () {
// Check that updateSnapshot was not called.
expect(mockBackupDatabase.updateSnapshot.calls.count()).toEqual(0);
// Check that updateSnapshot was called with the expected arguments.
expect(mockBackupDatabase.createSnapshot).toHaveBeenCalled();
var snapshot = mockBackupDatabase.createSnapshot.calls.mostRecent().args[0]
expect(snapshot.session_id).toEqual(session);
expect(snapshot.name).toEqual('piskel_name2');
expect(snapshot.description).toEqual('piskel_desc2');
expect(snapshot.date).toEqual(date2);
expect(snapshot.serialized).toEqual('serialized2');
done();
});
});
});
it('deletes old snapshots if there are too many of them', function (done) {
var session = 1;
var maxPerSession = 12;
preparePiskelMocks(session, 'piskel_name', 'piskel_desc', 'piskel_hash', 'serialized12');
snapshotDate = 12 * 6 * ONE_MINUTE;
// Prepare spies.
spyOn(mockBackupDatabase, 'deleteSnapshot').and.callThrough();
spyOn(mockBackupDatabase, 'createSnapshot').and.callThrough();
// Prepare array of already saved snapshots.
mockBackupDatabase._sessions[session] = [];
for (var i = maxPerSession - 1 ; i >= 0 ; i--) {
mockBackupDatabase._sessions[session].push(
createSnapshotObject(session, 'piskel_name', 'piskel_desc', i * 6 * ONE_MINUTE, 'serialized' + i)
);
}
backupService.backup().then(function () {
expect(mockBackupDatabase.createSnapshot).toHaveBeenCalled();
expect(mockBackupDatabase.deleteSnapshot).toHaveBeenCalled();
// It will simply attempt to delete the last item from the array of saved sessions
var snapshot = mockBackupDatabase.deleteSnapshot.calls.mostRecent().args[0];
expect(snapshot.session_id).toEqual(session);
expect(snapshot.name).toEqual('piskel_name');
expect(snapshot.description).toEqual('piskel_desc');
expect(snapshot.date).toEqual(0);
expect(snapshot.serialized).toEqual('serialized0');
done();
});
});
it('deletes a session if there are too many of them', function (done) {
var session = 'session10';
var maxSessions = 10;
preparePiskelMocks(session, 'piskel_name', 'piskel_desc', 'piskel_hash', 'serialized12');
snapshotDate = 10 * ONE_MINUTE;
// Prepare array of sessions.
var sessions = [];
for (var i = 0 ; i < maxSessions + 1 ; i++) {
sessions.push({
id: 'session' + i,
startDate: i * ONE_MINUTE
});
}
// Prepare spies.
spyOn(mockBackupDatabase, 'getSessions').and.returnValue(Promise.resolve(sessions));
spyOn(mockBackupDatabase, 'createSnapshot').and.callThrough();
spyOn(mockBackupDatabase, 'deleteSnapshotsForSession').and.callThrough();
backupService.backup().then(function () {
expect(mockBackupDatabase.createSnapshot).toHaveBeenCalled();
expect(mockBackupDatabase.deleteSnapshotsForSession).toHaveBeenCalled();
// It will simply attempt to delete the last item from the array of saved sessions
var sessionId = mockBackupDatabase.deleteSnapshotsForSession.calls.mostRecent().args[0];
expect(sessionId).toEqual('session0');
done();
});
});
});