Skip to content

Commit

Permalink
Merge pull request #1052 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 2, 2023
2 parents 8036a47 + deb0a73 commit e039d3f
Show file tree
Hide file tree
Showing 17 changed files with 1,120 additions and 1,809 deletions.
112 changes: 55 additions & 57 deletions client/src/components/ElementActions/tests/AbstractAction-test.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,60 @@
/* eslint-disable import/no-extraneous-dependencies */
/* global jest, describe, it, expect */
/* global jest, test, describe, it, expect */

import React from 'react';
import AbstractAction from '../AbstractAction';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16/build/index';

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

describe('AbstractAction', () => {
const clickHandler = jest.fn();
let wrapper = null;

beforeEach(() => {
wrapper = mount(
<AbstractAction
onClick={clickHandler}
title="My abstract action"
disabled={false}
className="foo-bar"
toggle={false}
/>
);
});

it('renders a DropdownItem', () => {
expect(wrapper.find('DropdownItem').length).toBe(1);
});

it('includes the title text', () => {
expect(wrapper.text()).toContain('My abstract action');
});

it('delegates clicking to the provided handler', () => {
wrapper.find('button').simulate('click');
expect(clickHandler).toHaveBeenCalled();
});

it('adds provided extra classes', () => {
expect(wrapper.find('button').hasClass('foo-bar')).toBe(true);
});

it('uses the label prop for the button label if label prop is supplied', () => {
const wrapperWithLabel = mount(
<AbstractAction
title="My title"
label="My label"
/>
);
expect(wrapperWithLabel.find('button').text()).toBe('My label');
});

it('uses the title prop for the button label if label prop is not supplied', () => {
const wrapperWithLabel = mount(
<AbstractAction
title="My title"
/>
);
expect(wrapperWithLabel.find('button').text()).toBe('My title');
});
import { render, fireEvent } from '@testing-library/react';

function makeProps(obj = {}) {
return {
onClick: () => {},
title: 'My abstract action',
disabled: false,
className: 'foo-bar',
toggle: false,
...obj,
};
}

test('AbstractAction renders a DropdownItem', () => {
const { container } = render(<AbstractAction {...makeProps()}/>);
expect(container.querySelector('.dropdown-item')).not.toBeNull();
});

test('AbstractAction includes the title text', () => {
const { container } = render(<AbstractAction {...makeProps()}/>);
expect(container.querySelector('.dropdown-item').textContent).toBe('My abstract action');
});

test('AbstractAction delegates clicking to the provided handler', () => {
const onClick = jest.fn();
const { container } = render(<AbstractAction {...makeProps({ onClick })}/>);
fireEvent.click(container.querySelector('.dropdown-item'));
expect(onClick).toHaveBeenCalled();
});

test('AbstractAction adds provided extra classes', () => {
const { container } = render(<AbstractAction {...makeProps()}/>);
expect(container.querySelector('.dropdown-item').classList.contains('foo-bar')).toBe(true);
});

test('AbstractAction uses the label prop for the button label if label prop is supplied', () => {
const { container } = render(
<AbstractAction {...makeProps({
title: 'My title',
label: 'My label'
})}
/>
);
expect(container.querySelector('.dropdown-item').textContent).toBe('My label');
});

test('AbstractAction uses the title prop for the button label if label prop is not supplied', () => {
const { container } = render(
<AbstractAction {...makeProps({
title: 'My title'
})}
/>
);
expect(container.querySelector('.dropdown-item').textContent).toBe('My title');
});
204 changes: 89 additions & 115 deletions client/src/components/ElementActions/tests/ArchiveAction-test.js
Original file line number Diff line number Diff line change
@@ -1,127 +1,101 @@
/* eslint-disable import/no-extraneous-dependencies */
/* global jest, describe, it, expect */
/* global jest, test, describe, it, expect */

import React from 'react';
import { Component as ArchiveAction } from '../ArchiveAction';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });
import { render, fireEvent } from '@testing-library/react';

const WrappedComponent = (props) => <div>{props.children}</div>;
const ActionComponent = ArchiveAction(WrappedComponent);
const jQuery = jest.fn();
window.jQuery = jQuery;

function makeProps(obj = {}) {
return {
title: 'My abstract action',
element: {
id: 123,
isPublished: true,
blockSchema: { type: 'Test' }
},
isPublished: true,
actions: {
handleArchiveBlock: () => {}
},
toggle: false,
...obj,
};
}

test('ArchiveAction renders the wrapped component', () => {
const { container } = render(<ActionComponent {...makeProps()}/>);
expect(container.querySelector('button.element-editor__actions-archive').textContent).toBe('Archive');
});

describe('ArchiveAction', () => {
let wrapper = null;
test('ArchiveAction does not archive when declining the confirmation', () => {
global.confirm = () => false;
const mockMutation = jest.fn(() => new Promise((resolve) => { resolve(); }));
const WrappedComponent = (props) => <div>{props.children}</div>;
const ActionComponent = ArchiveAction(WrappedComponent);
const jQuery = jest.fn();
window.jQuery = jQuery;

beforeEach(() => {
wrapper = mount(
<ActionComponent
title="My abstract action"
element={{
id: 123,
isPublished: true,
blockSchema: { type: 'Test' }
}}
isPublished
actions={{ handleArchiveBlock: mockMutation }}
toggle={false}
/>
);
});

it('renders the wrapped component', () => {
expect(wrapper.children().first().type()).toEqual(WrappedComponent);
});

it('renders a button', () => {
expect(wrapper.find('button').length).toBe(1);
});

it('renders the title and class', () => {
expect(wrapper.find('button').text()).toContain('Archive');
expect(wrapper.find('button').hasClass('element-editor__actions-archive')).toBe(true);
});

it('does not archive when declining the confirmation', () => {
global.confirm = () => false;
wrapper.find('button').simulate('click');
expect(mockMutation).not.toHaveBeenCalled();
});

it('archives when accepting the confirmation', () => {
global.confirm = () => true;
wrapper.find('button').simulate('click');
expect(mockMutation).toHaveBeenCalled();
});

it('indicates that the block will be sent to archive', () => {
const unpublishedWrapper = mount(
<ActionComponent
title="My abstract action"
element={{
id: 123,
isPublished: false,
blockSchema: { type: 'Test' }
}}
actions={{ handleArchiveBlock: mockMutation }}
toggle={false}
/>
);
const mockConfirm = jest.fn();
global.confirm = mockConfirm;

unpublishedWrapper.find('button').simulate('click');
expect(mockConfirm).toHaveBeenCalledWith(
'Are you sure you want to send this block to the archive?'
);
});
const { container } = render(<ActionComponent {...makeProps({
actions: {
handleArchiveBlock: mockMutation
}
})}
/>);
fireEvent.click(container.querySelector('button.element-editor__actions-archive'));
expect(mockMutation).not.toHaveBeenCalled();
});

it('indicates that the block will be unpublished before archiving', () => {
const mockConfirm = jest.fn();
global.confirm = mockConfirm;
test('ArchiveAction archives when accepting the confirmation', () => {
global.confirm = () => true;
const mockMutation = jest.fn(() => new Promise((resolve) => { resolve(); }));
const { container } = render(<ActionComponent {...makeProps({
actions: {
handleArchiveBlock: mockMutation
}
})}
/>);
fireEvent.click(container.querySelector('button.element-editor__actions-archive'));
expect(mockMutation).toHaveBeenCalled();
});

wrapper.find('button').simulate('click');
expect(mockConfirm).toHaveBeenCalledWith(expect.stringContaining(
'Warning: This block will be unpublished'
));
});
test('ArchiveAction indicates that the block will be sent to archive when it is unpublished', () => {
const mockConfirm = jest.fn();
global.confirm = mockConfirm;
const { container } = render(<ActionComponent {...makeProps({
isPublished: false,
})}
/>);
fireEvent.click(container.querySelector('button.element-editor__actions-archive'));
expect(mockConfirm).toHaveBeenCalledWith('Are you sure you want to send this block to the archive?');
});

it('is disabled when user doesn\'t have correct permissions', () => {
const archiveWrapper = mount(
<ActionComponent
title="My abstract action"
element={{
ID: 123,
IsPublished: false,
BlockSchema: { type: 'Test' },
canDelete: false
}}
actions={{ handleArchiveBlock: mockMutation }}
toggle={false}
/>
);
test('ArchiveAction indicates that the block will be sent to archive when it is published', () => {
const mockConfirm = jest.fn();
global.confirm = mockConfirm;
const { container } = render(<ActionComponent {...makeProps({
isPublished: true,
})}
/>);
fireEvent.click(container.querySelector('button.element-editor__actions-archive'));
expect(mockConfirm).toHaveBeenCalledWith('Warning: This block will be unpublished before being sent to the archive. Are you sure you want to proceed?');
});

expect(archiveWrapper.find('button').first().prop('disabled')).toBe(true);
});
test('ArchiveAction is disabled when user doesn\'t have correct permissions', () => {
const { container } = render(<ActionComponent {...makeProps({
element: {
canDelete: false
}
})}
/>);
expect(container.querySelector('button.element-editor__actions-archive').disabled).toBe(true);
});

it('renders a button even when block is broken', () => {
wrapper = mount(
<ActionComponent
title="My unpublish action"
element={{
id: 123,
isPublished: true,
blockSchema: { type: 'Test' }
}}
isPublished
type={{ broken: true }}
actions={{ handleArchiveBlock: mockMutation }}
toggle={false}
/>
);
expect(wrapper.find('button').length).toBe(1);
});
test('ArchiveAction renders a button even when block is broken', () => {
const { container } = render(<ActionComponent {...makeProps({
type: {
broken: true
}
})}
/>);
expect(container.querySelector('button.element-editor__actions-archive')).not.toBeNull();
});
Loading

0 comments on commit e039d3f

Please sign in to comment.