Skip to content

Commit

Permalink
Merge pull request #2849 from creative-commoners/pulls/5.0/react-test…
Browse files Browse the repository at this point in the history
…ing-library

MNT Use React Testing Library
  • Loading branch information
GuySartorelli authored May 1, 2023
2 parents ca837d6 + 28ecbdc commit 81e7e1a
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 127 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,14 @@ class AnchorSelectorField extends SilverStripeComponent {
}

render() {
const className = classnames('anchorselectorfield', this.props.extraClass);
const { extraClass, CreatableSelectComponent } = this.props;
const className = classnames('anchorselectorfield', extraClass);
const options = this.getDropdownOptions();
const rawValue = this.props.value || '';
const placeholder = i18n._t('CMS.ANCHOR_SELECT_OR_TYPE', 'Select or enter anchor');
return (
<EmotionCssCacheProvider>
<CreatableSelect
<CreatableSelectComponent
isSearchable
isClearable
options={options}
Expand Down Expand Up @@ -166,6 +167,7 @@ AnchorSelectorField.defaultProps = {
extraClass: '',
onLoadingError: noop,
attributes: {},
CreatableSelectComponent: CreatableSelect
};

function mapStateToProps(state, ownProps) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,103 +1,129 @@
/* global jest, describe, beforeEach, it, expect, setTimeout */
/* global jest, test, describe, beforeEach, it, expect, setTimeout */

import React from 'react';
import { Component as AnchorSelectorField } from '../AnchorSelectorField';
import anchorSelectorStates from 'state/anchorSelector/AnchorSelectorStates';
import { render, screen } from '@testing-library/react';

jest.mock('isomorphic-fetch', () =>
() => Promise.resolve({
json: () => ['anchor3', 'anchor4'],
}));
jest.mock('i18n');

import React from 'react';
import ReactTestUtils from 'react-dom/test-utils';
import { Component as AnchorSelectorField } from '../AnchorSelectorField';
import anchorSelectorStates from 'state/anchorSelector/AnchorSelectorStates';
function makeProps(obj = {}) {
return {
id: 'Form_Test',
name: 'Test',
data: {
endpoint: 'url-callback',
},
pageId: 4,
anchors: ['anchor1', 'anchor2'],
value: 'selectedanchor',
loadingState: anchorSelectorStates.SUCCESS,
CreatableSelectComponent: ({ options }) => (
<div data-testid="test-creatable-select">
{options.map(option => <div key={option.value} data-option={option.value}/>)}
</div>
),
...obj,
};
}

describe('AnchorSelectorField', () => {
let props = null;
let field = null;

beforeEach(() => {
props = {
id: 'Form_Test',
name: 'Test',
data: {
endpoint: 'url-callback',
},
pageId: 4,
anchors: ['anchor1', 'anchor2'],
value: 'selectedanchor',
loadingState: anchorSelectorStates.SUCCESS,
actions: {
anchorSelector: {
beginUpdating: jest.fn(),
updated: jest.fn(),
updateFailed: jest.fn(),
},
test('AnchorSelectorField componentDidMount() Loads dirty selectors', async () => {
const beginUpdating = jest.fn();
render(<AnchorSelectorField {...makeProps({
loadingState: anchorSelectorStates.DIRTY,
actions: {
anchorSelector: {
beginUpdating,
updated: () => {},
updateFailed: () => {},
},
};
});
},
})}
/>);
await screen.findByTestId('test-creatable-select');
expect(beginUpdating).toBeCalledWith(4);
});

describe('componentDidMount()', () => {
it('Loads dirty selectors', () => {
props.loadingState = anchorSelectorStates.DIRTY;
field = ReactTestUtils.renderIntoDocument(<AnchorSelectorField {...props} />);
expect(props.actions.anchorSelector.beginUpdating)
.toHaveBeenCalledWith(4);
});
it('Does not load success selectors', () => {
props.loadingState = anchorSelectorStates.SUCCESS;
field = ReactTestUtils.renderIntoDocument(<AnchorSelectorField {...props} />);
expect(props.actions.anchorSelector.beginUpdating)
.not
.toHaveBeenCalled();
});
});
test('AnchorSelectorField Merges value with page anchors', async () => {
const beginUpdating = jest.fn();
const { container } = render(<AnchorSelectorField {...makeProps({
loadingState: anchorSelectorStates.DIRTY,
actions: {
anchorSelector: {
beginUpdating,
updated: () => {},
updateFailed: () => {},
},
},
})}
/>);
const select = await screen.findByTestId('test-creatable-select');
const options = select.querySelectorAll('[data-option]');
expect(options).toHaveLength(3);
expect(options[0].getAttribute('data-option')).toBe('selectedanchor');
expect(options[1].getAttribute('data-option')).toBe('anchor1');
expect(options[2].getAttribute('data-option')).toBe('anchor2');
});

describe('getDropdownOptions()', () => {
it('Merges value with page anchors', () => {
field = ReactTestUtils.renderIntoDocument(<AnchorSelectorField {...props} />);
expect(field.getDropdownOptions()).toEqual([
{ value: 'selectedanchor' },
{ value: 'anchor1' },
{ value: 'anchor2' },
]);
});
});
test('AnchorSelectorField componentDidMount() Does not load success selectors', async () => {
const beginUpdating = jest.fn();
render(<AnchorSelectorField {...makeProps({
loadingState: anchorSelectorStates.SUCCESS,
actions: {
anchorSelector: {
beginUpdating,
updated: () => {},
updateFailed: () => {},
},
},
})}
/>);
await screen.findByTestId('test-creatable-select');
expect(beginUpdating).not.toBeCalled();
});

describe('ensurePagesLoaded', () => {
it('Triggers loading on dirty', () => {
props.loadingState = anchorSelectorStates.DIRTY;
field = ReactTestUtils.renderIntoDocument(<AnchorSelectorField {...props} />);
return field
.ensurePagesLoaded()
.then((result) => {
expect(props.actions.anchorSelector.beginUpdating)
.toHaveBeenCalledWith(4);
expect(props.actions.anchorSelector.updated)
.toHaveBeenCalledWith(4, ['anchor3', 'anchor4']);
expect(props.actions.anchorSelector.updateFailed)
.not
.toHaveBeenCalled();
expect(result).toEqual(['anchor3', 'anchor4']);
});
});
test('AnchorSelectorField ensurePagesLoaded Triggers loading on dirty', async () => {
const beginUpdating = jest.fn();
const updated = jest.fn();
const updateFailed = jest.fn();
render(<AnchorSelectorField {...makeProps({
loadingState: anchorSelectorStates.DIRTY,
actions: {
anchorSelector: {
beginUpdating,
updated,
updateFailed,
},
},
})}
/>);
await screen.findByTestId('test-creatable-select');
expect(beginUpdating).toBeCalledWith(4);
expect(updated).toBeCalledWith(4, ['anchor3', 'anchor4']);
expect(updateFailed).not.toBeCalled();
});

it('Does not trigger updating', () => {
props.loadingState = anchorSelectorStates.UPDATING;
field = ReactTestUtils.renderIntoDocument(<AnchorSelectorField {...props} />);
return field
.ensurePagesLoaded()
.then((result) => {
expect(props.actions.anchorSelector.beginUpdating)
.not
.toHaveBeenCalled();
expect(props.actions.anchorSelector.updated)
.not
.toHaveBeenCalled();
expect(props.actions.anchorSelector.updateFailed)
.not
.toHaveBeenCalled();
expect(result).toBe(undefined);
});
});
});
test('AnchorSelectorField ensurePagesLoaded Does not trigger updating', async () => {
const beginUpdating = jest.fn();
const updated = jest.fn();
const updateFailed = jest.fn();
render(<AnchorSelectorField {...makeProps({
loadingState: anchorSelectorStates.UPDATING,
actions: {
anchorSelector: {
beginUpdating,
updated,
updateFailed,
},
},
})}
/>);
await screen.findByTestId('test-creatable-select');
expect(beginUpdating).not.toBeCalled();
expect(updated).not.toBeCalled();
expect(updateFailed).not.toBeCalled();
});
8 changes: 1 addition & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,12 @@
"devDependencies": {
"@silverstripe/eslint-config": "^1.0.0",
"@silverstripe/webpack-config": "^2.0.0",
"@testing-library/react": "^14.0.0",
"babel-jest": "^29.3.0",
"copy-webpack-plugin": "^11.0.0",
"core-js": "^3.26.0",
"jest-cli": "^29.3.0",
"jest-environment-jsdom": "^29.3.1",
"react-16": "npm:react@^16.14.0",
"react-dom-16": "npm:react-dom@^16.14.0",
"webpack": "^5.74.0",
"webpack-cli": "^5.0.0"
},
Expand All @@ -72,11 +71,6 @@
"roots": [
"client/src"
],
"moduleNameMapper": {
"^react-dom/client$": "react-dom-16",
"^react-dom((/.*)?)$": "react-dom-16$1",
"^react((/.*)?)$": "react-16$1"
},
"moduleDirectories": [
"client/src",
"node_modules",
Expand Down
Loading

0 comments on commit 81e7e1a

Please sign in to comment.