Migrated RealTimeUpdatesSettings test to react testing library

This commit is contained in:
Alejandro Celaya 2022-06-06 22:23:21 +02:00
parent 53e15b041d
commit a90c3da7b6
2 changed files with 87 additions and 97 deletions

View file

@ -5,6 +5,7 @@ import { SimpleCard } from '../utils/SimpleCard';
import { FormText } from '../utils/forms/FormText'; import { FormText } from '../utils/forms/FormText';
import { LabeledFormGroup } from '../utils/forms/LabeledFormGroup'; import { LabeledFormGroup } from '../utils/forms/LabeledFormGroup';
import { Settings } from './reducers/settings'; import { Settings } from './reducers/settings';
import { useDomId } from '../utils/helpers/hooks';
interface RealTimeUpdatesProps { interface RealTimeUpdatesProps {
settings: Settings; settings: Settings;
@ -16,7 +17,10 @@ const intervalValue = (interval?: number) => (!interval ? '' : `${interval}`);
export const RealTimeUpdatesSettings = ( export const RealTimeUpdatesSettings = (
{ settings: { realTimeUpdates }, toggleRealTimeUpdates, setRealTimeUpdatesInterval }: RealTimeUpdatesProps, { settings: { realTimeUpdates }, toggleRealTimeUpdates, setRealTimeUpdatesInterval }: RealTimeUpdatesProps,
) => ( ) => {
const inputId = useDomId();
return (
<SimpleCard title="Real-time updates" className="h-100"> <SimpleCard title="Real-time updates" className="h-100">
<FormGroup> <FormGroup>
<ToggleSwitch checked={realTimeUpdates.enabled} onChange={toggleRealTimeUpdates}> <ToggleSwitch checked={realTimeUpdates.enabled} onChange={toggleRealTimeUpdates}>
@ -30,6 +34,7 @@ export const RealTimeUpdatesSettings = (
noMargin noMargin
label="Real-time updates frequency (in minutes):" label="Real-time updates frequency (in minutes):"
labelClassName={classNames('form-label', { 'text-muted': !realTimeUpdates.enabled })} labelClassName={classNames('form-label', { 'text-muted': !realTimeUpdates.enabled })}
id={inputId}
> >
<Input <Input
type="number" type="number"
@ -37,13 +42,15 @@ export const RealTimeUpdatesSettings = (
placeholder="Immediate" placeholder="Immediate"
disabled={!realTimeUpdates.enabled} disabled={!realTimeUpdates.enabled}
value={intervalValue(realTimeUpdates.interval)} value={intervalValue(realTimeUpdates.interval)}
id={inputId}
onChange={({ target }) => setRealTimeUpdatesInterval(Number(target.value))} onChange={({ target }) => setRealTimeUpdatesInterval(Number(target.value))}
/> />
{realTimeUpdates.enabled && ( {realTimeUpdates.enabled && (
<FormText> <FormText>
{realTimeUpdates.interval !== undefined && realTimeUpdates.interval > 0 && ( {realTimeUpdates.interval !== undefined && realTimeUpdates.interval > 0 && (
<span> <span>
Updates will be reflected in the UI every <b>{realTimeUpdates.interval}</b> minute{realTimeUpdates.interval > 1 && 's'}. Updates will be reflected in the UI
every <b>{realTimeUpdates.interval}</b> minute{realTimeUpdates.interval > 1 && 's'}.
</span> </span>
)} )}
{!realTimeUpdates.interval && 'Updates will be reflected in the UI as soon as they happen.'} {!realTimeUpdates.interval && 'Updates will be reflected in the UI as soon as they happen.'}
@ -51,4 +58,5 @@ export const RealTimeUpdatesSettings = (
)} )}
</LabeledFormGroup> </LabeledFormGroup>
</SimpleCard> </SimpleCard>
); );
};

View file

@ -1,64 +1,54 @@
import { shallow, ShallowWrapper } from 'enzyme'; import userEvent from '@testing-library/user-event';
import { render, screen } from '@testing-library/react';
import { Mock } from 'ts-mockery'; import { Mock } from 'ts-mockery';
import { Input } from 'reactstrap';
import { FormText } from '../../src/utils/forms/FormText';
import { import {
RealTimeUpdatesSettings as RealTimeUpdatesSettingsOptions, RealTimeUpdatesSettings as RealTimeUpdatesSettingsOptions,
Settings, Settings,
} from '../../src/settings/reducers/settings'; } from '../../src/settings/reducers/settings';
import { RealTimeUpdatesSettings } from '../../src/settings/RealTimeUpdatesSettings'; import { RealTimeUpdatesSettings } from '../../src/settings/RealTimeUpdatesSettings';
import { ToggleSwitch } from '../../src/utils/ToggleSwitch';
import { LabeledFormGroup } from '../../src/utils/forms/LabeledFormGroup';
describe('<RealTimeUpdatesSettings />', () => { describe('<RealTimeUpdatesSettings />', () => {
const toggleRealTimeUpdates = jest.fn(); const toggleRealTimeUpdates = jest.fn();
const setRealTimeUpdatesInterval = jest.fn(); const setRealTimeUpdatesInterval = jest.fn();
let wrapper: ShallowWrapper; const setUp = (realTimeUpdates: Partial<RealTimeUpdatesSettingsOptions> = {}) => ({
const createWrapper = (realTimeUpdates: Partial<RealTimeUpdatesSettingsOptions> = {}) => { user: userEvent.setup(),
const settings = Mock.of<Settings>({ realTimeUpdates }); ...render(
wrapper = shallow(
<RealTimeUpdatesSettings <RealTimeUpdatesSettings
settings={settings} settings={Mock.of<Settings>({ realTimeUpdates })}
toggleRealTimeUpdates={toggleRealTimeUpdates} toggleRealTimeUpdates={toggleRealTimeUpdates}
setRealTimeUpdatesInterval={setRealTimeUpdatesInterval} setRealTimeUpdatesInterval={setRealTimeUpdatesInterval}
/>, />,
); ),
});
return wrapper;
};
afterEach(jest.clearAllMocks); afterEach(jest.clearAllMocks);
afterEach(() => wrapper?.unmount());
it('renders enabled real time updates as expected', () => { it('renders enabled real time updates as expected', () => {
const wrapper = createWrapper({ enabled: true }); setUp({ enabled: true });
const toggle = wrapper.find(ToggleSwitch);
const label = wrapper.find(LabeledFormGroup);
const input = wrapper.find(Input);
const formText = wrapper.find(FormText);
expect(toggle.prop('checked')).toEqual(true); expect(screen.getByLabelText(/^Enable or disable real-time updates./)).toBeChecked();
expect(toggle.html()).toContain('processed'); expect(screen.getByText(/^Real-time updates are currently being/)).toHaveTextContent('processed');
expect(toggle.html()).not.toContain('ignored'); expect(screen.getByText(/^Real-time updates are currently being/)).not.toHaveTextContent('ignored');
expect(label.prop('labelClassName')).not.toContain('text-muted'); expect(screen.getByText('Real-time updates frequency (in minutes):')).not.toHaveAttribute(
expect(input.prop('disabled')).toEqual(false); 'class',
expect(formText).toHaveLength(2); expect.stringContaining('text-muted'),
);
expect(screen.getByLabelText('Real-time updates frequency (in minutes):')).not.toHaveAttribute('disabled');
expect(screen.getByText('Updates will be reflected in the UI as soon as they happen.')).toBeInTheDocument();
}); });
it('renders disabled real time updates as expected', () => { it('renders disabled real time updates as expected', () => {
const wrapper = createWrapper({ enabled: false }); setUp({ enabled: false });
const toggle = wrapper.find(ToggleSwitch);
const label = wrapper.find(LabeledFormGroup);
const input = wrapper.find(Input);
const formText = wrapper.find(FormText);
expect(toggle.prop('checked')).toEqual(false); expect(screen.getByLabelText(/^Enable or disable real-time updates./)).not.toBeChecked();
expect(toggle.html()).not.toContain('processed'); expect(screen.getByText(/^Real-time updates are currently being/)).not.toHaveTextContent('processed');
expect(toggle.html()).toContain('ignored'); expect(screen.getByText(/^Real-time updates are currently being/)).toHaveTextContent('ignored');
expect(label.prop('labelClassName')).toContain('text-muted'); expect(screen.getByText('Real-time updates frequency (in minutes):')).toHaveAttribute(
expect(input.prop('disabled')).toEqual(true); 'class',
expect(formText).toHaveLength(1); expect.stringContaining('text-muted'),
);
expect(screen.getByLabelText('Real-time updates frequency (in minutes):')).toHaveAttribute('disabled');
expect(screen.queryByText('Updates will be reflected in the UI as soon as they happen.')).not.toBeInTheDocument();
}); });
it.each([ it.each([
@ -67,43 +57,35 @@ describe('<RealTimeUpdatesSettings />', () => {
[10, 'minutes'], [10, 'minutes'],
[100, 'minutes'], [100, 'minutes'],
])('shows expected children when interval is greater than 0', (interval, minutesWord) => { ])('shows expected children when interval is greater than 0', (interval, minutesWord) => {
const wrapper = createWrapper({ enabled: true, interval }); setUp({ enabled: true, interval });
const span = wrapper.find('span');
const input = wrapper.find(Input);
expect(span).toHaveLength(1); expect(screen.getByText(/^Updates will be reflected in the UI every/)).toHaveTextContent(
expect(span.html()).toEqual( `${interval} ${minutesWord}`,
`<span>Updates will be reflected in the UI every <b>${interval}</b> ${minutesWord}.</span>`,
); );
expect(input.prop('value')).toEqual(`${interval}`); expect(screen.getByLabelText('Real-time updates frequency (in minutes):')).toHaveValue(interval);
expect(screen.queryByText('Updates will be reflected in the UI as soon as they happen.')).not.toBeInTheDocument();
}); });
it.each([[undefined], [0]])('shows expected children when interval is 0 or undefined', (interval) => { it.each([[undefined], [0]])('shows expected children when interval is 0 or undefined', (interval) => {
const wrapper = createWrapper({ enabled: true, interval }); setUp({ enabled: true, interval });
const span = wrapper.find('span');
const formText = wrapper.find(FormText).at(1);
const input = wrapper.find(Input);
expect(span).toHaveLength(0); expect(screen.queryByText(/^Updates will be reflected in the UI every/)).not.toBeInTheDocument();
expect(formText.html()).toContain('Updates will be reflected in the UI as soon as they happen.'); expect(screen.getByText('Updates will be reflected in the UI as soon as they happen.')).toBeInTheDocument();
expect(input.prop('value')).toEqual('');
}); });
it('updates real time updates on input change', () => { it('updates real time updates when typing on input', async () => {
const wrapper = createWrapper(); const { user } = setUp({ enabled: true });
const input = wrapper.find(Input);
expect(setRealTimeUpdatesInterval).not.toHaveBeenCalled(); expect(setRealTimeUpdatesInterval).not.toHaveBeenCalled();
input.simulate('change', { target: { value: '10' } }); await user.type(screen.getByLabelText('Real-time updates frequency (in minutes):'), '5');
expect(setRealTimeUpdatesInterval).toHaveBeenCalledWith(10); expect(setRealTimeUpdatesInterval).toHaveBeenCalledWith(5);
}); });
it('toggles real time updates on switch change', () => { it('toggles real time updates on switch change', async () => {
const wrapper = createWrapper(); const { user } = setUp({ enabled: true });
const toggle = wrapper.find(ToggleSwitch);
expect(toggleRealTimeUpdates).not.toHaveBeenCalled(); expect(toggleRealTimeUpdates).not.toHaveBeenCalled();
toggle.simulate('change'); await user.click(screen.getByText(/^Enable or disable real-time updates./));
expect(toggleRealTimeUpdates).toHaveBeenCalled(); expect(toggleRealTimeUpdates).toHaveBeenCalled();
}); });
}); });