diff --git a/__tests__/plugins/alt-fetch.test.js b/__tests__/plugins/alt-fetch.test.js index acaadba..90d9a76 100644 --- a/__tests__/plugins/alt-fetch.test.js +++ b/__tests__/plugins/alt-fetch.test.js @@ -1,18 +1,88 @@ const makeServiceWorkerEnv = require('service-worker-mock'); +global.fetch = require('node-fetch'); +jest.mock('node-fetch') + +/* + * we need a Promise.any() polyfill + * so here it is + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any + * + * TODO: remove once Promise.any() is implemented broadly + */ +if (typeof Promise.any === 'undefined') { + Promise.any = async (promises) => { + // Promise.all() is the polar opposite of Promise.any() + // in that it returns as soon as there is a first rejection + // but without it, it returns an array of resolved results + return Promise.all( + promises.map(p => { + return new Promise((resolve, reject) => + // swap reject and resolve, so that we can use Promise.all() + // and get the result we need + Promise.resolve(p).then(reject, resolve) + ); + }) + // now, swap errors and values back + ).then( + err => Promise.reject(err), + val => Promise.resolve(val) + ); + }; +} + describe("plugin: alt-fetch", () => { + beforeEach(() => { Object.assign(global, makeServiceWorkerEnv()); jest.resetModules(); self.LibResilientPlugins = new Array() self.LibResilientConfig = { plugins: { - 'alt-fetch':{} + 'alt-fetch':{ + endpoints: [ + 'https://alt.resilient.is/test.json', + 'https://error.resilientis/test.json', + 'https://timeout.resilientis/test.json' + ] + } } } + self.log = function(component, ...items) { + console.debug(component + ' :: ', ...items) + } }) + test("it should register in LibResilientPlugins", () => { require("../../plugins/alt-fetch.js"); expect(self.LibResilientPlugins[0].name).toEqual('alt-fetch'); }); + + test("it should fetch the content", async () => { + const altFetch = require("../../plugins/alt-fetch.js"); + + global.fetch.mockImplementation((url, init) => { + const response = new Response( + new Blob( + [JSON.stringify({ test: "success" })], + {type: "application/json"} + ), + { + status: 200, + statusText: "OK", + headers: { + 'ETag': 'TestingETagHeader' + }, + url: url + }); + return Promise.resolve(response); + }); + + const response = await self.LibResilientPlugins[0].fetch('https://resilient.is/test.json'); + + expect(fetch).toHaveBeenCalled(); + expect(await response.json()).toEqual({test: "success"}) + expect(response.url).toEqual('https://resilient.is/test.json') + }) + }); diff --git a/plugins/alt-fetch.js b/plugins/alt-fetch.js index b750cc9..f8fade1 100644 --- a/plugins/alt-fetch.js +++ b/plugins/alt-fetch.js @@ -71,7 +71,7 @@ // we don't want to modify the original endpoints array var sourceEndpoints = [...config.endpoints] - // if we have fewer than the configured concurrency, use all of them + // if we have fewer than the configured concurrency or just as many, use all of them if (sourceEndpoints.length <= config.concurrency) { var useEndpoints = sourceEndpoints // otherwise get `config.concurrency` endpoints at random