Skip to content

Commit

Permalink
MNT Use React Testing Library
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Apr 20, 2023
1 parent 36aa92d commit fbd9c43
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 710 deletions.
376 changes: 91 additions & 285 deletions client/src/components/BlockLinkField/tests/BlockLinkField-test.js
Original file line number Diff line number Diff line change
@@ -1,305 +1,111 @@
/* eslint-disable import/no-extraneous-dependencies */
/* global jest, describe, it, expect */
/* global jest, test, describe, it, expect */

import React from 'react';
import { Component as BlockLinkField } from '../BlockLinkField';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Injector from 'lib/Injector';
import { render } from '@testing-library/react';

Injector.load();
Enzyme.configure({ adapter: new Adapter() });

describe('BlockLinkField', () => {
const mockedBlockLinkFieldActionsComponent = () =>
<div className=".block-link-field__actions-component" />;
let mockRegisterChange;
let mockHandleCloseModal;
let mockHandleClick;
let mockToggle;
let mockGetLinkedPage;

beforeEach(() => {
mockRegisterChange = jest.fn();
mockHandleCloseModal = jest.fn();
mockHandleClick = jest.fn();
mockToggle = jest.fn();
mockGetLinkedPage = jest.fn();
});

const props = {
function makeProps(obj = {}) {
return {
extraClass: '',
linkedPage: {},
showLinkText: true,
onChange: jest.fn(),
title: '',
value: '',
BlockLinkFieldActionsComponent: mockedBlockLinkFieldActionsComponent,
};

describe('render()', () => {
it('should render the class icon, the link, and the actions', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
toggle={mockToggle}
BlockLinkFieldActionsComponent={mockedBlockLinkFieldActionsComponent}
/>
);

expect(wrapper.find('.block-link-field__icon')).toHaveLength(1);
expect(wrapper.find('.block-link-field__content')).toHaveLength(1);
expect(wrapper.find('.block-link-field__actions')).toHaveLength(1);
});

it('should throw and error if no BlockLinkActionsComponent is given', () => {
// eslint-disable-next-line no-unused-vars
const { BlockLinkFieldActionsComponent, ...otherProps } = props;
const wrapper = shallow(
<BlockLinkField
{...otherProps}
/>
);

expect(wrapper.find('.block-link-field__icon')).toHaveLength(1);
expect(wrapper.find('.block-link-field__content')).toHaveLength(1);
expect(wrapper.find('.block-link-field__actions')).toHaveLength(0);
});
});

describe('renderModal()', () => {
it('should render the given InsertModalLink component', () => {
const MockModalComponent = () => <div />;

const wrapper = shallow(
<BlockLinkField
{...props}
toggle={mockToggle}
InsertModalLinkComponent={MockModalComponent}
/>
);

expect(wrapper.find(MockModalComponent)).toHaveLength(1);
});
});

describe('renderLinkContent()', () => {
it('renders a message if the state is dirty', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);

expect(wrapper.find('.block-link-field__content--message-modified')).toHaveLength(0);
wrapper.setState({ isDirty: true });
expect(wrapper.find('.block-link-field__content--message-modified')).toHaveLength(1);
});

it('renders the link and the title if provided', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);

wrapper.setState({ isDirty: true });
expect(wrapper.find('Changes will be visible upon save')).toHaveLength(0);
});
});

describe('renderActions()', () => {
it('', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);

expect(wrapper.find('.block-link-field__actions')).toHaveLength(1);
expect(wrapper.find(mockedBlockLinkFieldActionsComponent)).toHaveLength(1);
});
});

describe('handleSubmitModal()', () => {
it('Handles the insert link modal form submission', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);

wrapper.instance().handleCloseModal = mockHandleCloseModal;
wrapper.instance().registerChange = mockRegisterChange;

const mockData = {
SecurityID: 1,
action_insert: false,
content: 'test-mock-data'
};

wrapper.setState({ value: { content: '' } });
wrapper.instance().handleSubmitModal(mockData);

expect(wrapper.state('value')).toEqual({ content: 'test-mock-data' });
expect(mockRegisterChange).toHaveBeenCalled();
expect(mockHandleCloseModal).toHaveBeenCalled();
});
});

describe('handleCloseModal()', () => {
it('triggers the insert link modal to close', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);
wrapper.setState({ modalOpen: true });
wrapper.instance().handleCloseModal();

expect(wrapper.state('modalOpen')).toEqual(false);
});
});

describe('handleKeyUp()', () => {
it('triggers the handleClick function', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);

wrapper.instance().handleClick = mockHandleClick;

const mockEvent = {
keyCode: 13
};

wrapper.instance().handleKeyUp(mockEvent);

expect(mockHandleClick).toHaveBeenCalledWith(mockEvent);
});
});
value: '{"PageID":1}',
toggle: () => {},
BlockLinkFieldActionsComponent: () => <div className="test-block-link-field-actions" />,
// using a change handler to trigger the insert handler
InsertModalLinkComponent: ({onInsert}) => <input className="test-insert-modal-link" onChange={(evt) => onInsert(evt)} />,
...obj
}
}

test('BlockLinkField should render the class icon, the link, and the actions', () => {
const { container } = render(<BlockLinkField {...makeProps()}/>);
expect(container.querySelector('.block-link-field__icon')).not.toBeNull()
expect(container.querySelector('.block-link-field__content')).not.toBeNull()
expect(container.querySelector('.block-link-field__actions')).not.toBeNull()
});

describe('handleClick()', () => {
it('triggers the insert link modal to open', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);
test('BlockLinkField should render no actions if BlockLinkActionsComponent is not given', () => {
const { container } = render(
<BlockLinkField {...makeProps({
BlockLinkFieldActionsComponent: null
})}
/>
);
expect(container.querySelector('.block-link-field__icon')).not.toBeNull()
expect(container.querySelector('.block-link-field__content')).not.toBeNull()
expect(container.querySelector('.block-link-field__actions')).toBeNull()
});

const event = {
target: {
type: 'div'
}
};
wrapper.setState({ modalOpen: false });
wrapper.instance().handleClick(event);
test('BlockLinkField should render the InsertModalLinkComponent', () => {
const { container } = render(<BlockLinkField {...makeProps()}/>);
expect(container.querySelector('.test-insert-modal-link')).not.toBeNull()
});

expect(wrapper.state('modalOpen')).toEqual(true);
});
test('BlockLinkField should render the BlockLinkFieldActionsComponent', () => {
const { container } = render(<BlockLinkField {...makeProps()}/>);
expect(container.querySelector('.test-block-link-field-actions')).not.toBeNull()
});

it('does not trigger the insert link modal to open on button click', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);
const event = {
target: {
type: 'button'
test('BlockLinkField should return the linked page within the Entwine context', () => {
const { container } = render(
<BlockLinkField {...makeProps({
linkedPage: {},
data: {
linkedPage: {
URLSegment: '/react',
}
};

wrapper.setState({ modalOpen: false });
wrapper.instance().handleClick(event);

expect(wrapper.state('modalOpen')).toEqual(false);
});
});

describe('registerChange()', () => {
it('', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);

wrapper.setState({ isDirty: false });
wrapper.instance().registerChange();

expect(wrapper.state('isDirty')).toEqual(true);
});
});

describe('getLinkedPage()', () => {
it('should return the linked page within the Entwine context', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);
wrapper.setProps({
linkedPage: {},
data: { linkedPage: '/react' }
});

expect(wrapper.instance().getLinkedPage()).toEqual('/react');
});


it('should return the linked page within the React context', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);
wrapper.setProps({ linkedPage: { URLSegment: '/entwine' } });

expect(wrapper.instance().getLinkedPage()).toEqual({ URLSegment: '/entwine' });
});
});

describe('getLinkRelativeUrl()', () => {
it('returns relative URL for the linked page with a leading slash', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);

wrapper.instance().getLinkedPage = mockGetLinkedPage.mockReturnValue('/mockUrlWithSlash');
expect(wrapper.instance().getLinkRelativeUrl()).toEqual('/mockUrlWithSlash');

wrapper.instance().getLinkedPage = mockGetLinkedPage.mockReturnValue('/mockUrlWithOutSlash');
expect(wrapper.instance().getLinkRelativeUrl()).toEqual('/mockUrlWithOutSlash');
});

it('returns empty string if no relative URL provided', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);
},
})}
/>
);
expect(container.querySelector('.block-link-field__link').textContent).toBe('/react')
});

wrapper.instance().getLinkedPage = mockGetLinkedPage.mockReturnValue(null);
expect(wrapper.instance().getLinkRelativeUrl()).toEqual('');
});
});
test('BlockLinkField should return the linked page within the React context', () => {
const { container } = render(
<BlockLinkField {...makeProps({
linkedPage: {
URLSegment: '/entwine',
},
value: '{"PageID":1}'
})}
/>
);
expect(container.querySelector('.block-link-field__link').textContent).toBe('/entwine')
});

describe('getClassNames()', () => {
it('fetches extra class names if provided', () => {
const wrapper = shallow(
<BlockLinkField
{...props}
/>
);
test('BlockLinkField returns relative URL for the linked page with a leading slash', () => {
const { container } = render(
<BlockLinkField {...makeProps({
linkedPage: {
URLSegment: 'foo',
},
})}
/>
);
expect(container.querySelector('.block-link-field__link').textContent).toBe('/foo')
});

wrapper.setProps({ extraClass: 'test-class' });
test('BlockLinkField returns empty string if no relative URL provided', () => {
const { container } = render(
<BlockLinkField {...makeProps({
linkedPage: {},
})}
/>
);
expect(container.querySelector('.block-link-field__link')).toBeNull();
});

expect(wrapper.instance().getClassNames()).toMatch('test-class');
});
});
test('BlockLinkField fetches extra class names if provided', () => {
const { container } = render(
<BlockLinkField {...makeProps({
extraClass: 'test-class',
})}
/>
);
expect(container.querySelector('.test-class')).not.toBeNull();
});
Loading

0 comments on commit fbd9c43

Please sign in to comment.