VulpesOS/gaia/apps/sharedtest/test/unit/sync/sync-engine/kinto-mock.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

256 lines
7.3 KiB
JavaScript
Executable file

/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
/* global SynctoServerFixture */
/* exported Kinto */
var Kinto = (function() {
var mockProblem = null;
var listData = {};
var KintoCollectionMock = function(collectionName, options = {}) {
this.collectionName = collectionName;
this.data = null;
this.fireConflicts = options.fireConflicts || [];
this._idSchemaUsed = options.idSchema; // Not mocking default UUID IdSchema.
this._remoteTransformersUsed = options.remoteTransformers;
};
KintoCollectionMock.prototype = {
sync: function() {
var dataRecordIn = JSON.parse(JSON.stringify(
SynctoServerFixture.remoteData[this.collectionName]));
var transformOut = (item) => {
if (!this._remoteTransformersUsed) {
return Promise.resolve(item);
}
// We're only mocking the case where there is just one
// remoteTransformer.
return this._remoteTransformersUsed[0].encode(item);
};
var transformIn = () => {
if (!this._remoteTransformersUsed) {
return Promise.resolve();
}
try {
// We're only mocking the case where there is just one
// remoteTransformer.
return this._remoteTransformersUsed[0].decode(dataRecordIn).
then(decoded => {
dataRecordIn = decoded;
});
} catch(err) {
return Promise.reject(err);
}
};
var pushOut = () => {
if (!listData[this.collectionName]) {
return Promise.resolve();
}
return Promise.all(listData[this.collectionName].data.map(item => {
var dataRecordOut = JSON.parse(JSON.stringify(item));
transformOut(dataRecordOut).then(encoded => {
this.pushData.push(encoded);
});
}));
};
var checkIdSchema = () => {
if (!this._idSchemaUsed.validate(dataRecordIn.id)) {
return Promise.reject(new Error('Invalid id: ' +
dataRecordIn.id));
}
};
var storeListData = () => {
if (!listData[this.collectionName]) {
listData[this.collectionName] = { data: [ dataRecordIn ] };
}
return Promise.resolve({ ok: true, conflicts: this.fireConflicts });
};
var markSyncCount = (syncResults) => {
if (!Kinto.syncCount[this.collectionName]) {
Kinto.syncCount[this.collectionName] = 0;
}
Kinto.syncCount[this.collectionName]++;
return Promise.resolve(syncResults);
};
var reportError = (error) => {
listData[this.collectionName] = { data: [] };
return Promise.resolve({ ok: false, conflicts: [], errors: [ error ] });
};
this.pushData = [];
return pushOut().
then(transformIn).
then(checkIdSchema).
then(storeListData).
then(markSyncCount).
catch(reportError);
},
resolve: function(conflict, resolution) {
listData[this.collectionName] = { data: [ resolution ] };
return Promise.resolve();
},
list: function() {
return Promise.resolve(listData[this.collectionName]);
},
get: function(id) {
if (listData[this.collectionName]) {
return Promise.resolve({
data: listData[this.collectionName].data[0]
});
}
return Promise.reject(new Error(`Record with id=${id} not found.`));
},
create: function(obj, options = {}) {
if (options.forceId) {
if(!this._idSchemaUsed.validate(options.forceId)) {
return Promise.reject(new Error('Invalid id: ' + options.forceId));
}
obj.id = options.forceId;
} else {
obj.id = this._idSchemaUsed.generate();
}
listData[this.collectionName].data.push(obj);
return Promise.resolve();
},
update: function(obj) {
for (var i = 0; i < listData[this.collectionName].data.length; i++) {
if (listData[this.collectionName].data[i].id === obj.id) {
listData[this.collectionName].data[i] = obj;
return Promise.resolve();
}
}
return Promise.reject('not found!');
},
delete: function(id) {
for (var i = 0; i < listData[this.collectionName].data.length; i++) {
if (listData[this.collectionName].data[i].id === id) {
listData[this.collectionName].data.splice(i, 1);
return Promise.resolve();
}
}
return Promise.reject('not found!');
},
clear: function() {
Kinto.clearCalled = true;
listData[this.collectionName] = { data: [] };
return Promise.resolve();
}
};
var UnreachableKintoCollectionMock = function() {};
UnreachableKintoCollectionMock.prototype = {
sync() {
return Promise.reject(new Error(`HTTP 0; TypeError: NetworkError when att\
empting to fetch resource.`));
},
list() {},
get(id) {
return Promise.reject(new Error(`Record with id=${id} not found.`));
},
create() {},
update() {},
delete() {},
clear() {
Kinto.clearCalled = true;
},
};
var HttpCodeKintoCollectionMock = function(status) {
this.status = status;
};
HttpCodeKintoCollectionMock.prototype = {
sync() {
var err = new Error();
err.response = {
status: this.status
};
return Promise.reject(err);
},
list() {},
get(id) {
return Promise.reject(new Error(`Record with id=${id} not found.`));
},
create() {},
update() {},
delete() {},
clear() {
Kinto.clearCalled = true;
},
};
var Kinto = function(kintoOptions) {
this.options = kintoOptions;
this.collection = function(collectionName, collectionOptions = {}) {
var mockProblemCase = () => {
var httpCode;
if (mockProblem &&
mockProblem.collectionName === collectionName) {
httpCode = parseInt(mockProblem.problem);
if (isNaN(httpCode)) {
if (mockProblem.problem === 'conflicts') {
collectionOptions.fireConflicts = [{
local: { bar: 'local' },
remote: SynctoServerFixture.historyEntryDec.payload
}];
return new KintoCollectionMock(collectionName, collectionOptions);
}
return new KintoCollectionMock(mockProblem.problem,
collectionOptions);
}
return new HttpCodeKintoCollectionMock(httpCode);
}
};
var unauthCase = () => {
if (kintoOptions.headers.Authorization !==
'BrowserID test-assertion-mock') {
return new HttpCodeKintoCollectionMock(401);
}
};
var unreachableCase = () => {
if (kintoOptions.remote !== 'http://localhost:8000/v1/') {
return new UnreachableKintoCollectionMock(collectionName);
}
};
var defaultCase = () => {
return new KintoCollectionMock(collectionName, collectionOptions);
};
return mockProblemCase() ||
unauthCase() ||
unreachableCase() ||
defaultCase();
};
};
Kinto.syncCount = {};
Kinto.clearCalled = false;
Kinto.setMockProblem = (problem) => {
mockProblem = problem;
Kinto.syncCount = {};
Kinto.clearCalled = false;
listData = {};
};
return Kinto;
})();