test(service-worker): better align mock event implementations with actual implementations (#42736)
This commit better aligns the mock event implementations used in ServiceWorker tests (and the associated typings) with the actual implementations (and the official TypeScript typings). This allows verifying the ServiceWorker behavior in a slightly more realistic environment. This is in preparation of switching from our custom typings to the official TypeScript typings (`lib.webworker.d.ts`). PR Close #42736
This commit is contained in:
parent
a86c404f14
commit
22a81231f2
|
@ -64,29 +64,24 @@ type WindowClientState = 'hidden'|'visible'|'prerender'|'unloaded';
|
|||
// Fetch API
|
||||
|
||||
interface FetchEvent extends ExtendableEvent {
|
||||
request: Request;
|
||||
clientId?: string;
|
||||
resultingClientId?: string;
|
||||
respondWith(response: Promise<Response>|Response): Promise<Response>;
|
||||
readonly clientId: string;
|
||||
readonly preloadResponse: Promise<any>;
|
||||
readonly request: Request;
|
||||
readonly resultingClientId: string;
|
||||
respondWith(r: Response|Promise<Response>): void;
|
||||
}
|
||||
|
||||
interface InstallEvent extends ExtendableEvent {
|
||||
activeWorker: ServiceWorker;
|
||||
}
|
||||
|
||||
interface ActivateEvent extends ExtendableEvent {}
|
||||
|
||||
// Notification API
|
||||
|
||||
interface NotificationEvent extends ExtendableEvent {
|
||||
action: string;
|
||||
notification: Notification;
|
||||
readonly action: string;
|
||||
readonly notification: Notification;
|
||||
}
|
||||
|
||||
// Push API
|
||||
|
||||
interface PushEvent extends ExtendableEvent {
|
||||
data: PushMessageData;
|
||||
readonly data: PushMessageData|null;
|
||||
}
|
||||
|
||||
interface PushMessageData {
|
||||
|
@ -99,13 +94,16 @@ interface PushMessageData {
|
|||
// Sync API
|
||||
|
||||
interface SyncEvent extends ExtendableEvent {
|
||||
lastChance: boolean;
|
||||
tag: string;
|
||||
readonly lastChance: boolean;
|
||||
readonly tag: string;
|
||||
}
|
||||
|
||||
interface ExtendableMessageEvent extends ExtendableEvent {
|
||||
data: any;
|
||||
source: Client|Object;
|
||||
readonly data: any;
|
||||
readonly lastEventId: string;
|
||||
readonly origin: string;
|
||||
readonly ports: ReadonlyArray<MessagePort>;
|
||||
readonly source: Client|ServiceWorker|MessagePort|null;
|
||||
}
|
||||
|
||||
// ServiceWorkerGlobalScope
|
||||
|
|
|
@ -783,7 +783,7 @@ describe('Driver', () => {
|
|||
const message: any = scope.clients.getMock('default')!.messages[0];
|
||||
|
||||
expect(message.type).toEqual('NOTIFICATION_CLICK');
|
||||
expect(message.data.action).toBeUndefined();
|
||||
expect(message.data.action).toBe('');
|
||||
expect(message.data.notification.title).toEqual('This is a test without action');
|
||||
expect(message.data.notification.body).toEqual('Test body without action');
|
||||
});
|
||||
|
|
|
@ -49,7 +49,7 @@ export class MockEvent implements Event {
|
|||
}
|
||||
|
||||
export class MockExtendableEvent extends MockEvent implements ExtendableEvent {
|
||||
private queue: Promise<void>[] = [];
|
||||
private queue: Promise<unknown>[] = [];
|
||||
|
||||
get ready(): Promise<void> {
|
||||
return (async () => {
|
||||
|
@ -59,7 +59,7 @@ export class MockExtendableEvent extends MockEvent implements ExtendableEvent {
|
|||
})();
|
||||
}
|
||||
|
||||
waitUntil(promise: Promise<void>): void {
|
||||
waitUntil(promise: Promise<unknown>): void {
|
||||
this.queue.push(promise);
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,8 @@ export class MockActivateEvent extends MockExtendableEvent {
|
|||
}
|
||||
}
|
||||
|
||||
export class MockFetchEvent extends MockExtendableEvent {
|
||||
export class MockFetchEvent extends MockExtendableEvent implements FetchEvent {
|
||||
readonly preloadResponse = Promise.resolve();
|
||||
response: Promise<Response|undefined> = Promise.resolve(undefined);
|
||||
|
||||
constructor(
|
||||
|
@ -78,9 +79,8 @@ export class MockFetchEvent extends MockExtendableEvent {
|
|||
super('fetch');
|
||||
}
|
||||
|
||||
respondWith(promise: Promise<Response>): Promise<Response> {
|
||||
this.response = promise;
|
||||
return promise;
|
||||
respondWith(r: Response|Promise<Response>): void {
|
||||
this.response = Promise.resolve(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,27 +90,33 @@ export class MockInstallEvent extends MockExtendableEvent {
|
|||
}
|
||||
}
|
||||
|
||||
export class MockMessageEvent extends MockExtendableEvent {
|
||||
constructor(readonly data: Object, readonly source: MockClient|null) {
|
||||
export class MockExtendableMessageEvent extends MockExtendableEvent implements
|
||||
ExtendableMessageEvent {
|
||||
readonly lastEventId = '';
|
||||
readonly origin = '';
|
||||
readonly ports: ReadonlyArray<MessagePort> = [];
|
||||
|
||||
constructor(readonly data: any, readonly source: Client|MessagePort|ServiceWorker|null) {
|
||||
super('message');
|
||||
}
|
||||
}
|
||||
|
||||
export class MockNotificationEvent extends MockExtendableEvent {
|
||||
export class MockNotificationEvent extends MockExtendableEvent implements NotificationEvent {
|
||||
readonly notification = {
|
||||
...this._notification,
|
||||
close: () => undefined,
|
||||
};
|
||||
} as Notification;
|
||||
|
||||
constructor(private _notification: any, readonly action?: string) {
|
||||
constructor(private _notification: Partial<Notification>, readonly action = '') {
|
||||
super('notification');
|
||||
}
|
||||
}
|
||||
|
||||
export class MockPushEvent extends MockExtendableEvent {
|
||||
data = {
|
||||
export class MockPushEvent extends MockExtendableEvent implements PushEvent {
|
||||
readonly data = {
|
||||
json: () => this._data,
|
||||
};
|
||||
text: () => JSON.stringify(this._data),
|
||||
} as PushMessageData;
|
||||
|
||||
constructor(private _data: object) {
|
||||
super('push');
|
||||
|
|
|
@ -13,7 +13,7 @@ import {AssetGroupConfig, Manifest} from '../src/manifest';
|
|||
import {sha1} from '../src/sha1';
|
||||
|
||||
import {MockCacheStorage} from './cache';
|
||||
import {MockActivateEvent, MockFetchEvent, MockInstallEvent, MockMessageEvent, MockNotificationEvent, MockPushEvent} from './events';
|
||||
import {MockActivateEvent, MockExtendableMessageEvent, MockFetchEvent, MockInstallEvent, MockNotificationEvent, MockPushEvent} from './events';
|
||||
import {MockHeaders, MockRequest, MockResponse} from './fetch';
|
||||
import {MockServerState, MockServerStateBuilder} from './mock';
|
||||
import {normalizeUrl, parseUrl} from './utils';
|
||||
|
@ -244,12 +244,13 @@ export class SwTestHarness extends Adapter<MockCacheStorage> implements ServiceW
|
|||
if (!this.eventHandlers.has('message')) {
|
||||
throw new Error('No message handler registered');
|
||||
}
|
||||
let event: MockMessageEvent;
|
||||
let event: MockExtendableMessageEvent;
|
||||
if (clientId === null) {
|
||||
event = new MockMessageEvent(data, null);
|
||||
event = new MockExtendableMessageEvent(data, null);
|
||||
} else {
|
||||
this.clients.add(clientId);
|
||||
event = new MockMessageEvent(data, this.clients.getMock(clientId) || null);
|
||||
event = new MockExtendableMessageEvent(
|
||||
data, this.clients.getMock(clientId) as unknown as Client || null);
|
||||
}
|
||||
this.eventHandlers.get('message')!.call(this, event);
|
||||
return event.ready;
|
||||
|
|
Loading…
Reference in New Issue