feat: mock paragon and i18n library for tests

This commit is contained in:
Ben Warzeski
2022-02-22 12:45:30 -05:00
committed by GitHub
parent 5a1d71a62c
commit 362139edd2
4 changed files with 103 additions and 0 deletions

6
.gitignore vendored
View File

@@ -102,3 +102,9 @@ dist
# TernJS port file
.tern-port
### Emacs/vi ###
*~
*.swo
*.swp

View File

@@ -43,3 +43,41 @@ process.env.LOGO_URL = 'https://edx-cdn.org/v3/default/logo.svg';
process.env.LOGO_TRADEMARK_URL = 'https://edx-cdn.org/v3/default/logo-trademark.svg';
process.env.LOGO_WHITE_URL = 'https://edx-cdn.org/v3/default/logo-white.svg';
process.env.FAVICON_URL = 'https://edx-cdn.org/v3/default/favicon.ico';
jest.mock('@edx/frontend-platform/i18n', () => {
const i18n = jest.requireActual('@edx/frontend-platform/i18n');
const PropTypes = jest.requireActual('prop-types');
return {
...i18n,
intlShape: PropTypes.shape({
formatMessage: PropTypes.func,
}),
defineMessages: m => m,
FormattedMessage: () => 'FormattedMessage',
};
});
jest.mock('@edx/paragon', () => jest.requireActual('testUtils').mockNestedComponents({
ActionRow: 'ActionRow',
Button: 'Button',
Icon: 'Icon',
IconButton: 'IconButton',
ModalDialog: {
Header: 'ModalDialog.Header',
Title: 'ModalDialog.Title',
},
Form: {
Control: {
Feedback: 'Form.Control.Feedback',
},
Group: 'Form.Group',
Label: 'Form.Label',
},
Spinner: 'Spinner',
Toast: 'Toast',
}));
jest.mock('@edx/paragon/icons', () => ({
Close: jest.fn().mockName('icons.Close'),
Edit: jest.fn().mockName('icons.Edit'),
}));

59
src/testUtils.js Normal file
View File

@@ -0,0 +1,59 @@
/**
* Mocked formatMessage provided by react-intl
*/
export const formatMessage = (msg, values) => {
let message = msg.defaultMessage;
if (values === undefined) {
return message;
}
Object.keys(values).forEach((key) => {
// eslint-disable-next-line
message = message.replace(`{${key}}`, values[key]);
});
return message;
};
/**
* Mock a single component, or a nested component so that its children render nicely
* in snapshots.
* @param {string} name - parent component name
* @param {obj} contents - object of child components with intended component
* render name.
* @return {func} - mock component with nested children.
*
* usage:
* mockNestedComponent('Card', { Body: 'Card.Body', Form: { Control: { Feedback: 'Form.Control.Feedback' }}... });
* mockNestedComponent('IconButton', 'IconButton');
*/
export const mockNestedComponent = (name, contents) => {
if (typeof contents !== 'object') {
return contents;
}
const fn = () => name;
Object.defineProperty(fn, 'name', { value: name });
Object.keys(contents).forEach((nestedName) => {
const value = contents[nestedName];
fn[nestedName] = typeof value !== 'object'
? value
: mockNestedComponent(`${name}.${nestedName}`, value);
});
return fn;
};
/**
* Mock a module of components. nested components will be rendered nicely in snapshots.
* @param {obj} mapping - component module mock config.
* @return {obj} - module of flat and nested components that will render nicely in snapshots.
* usage:
* mockNestedComponents({
* Card: { Body: 'Card.Body' },
* IconButton: 'IconButton',
* })
*/
export const mockNestedComponents = (mapping) => Object.entries(mapping).reduce(
(obj, [name, value]) => ({
...obj,
[name]: mockNestedComponent(name, value),
}),
{},
);