additional tests for handling HTTP errors from plugins (ref. #36)

master
Michał 'rysiek' Woźniak 2024-03-13 03:20:10 +00:00
rodzic e4db403d62
commit 935b9c27ac
1 zmienionych plików z 243 dodań i 3 usunięć

Wyświetl plik

@ -1592,6 +1592,246 @@ describe('service-worker', async () => {
assertEquals(await response.json(), { test: "success" })
});
it("should use return a 4xx error directly from the last plugin, regardless of previous plugin errors or rejection", async () => {
window.LibResilientConfig = {
plugins: [{
name: 'reject-all'
},{
name: 'error-out'
},{
name: 'return-418'
}],
loggedComponents: [
'service-worker'
]
}
let rejectingFetch = spy(
(request, init)=>{ return Promise.reject('reject-all rejecting a request for: ' + request); }
)
window.LibResilientPluginConstructors.set('reject-all', ()=>{
return {
name: 'reject-all',
description: 'Reject all requests.',
version: '0.0.1',
fetch: rejectingFetch
}
})
let throwingFetch = spy(
(request, init)=>{ throw new Error('error-out throwing an Error for: ' + request); }
)
window.LibResilientPluginConstructors.set('error-out', ()=>{
return {
name: 'error-out',
description: 'Throws.',
version: '0.0.1',
fetch: throwingFetch
}
})
let mock_response_data = {
data: JSON.stringify({text: "success"}),
status: 418,
statusText: "Im A Teapot"
}
window.fetch = spy(window.getMockedFetch(mock_response_data))
window.LibResilientPluginConstructors.set('return-418', ()=>{
return {
name: 'return-418',
description: 'Return 418 HTTP Error.',
version: '0.0.1',
fetch: fetch
}
})
await import("../../service-worker.js?" + window.test_id);
await self.dispatchEvent(new Event('install'))
await self.waitForSWInstall()
let fetch_event = new FetchEvent('test.json')
window.dispatchEvent(fetch_event)
let response = await fetch_event.waitForResponse()
assertSpyCalls(window.fetch, 2); // two, because the first one is for config.json
assertSpyCalls(rejectingFetch, 1);
assertSpyCalls(throwingFetch, 1);
assertSpyCall(window.fetch, 1, { args: [
"https://test.resilient.is/test.json",
{
cache: undefined,
integrity: undefined,
method: "GET",
redirect: "follow",
referrer: undefined,
}]
})
assertEquals(response.status, 418)
assertEquals(response.statusText, 'Im A Teapot')
assertEquals(await response.json(), { text: "success" })
});
it("should use return a 4xx error directly from a plugin, regardless of any following plugins", async () => {
window.LibResilientConfig = {
plugins: [{
name: 'return-418'
},{
name: 'reject-all'
},{
name: 'error-out'
}],
loggedComponents: [
'service-worker'
]
}
let rejectingFetch = spy(
(request, init)=>{ return Promise.reject('reject-all rejecting a request for: ' + request); }
)
window.LibResilientPluginConstructors.set('reject-all', ()=>{
return {
name: 'reject-all',
description: 'Reject all requests.',
version: '0.0.1',
fetch: rejectingFetch
}
})
let throwingFetch = spy(
(request, init)=>{ throw new Error('error-out throwing an Error for: ' + request); }
)
window.LibResilientPluginConstructors.set('error-out', ()=>{
return {
name: 'error-out',
description: 'Throws.',
version: '0.0.1',
fetch: throwingFetch
}
})
let mock_response_data = {
data: JSON.stringify({text: "success"}),
status: 418,
statusText: "Im A Teapot"
}
window.fetch = spy(window.getMockedFetch(mock_response_data))
window.LibResilientPluginConstructors.set('return-418', ()=>{
return {
name: 'return-418',
description: 'Return 418 HTTP Error.',
version: '0.0.1',
fetch: fetch
}
})
await import("../../service-worker.js?" + window.test_id);
await self.dispatchEvent(new Event('install'))
await self.waitForSWInstall()
let fetch_event = new FetchEvent('test.json')
window.dispatchEvent(fetch_event)
let response = await fetch_event.waitForResponse()
assertSpyCalls(window.fetch, 2); // two, because the first one is for config.json
assertSpyCalls(rejectingFetch, 0);
assertSpyCalls(throwingFetch, 0);
assertSpyCall(window.fetch, 1, { args: [
"https://test.resilient.is/test.json",
{
cache: undefined,
integrity: undefined,
method: "GET",
redirect: "follow",
referrer: undefined,
}]
})
assertEquals(response.status, 418)
assertEquals(response.statusText, 'Im A Teapot')
assertEquals(await response.json(), { text: "success" })
});
it("should use treat a 5xx error from a plugin as internal error and try following plugins", async () => {
window.LibResilientConfig = {
plugins: [{
name: 'return-500'
},{
name: 'reject-all'
},{
name: 'error-out'
}],
loggedComponents: [
'service-worker'
]
}
let rejectingFetch = spy(
(request, init)=>{ return Promise.reject('reject-all rejecting a request for: ' + request); }
)
window.LibResilientPluginConstructors.set('reject-all', ()=>{
return {
name: 'reject-all',
description: 'Reject all requests.',
version: '0.0.1',
fetch: rejectingFetch
}
})
let throwingFetch = spy(
(request, init)=>{ throw new Error('error-out throwing an Error for: ' + request); }
)
window.LibResilientPluginConstructors.set('error-out', ()=>{
return {
name: 'error-out',
description: 'Throws.',
version: '0.0.1',
fetch: throwingFetch
}
})
let mock_response_data = {
data: JSON.stringify({text: "success"}),
status: 500,
statusText: "Internal Server Error"
}
window.fetch = spy(window.getMockedFetch(mock_response_data))
window.LibResilientPluginConstructors.set('return-500', ()=>{
return {
name: 'return-500',
description: 'Return 500 HTTP Error.',
version: '0.0.1',
fetch: fetch
}
})
await import("../../service-worker.js?" + window.test_id);
await self.dispatchEvent(new Event('install'))
await self.waitForSWInstall()
let fetch_event = new FetchEvent('test.json')
window.dispatchEvent(fetch_event)
let response = fetch_event.waitForResponse()
assertRejects( async () => {
return await response
})
// wait for the response to resolve
await response.catch((e)=>{})
assertSpyCalls(window.fetch, 2);
assertSpyCalls(rejectingFetch, 1);
assertSpyCalls(throwingFetch, 1);
});
it("should normalize query params in requested URLs by default", async () => {
console.log(self.LibResilientConfig)
@ -2883,7 +3123,7 @@ describe('service-worker', async () => {
assertEquals(await response.json(), { test: "success" })
})
it("should return a 404 Not Found HTTP response object when handling a failed navigation request", async () => {
it("should return a 404 Not Found HTTP response object with an error screen when handling a rejected navigation request", async () => {
window.LibResilientConfig = {
plugins: [{
name: 'reject-all'
@ -2920,7 +3160,7 @@ describe('service-worker', async () => {
assertEquals((await response.text()).slice(0, 57), '<!DOCTYPE html><html><head><title>Loading failed.</title>')
})
it("should not return a 404 Not Found HTTP response object when handling a rejected non-navigation request", async () => {
it("should not return a 404 Not Found HTTP response object with an error screen when handling a rejected non-navigation request", async () => {
window.LibResilientConfig = {
plugins: [{
name: 'reject-all'
@ -2952,7 +3192,7 @@ describe('service-worker', async () => {
assertRejects(async ()=>{ await fetch_event.waitForResponse() })
})
it("should not return a 404 Not Found HTTP response object when handling a non-navigation request that throws an error", async () => {
it("should not return a 404 Not Found HTTP response object with an error screen when handling a non-navigation request that throws an error", async () => {
window.LibResilientConfig = {
plugins: [{
name: 'error-out'