kopia lustrzana https://gitlab.com/rysiekpl/libresilient
test coverage for config.json handling (ref. 31)
rodzic
e7c09f3065
commit
629b2eef33
|
@ -3,7 +3,11 @@ const makeServiceWorkerEnv = require('service-worker-mock');
|
|||
global.fetch = require('node-fetch');
|
||||
jest.mock('node-fetch')
|
||||
|
||||
global.fetch.mockImplementation((url, init) => {
|
||||
|
||||
describe("service-worker", () => {
|
||||
beforeEach(() => {
|
||||
|
||||
global.fetch.mockImplementation((url, init) => {
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
new Blob(
|
||||
|
@ -20,9 +24,7 @@ global.fetch.mockImplementation((url, init) => {
|
|||
})
|
||||
);
|
||||
});
|
||||
|
||||
describe("service-worker", () => {
|
||||
beforeEach(() => {
|
||||
|
||||
Object.assign(global, makeServiceWorkerEnv());
|
||||
global.self = new ServiceWorkerGlobalScope()
|
||||
jest.resetModules();
|
||||
|
@ -81,15 +83,196 @@ describe("service-worker", () => {
|
|||
}
|
||||
})
|
||||
|
||||
test("basic set-up: LibResilientConfig", async () => {
|
||||
test("basic set-up: use default LibResilientConfig values when config.json missing", async () => {
|
||||
self.LibResilientConfig = null
|
||||
|
||||
global.fetch.mockImplementation((url, init) => {
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
new Blob(
|
||||
[JSON.stringify({ test: "fail" })],
|
||||
{type: "application/json"}
|
||||
),
|
||||
{
|
||||
status: 404,
|
||||
statusText: "Not Found",
|
||||
headers: {
|
||||
'ETag': 'TestingETagHeader'
|
||||
},
|
||||
url: url
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
try {
|
||||
require("../service-worker.js");
|
||||
} catch(e) {}
|
||||
await self.trigger('install')
|
||||
await self.trigger('activate')
|
||||
expect(typeof self.LibResilientConfig).toEqual('object')
|
||||
expect(self.LibResilientConfig.defaultPluginTimeout).toBe(10000)
|
||||
expect(typeof self.LibResilientConfig.plugins).toEqual('object')
|
||||
expect(self.LibResilientConfig.loggedComponents).toBeInstanceOf(Array)
|
||||
expect(self.LibResilientConfig.plugins).toStrictEqual([{name: "fetch"},{name: "cache"}])
|
||||
expect(self.LibResilientConfig.loggedComponents).toStrictEqual(['service-worker', 'fetch', 'cache'])
|
||||
})
|
||||
|
||||
test("basic set-up: use default LibResilientConfig values when config.json not valid JSON", async () => {
|
||||
self.LibResilientConfig = null
|
||||
|
||||
global.fetch.mockImplementation((url, init) => {
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
new Blob(
|
||||
["not a JSON"],
|
||||
{type: "application/json"}
|
||||
),
|
||||
{
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
headers: {
|
||||
'ETag': 'TestingETagHeader'
|
||||
},
|
||||
url: url
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
try {
|
||||
require("../service-worker.js");
|
||||
} catch(e) {}
|
||||
await self.trigger('install')
|
||||
await self.trigger('activate')
|
||||
expect(typeof self.LibResilientConfig).toEqual('object')
|
||||
expect(self.LibResilientConfig.defaultPluginTimeout).toBe(10000)
|
||||
expect(self.LibResilientConfig.plugins).toStrictEqual([{name: "fetch"},{name: "cache"}])
|
||||
expect(self.LibResilientConfig.loggedComponents).toStrictEqual(['service-worker', 'fetch', 'cache'])
|
||||
})
|
||||
|
||||
test("basic set-up: use default LibResilientConfig values when no valid 'plugins' field in config.json", async () => {
|
||||
self.LibResilientConfig = null
|
||||
|
||||
global.fetch.mockImplementation((url, init) => {
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
new Blob(
|
||||
[JSON.stringify({loggedComponents: ['service-worker', 'fetch'], plugins: 'not a valid array'})],
|
||||
{type: "application/json"}
|
||||
),
|
||||
{
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
headers: {
|
||||
'ETag': 'TestingETagHeader'
|
||||
},
|
||||
url: url
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
try {
|
||||
require("../service-worker.js");
|
||||
} catch(e) {}
|
||||
await self.trigger('install')
|
||||
await self.trigger('activate')
|
||||
expect(typeof self.LibResilientConfig).toEqual('object')
|
||||
expect(self.LibResilientConfig.defaultPluginTimeout).toBe(10000)
|
||||
expect(self.LibResilientConfig.plugins).toStrictEqual([{name: "fetch"},{name: "cache"}])
|
||||
expect(self.LibResilientConfig.loggedComponents).toStrictEqual(['service-worker', 'fetch', 'cache'])
|
||||
})
|
||||
|
||||
test("basic set-up: use default LibResilientConfig values when no valid 'loggedComponents' field in config.json", async () => {
|
||||
self.LibResilientConfig = null
|
||||
|
||||
global.fetch.mockImplementation((url, init) => {
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
new Blob(
|
||||
[JSON.stringify({loggedComponents: 'not a valid array', plugins: [{name: "fetch"}]})],
|
||||
{type: "application/json"}
|
||||
),
|
||||
{
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
headers: {
|
||||
'ETag': 'TestingETagHeader'
|
||||
},
|
||||
url: url
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
try {
|
||||
require("../service-worker.js");
|
||||
} catch(e) {}
|
||||
await self.trigger('install')
|
||||
await self.trigger('activate')
|
||||
expect(typeof self.LibResilientConfig).toEqual('object')
|
||||
expect(self.LibResilientConfig.defaultPluginTimeout).toBe(10000)
|
||||
expect(self.LibResilientConfig.plugins).toStrictEqual([{name: "fetch"},{name: "cache"}])
|
||||
expect(self.LibResilientConfig.loggedComponents).toStrictEqual(['service-worker', 'fetch', 'cache'])
|
||||
})
|
||||
|
||||
test("basic set-up: use default LibResilientConfig values when 'defaultPluginTimeout' field in config.json contains an invalid value", async () => {
|
||||
self.LibResilientConfig = null
|
||||
|
||||
global.fetch.mockImplementation((url, init) => {
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
new Blob(
|
||||
[JSON.stringify({loggedComponents: ['service-worker', 'fetch'], plugins: [{name: "fetch"}], defaultPluginTimeout: 'not an integer'})],
|
||||
{type: "application/json"}
|
||||
),
|
||||
{
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
headers: {
|
||||
'ETag': 'TestingETagHeader'
|
||||
},
|
||||
url: url
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
try {
|
||||
require("../service-worker.js");
|
||||
} catch(e) {}
|
||||
await self.trigger('install')
|
||||
await self.trigger('activate')
|
||||
expect(typeof self.LibResilientConfig).toEqual('object')
|
||||
expect(self.LibResilientConfig.defaultPluginTimeout).toBe(10000)
|
||||
expect(self.LibResilientConfig.plugins).toStrictEqual([{name: "fetch"},{name: "cache"}])
|
||||
expect(self.LibResilientConfig.loggedComponents).toStrictEqual(['service-worker', 'fetch', 'cache'])
|
||||
})
|
||||
|
||||
test("basic set-up: use config values from a valid config.json file", async () => {
|
||||
self.LibResilientConfig = null
|
||||
|
||||
global.fetch.mockImplementation((url, init) => {
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
new Blob(
|
||||
[JSON.stringify({loggedComponents: ['service-worker', 'cache'], plugins: [{name: "cache"}], defaultPluginTimeout: 5000})],
|
||||
{type: "application/json"}
|
||||
),
|
||||
{
|
||||
status: 200,
|
||||
statusText: "OK",
|
||||
headers: {
|
||||
'ETag': 'TestingETagHeader'
|
||||
},
|
||||
url: url
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
try {
|
||||
require("../service-worker.js");
|
||||
} catch(e) {}
|
||||
await self.trigger('install')
|
||||
await self.trigger('activate')
|
||||
expect(typeof self.LibResilientConfig).toEqual('object')
|
||||
expect(self.LibResilientConfig.defaultPluginTimeout).toBe(5000)
|
||||
expect(self.LibResilientConfig.plugins).toStrictEqual([{name: "cache"}])
|
||||
expect(self.LibResilientConfig.loggedComponents).toStrictEqual(['service-worker', 'cache'])
|
||||
})
|
||||
|
||||
test("fetching content should work", async () => {
|
||||
|
|
|
@ -107,6 +107,13 @@ let verifyConfigData = (cdata) => {
|
|||
self.log('service-worker', 'fetched config does not contain a valid "loggedComponents" field')
|
||||
return false;
|
||||
}
|
||||
// defaultPluginTimeout optional
|
||||
if ("defaultPluginTimeout" in cdata) {
|
||||
if (!Number.isInteger(cdata.defaultPluginTimeout)) {
|
||||
self.log('service-worker', 'fetched config contains invalid "defaultPluginTimeout" data (integer expected)')
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// we're good
|
||||
return true;
|
||||
}
|
||||
|
@ -129,16 +136,23 @@ let initServiceWorker = async () => {
|
|||
try {
|
||||
//self.importScripts(self.registration.scope + "config.json")
|
||||
var cdata = await fetch(self.registration.scope + "config.json")
|
||||
cdata = await cdata.json()
|
||||
if (verifyConfigData(cdata)) {
|
||||
self.LibResilientConfig.plugins = cdata.plugins
|
||||
self.LibResilientConfig.loggedComponents = cdata.loggedComponents
|
||||
self.log('service-worker', 'config loaded.')
|
||||
if (cdata.status != 200) {
|
||||
self.log('service-worker', `failed to fetch config (${cdata.status} ${cdata.statusText}).`)
|
||||
} else {
|
||||
self.log('service-worker', 'ignoring invalid config, using defaults.')
|
||||
cdata = await cdata.json()
|
||||
if (verifyConfigData(cdata)) {
|
||||
self.LibResilientConfig.plugins = cdata.plugins
|
||||
self.LibResilientConfig.loggedComponents = cdata.loggedComponents
|
||||
if ("defaultPluginTimeout" in cdata) {
|
||||
self.LibResilientConfig.defaultPluginTimeout = cdata.defaultPluginTimeout
|
||||
}
|
||||
self.log('service-worker', 'config loaded.')
|
||||
} else {
|
||||
self.log('service-worker', 'ignoring invalid config, using defaults.')
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
self.log('service-worker', 'config loading failed, using defaults')
|
||||
self.log('service-worker', 'config loading failed, using defaults; error:', e)
|
||||
}
|
||||
|
||||
// create the LibResilientPluginConstructors map
|
||||
|
@ -146,14 +160,19 @@ let initServiceWorker = async () => {
|
|||
// TODO: find a better way
|
||||
self.LibResilientPluginConstructors = self.LibResilientPluginConstructors || new Map()
|
||||
|
||||
// copy of the plugins config
|
||||
// we need to work on it so that self.LibResilientConfig.plugins remains unmodified
|
||||
// in case we need it later (for example, when re-loading the config)
|
||||
var pluginsConfig = [...self.LibResilientConfig.plugins]
|
||||
|
||||
// this is the stash for plugins that need dependencies instantiated first
|
||||
var dependentPlugins = new Array()
|
||||
|
||||
// only now load the plugins (config.json could have changed the defaults)
|
||||
while (self.LibResilientConfig.plugins.length > 0) {
|
||||
while (pluginsConfig.length > 0) {
|
||||
|
||||
// get the first plugin config from the array
|
||||
let pluginConfig = self.LibResilientConfig.plugins.shift()
|
||||
let pluginConfig = pluginsConfig.shift()
|
||||
self.log('service-worker', `handling plugin type: ${pluginConfig.name}`)
|
||||
|
||||
// load the relevant plugin script (if not yet loaded)
|
||||
|
@ -170,7 +189,7 @@ let initServiceWorker = async () => {
|
|||
for (var i=(pluginConfig.uses.length); i--; i>=0) {
|
||||
self.log('service-worker', `${pluginConfig.name}: dependency found: ${pluginConfig.uses[i].name}`)
|
||||
// put the plugin config in front of the plugin configs array
|
||||
self.LibResilientConfig.plugins.unshift(pluginConfig.uses[i])
|
||||
pluginsConfig.unshift(pluginConfig.uses[i])
|
||||
// set each dependency plugin config to false so that we can keep track
|
||||
// as we fill those gaps later with instantiated dependency plugins
|
||||
pluginConfig.uses[i] = false
|
||||
|
@ -702,7 +721,6 @@ self.addEventListener('install', async (event) => {
|
|||
// TODO: Might we want to have a local cache?
|
||||
// "COMMIT_UNKNOWN" will be replaced with commit ID
|
||||
self.log('service-worker', "0. Installed LibResilient Service Worker (commit: COMMIT_UNKNOWN).");
|
||||
// TODO: should we do some plugin initialization here?
|
||||
});
|
||||
|
||||
self.addEventListener('activate', event => {
|
||||
|
|
Ładowanie…
Reference in New Issue