feat(aio): make the ServiceWorker update process more intuitive/user-friendly (#16170)
Fixes #16093
This commit is contained in:
		
							parent
							
								
									e07b7ea114
								
							
						
					
					
						commit
						24c34385ee
					
				| @ -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') | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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> { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user