diff --git a/packages/service-worker/worker/src/data.ts b/packages/service-worker/worker/src/data.ts index 3b476111c9..ac48b2e7c4 100644 --- a/packages/service-worker/worker/src/data.ts +++ b/packages/service-worker/worker/src/data.ts @@ -481,10 +481,10 @@ export class DataGroup { * If the request times out on the server, an error will be returned but the real network * request will still be running in the background, to be cached when it completes. */ - private async cacheResponse( - req: Request, res: Response, lru: LruList, okToCacheOpaque: boolean = false): Promise { + private async cacheResponse(req: Request, res: Response, lru: LruList, okToCacheOpaque = false): + Promise { // Only cache successful responses. - if (!res.ok || (okToCacheOpaque && res.type === 'opaque')) { + if (!(res.ok || (okToCacheOpaque && res.type === 'opaque'))) { return; } diff --git a/packages/service-worker/worker/test/data_spec.ts b/packages/service-worker/worker/test/data_spec.ts index f7258efde6..965f79267d 100644 --- a/packages/service-worker/worker/test/data_spec.ts +++ b/packages/service-worker/worker/test/data_spec.ts @@ -150,6 +150,14 @@ import {SwTestHarness, SwTestHarnessBuilder} from '../testing/scope'; server.assertNoOtherRequests(); }); + it('does not cache opaque responses', async() => { + expect(await makeNoCorsRequest(scope, '/api/test')).toBe(''); + server.assertSawRequestFor('/api/test'); + + expect(await makeNoCorsRequest(scope, '/api/test')).toBe(''); + server.assertSawRequestFor('/api/test'); + }); + it('refreshes after awhile', async() => { expect(await makeRequest(scope, '/api/test')).toEqual('version 1'); server.clearRequests(); @@ -199,6 +207,16 @@ import {SwTestHarness, SwTestHarnessBuilder} from '../testing/scope'; serverUpdate.assertNoOtherRequests(); }); + it('caches opaque responses', async() => { + expect(await makeNoCorsRequest(scope, '/fresh/data')).toBe(''); + server.assertSawRequestFor('/fresh/data'); + + server.online = false; + + expect(await makeRequest(scope, '/fresh/data')).toBe(''); + server.assertNoOtherRequests(); + }); + it('falls back on the cache when server times out', async() => { expect(await makeRequest(scope, '/fresh/data')).toEqual('this is fresh data'); server.assertSawRequestFor('/fresh/data'); @@ -250,9 +268,18 @@ function makeRequest(scope: SwTestHarness, url: string, clientId?: string): Prom return done.then(() => resTextPromise); } +function makeNoCorsRequest( + scope: SwTestHarness, url: string, clientId?: string): Promise { + const req = new MockRequest(url, {mode: 'no-cors'}); + const [resTextPromise, done] = makePendingRequest(scope, req, clientId); + return done.then(() => resTextPromise); +} + function makePendingRequest( - scope: SwTestHarness, url: string, clientId?: string): [Promise, Promise] { - const [resPromise, done] = scope.handleFetch(new MockRequest(url), clientId || 'default'); + scope: SwTestHarness, urlOrReq: string | MockRequest, + clientId?: string): [Promise, Promise] { + const req = (typeof urlOrReq === 'string') ? new MockRequest(urlOrReq) : urlOrReq; + const [resPromise, done] = scope.handleFetch(req, clientId || 'default'); return [ resPromise.then(res => res ? res.text() : null), done,