Migrated MainHeader test to react testing library

This commit is contained in:
Alejandro Celaya 2022-05-03 20:36:24 +02:00
parent 29182ae349
commit a322886710
3 changed files with 41 additions and 46 deletions

View file

@ -8,7 +8,7 @@ import { useToggle } from '../utils/helpers/hooks';
import { ShlinkLogo } from './img/ShlinkLogo'; import { ShlinkLogo } from './img/ShlinkLogo';
import './MainHeader.scss'; import './MainHeader.scss';
const MainHeader = (ServersDropdown: FC) => () => { export const MainHeader = (ServersDropdown: FC) => () => {
const [isOpen, toggleOpen, , close] = useToggle(); const [isOpen, toggleOpen, , close] = useToggle();
const location = useLocation(); const location = useLocation();
const { pathname } = location; const { pathname } = location;
@ -41,5 +41,3 @@ const MainHeader = (ServersDropdown: FC) => () => {
</Navbar> </Navbar>
); );
}; };
export default MainHeader;

View file

@ -1,7 +1,7 @@
import axios from 'axios'; import axios from 'axios';
import Bottle from 'bottlejs'; import Bottle from 'bottlejs';
import ScrollToTop from '../ScrollToTop'; import ScrollToTop from '../ScrollToTop';
import MainHeader from '../MainHeader'; import { MainHeader } from '../MainHeader';
import { Home } from '../Home'; import { Home } from '../Home';
import MenuLayout from '../MenuLayout'; import MenuLayout from '../MenuLayout';
import AsideMenu from '../AsideMenu'; import AsideMenu from '../AsideMenu';

View file

@ -1,34 +1,24 @@
import { shallow, ShallowWrapper } from 'enzyme'; import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { useLocation } from 'react-router-dom'; import { Router } from 'react-router-dom';
import { Collapse, NavbarToggler, NavLink } from 'reactstrap'; import { createMemoryHistory } from 'history';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { MainHeader as createMainHeader } from '../../src/common/MainHeader';
import createMainHeader from '../../src/common/MainHeader';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useLocation: jest.fn().mockReturnValue({}),
}));
describe('<MainHeader />', () => { describe('<MainHeader />', () => {
const ServersDropdown = () => null; const MainHeader = createMainHeader(() => <>ServersDropdown</>);
const MainHeader = createMainHeader(ServersDropdown); const setUp = (pathname = '') => {
let wrapper: ShallowWrapper; const history = createMemoryHistory();
history.push(pathname);
const createWrapper = (pathname = '') => { return render(
(useLocation as any).mockReturnValue({ pathname }); <Router location={history.location} navigator={history}>
<MainHeader />
wrapper = shallow(<MainHeader />); </Router>,
);
return wrapper;
}; };
afterEach(jest.clearAllMocks);
afterEach(() => wrapper?.unmount());
it('renders ServersDropdown', () => { it('renders ServersDropdown', () => {
const wrapper = createWrapper(); setUp();
expect(screen.getByText('ServersDropdown')).toBeInTheDocument();
expect(wrapper.find(ServersDropdown)).toHaveLength(1);
}); });
it.each([ it.each([
@ -38,31 +28,38 @@ describe('<MainHeader />', () => {
['/settings/foo', true], ['/settings/foo', true],
['/settings/bar', true], ['/settings/bar', true],
])('sets link to settings as active only when current path is settings', (currentPath, isActive) => { ])('sets link to settings as active only when current path is settings', (currentPath, isActive) => {
const wrapper = createWrapper(currentPath); setUp(currentPath);
const settingsLink = wrapper.find(NavLink);
expect(settingsLink.prop('active')).toEqual(isActive); if (isActive) {
expect(screen.getByText(/Settings$/).getAttribute('class')).toContain('active');
} else {
expect(screen.getByText(/Settings$/).getAttribute('class')).not.toContain('active');
}
}); });
it('renders expected class based on the nav bar state', () => { it('renders expected class based on the nav bar state', () => {
const wrapper = createWrapper(); setUp();
expect(wrapper.find(NavbarToggler).find(FontAwesomeIcon).prop('className')).toEqual('main-header__toggle-icon'); const toggle = screen.getByLabelText('Toggle navigation');
wrapper.find(NavbarToggler).simulate('click'); const icon = toggle.firstChild;
expect(wrapper.find(NavbarToggler).find(FontAwesomeIcon).prop('className')).toEqual(
'main-header__toggle-icon main-header__toggle-icon--opened', expect(icon).toHaveAttribute('class', expect.stringMatching(/main-header__toggle-icon$/));
fireEvent.click(toggle);
expect(icon).toHaveAttribute(
'class',
expect.stringMatching(/main-header__toggle-icon main-header__toggle-icon--opened$/),
); );
wrapper.find(NavbarToggler).simulate('click'); fireEvent.click(toggle);
expect(wrapper.find(NavbarToggler).find(FontAwesomeIcon).prop('className')).toEqual('main-header__toggle-icon'); expect(icon).toHaveAttribute('class', expect.stringMatching(/main-header__toggle-icon$/));
}); });
it('opens Collapse when clicking toggle', () => { it('opens Collapse when clicking toggle', async () => {
const wrapper = createWrapper(); const { container } = setUp();
const collapse = container.querySelector('.collapse');
const toggle = screen.getByLabelText('Toggle navigation');
expect(wrapper.find(Collapse).prop('isOpen')).toEqual(false); expect(collapse).not.toHaveAttribute('class', expect.stringContaining('show'));
wrapper.find(NavbarToggler).simulate('click'); fireEvent.click(toggle);
expect(wrapper.find(Collapse).prop('isOpen')).toEqual(true); await waitFor(() => expect(collapse).toHaveAttribute('class', expect.stringContaining('show')));
wrapper.find(NavbarToggler).simulate('click');
expect(wrapper.find(Collapse).prop('isOpen')).toEqual(false);
}); });
}); });