fix(service-worker): Fix public api guard typing (#25860)

PR Close #25860
This commit is contained in:
Joost Zöllner 2018-09-28 10:28:53 +02:00 committed by Kara Erickson
parent 10618752e6
commit 4a01ada291
8 changed files with 29 additions and 29 deletions

View File

@ -52,8 +52,6 @@ interface StatusEvent {
error?: string;
}
export interface NotificationObject extends NotificationOptions { title: string; }
function errorObservable(message: string): Observable<any> {
return defer(() => throwError(new Error(message)));

View File

@ -10,7 +10,7 @@ import {Injectable} from '@angular/core';
import {NEVER, Observable, Subject, merge} from 'rxjs';
import {map, switchMap, take} from 'rxjs/operators';
import {ERR_SW_NOT_SUPPORTED, NgswCommChannel, NotificationObject, PushEvent} from './low_level';
import {ERR_SW_NOT_SUPPORTED, NgswCommChannel, PushEvent} from './low_level';
/**
@ -30,14 +30,16 @@ export class SwPush {
* interacted with.
* If no action was used the action property will be an empty string `''`.
*
* Note that the `notification` property is __not__ a
* [Notification](https://developer.mozilla.org/en-US/docs/Web/API/Notification) but rather a
* Note that the `notification` property is **not** a
* [Notification](https://developer.mozilla.org/en-US/docs/Web/API/Notification) object but rather
* a
* [NotificationOptions](https://notifications.spec.whatwg.org/#dictdef-notificationoptions)
* object that also includes the notification `title`.
* object that also includes the `title` of the
* [Notification](https://developer.mozilla.org/en-US/docs/Web/API/Notification) object.
*/
readonly messagesClicked: Observable < {
readonly notificationClicks: Observable < {
action: string;
notification: NotificationObject
notification: NotificationOptions&{ title: string }
}
> ;
@ -61,14 +63,14 @@ export class SwPush {
constructor(private sw: NgswCommChannel) {
if (!sw.isEnabled) {
this.messages = NEVER;
this.messagesClicked = NEVER;
this.notificationClicks = NEVER;
this.subscription = NEVER;
return;
}
this.messages = this.sw.eventsOfType<PushEvent>('PUSH').pipe(map(message => message.data));
this.messagesClicked =
this.notificationClicks =
this.sw.eventsOfType('NOTIFICATION_CLICK').pipe(map((message: any) => message.data));
this.pushManager = this.sw.registration.pipe(map(registration => registration.pushManager));

View File

@ -304,13 +304,13 @@ import {async_fit, async_it} from './async';
});
});
describe('messagesClicked', () => {
describe('notificationClicks', () => {
it('receives notification clicked messages', () => {
const sendMessage = (type: string, action: string) =>
mock.sendMessage({type, data: {action}});
const receivedMessages: string[] = [];
push.messagesClicked.subscribe(
push.notificationClicks.subscribe(
(msg: {action: string}) => receivedMessages.push(msg.action));
sendMessage('NOTIFICATION_CLICK', 'this was a click');
@ -388,7 +388,7 @@ import {async_fit, async_it} from './async';
it('does not crash on subscription to observables', () => {
push.messages.toPromise().catch(err => fail(err));
push.messagesClicked.toPromise().catch(err => fail(err));
push.notificationClicks.toPromise().catch(err => fail(err));
push.subscription.toPromise().catch(err => fail(err));
});

View File

@ -88,7 +88,7 @@ const serverUpdate =
scope.clients.getMock('default') !.queue.subscribe(msg => { mock.sendMessage(msg); });
mock.messages.subscribe(msg => { scope.handleMessage(msg, 'default'); });
mock.messagesClicked.subscribe(msg => { scope.handleMessage(msg, 'default'); });
mock.notificationClicks.subscribe(msg => { scope.handleMessage(msg, 'default'); });
mock.setupSw();
reg = mock.mockRegistration !;
@ -135,7 +135,7 @@ const serverUpdate =
scope.updateServerState(serverUpdate);
const gotNotificationClick = (async() => {
const event: any = await obsToSinglePromise(push.messagesClicked);
const event: any = await obsToSinglePromise(push.notificationClicks);
expect(event.action).toEqual('clicked');
expect(event.notification.title).toEqual('This is a test');
})();

View File

@ -28,7 +28,7 @@ export class MockServiceWorkerContainer {
mockRegistration: MockServiceWorkerRegistration|null = null;
controller: MockServiceWorker|null = null;
messages = new Subject();
messagesClicked = new Subject();
notificationClicks = new Subject();
addEventListener(event: 'controllerchange'|'message', handler: Function) {
if (event === 'controllerchange') {

View File

@ -29,13 +29,9 @@ const IDLE_THRESHOLD = 5000;
const SUPPORTED_CONFIG_VERSION = 1;
const NOTIFICATION_OPTION_NAMES = [
'actions', 'badge', 'body', 'dir', 'icon', 'lang', 'renotify', 'requireInteraction', 'tag',
'vibrate', 'data'
];
const NOTIFICATION_CLICK_OPTION_NAMES = [
'actions', 'badge', 'title', 'body', 'dir', 'icon', 'image', 'lang', 'renotify',
'requireInteraction', 'tag', 'timestamp', 'vibrate', 'data'
const NOTIFICATION_OPTION_NAMES: (keyof Notification)[] = [
'actions', 'badge', 'body', 'data', 'dir', 'icon', 'image', 'lang', 'renotify',
'requireInteraction', 'silent', 'tag', 'timestamp', 'title', 'vibrate'
];
interface LatestEntry {
@ -312,10 +308,9 @@ export class Driver implements Debuggable, UpdateSource {
private async handleClick(notification: Notification, action?: string): Promise<void> {
notification.close();
const desc = notification as any;
let options: {[key: string]: string | undefined} = {};
NOTIFICATION_CLICK_OPTION_NAMES.filter(name => desc.hasOwnProperty(name))
.forEach(name => options[name] = desc[name]);
const options: {-readonly[K in keyof Notification]?: Notification[K]} = {};
NOTIFICATION_OPTION_NAMES.filter(name => name in notification)
.forEach(name => options[name] = notification[name]);
await this.broadcast({
type: 'NOTIFICATION_CLICK',

View File

@ -576,7 +576,7 @@ const manifestUpdateHash = sha1(JSON.stringify(manifestUpdate));
});
expect(scope.notifications).toEqual([{
title: 'This is a test',
options: {body: 'Test body'},
options: {title: 'This is a test', body: 'Test body'},
}]);
expect(scope.clients.getMock('default') !.messages).toEqual([{
type: 'PUSH',

View File

@ -8,7 +8,12 @@ export declare class ServiceWorkerModule {
export declare class SwPush {
readonly isEnabled: boolean;
readonly messages: Observable<object>;
readonly messagesClicked: Observable<{ action: string; notification: NotificationObject }>;
readonly notificationClicks: Observable<{
action: string;
notification: NotificationOptions & {
title: string;
};
}>;
readonly subscription: Observable<PushSubscription | null>;
constructor(sw: NgswCommChannel);
requestSubscription(options: {