mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-12 17:45:22 +00:00
implement license saga tests
This commit is contained in:
+13
-1
@@ -6,6 +6,7 @@ import { LicenseInfo, LicenseList } from '../reducers/license';
|
||||
|
||||
export enum LicenseActionType {
|
||||
DidFetchList = 'license.action.didFetchList',
|
||||
DidFailToFetchList = 'license.action.didFailToFetchList',
|
||||
Select = 'license.action.select',
|
||||
}
|
||||
|
||||
@@ -17,6 +18,14 @@ export function didFetchList(list: LicenseList): LicenseDidFetchListAction {
|
||||
return { type: LicenseActionType.DidFetchList, list };
|
||||
}
|
||||
|
||||
export type LicenseDidFailToFetchListAction = Action<LicenseActionType.DidFailToFetchList> & {
|
||||
reason: Response;
|
||||
};
|
||||
|
||||
export function didFailToFetchList(reason: Response): LicenseDidFailToFetchListAction {
|
||||
return { type: LicenseActionType.DidFailToFetchList, reason };
|
||||
}
|
||||
|
||||
export type LicenseSelectAction = Action<LicenseActionType.Select> & {
|
||||
info: LicenseInfo;
|
||||
};
|
||||
@@ -25,4 +34,7 @@ export function select(info: LicenseInfo): LicenseSelectAction {
|
||||
return { type: LicenseActionType.Select, info };
|
||||
}
|
||||
|
||||
export type LicenseAction = LicenseDidFetchListAction | LicenseSelectAction;
|
||||
export type LicenseAction =
|
||||
| LicenseDidFetchListAction
|
||||
| LicenseDidFailToFetchListAction
|
||||
| LicenseSelectAction;
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
didFailToConnect as bleDidFailToConnect,
|
||||
} from '../actions/ble';
|
||||
import { didFailToWrite } from '../actions/ble-uart';
|
||||
import { didFailToFetchList } from '../actions/license';
|
||||
import {
|
||||
BootloaderConnectionFailureReason,
|
||||
didError,
|
||||
@@ -68,3 +69,17 @@ test('bootloaderDidError', async () => {
|
||||
|
||||
await saga.end();
|
||||
});
|
||||
|
||||
test('licenseDidFailToFetch', async () => {
|
||||
const saga = new AsyncSaga(errorLog);
|
||||
|
||||
console.error = jest.fn();
|
||||
saga.put(
|
||||
didFailToFetchList(
|
||||
new Response(undefined, { status: 404, statusText: 'not found' }),
|
||||
),
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
|
||||
await saga.end();
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
BleDeviceFailToConnectReasonType,
|
||||
} from '../actions/ble';
|
||||
import { BleUartActionType, BleUartDidFailToWriteAction } from '../actions/ble-uart';
|
||||
import { LicenseActionType, LicenseDidFailToFetchListAction } from '../actions/license';
|
||||
import {
|
||||
BootloaderConnectionActionType,
|
||||
BootloaderConnectionDidErrorAction,
|
||||
@@ -39,6 +40,10 @@ function bootloaderDidError(action: BootloaderConnectionDidErrorAction): void {
|
||||
console.error(action.err);
|
||||
}
|
||||
|
||||
function licenseDidFailToFetch(action: LicenseDidFailToFetchListAction): void {
|
||||
console.error(`Failed to fetch licenses: ${action.reason.statusText}`);
|
||||
}
|
||||
|
||||
export default function* (): Generator {
|
||||
yield takeEvery(BleDeviceActionType.DidFailToConnect, bleDeviceDidFailToConnect);
|
||||
yield takeEvery(BleUartActionType.DidFailToWrite, bleDataDidFailToWrite);
|
||||
@@ -47,4 +52,5 @@ export default function* (): Generator {
|
||||
bootloaderDidFailToConnect,
|
||||
);
|
||||
yield takeEvery(BootloaderConnectionActionType.DidError, bootloaderDidError);
|
||||
yield takeEvery(LicenseActionType.DidFailToFetchList, licenseDidFailToFetch);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2020-2021 The Pybricks Authors
|
||||
|
||||
// Tests for license sagas.
|
||||
|
||||
import { AsyncSaga, delay } from '../../test';
|
||||
import { openLicenseDialog } from '../actions/app';
|
||||
import { didFailToFetchList, didFetchList } from '../actions/license';
|
||||
import { LicenseList, LicenseState } from '../reducers/license';
|
||||
import license from './license';
|
||||
|
||||
afterAll(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('fetchLicenses', () => {
|
||||
test('first call', async () => {
|
||||
const testLicenseList: LicenseList = [];
|
||||
const saga = new AsyncSaga(license);
|
||||
|
||||
jest.spyOn(globalThis, 'fetch').mockResolvedValue(
|
||||
new Response(JSON.stringify(testLicenseList)),
|
||||
);
|
||||
|
||||
// initially, license list starts as null, so fetch is called to get
|
||||
// the list
|
||||
saga.setState({ license: { list: null } as LicenseState });
|
||||
saga.put(openLicenseDialog());
|
||||
|
||||
const action = await saga.take();
|
||||
expect(action).toEqual(didFetchList(testLicenseList));
|
||||
|
||||
await saga.end();
|
||||
});
|
||||
test('second call', async () => {
|
||||
const testLicenseList: LicenseList = [];
|
||||
const saga = new AsyncSaga(license);
|
||||
|
||||
jest.spyOn(globalThis, 'fetch').mockRejectedValue(
|
||||
'fetch () should not have been called',
|
||||
);
|
||||
|
||||
// after we have the list, we don't fetch it again since it will
|
||||
// always be the same list
|
||||
saga.setState({ license: { list: testLicenseList } as LicenseState });
|
||||
saga.put(openLicenseDialog());
|
||||
|
||||
// have to yield to be sure fetch call would have taken place on error
|
||||
await delay(0);
|
||||
|
||||
await saga.end();
|
||||
});
|
||||
test('failed fetch', async () => {
|
||||
const failResponse = new Response(undefined, { status: 404 });
|
||||
const saga = new AsyncSaga(license);
|
||||
|
||||
jest.spyOn(globalThis, 'fetch').mockResolvedValue(failResponse);
|
||||
|
||||
saga.setState({ license: { list: null } as LicenseState });
|
||||
saga.put(openLicenseDialog());
|
||||
|
||||
const action = await saga.take();
|
||||
expect(action).toEqual(didFailToFetchList(failResponse));
|
||||
|
||||
await saga.end();
|
||||
});
|
||||
});
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import { call, put, select, takeEvery } from 'redux-saga/effects';
|
||||
import { AppActionType } from '../actions/app';
|
||||
import { didFetchList } from '../actions/license';
|
||||
import { didFailToFetchList, didFetchList } from '../actions/license';
|
||||
import { RootState } from '../reducers';
|
||||
import { LicenseList } from '../reducers/license';
|
||||
|
||||
@@ -19,8 +19,7 @@ function* fetchLicenses(): Generator {
|
||||
|
||||
const response = (yield call(() => fetch('static/oss-licenses.json'))) as Response;
|
||||
if (!response.ok || response.body === null) {
|
||||
// TODO: dispatch an action to notify user
|
||||
console.error('failed to fetch oss-licenses.json', response.statusText);
|
||||
yield put(didFailToFetchList(response));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user