Skip to content

Commit

Permalink
Modified jest config, added test for wallet effect
Browse files Browse the repository at this point in the history
  • Loading branch information
tortcherx committed Jul 19, 2022
1 parent 9561567 commit 323218c
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 38 deletions.
7 changes: 4 additions & 3 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ module.exports = {
'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
'^.+\\.tsx?$': 'ts-jest',
},
testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$',
cacheDirectory: '.jest/cache',
setupFilesAfterEnv: ['<rootDir>/test/afterEnv.ts'],
moduleNameMapper: {
'\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/test/mock.js',
'<rootDir>/test/mock.js',
'\\.(css|less)$': '<rootDir>/test/mock.js',
'@/(.*)': '<rootDir>/src/$1',
'@test/(.*)': '<rootDir>/test/$1',
},
resetMocks: true,
roots: ['<rootDir>/src/'],
};
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"ios": "react-native run-ios",
"ios:device": "react-native run-ios --device",
"start": "react-native start",
"test:coverage": "jest --coverage ./__tests__/*.tsx",
"test:unit": "jest --watch ./__tests__/*.tsx",
"test:coverage": "jest --coverage ./__tests__/unit/*.tsx",
"test:unit": "jest --watch --testMatch='**/*.spec.{js,tsx}' --config='jest.config.js'",
"prebuild:android:debug": "yarn set:dev",
"build:android:debug": "./scripts/android-debug.sh",
"postbuild:android:debug": "yarn reset:dev",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import Button from '../src/components/button/Button';
import {fireEvent, render} from './render';
import Button from './Button';
import {fireEvent, render} from '@test/render';

jest.mock('react-native-haptic-feedback', () => {
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';
import Checkbox from '../src/components/checkbox/Checkbox';
import {fireEvent, render} from './render';
import {SlateDark, Action} from '../src/styles/colors';
import Checkbox from './Checkbox';
import {fireEvent, render} from '@test/render';
import {SlateDark, Action} from '@/styles/colors';

it('renders correctly', async () => {
const mockFn = jest.fn();
const {getByTestId, rerender} = render(
<Checkbox onPress={mockFn} checked={false} />
<Checkbox onPress={mockFn} checked={false} />,
);
const checkbox = await getByTestId('checkbox');
expect(getByTestId('checkboxBorder')).toHaveStyle({borderColor: SlateDark});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import {cleanup, fireEvent, render} from './render';
import {cleanup, fireEvent, render} from '@test/render';
import {Provider} from 'react-redux';
import BottomNotification from '../src/components/modal/bottom-notification/BottomNotification';
import {configureTestStore} from '../src/store';
import BottomNotification from './BottomNotification';
import configureTestStore from '@test/store';

const mockFn = jest.fn();

Expand Down Expand Up @@ -30,17 +30,17 @@ describe('Bottom Notification Modal', () => {
afterEach(cleanup);
it('should render correctly', async () => {
render(
<Provider store={store}>
<BottomNotification />
</Provider>,
<Provider store={store}>
<BottomNotification />
</Provider>,
);
});

it('should display all the details', async () => {
const {findByText, getByText} = render(
<Provider store={store}>
<BottomNotification />
</Provider>,
<Provider store={store}>
<BottomNotification />
</Provider>,
);

const title = await findByText('Modal Title');
Expand All @@ -54,9 +54,9 @@ describe('Bottom Notification Modal', () => {

it('should enable backdrop', async () => {
const {getByTestId} = render(
<Provider store={store}>
<BottomNotification />
</Provider>,
<Provider store={store}>
<BottomNotification />
</Provider>,
);

const backdrop = await getByTestId('modalBackdrop');
Expand All @@ -66,9 +66,9 @@ describe('Bottom Notification Modal', () => {

it('should close modal on cta press', async () => {
const {getAllByText} = render(
<Provider store={store}>
<BottomNotification />
</Provider>,
<Provider store={store}>
<BottomNotification />
</Provider>,
);
const buttons = getAllByText('CLOSE');
expect(buttons.length).toBe(1);
Expand Down
7 changes: 6 additions & 1 deletion src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,5 +291,10 @@ export type Effect<ReturnType = void> = ThunkAction<
export default getStore;

export function configureTestStore(initialState: any) {
return createStore(rootReducer, initialState);
const middlewares = [thunkMiddleware];
const middlewareEnhancers = composeWithDevTools({
trace: true,
traceLimit: 25,
})(applyMiddleware(...middlewares));
return createStore(rootReducer, initialState, middlewareEnhancers);
}
77 changes: 77 additions & 0 deletions src/store/wallet/effects/create/getDecryptPassword.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React from 'react';
import {getDecryptPassword} from './create';
import configureTestStore from '@test/store';
import {
dismissDecryptPasswordModal,
showDecryptPasswordModal,
} from '../../../app/app.actions';
import {checkEncryptPassword} from '../../utils/wallet';

/**
* Mock showDecryptPasswordModal and Spy on dismissDecryptPasswordModal
*/
jest.mock('../../../app/app.actions', () => ({
...jest.requireActual('../../../app/app.actions'),
showDecryptPasswordModal: jest.fn().mockImplementation(() => {
return {type: 'MOCK'};
}),
dismissDecryptPasswordModal: jest.fn().mockImplementation(() => {
return {type: 'MOCK'};
}),
}));

/**
* Mock checkEncryptPassword
*/
jest.mock('../../utils/wallet', () => ({
...jest.requireActual('../../utils/wallet'),
checkEncryptPassword: jest
.fn()
.mockImplementation((key, pass) => key === 'unlocked'),
}));

/**
* getDecryptPassword Tests
*/
describe('getDecryptPassword', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('calls showDecryptPasswordModal with onSubmitHandler config', () => {
const store = configureTestStore({});
store.dispatch(getDecryptPassword('test'));
const argument = showDecryptPasswordModal.mock.calls[0][0];
expect(showDecryptPasswordModal).toHaveBeenCalledTimes(1);
expect(typeof argument.onSubmitHandler).toEqual('function');
});

it('calls dismissDecryptPasswordModal when submit handler is called', () => {
const store = configureTestStore({});
store.dispatch(getDecryptPassword('test'));

const argument = showDecryptPasswordModal.mock.calls[0][0];
argument.onSubmitHandler();
expect(dismissDecryptPasswordModal).toHaveBeenCalledTimes(1);
});

it('will resolve the promise as we expect', async () => {
const store = configureTestStore({});
const promiseSuccessResult = store.dispatch(getDecryptPassword('unlocked'));
const successArgument = showDecryptPasswordModal.mock.calls[0][0];
await successArgument.onSubmitHandler('privatekey');
await expect(promiseSuccessResult).resolves.toEqual('privatekey');
expect(checkEncryptPassword).toHaveBeenCalledWith('unlocked', 'privatekey');
});

it('will reject the promise as we expect', async () => {
const store = configureTestStore({});
const promiseFailedResult = store.dispatch(getDecryptPassword('test'));
const failedArgument = showDecryptPasswordModal.mock.calls[0][0];
await failedArgument.onSubmitHandler('privatekey');
await expect(promiseFailedResult).rejects.toEqual({
message: 'invalid password',
});
expect(checkEncryptPassword).toHaveBeenCalledWith('test', 'privatekey');
});
});
11 changes: 3 additions & 8 deletions __tests__/render.tsx → test/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,16 @@ import {ThemeProvider} from 'styled-components/native';
import {BitPayLightTheme} from '../src/themes/bitpay';

const AllTheProviders = ({children}: {children: React.ReactNode}) => {
return <ThemeProvider theme={BitPayLightTheme}>{children}</ThemeProvider>;
return <ThemeProvider theme={BitPayLightTheme}>{children}</ThemeProvider>;
};

const customRender = (
component: React.ReactElement<any>,
options?: RenderOptions,
component: React.ReactElement<any>,
options?: RenderOptions,
) => render(component, {wrapper: AllTheProviders, ...options});

// re-export everything from the `react-testing-library`
export * from '@testing-library/react-native';

// export our custom render method
export {customRender as render};

// This is a workaround for performance issues only, rather than using Jest ignore patterns
it('renders correctly', async () => {
expect(1).toEqual(1);
});
6 changes: 3 additions & 3 deletions test/setup.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import mockRNDeviceInfo from '../node_modules/react-native-device-info/jest/react-native-device-info-mock';
import mockRNDeviceInfo from 'react-native-device-info/jest/react-native-device-info-mock';
jest.mock('react-native-device-info', () => mockRNDeviceInfo);

import mockAsyncStorage from '@react-native-async-storage/async-storage/jest/async-storage-mock';
Expand All @@ -16,7 +16,7 @@ jest.mock('react-native/Libraries/Utilities/Platform', () => ({
}));

jest.mock('react-native-reanimated', () =>
require('react-native-reanimated/mock'),
require('react-native-reanimated/mock'),
);
global.__reanimatedWorkletInit = jest.fn();
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
Expand All @@ -28,7 +28,7 @@ jest.mock('@segment/analytics-react-native', () => ({
}));

jest.mock('react-native-permissions', () =>
require('react-native-permissions/mock'),
require('react-native-permissions/mock'),
);

jest.mock('react-native-fs', () => {
Expand Down
2 changes: 2 additions & 0 deletions test/store.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import {configureTestStore} from '../src/store';
export default configureTestStore;

0 comments on commit 323218c

Please sign in to comment.