Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup RTL and jest infrastructure, refs ERM-1216 #308

Merged
merged 3 commits into from
Nov 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
{
"parser": "babel-eslint",
"extends": "@folio/eslint-config-stripes",
"rules":{
"rules": {
"react/jsx-curly-newline": "off",
"react/jsx-sort-props": "error",
"react/state-in-constructor": "off"
},
"env": {
"jest/globals": true
},
"plugins": ["babel", "jest"],
"overrides": [
{
"files": ["lib/**/tests/*", "tests/**"],
Expand All @@ -17,5 +21,5 @@
"no-unused-expressions": "off"
}
}
],
]
}
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,8 @@ typings/
# Eclipse project files.
.settings
.project

artifacts/

# jest
junit.xml
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change history for stripes-erm-components

## 4.1.0 IN PROGRESS
* Setup React testing library and jest infrastructure. ERM-1216.

## 4.0.1 2020-11-05
* Fixed issue with decimal separators not working as expected with non-English locales. ERM-1199.

## 4.0.0 2020-10-15
* Added `EResourceType`, `getResourceIdentifier`, `getSiblingIdentifier` and `isPackage` utility functions. ERM-958
* Added `Embargo` component. ERM-951
Expand Down
24 changes: 24 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// eslint-disable-next-line import/no-extraneous-dependencies
const path = require('path');

const esModules = ['@folio', 'ky'].join('|');

module.exports = {
collectCoverageFrom: [
'**/(lib|src)/**/*.{js,jsx}',
'!**/node_modules/**',
'!**/test/**',
],
coverageDirectory: './artifacts/coverage-jest/',
coverageReporters: ['lcov'],
reporters: ['jest-junit', 'default'],
transform: { '^.+\\.(js|jsx)$': path.join(__dirname, './test/jest/jest-transformer.js') },
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
moduleNameMapper: {
'^.+\\.(css)$': 'identity-obj-proxy',
'^.+\\.(svg)$': 'identity-obj-proxy',
},
testMatch: ['**/(lib|src)/**/?(*.)test.{js,jsx}'],
testPathIgnorePatterns: ['/node_modules/'],
setupFilesAfterEnv: [path.join(__dirname, './test/jest/jest.setup.js')],
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default class CustomPropertiesConfigListFieldArray extends React.Componen
name: PropTypes.string,
remove: PropTypes.func,
unshift: PropTypes.func.isRequired,
value: PropTypes.array.isRequired,
value: PropTypes.arrayOf(PropTypes.object).isRequired,
}).isRequired,
mutators: PropTypes.object,
onDelete: PropTypes.func.isRequired,
Expand Down
2 changes: 1 addition & 1 deletion lib/CustomPropertyFilters/CustomPropertyRule.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const propTypes = {
custPropDefinition: PropTypes.shape({
type: PropTypes.string,
category: PropTypes.shape({
values: PropTypes.array,
values: PropTypes.arrayOf(PropTypes.object),
}),
}),
value: PropTypes.shape({
Expand Down
2 changes: 1 addition & 1 deletion lib/FormCustomProperties/CustomPropertiesListField.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default class CustomPropertiesListField extends React.Component {
availableCustomProperties: PropTypes.arrayOf(PropTypes.shape({
description: PropTypes.string,
label: PropTypes.string.isRequired,
options: PropTypes.array,
options: PropTypes.arrayOf(PropTypes.object),
type: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
defaultInternal: PropTypes.bool,
Expand Down
2 changes: 1 addition & 1 deletion lib/withKiwtFieldArray/withKiwtFieldArray.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function withKiwtFieldArray(WrappedComponent) {
remove: PropTypes.func.isRequired,
unshift: PropTypes.func.isRequired,
update: PropTypes.func, // react-final-form-arrays
value: PropTypes.array, // react-final-form-arrays
value: PropTypes.arrayOf(PropTypes.object), // react-final-form-arrays
}).isRequired,
}

Expand Down
22 changes: 21 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,43 @@
},
"scripts": {
"test": "stripes test karma",
"lint": "eslint lib tests"
"lint": "eslint lib tests",
"test:unit": "jest --ci --coverage"
},
"devDependencies": {
"@babel/plugin-proposal-class-properties": "^7.12.1",
"@babel/plugin-proposal-decorators": "^7.12.1",
"@babel/plugin-transform-runtime": "^7.12.1",
"@babel/preset-react": "^7.12.5",
"@bigtest/convergence": "^1.1.1",
"@bigtest/interactor": "^0.7.2",
"@bigtest/mocha": "^0.5.0",
"@bigtest/react": "^0.1.2",
"@folio/eslint-config-stripes": "^5.1.0",
"@folio/stripes": "^5.0.0",
"@folio/stripes-cli": "^1.10.0",
"@testing-library/dom": "^7.26.5",
"@testing-library/jest-dom": "^5.11.5",
"@testing-library/react": "^11.1.1",
"@testing-library/user-event": "^12.2.0",
"babel-eslint": "^9.0.0",
"babel-jest": "^26.6.3",
"babel-plugin-module-resolver": "^4.0.0",
"babel-plugin-require-context-hook": "^1.0.0",
"babel-polyfill": "^6.26.0",
"chai": "^4.1.2",
"chai-spies": "^1.0.0",
"eslint": "^6.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.1.0",
"eslint-plugin-jest-dom": "^3.2.4",
"eslint-plugin-testing-library": "^3.10.0",
"faker": "^4.1.0",
"identity-obj-proxy": "^3.0.0",
"inflected": "^2.0.4",
"jest": "^26.6.3",
"jest-css-modules": "^2.1.0",
"jest-junit": "^12.0.0",
"miragejs": "^0.1.40",
"react": "^16.6.3",
"react-dom": "^16.6.3",
Expand Down
1 change: 1 addition & 0 deletions test/jest/__mock__/currencyData.mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
jest.mock('currency-codes/data', () => ({ filter: () => [] }));
6 changes: 6 additions & 0 deletions test/jest/__mock__/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import './currencyData.mock';
import './reactIntl.mock';
import './stripesConfig.mock';
import './stripesCore.mock';
import './stripesIcon.mock';
import './stripesSmartComponents.mock';
27 changes: 27 additions & 0 deletions test/jest/__mock__/reactIntl.mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';

jest.mock('react-intl', () => {
const intl = {
formatMessage: ({ id }) => id,
};

return {
...jest.requireActual('react-intl'),
FormattedMessage: jest.fn(({ id, children }) => {
if (children) {
return children([id]);
}

return id;
}),
FormattedTime: jest.fn(({ value, children }) => {
if (children) {
return children([value]);
}

return value;
}),
useIntl: () => intl,
injectIntl: (Component) => (props) => <Component {...props} intl={intl} />,
};
});
1 change: 1 addition & 0 deletions test/jest/__mock__/stripesConfig.mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
jest.mock('stripes-config', () => ({ modules: [] }), { virtual: true });
94 changes: 94 additions & 0 deletions test/jest/__mock__/stripesCore.mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@

import React from 'react';

jest.mock('@folio/stripes/core', () => {
const STRIPES = {
actionNames: [],
clone: () => ({ ...STRIPES }),
connect: (Component) => Component,
config: {},
currency: 'USD',
hasInterface: () => true,
hasPerm: jest.fn().mockReturnValue(true),
locale: 'en-US',
logger: {
log: () => { },
},
okapi: {
tenant: 'diku',
url: 'https://folio-testing-okapi.dev.folio.org',
},
plugins: {},
setBindings: () => { },
setCurrency: () => { },
setLocale: () => { },
setSinglePlugin: () => { },
setTimezone: () => { },
setToken: () => { },
store: {
getState: () => { },
dispatch: () => { },
subscribe: () => { },
replaceReducer: () => { },
},
timezone: 'UTC',
user: {
perms: {},
user: {
id: 'b1add99d-530b-5912-94f3-4091b4d87e2c',
username: 'diku_admin',
},
},
withOkapi: true,
};

const stripesConnect = (Component, options) => ({ mutator, resources, stripes, ...rest }) => {
const fakeMutator = mutator || Object.keys(Component.manifest).reduce((acc, mutatorName) => {
const returnValue = Component.manifest[mutatorName].records ? [] : {};

acc[mutatorName] = {
GET: jest.fn().mockReturnValue(Promise.resolve(returnValue)),
PUT: jest.fn().mockReturnValue(Promise.resolve()),
POST: jest.fn().mockReturnValue(Promise.resolve()),
DELETE: jest.fn().mockReturnValue(Promise.resolve()),
reset: jest.fn(),
};

return acc;
}, {});

const fakeResources = resources || Object.keys(Component.manifest).reduce((acc, resourceName) => {
if (options?.resources?.[resourceName]) {
acc[resourceName] = options.resources[resourceName];
} else {
acc[resourceName] = {
records: [],
};
}

return acc;
}, {});

const fakeStripes = stripes || STRIPES;
return <Component {...rest} mutator={fakeMutator} resources={fakeResources} stripes={fakeStripes} />;
};

const withStripes = (Component, options) => ({ stripes, ...rest }) => {
const fakeStripes = stripes || STRIPES;

fakeStripes.connect = Comp => stripesConnect(Comp, options);

return <Component {...rest} stripes={fakeStripes} />;
};

const useStripes = ({ ...STRIPES, connect: Component => stripesConnect(Component) });

return {
...jest.requireActual('@folio/stripes/core'),
stripesConnect,
useStripes,
withStripes,
IfPermission: props => <>{props.children}</>,
Pluggable: props => <>{props.children}</>,
};
}, { virtual: true });
5 changes: 5 additions & 0 deletions test/jest/__mock__/stripesIcon.mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from 'react';

jest.mock('@folio/stripes-components/lib/Icon/icons', () => {
return () => <span>Icon</span>;
});
7 changes: 7 additions & 0 deletions test/jest/__mock__/stripesSmartComponents.mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';

jest.mock('@folio/stripes/smart-components', () => ({
...jest.requireActual('@folio/stripes/smart-components'),
LocationLookup: () => <div>LocationLookup</div>,
ViewMetaData: () => <div>ViewMetaData</div>,
}), { virtual: true });
14 changes: 14 additions & 0 deletions test/jest/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-react',
],
plugins: [
'@babel/plugin-proposal-class-properties',
[
'@babel/plugin-proposal-decorators',
{ decoratorsBeforeExport: false },
],
'@babel/plugin-transform-runtime',
],
};
3 changes: 3 additions & 0 deletions test/jest/helpers/withStripes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { withStripes } from '@folio/stripes/core';

export default withStripes;
5 changes: 5 additions & 0 deletions test/jest/jest-transformer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const babelJest = require('babel-jest');

const babelConf = require('./babel.config');

module.exports = babelJest.createTransformer(babelConf);
1 change: 1 addition & 0 deletions test/jest/jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@testing-library/jest-dom/extend-expect';
Empty file added test/jest/setupTests.js
Empty file.