angular-cn/packages/service-worker/test/comm_spec.ts

192 lines
6.6 KiB
TypeScript

/**
* @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
*/
import {TestBed} from '@angular/core/testing';
import {NgswCommChannel} from '../src/low_level';
import {SwPush} from '../src/push';
import {SwUpdate} from '../src/update';
import {MockServiceWorkerContainer, MockServiceWorkerRegistration} from '../testing/mock';
{
describe('ServiceWorker library', () => {
let mock: MockServiceWorkerContainer;
let comm: NgswCommChannel;
beforeEach(() => {
mock = new MockServiceWorkerContainer();
comm = new NgswCommChannel(mock as any, 'browser');
});
describe('NgswCommsChannel', () => {
it('can access the registration when it comes before subscription', (done: DoneFn) => {
const mock = new MockServiceWorkerContainer();
const comm = new NgswCommChannel(mock as any, 'browser');
const regPromise = mock.getRegistration() as any as MockServiceWorkerRegistration;
mock.setupSw();
(comm as any).registration.subscribe((reg: any) => { done(); });
});
it('can access the registration when it comes after subscription', (done: DoneFn) => {
const mock = new MockServiceWorkerContainer();
const comm = new NgswCommChannel(mock as any, 'browser');
const regPromise = mock.getRegistration() as any as MockServiceWorkerRegistration;
(comm as any).registration.subscribe((reg: any) => { done(); });
mock.setupSw();
});
it('is disabled for platform-server', () => {
const mock = new MockServiceWorkerContainer();
const comm = new NgswCommChannel(mock as any, 'server');
expect(comm.isEnabled).toEqual(false);
});
});
describe('SwPush', () => {
let push: SwPush;
beforeEach(() => {
push = new SwPush(comm);
mock.setupSw();
});
it('receives push messages', (done: DoneFn) => {
push.messages.subscribe(msg => {
expect(msg).toEqual({
message: 'this was a push message',
});
done();
});
mock.sendMessage({
type: 'PUSH',
data: {
message: 'this was a push message',
},
});
});
it('is injectable', () => {
TestBed.configureTestingModule({
providers: [
SwPush,
{provide: NgswCommChannel, useValue: comm},
]
});
expect(() => TestBed.get(SwPush)).not.toThrow();
});
describe('with no SW', () => {
beforeEach(() => { comm = new NgswCommChannel(undefined, 'browser'); });
it('can be instantiated', () => { push = new SwPush(comm); });
it('does not crash on subscription to observables', () => {
push = new SwPush(comm);
push.messages.toPromise().catch(err => fail(err));
push.subscription.toPromise().catch(err => fail(err));
});
it('gives an error when registering', done => {
push = new SwPush(comm);
push.requestSubscription({serverPublicKey: 'test'}).catch(err => { done(); });
});
it('gives an error when unsubscribing', done => {
push = new SwPush(comm);
push.unsubscribe().catch(err => { done(); });
});
});
});
describe('SwUpdate', () => {
let update: SwUpdate;
beforeEach(() => {
update = new SwUpdate(comm);
mock.setupSw();
});
it('processes update availability notifications when sent', (done: DoneFn) => {
update.available.subscribe(event => {
expect(event.current).toEqual({version: 'A'});
expect(event.available).toEqual({version: 'B'});
expect(event.type).toEqual('UPDATE_AVAILABLE');
done();
});
mock.sendMessage({
type: 'UPDATE_AVAILABLE',
current: {
version: 'A',
},
available: {
version: 'B',
},
});
});
it('processes update activation notifications when sent', (done: DoneFn) => {
update.activated.subscribe(event => {
expect(event.previous).toEqual({version: 'A'});
expect(event.current).toEqual({version: 'B'});
expect(event.type).toEqual('UPDATE_ACTIVATED');
done();
});
mock.sendMessage({
type: 'UPDATE_ACTIVATED',
previous: {
version: 'A',
},
current: {
version: 'B',
},
});
});
it('activates updates when requested', (done: DoneFn) => {
mock.messages.subscribe((msg: {action: string, statusNonce: number}) => {
expect(msg.action).toEqual('ACTIVATE_UPDATE');
mock.sendMessage({
type: 'STATUS',
nonce: msg.statusNonce,
status: true,
});
});
return update.activateUpdate().then(() => done()).catch(err => done.fail(err));
});
it('reports activation failure when requested', (done: DoneFn) => {
mock.messages.subscribe((msg: {action: string, statusNonce: number}) => {
expect(msg.action).toEqual('ACTIVATE_UPDATE');
mock.sendMessage({
type: 'STATUS',
nonce: msg.statusNonce,
status: false,
error: 'Failed to activate',
});
});
return update.activateUpdate()
.catch(err => { expect(err.message).toEqual('Failed to activate'); })
.then(() => done())
.catch(err => done.fail(err));
});
it('is injectable', () => {
TestBed.configureTestingModule({
providers: [
SwUpdate,
{provide: NgswCommChannel, useValue: comm},
]
});
expect(() => TestBed.get(SwUpdate)).not.toThrow();
});
describe('with no SW', () => {
beforeEach(() => { comm = new NgswCommChannel(undefined, 'browser'); });
it('can be instantiated', () => { update = new SwUpdate(comm); });
it('does not crash on subscription to observables', () => {
update = new SwUpdate(comm);
update.available.toPromise().catch(err => fail(err));
update.activated.toPromise().catch(err => fail(err));
});
it('gives an error when checking for updates', done => {
update = new SwUpdate(comm);
update.checkForUpdate().catch(err => { done(); });
});
it('gives an error when activating updates', done => {
update = new SwUpdate(comm);
update.activateUpdate().catch(err => { done(); });
});
});
});
});
}