mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Created EditTagModal test
This commit is contained in:
parent
856ee6d65c
commit
56a3dbd07f
2 changed files with 120 additions and 11 deletions
|
@ -1,5 +1,5 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader, Popover } from 'reactstrap';
|
import { Button, Input, Modal, ModalBody, ModalFooter, ModalHeader, Popover } from 'reactstrap';
|
||||||
import { ChromePicker } from 'react-color';
|
import { ChromePicker } from 'react-color';
|
||||||
import { faPalette as colorIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faPalette as colorIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
@ -25,10 +25,12 @@ const EditTagModal = ({ getColorForKey }: ColorGenerator) => (
|
||||||
const [ color, setColor ] = useState(getColorForKey(tag));
|
const [ color, setColor ] = useState(getColorForKey(tag));
|
||||||
const [ showColorPicker, toggleColorPicker, , hideColorPicker ] = useToggle();
|
const [ showColorPicker, toggleColorPicker, , hideColorPicker ] = useToggle();
|
||||||
const { editing, error, errorData } = tagEdit;
|
const { editing, error, errorData } = tagEdit;
|
||||||
const saveTag = handleEventPreventingDefault(async () => editTag(tag, newTagName, color)
|
const saveTag = handleEventPreventingDefault(
|
||||||
.then(() => tagEdited(tag, newTagName, color))
|
async () => editTag(tag, newTagName, color)
|
||||||
.then(toggle)
|
.then(() => tagEdited(tag, newTagName, color))
|
||||||
.catch(() => {}));
|
.then(toggle)
|
||||||
|
.catch(() => {}),
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} toggle={toggle} centered onClosed={hideColorPicker}>
|
<Modal isOpen={isOpen} toggle={toggle} centered onClosed={hideColorPicker}>
|
||||||
|
@ -47,13 +49,11 @@ const EditTagModal = ({ getColorForKey }: ColorGenerator) => (
|
||||||
<Popover isOpen={showColorPicker} toggle={toggleColorPicker} target="colorPickerBtn" placement="right">
|
<Popover isOpen={showColorPicker} toggle={toggleColorPicker} target="colorPickerBtn" placement="right">
|
||||||
<ChromePicker color={color} disableAlpha onChange={({ hex }) => setColor(hex)} />
|
<ChromePicker color={color} disableAlpha onChange={({ hex }) => setColor(hex)} />
|
||||||
</Popover>
|
</Popover>
|
||||||
<input
|
<Input
|
||||||
type="text"
|
|
||||||
value={newTagName}
|
value={newTagName}
|
||||||
placeholder="Tag"
|
placeholder="Tag"
|
||||||
required
|
required
|
||||||
className="form-control"
|
onChange={({ target }) => setNewTagName(target.value)}
|
||||||
onChange={(e) => setNewTagName(e.target.value)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -64,8 +64,8 @@ const EditTagModal = ({ getColorForKey }: ColorGenerator) => (
|
||||||
)}
|
)}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<button type="button" className="btn btn-link" onClick={toggle}>Cancel</button>
|
<Button type="button" color="link" onClick={toggle}>Cancel</Button>
|
||||||
<button type="submit" className="btn btn-primary" disabled={editing}>{editing ? 'Saving...' : 'Save'}</button>
|
<Button color="primary" disabled={editing}>{editing ? 'Saving...' : 'Save'}</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</form>
|
</form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
109
test/tags/helpers/EditTagModal.test.tsx
Normal file
109
test/tags/helpers/EditTagModal.test.tsx
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
|
import { Mock } from 'ts-mockery';
|
||||||
|
import { Button, Input, Modal, ModalHeader, Popover } from 'reactstrap';
|
||||||
|
import { TagEdition } from '../../../src/tags/reducers/tagEdit';
|
||||||
|
import createEditTagModal from '../../../src/tags/helpers/EditTagModal';
|
||||||
|
import ColorGenerator from '../../../src/utils/services/ColorGenerator';
|
||||||
|
import { Result } from '../../../src/utils/Result';
|
||||||
|
import { ProblemDetailsError } from '../../../src/api/types';
|
||||||
|
import { ShlinkApiError } from '../../../src/api/ShlinkApiError';
|
||||||
|
import { ChromePicker } from 'react-color';
|
||||||
|
|
||||||
|
describe('<EditTagModal />', () => {
|
||||||
|
const EditTagModal = createEditTagModal(Mock.of<ColorGenerator>({ getColorForKey: jest.fn(() => 'red') }));
|
||||||
|
const editTag = jest.fn().mockReturnValue(Promise.resolve());
|
||||||
|
const tagEdited = jest.fn().mockReturnValue(Promise.resolve());
|
||||||
|
const toggle = jest.fn();
|
||||||
|
let wrapper: ShallowWrapper;
|
||||||
|
const createWrapper = (tagEdit: Partial<TagEdition> = {}) => {
|
||||||
|
const edition = Mock.of<TagEdition>(tagEdit);
|
||||||
|
|
||||||
|
wrapper = shallow(
|
||||||
|
<EditTagModal isOpen tag="foo" tagEdit={edition} editTag={editTag} tagEdited={tagEdited} toggle={toggle} />,
|
||||||
|
);
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
};
|
||||||
|
|
||||||
|
afterEach(jest.clearAllMocks);
|
||||||
|
afterEach(() => wrapper?.unmount());
|
||||||
|
|
||||||
|
test('modal can be toggled with different mechanisms', () => {
|
||||||
|
const wrapper = createWrapper();
|
||||||
|
const modal = wrapper.find(Modal);
|
||||||
|
const modalHeader = wrapper.find(ModalHeader);
|
||||||
|
const cancelBtn = wrapper.find(Button).findWhere((btn) => btn.prop('type') === 'button');
|
||||||
|
|
||||||
|
expect(toggle).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
(modal.prop('toggle') as Function)();
|
||||||
|
(modalHeader.prop('toggle') as Function)();
|
||||||
|
cancelBtn.simulate('click');
|
||||||
|
|
||||||
|
expect(toggle).toHaveBeenCalledTimes(3);
|
||||||
|
expect(editTag).not.toHaveBeenCalled();
|
||||||
|
expect(tagEdited).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test.each([
|
||||||
|
[ true, 'Saving...' ],
|
||||||
|
[ false, 'Save' ],
|
||||||
|
])('submit button is rendered in expected state', (editing, expectedText) => {
|
||||||
|
const wrapper = createWrapper({ editing });
|
||||||
|
const submitBtn = wrapper.find(Button).findWhere((btn) => btn.prop('color') === 'primary');
|
||||||
|
|
||||||
|
expect(submitBtn.html()).toContain(expectedText);
|
||||||
|
expect(submitBtn.prop('disabled')).toEqual(editing);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.each([
|
||||||
|
[ true, 1 ],
|
||||||
|
[ false, 0 ],
|
||||||
|
])('error result is displayed in case of error', (error, expectedResultCount) => {
|
||||||
|
const wrapper = createWrapper({ error, errorData: Mock.all<ProblemDetailsError>() });
|
||||||
|
const result = wrapper.find(Result);
|
||||||
|
const apiError = wrapper.find(ShlinkApiError);
|
||||||
|
|
||||||
|
expect(result).toHaveLength(expectedResultCount);
|
||||||
|
expect(apiError).toHaveLength(expectedResultCount);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('tag value is updated when text changes', () => {
|
||||||
|
const wrapper = createWrapper();
|
||||||
|
|
||||||
|
expect(wrapper.find(Input).prop('value')).toEqual('foo');
|
||||||
|
wrapper.find(Input).simulate('change', { target: { value: 'bar' } });
|
||||||
|
expect(wrapper.find(Input).prop('value')).toEqual('bar');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('all functions are invoked on form submit', async () => {
|
||||||
|
const wrapper = createWrapper();
|
||||||
|
const form = wrapper.find('form');
|
||||||
|
|
||||||
|
expect(editTag).not.toHaveBeenCalled();
|
||||||
|
expect(tagEdited).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
await form.simulate('submit', { preventDefault: jest.fn() }); // eslint-disable-line @typescript-eslint/await-thenable
|
||||||
|
|
||||||
|
expect(editTag).toHaveBeenCalled();
|
||||||
|
expect(tagEdited).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('color is changed when changing on color picker', () => {
|
||||||
|
const wrapper = createWrapper();
|
||||||
|
|
||||||
|
expect(wrapper.find(ChromePicker).prop('color')).toEqual('red');
|
||||||
|
wrapper.find(ChromePicker).simulate('change', { hex: 'blue' });
|
||||||
|
expect(wrapper.find(ChromePicker).prop('color')).toEqual('blue');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('popover can be toggled with different mechanisms', () => {
|
||||||
|
const wrapper = createWrapper();
|
||||||
|
|
||||||
|
expect(wrapper.find(Popover).prop('isOpen')).toEqual(false);
|
||||||
|
(wrapper.find(Popover).prop('toggle') as Function)();
|
||||||
|
expect(wrapper.find(Popover).prop('isOpen')).toEqual(true);
|
||||||
|
wrapper.find('.input-group-prepend').simulate('click');
|
||||||
|
expect(wrapper.find(Popover).prop('isOpen')).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue