Skip to content

Commit

Permalink
fix(service-worker): Fix public api guard typing (#25860)
Browse files Browse the repository at this point in the history
PR Close #25860
  • Loading branch information
joostme authored and kara committed Nov 1, 2018
1 parent 1061875 commit 4a01ada
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 29 deletions.
2 changes: 0 additions & 2 deletions packages/service-worker/src/low_level.ts
Expand Up @@ -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)));
Expand Down
18 changes: 10 additions & 8 deletions packages/service-worker/src/push.ts
Expand Up @@ -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';


/**
Expand All @@ -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 }
}
> ;

Expand All @@ -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));
Expand Down
6 changes: 3 additions & 3 deletions packages/service-worker/test/comm_spec.ts
Expand Up @@ -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');
Expand Down Expand Up @@ -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));
});

Expand Down
4 changes: 2 additions & 2 deletions packages/service-worker/test/integration_spec.ts
Expand Up @@ -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 !;
Expand Down Expand Up @@ -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');
})();
Expand Down
2 changes: 1 addition & 1 deletion packages/service-worker/testing/mock.ts
Expand Up @@ -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') {
Expand Down
17 changes: 6 additions & 11 deletions packages/service-worker/worker/src/driver.ts
Expand Up @@ -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 {
Expand Down Expand Up @@ -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',
Expand Down
2 changes: 1 addition & 1 deletion packages/service-worker/worker/test/happy_spec.ts
Expand Up @@ -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',
Expand Down
7 changes: 6 additions & 1 deletion tools/public_api_guard/service-worker/service-worker.d.ts
Expand Up @@ -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: {
Expand Down

0 comments on commit 4a01ada

Please sign in to comment.