2017-09-28 19:18:12 -04:00
|
|
|
/**
|
|
|
|
* @license
|
|
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
|
|
* found in the LICENSE file at https://angular.io/license
|
|
|
|
*/
|
|
|
|
|
|
|
|
export class MockBody implements Body {
|
2018-08-05 11:31:27 -04:00
|
|
|
readonly body !: ReadableStream;
|
2017-09-28 19:18:12 -04:00
|
|
|
bodyUsed: boolean = false;
|
|
|
|
|
|
|
|
constructor(public _body: string|null) {}
|
|
|
|
|
2017-10-02 18:59:57 -04:00
|
|
|
async arrayBuffer(): Promise<ArrayBuffer> {
|
2019-06-24 08:04:11 -04:00
|
|
|
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);
|
2017-10-02 18:59:57 -04:00
|
|
|
}
|
2019-06-24 08:04:11 -04:00
|
|
|
|
|
|
|
return buffer;
|
2017-10-02 18:59:57 -04:00
|
|
|
}
|
2017-09-28 19:18:12 -04:00
|
|
|
|
|
|
|
async blob(): Promise<Blob> { throw 'Not implemented'; }
|
|
|
|
|
2019-06-24 08:04:11 -04:00
|
|
|
async json(): Promise<any> { return JSON.parse(this.getBody()); }
|
2017-09-28 19:18:12 -04:00
|
|
|
|
2019-06-24 08:04:11 -04:00
|
|
|
async text(): Promise<string> { return this.getBody(); }
|
2017-09-28 19:18:12 -04:00
|
|
|
|
|
|
|
async formData(): Promise<FormData> { throw 'Not implemented'; }
|
2017-10-10 15:54:41 -04:00
|
|
|
|
2019-06-24 08:04:11 -04:00
|
|
|
private getBody(): string {
|
2017-10-10 15:54:41 -04:00
|
|
|
if (this.bodyUsed === true) {
|
|
|
|
throw new Error('Cannot reuse body without cloning.');
|
|
|
|
}
|
|
|
|
this.bodyUsed = true;
|
2019-06-24 08:04:11 -04:00
|
|
|
|
|
|
|
// 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 || '';
|
2017-10-10 15:54:41 -04:00
|
|
|
}
|
2017-09-28 19:18:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export class MockHeaders implements Headers {
|
|
|
|
map = new Map<string, string>();
|
2017-12-22 12:36:47 -05:00
|
|
|
|
|
|
|
[Symbol.iterator]() { return this.map[Symbol.iterator](); }
|
|
|
|
|
2019-04-25 15:51:10 -04:00
|
|
|
append(name: string, value: string): void { this.map.set(name.toLowerCase(), value); }
|
2017-09-28 19:18:12 -04:00
|
|
|
|
2019-04-25 15:51:10 -04:00
|
|
|
delete (name: string): void { this.map.delete(name.toLowerCase()); }
|
2017-09-28 19:18:12 -04:00
|
|
|
|
2017-12-22 12:36:47 -05:00
|
|
|
entries() { return this.map.entries(); }
|
|
|
|
|
2017-09-28 19:18:12 -04:00
|
|
|
forEach(callback: Function): void { this.map.forEach(callback as any); }
|
|
|
|
|
2019-04-25 15:51:10 -04:00
|
|
|
get(name: string): string|null { return this.map.get(name.toLowerCase()) || null; }
|
2017-09-28 19:18:12 -04:00
|
|
|
|
2019-04-25 15:51:10 -04:00
|
|
|
has(name: string): boolean { return this.map.has(name.toLowerCase()); }
|
2017-09-28 19:18:12 -04:00
|
|
|
|
2017-12-22 12:36:47 -05:00
|
|
|
keys() { return this.map.keys(); }
|
|
|
|
|
2019-04-25 15:51:10 -04:00
|
|
|
set(name: string, value: string): void { this.map.set(name.toLowerCase(), value); }
|
2017-12-22 12:36:47 -05:00
|
|
|
|
|
|
|
values() { return this.map.values(); }
|
2017-09-28 19:18:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export class MockRequest extends MockBody implements Request {
|
2018-08-05 11:31:27 -04:00
|
|
|
readonly isHistoryNavigation: boolean = false;
|
|
|
|
readonly isReloadNavigation: boolean = false;
|
|
|
|
readonly body !: ReadableStream;
|
2017-09-28 19:18:12 -04:00
|
|
|
readonly cache: RequestCache = 'default';
|
|
|
|
readonly credentials: RequestCredentials = 'omit';
|
|
|
|
readonly destination: RequestDestination = 'document';
|
|
|
|
readonly headers: Headers = new MockHeaders();
|
|
|
|
readonly integrity: string = '';
|
|
|
|
readonly keepalive: boolean = true;
|
|
|
|
readonly method: string = 'GET';
|
|
|
|
readonly mode: RequestMode = 'cors';
|
|
|
|
readonly redirect: RequestRedirect = 'error';
|
|
|
|
readonly referrer: string = '';
|
|
|
|
readonly referrerPolicy: ReferrerPolicy = 'no-referrer';
|
2018-02-08 11:59:25 -05:00
|
|
|
readonly signal: AbortSignal = null as any;
|
|
|
|
|
2017-10-02 18:59:57 -04:00
|
|
|
url: string;
|
2017-09-28 19:18:12 -04:00
|
|
|
|
|
|
|
constructor(input: string|Request, init: RequestInit = {}) {
|
2018-02-08 11:59:25 -05:00
|
|
|
super(init !== undefined ? (init.body as(string | null)) || null : null);
|
2017-09-28 19:18:12 -04:00
|
|
|
if (typeof input !== 'string') {
|
|
|
|
throw 'Not implemented';
|
|
|
|
}
|
|
|
|
this.url = input;
|
2017-12-22 12:36:47 -05:00
|
|
|
const headers = init.headers as{[key: string]: string};
|
|
|
|
if (headers !== undefined) {
|
|
|
|
if (headers instanceof MockHeaders) {
|
|
|
|
this.headers = headers;
|
2017-09-28 19:18:12 -04:00
|
|
|
} else {
|
2017-12-22 12:36:47 -05:00
|
|
|
Object.keys(headers).forEach(header => { this.headers.set(header, headers[header]); });
|
2017-09-28 19:18:12 -04:00
|
|
|
}
|
|
|
|
}
|
2018-03-20 09:10:59 -04:00
|
|
|
if (init.cache !== undefined) {
|
|
|
|
this.cache = init.cache;
|
|
|
|
}
|
2017-09-28 19:18:12 -04:00
|
|
|
if (init.mode !== undefined) {
|
|
|
|
this.mode = init.mode;
|
|
|
|
}
|
2017-10-02 18:59:57 -04:00
|
|
|
if (init.credentials !== undefined) {
|
|
|
|
this.credentials = init.credentials;
|
|
|
|
}
|
2017-09-28 19:18:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
clone(): Request {
|
|
|
|
if (this.bodyUsed) {
|
|
|
|
throw 'Body already consumed';
|
|
|
|
}
|
2017-10-02 18:59:57 -04:00
|
|
|
return new MockRequest(
|
|
|
|
this.url,
|
|
|
|
{body: this._body, mode: this.mode, credentials: this.credentials, headers: this.headers});
|
2017-09-28 19:18:12 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class MockResponse extends MockBody implements Response {
|
2018-08-05 11:31:27 -04:00
|
|
|
readonly trailer: Promise<Headers> = Promise.resolve(new MockHeaders());
|
2017-09-28 19:18:12 -04:00
|
|
|
readonly headers: Headers = new MockHeaders();
|
|
|
|
get ok(): boolean { return this.status >= 200 && this.status < 300; }
|
|
|
|
readonly status: number;
|
|
|
|
readonly statusText: string;
|
|
|
|
readonly type: ResponseType = 'basic';
|
|
|
|
readonly url: string = '';
|
2017-10-02 18:59:57 -04:00
|
|
|
readonly redirected: boolean = false;
|
2017-09-28 19:18:12 -04:00
|
|
|
|
2017-10-02 18:59:57 -04:00
|
|
|
constructor(
|
|
|
|
body?: any,
|
|
|
|
init: ResponseInit&{type?: ResponseType, redirected?: boolean, url?: string} = {}) {
|
2017-09-28 19:18:12 -04:00
|
|
|
super(typeof body === 'string' ? body : null);
|
|
|
|
this.status = (init.status !== undefined) ? init.status : 200;
|
|
|
|
this.statusText = init.statusText || 'OK';
|
2017-12-22 12:36:47 -05:00
|
|
|
const headers = init.headers as{[key: string]: string};
|
|
|
|
if (headers !== undefined) {
|
|
|
|
if (headers instanceof MockHeaders) {
|
|
|
|
this.headers = headers;
|
2017-09-28 19:18:12 -04:00
|
|
|
} else {
|
2017-12-22 12:36:47 -05:00
|
|
|
Object.keys(headers).forEach(header => { this.headers.set(header, headers[header]); });
|
2017-09-28 19:18:12 -04:00
|
|
|
}
|
|
|
|
}
|
2017-10-02 18:59:57 -04:00
|
|
|
if (init.type !== undefined) {
|
|
|
|
this.type = init.type;
|
|
|
|
}
|
|
|
|
if (init.redirected !== undefined) {
|
|
|
|
this.redirected = init.redirected;
|
|
|
|
}
|
|
|
|
if (init.url !== undefined) {
|
|
|
|
this.url = init.url;
|
|
|
|
}
|
2017-09-28 19:18:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
clone(): Response {
|
|
|
|
if (this.bodyUsed) {
|
|
|
|
throw 'Body already consumed';
|
|
|
|
}
|
|
|
|
return new MockResponse(
|
|
|
|
this._body, {status: this.status, statusText: this.statusText, headers: this.headers});
|
|
|
|
}
|
2018-03-20 09:10:59 -04:00
|
|
|
}
|