Files
pybricks-code/src/app/reducers.test.ts
T
David Lechner b2e098f2dd app: catch error when checking for updates
ServiceWorkerRegistration.update() can raise exceptions, so we need to
catch and handle them, otherwise it will crash redux sagas and the app
will stop responding.

Fixes: https://github.com/pybricks/pybricks-code/issues/1299
2022-11-11 13:00:40 -06:00

131 lines
3.9 KiB
TypeScript

// SPDX-License-Identifier: MIT
// Copyright (c) 2021-2022 The Pybricks Authors
import { AnyAction } from 'redux';
import {
serviceWorkerDidSucceed,
serviceWorkerDidUpdate,
} from '../service-worker/actions';
import {
appCheckForUpdate,
appDidCheckForUpdate,
appDidFailToCheckForUpdate,
appDidReceiveBeforeInstallPrompt,
appDidResolveInstallPrompt,
appShowInstallPrompt,
didInstall,
} from './actions';
import reducers from './reducers';
type State = ReturnType<typeof reducers>;
test('initial state', () => {
expect(reducers(undefined, {} as AnyAction)).toMatchInlineSnapshot(`
{
"checkingForUpdate": false,
"hasUnresolvedInstallPrompt": false,
"isServiceWorkerRegistered": false,
"promptingInstall": false,
"readyForOfflineUse": false,
"updateAvailable": false,
}
`);
});
describe('isServiceWorkerRegistered', () => {
it('should be true when service worker registration succeeds', () => {
expect(
reducers(
{ isServiceWorkerRegistered: false } as State,
serviceWorkerDidSucceed(),
).isServiceWorkerRegistered,
).toBe(true);
});
});
test('checkingForUpdate', () => {
expect(
reducers({ checkingForUpdate: false } as State, appCheckForUpdate())
.checkingForUpdate,
).toBe(true);
expect(
reducers({ checkingForUpdate: false } as State, appDidCheckForUpdate(true))
.checkingForUpdate,
).toBe(false);
expect(
reducers({ checkingForUpdate: true } as State, appDidCheckForUpdate(true))
.checkingForUpdate,
).toBe(true);
expect(
reducers({ checkingForUpdate: true } as State, appDidCheckForUpdate(false))
.checkingForUpdate,
).toBe(false);
expect(
reducers({ checkingForUpdate: true } as State, appDidFailToCheckForUpdate())
.checkingForUpdate,
).toBe(false);
expect(
reducers({ checkingForUpdate: true } as State, serviceWorkerDidUpdate())
.checkingForUpdate,
).toBe(false);
});
test('updateAvailable', () => {
expect(
reducers({ updateAvailable: false } as State, serviceWorkerDidUpdate())
.updateAvailable,
).toBe(true);
});
describe('hasUnresolvedInstallPrompt', () => {
it('should be true after BeforeInstallPromptEvent is received', () => {
expect(
reducers(
{ hasUnresolvedInstallPrompt: false } as State,
appDidReceiveBeforeInstallPrompt(),
).hasUnresolvedInstallPrompt,
).toBe(true);
});
it('should be false after the app was successfully installed', () => {
expect(
reducers({ hasUnresolvedInstallPrompt: true } as State, didInstall())
.hasUnresolvedInstallPrompt,
).toBe(false);
});
});
describe('promptingInstall', () => {
it('should be true when action requesting to show install prompt is seen', () => {
expect(
reducers({ promptingInstall: false } as State, appShowInstallPrompt())
.promptingInstall,
).toBe(true);
});
it('should be false when user accepts the prompt', () => {
expect(
reducers(
{ promptingInstall: true } as State,
appDidResolveInstallPrompt({ outcome: 'accepted', platform: 'web' }),
).promptingInstall,
).toBe(false);
});
it('should be false when user dismisses the prompt', () => {
expect(
reducers(
{ promptingInstall: true } as State,
appDidResolveInstallPrompt({ outcome: 'dismissed', platform: 'web' }),
).promptingInstall,
).toBe(false);
});
});
test('readyForOfflineUse', () => {
expect(
reducers({ readyForOfflineUse: false } as State, serviceWorkerDidSucceed())
.readyForOfflineUse,
).toBe(true);
});