From 5306330d85ad68e98c5e9752fa18b8f27a16a3cd Mon Sep 17 00:00:00 2001 From: George Kalpakas Date: Mon, 24 Jun 2019 15:04:11 +0300 Subject: [PATCH] test(service-worker): better simulate opaque requests (#30977) Previously, opaque responses where handled a little differently than other responses from the mock server. More specifically, they were not tracked (so no assertions could be made for them) and their [`Body` mixin][1] methods (such as `arrayBuffer()`, `json()`, `text()`) would throw an error due to `body` being `null`. This commit ensures opaque responses are also captured on the mock server and also changes `Body` mixin methods to better simulate the [spec'd behavior][2]. (These improvements will be necessary to test caching of opaque responses in a subsequent commit.) [1]: https://developer.mozilla.org/en-US/docs/Web/API/Body [2]: https://fetch.spec.whatwg.org/#concept-body-consume-body PR Close #30977 --- .../service-worker/worker/testing/fetch.ts | 42 +++++++------------ .../service-worker/worker/testing/mock.ts | 5 ++- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/packages/service-worker/worker/testing/fetch.ts b/packages/service-worker/worker/testing/fetch.ts index acd1ba91d1..41605a3b20 100644 --- a/packages/service-worker/worker/testing/fetch.ts +++ b/packages/service-worker/worker/testing/fetch.ts @@ -13,46 +13,34 @@ export class MockBody implements Body { constructor(public _body: string|null) {} async arrayBuffer(): Promise { - this.markBodyUsed(); - if (this._body !== null) { - const buffer = new ArrayBuffer(this._body.length); - const access = new Uint8Array(buffer); - for (let i = 0; i < this._body.length; i++) { - access[i] = this._body.charCodeAt(i); - } - return buffer; - } else { - throw new Error('No body'); + const body = this.getBody(); + const buffer = new ArrayBuffer(body.length); + const view = new Uint8Array(buffer); + + for (let i = 0; i < body.length; i++) { + view[i] = body.charCodeAt(i); } + + return buffer; } async blob(): Promise { throw 'Not implemented'; } - async json(): Promise { - this.markBodyUsed(); - if (this._body !== null) { - return JSON.parse(this._body); - } else { - throw new Error('No body'); - } - } + async json(): Promise { return JSON.parse(this.getBody()); } - async text(): Promise { - this.markBodyUsed(); - if (this._body !== null) { - return this._body; - } else { - throw new Error('No body'); - } - } + async text(): Promise { return this.getBody(); } async formData(): Promise { throw 'Not implemented'; } - private markBodyUsed(): void { + private getBody(): string { if (this.bodyUsed === true) { throw new Error('Cannot reuse body without cloning.'); } this.bodyUsed = true; + + // According to the spec, a `null` body results in an empty `ReadableStream` (which for our + // needs is equivalent to `''`). See https://fetch.spec.whatwg.org/#concept-body-consume-body. + return this._body || ''; } } diff --git a/packages/service-worker/worker/testing/mock.ts b/packages/service-worker/worker/testing/mock.ts index 907e375614..66577d475b 100644 --- a/packages/service-worker/worker/testing/mock.ts +++ b/packages/service-worker/worker/testing/mock.ts @@ -120,11 +120,12 @@ export class MockServerState { throw new Error('Offline.'); } - if (req.credentials === 'include') { + this.requests.push(req); + + if ((req.credentials === 'include') || (req.mode === 'no-cors')) { return new MockResponse(null, {status: 0, statusText: '', type: 'opaque'}); } const url = req.url.split('?')[0]; - this.requests.push(req); if (this.resources.has(url)) { return this.resources.get(url) !.clone(); }