feat(aio): make the ServiceWorker update process more intuitive/user-friendly (#16170)

Fixes #16093
This commit is contained in:
Georgios Kalpakas 2017-04-19 19:29:36 +03:00 committed by Miško Hevery
parent e07b7ea114
commit 24c34385ee
2 changed files with 20 additions and 41 deletions

View File

@ -11,6 +11,8 @@ import { SwUpdatesService } from './sw-updates.service';
describe('SwUpdateNotificationsService', () => {
const UPDATE_AVAILABLE_MESSAGE = 'New update for angular.io is available.';
const UPDATE_FAILED_MESSAGE = 'Update activation failed :(';
let injector: ReflectiveInjector;
let service: SwUpdateNotificationsService;
let swUpdates: MockSwUpdatesService;
@ -65,8 +67,8 @@ describe('SwUpdateNotificationsService', () => {
swUpdates.$$isUpdateAvailableSubj.next(true);
expect(snackBar.$$lastRef.$$message).toContain('ServiceWorker update available');
expect(snackBar.$$lastRef.$$action).toBe('Activate');
expect(snackBar.$$lastRef.$$message).toBe(UPDATE_AVAILABLE_MESSAGE);
expect(snackBar.$$lastRef.$$action).toBe('Update now');
expect(snackBar.$$lastRef.$$config.duration).toBeUndefined();
});
@ -75,7 +77,7 @@ describe('SwUpdateNotificationsService', () => {
expect(snackBar.$$lastRef).toBeUndefined();
});
it('should activate the update when clicking on `Activate`', () => {
it('should activate the update when clicking on `Update now`', () => {
spyOn(swUpdates, 'activateUpdate').and.callThrough();
swUpdates.$$isUpdateAvailableSubj.next(true);
@ -85,30 +87,19 @@ describe('SwUpdateNotificationsService', () => {
expect(swUpdates.activateUpdate).toHaveBeenCalled();
});
it('should report a successful activation', fakeAsync(() => {
it('should reload the page after a successful activation', fakeAsync(() => {
const global = injector.get(Global);
expect(global.location.reload).not.toHaveBeenCalled();
activateUpdate(true);
expect(snackBar.$$lastRef.$$message).toContain('Update activated successfully');
expect(snackBar.$$lastRef.$$action).toBe('Reload');
expect(snackBar.$$lastRef.$$config.duration).toBeUndefined();
expect(global.location.reload).toHaveBeenCalled();
}));
it('should reload the page when clicking on `Reload` (after a successful activation)',
fakeAsync(() => {
const global = injector.get(Global);
activateUpdate(true);
expect(global.location.reload).not.toHaveBeenCalled();
snackBar.$$lastRef.$$onActionSubj.next();
expect(global.location.reload).toHaveBeenCalled();
})
);
it('should report a failed activation', fakeAsync(() => {
activateUpdate(false);
expect(snackBar.$$lastRef.$$message).toContain('Update activation failed');
expect(snackBar.$$lastRef.$$message).toBe(UPDATE_FAILED_MESSAGE);
expect(snackBar.$$lastRef.$$action).toBe('Dismiss');
expect(snackBar.$$lastRef.$$config.duration).toBeGreaterThan(0);
}));
@ -128,22 +119,13 @@ describe('SwUpdateNotificationsService', () => {
it('should dismiss open update notification', () => {
swUpdates.$$isUpdateAvailableSubj.next(true);
expect(snackBar.$$lastRef.$$message).toContain('ServiceWorker update available');
expect(snackBar.$$lastRef.$$message).toBe(UPDATE_AVAILABLE_MESSAGE);
expect(snackBar.$$lastRef.$$dismissed).toBe(false);
service.disable();
expect(snackBar.$$lastRef.$$dismissed).toBe(true);
});
it('should dismiss open activation notification', fakeAsync(() => {
activateUpdate(true);
expect(snackBar.$$lastRef.$$message).toContain('Update activated successfully');
expect(snackBar.$$lastRef.$$dismissed).toBe(false);
service.disable();
expect(snackBar.$$lastRef.$$dismissed).toBe(true);
}));
it('should ignore further updates', () => {
service.disable();
swUpdates.$$isUpdateAvailableSubj.next(true);
@ -157,7 +139,7 @@ describe('SwUpdateNotificationsService', () => {
expect(snackBar.$$lastRef).toBeUndefined();
swUpdates.$$isUpdateAvailableSubj.next(true);
expect(snackBar.$$lastRef.$$message).toContain('ServiceWorker update available');
expect(snackBar.$$lastRef.$$message).toBe(UPDATE_AVAILABLE_MESSAGE);
});
it('should not ignore pending updates if re-enabled', () => {
@ -166,7 +148,7 @@ describe('SwUpdateNotificationsService', () => {
expect(snackBar.$$lastRef).toBeUndefined();
service.enable();
expect(snackBar.$$lastRef.$$message).toContain('ServiceWorker update available');
expect(snackBar.$$lastRef.$$message).toBe(UPDATE_AVAILABLE_MESSAGE);
});
});
});
@ -174,7 +156,7 @@ describe('SwUpdateNotificationsService', () => {
// Mocks
class MockGlobal {
location = {
reload: jasmine.createSpy('MockGlobal.reload')
reload: jasmine.createSpy('MockGlobal.location.reload')
};
}

View File

@ -12,9 +12,8 @@ import { SwUpdatesService } from './sw-updates.service';
*
* @description
* Once enabled:
* 1. Subscribes to ServiceWorker updates and prompts the user to activate.
* 2. When the user confirms, it activates the update and notifies the user (upon activation success
* or failure).
* 1. Subscribes to ServiceWorker updates and prompts the user to update.
* 2. When the user confirms, it activates the update and reloads the page upon activation success.
* 3. Continues to listen for available ServiceWorker updates.
*
* @method
@ -64,7 +63,7 @@ export class SwUpdateNotificationsService {
}
private notifyForUpdate() {
this.openSnackBar('ServiceWorker update available.', 'Activate')
this.openSnackBar('New update for angular.io is available.', 'Update now')
.onAction().subscribe(() => this.activateUpdate());
}
@ -74,9 +73,7 @@ export class SwUpdateNotificationsService {
}
private onActivateSuccess() {
const message = 'Update activated successfully! Reload the page to see the latest content.';
this.openSnackBar(message, 'Reload')
.onAction().subscribe(() => this.reloadPage());
this.reloadPage();
}
private openSnackBar(message: string, action?: string, config?: MdSnackBarConfig): MdSnackBarRef<any> {