mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-09 01:37:24 +03:00
Migrated short URL helper modal components to TS
This commit is contained in:
parent
b19bbee7fc
commit
f283dc8569
14 changed files with 90 additions and 130 deletions
|
@ -1,6 +1,7 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { HorizontalFormGroup } from '../../utils/HorizontalFormGroup';
|
||||
import { handleEventPreventingDefault } from '../../utils/utils';
|
||||
|
||||
const propTypes = {
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
|
@ -16,10 +17,7 @@ export const ServerForm = ({ onSubmit, initialValues, children }) => {
|
|||
const [ name, setName ] = useState('');
|
||||
const [ url, setUrl ] = useState('');
|
||||
const [ apiKey, setApiKey ] = useState('');
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
onSubmit({ name, url, apiKey });
|
||||
};
|
||||
const handleSubmit = handleEventPreventingDefault(() => onSubmit({ name, url, apiKey }));
|
||||
|
||||
useEffect(() => {
|
||||
initialValues && setName(initialValues.name);
|
||||
|
|
|
@ -8,7 +8,7 @@ import DateInput from '../utils/DateInput';
|
|||
import Checkbox from '../utils/Checkbox';
|
||||
import { serverType } from '../servers/prop-types';
|
||||
import { versionMatch } from '../utils/helpers/version';
|
||||
import { hasValue } from '../utils/utils';
|
||||
import { handleEventPreventingDefault, hasValue } from '../utils/utils';
|
||||
import { useToggle } from '../utils/helpers/hooks';
|
||||
import { createShortUrlResultType } from './reducers/shortUrlCreation';
|
||||
import UseExistingIfFoundInfoIcon from './UseExistingIfFoundInfoIcon';
|
||||
|
@ -42,9 +42,7 @@ const CreateShortUrl = (TagsSelector, CreateShortUrlResult, ForServerVersion) =>
|
|||
|
||||
const changeTags = (tags) => setShortUrlCreation({ ...shortUrlCreation, tags: tags.map(normalizeTag) });
|
||||
const reset = () => setShortUrlCreation(initialState);
|
||||
const save = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const save = handleEventPreventingDefault(() => {
|
||||
const shortUrlData = {
|
||||
...shortUrlCreation,
|
||||
validSince: formatDate(shortUrlCreation.validSince),
|
||||
|
@ -52,7 +50,7 @@ const CreateShortUrl = (TagsSelector, CreateShortUrlResult, ForServerVersion) =>
|
|||
};
|
||||
|
||||
createShortUrl(shortUrlData).then(reset).catch(() => {});
|
||||
};
|
||||
});
|
||||
const renderOptionalInput = (id, placeholder, type = 'text', props = {}) => (
|
||||
<FormGroup>
|
||||
<Input
|
||||
|
|
|
@ -27,3 +27,9 @@ export interface ShortUrlMeta {
|
|||
validUntil?: string;
|
||||
maxVisits?: number;
|
||||
}
|
||||
|
||||
export interface ShortUrlModalProps {
|
||||
shortUrl: ShortUrl;
|
||||
isOpen: boolean;
|
||||
toggle: () => void;
|
||||
}
|
||||
|
|
|
@ -1,40 +1,37 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
||||
import PropTypes from 'prop-types';
|
||||
import { identity, pipe } from 'ramda';
|
||||
import { shortUrlType } from '../reducers/shortUrlsList';
|
||||
import { shortUrlDeletionType } from '../reducers/shortUrlDeletion';
|
||||
import { ShortUrlDeletion } from '../reducers/shortUrlDeletion';
|
||||
import { ShortUrlModalProps } from '../data';
|
||||
import { handleEventPreventingDefault, OptionalString } from '../../utils/utils';
|
||||
|
||||
const THRESHOLD_REACHED = 'INVALID_SHORTCODE_DELETION';
|
||||
|
||||
const propTypes = {
|
||||
shortUrl: shortUrlType,
|
||||
toggle: PropTypes.func,
|
||||
isOpen: PropTypes.bool,
|
||||
shortUrlDeletion: shortUrlDeletionType,
|
||||
deleteShortUrl: PropTypes.func,
|
||||
resetDeleteShortUrl: PropTypes.func,
|
||||
};
|
||||
interface DeleteShortUrlModalConnectProps extends ShortUrlModalProps {
|
||||
shortUrlDeletion: ShortUrlDeletion;
|
||||
deleteShortUrl: (shortCode: string, domain: OptionalString) => Promise<void>;
|
||||
resetDeleteShortUrl: () => void;
|
||||
}
|
||||
|
||||
const DeleteShortUrlModal = ({ shortUrl, toggle, isOpen, shortUrlDeletion, resetDeleteShortUrl, deleteShortUrl }) => {
|
||||
const DeleteShortUrlModal = (
|
||||
{ shortUrl, toggle, isOpen, shortUrlDeletion, resetDeleteShortUrl, deleteShortUrl }: DeleteShortUrlModalConnectProps,
|
||||
) => {
|
||||
const [ inputValue, setInputValue ] = useState('');
|
||||
|
||||
useEffect(() => resetDeleteShortUrl, []);
|
||||
|
||||
const { error, errorData } = shortUrlDeletion;
|
||||
const errorCode = error && errorData && (errorData.type || errorData.error);
|
||||
const errorCode = error && (errorData?.type || errorData?.error);
|
||||
const hasThresholdError = errorCode === THRESHOLD_REACHED;
|
||||
const hasErrorOtherThanThreshold = error && errorCode !== THRESHOLD_REACHED;
|
||||
const close = pipe(resetDeleteShortUrl, toggle);
|
||||
const handleDeleteUrl = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const handleDeleteUrl = handleEventPreventingDefault(() => {
|
||||
const { shortCode, domain } = shortUrl;
|
||||
|
||||
deleteShortUrl(shortCode, domain)
|
||||
.then(toggle)
|
||||
.catch(identity);
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} toggle={close} centered>
|
||||
|
@ -56,8 +53,8 @@ const DeleteShortUrlModal = ({ shortUrl, toggle, isOpen, shortUrlDeletion, reset
|
|||
|
||||
{hasThresholdError && (
|
||||
<div className="p-2 mt-2 bg-warning text-center">
|
||||
{errorData.threshold && `This short URL has received more than ${errorData.threshold} visits, and therefore, it cannot be deleted.`}
|
||||
{!errorData.threshold && 'This short URL has received too many visits, and therefore, it cannot be deleted.'}
|
||||
{errorData?.threshold && `This short URL has received more than ${errorData.threshold} visits, and therefore, it cannot be deleted.`}
|
||||
{!errorData?.threshold && 'This short URL has received too many visits, and therefore, it cannot be deleted.'}
|
||||
</div>
|
||||
)}
|
||||
{hasErrorOtherThanThreshold && (
|
||||
|
@ -81,6 +78,4 @@ const DeleteShortUrlModal = ({ shortUrl, toggle, isOpen, shortUrlDeletion, reset
|
|||
);
|
||||
};
|
||||
|
||||
DeleteShortUrlModal.propTypes = propTypes;
|
||||
|
||||
export default DeleteShortUrlModal;
|
|
@ -1,4 +1,4 @@
|
|||
import React, { ChangeEvent, SyntheticEvent, useState } from 'react';
|
||||
import React, { ChangeEvent, useState } from 'react';
|
||||
import { Modal, ModalBody, ModalFooter, ModalHeader, FormGroup, Input, UncontrolledTooltip } from 'reactstrap';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faInfoCircle as infoIcon } from '@fortawesome/free-solid-svg-icons';
|
||||
|
@ -8,16 +8,10 @@ import { isEmpty, pipe } from 'ramda';
|
|||
import { ShortUrlMetaEdition } from '../reducers/shortUrlMeta';
|
||||
import DateInput from '../../utils/DateInput';
|
||||
import { formatIsoDate } from '../../utils/helpers/date';
|
||||
import { ShortUrl, ShortUrlMeta } from '../data';
|
||||
import { Nullable, OptionalString } from '../../utils/utils';
|
||||
import { ShortUrl, ShortUrlMeta, ShortUrlModalProps } from '../data';
|
||||
import { handleEventPreventingDefault, Nullable, OptionalString } from '../../utils/utils';
|
||||
|
||||
export interface EditMetaModalProps {
|
||||
shortUrl: ShortUrl;
|
||||
isOpen: boolean;
|
||||
toggle: () => void;
|
||||
}
|
||||
|
||||
interface EditMetaModalConnectProps extends EditMetaModalProps {
|
||||
interface EditMetaModalConnectProps extends ShortUrlModalProps {
|
||||
shortUrlMeta: ShortUrlMetaEdition;
|
||||
resetShortUrlMeta: () => void;
|
||||
editShortUrlMeta: (shortCode: string, domain: OptionalString, meta: Nullable<ShortUrlMeta>) => Promise<void>;
|
||||
|
@ -54,7 +48,7 @@ const EditMetaModal = (
|
|||
<p>If any of the params is not met, the URL will behave as if it was an invalid short URL.</p>
|
||||
</UncontrolledTooltip>
|
||||
</ModalHeader>
|
||||
<form onSubmit={pipe((e: SyntheticEvent) => e.preventDefault(), doEdit)}>
|
||||
<form onSubmit={handleEventPreventingDefault(doEdit)}>
|
||||
<ModalBody>
|
||||
<FormGroup>
|
||||
<DateInput
|
||||
|
|
|
@ -1,32 +1,28 @@
|
|||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Modal, ModalBody, ModalFooter, ModalHeader, FormGroup, Input, Button } from 'reactstrap';
|
||||
import { ExternalLink } from 'react-external-link';
|
||||
import { shortUrlType } from '../reducers/shortUrlsList';
|
||||
import { ShortUrlEditionType } from '../reducers/shortUrlEdition';
|
||||
import { hasValue } from '../../utils/utils';
|
||||
import { ShortUrlEdition } from '../reducers/shortUrlEdition';
|
||||
import { handleEventPreventingDefault, hasValue, OptionalString } from '../../utils/utils';
|
||||
import { ShortUrlModalProps } from '../data';
|
||||
|
||||
const propTypes = {
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
toggle: PropTypes.func.isRequired,
|
||||
shortUrl: shortUrlType.isRequired,
|
||||
shortUrlEdition: ShortUrlEditionType,
|
||||
editShortUrl: PropTypes.func,
|
||||
};
|
||||
interface EditShortUrlModalProps extends ShortUrlModalProps {
|
||||
shortUrlEdition: ShortUrlEdition;
|
||||
editShortUrl: (shortUrl: string, domain: OptionalString, longUrl: string) => Promise<void>;
|
||||
}
|
||||
|
||||
const EditShortUrlModal = ({ isOpen, toggle, shortUrl, shortUrlEdition, editShortUrl }) => {
|
||||
const EditShortUrlModal = ({ isOpen, toggle, shortUrl, shortUrlEdition, editShortUrl }: EditShortUrlModalProps) => {
|
||||
const { saving, error } = shortUrlEdition;
|
||||
const url = shortUrl && (shortUrl.shortUrl || '');
|
||||
const url = shortUrl?.shortUrl ?? '';
|
||||
const [ longUrl, setLongUrl ] = useState(shortUrl.longUrl);
|
||||
|
||||
const doEdit = () => editShortUrl(shortUrl.shortCode, shortUrl.domain, longUrl).then(toggle);
|
||||
const doEdit = async () => editShortUrl(shortUrl.shortCode, shortUrl.domain, longUrl).then(toggle);
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} toggle={toggle} centered>
|
||||
<ModalHeader toggle={toggle}>
|
||||
Edit long URL for <ExternalLink href={url} />
|
||||
</ModalHeader>
|
||||
<form onSubmit={(e) => e.preventDefault() || doEdit()}>
|
||||
<form onSubmit={handleEventPreventingDefault(doEdit)}>
|
||||
<ModalBody>
|
||||
<FormGroup className="mb-0">
|
||||
<Input
|
||||
|
@ -52,6 +48,4 @@ const EditShortUrlModal = ({ isOpen, toggle, shortUrl, shortUrlEdition, editShor
|
|||
);
|
||||
};
|
||||
|
||||
EditShortUrlModal.propTypes = propTypes;
|
||||
|
||||
export default EditShortUrlModal;
|
|
@ -1,6 +1,4 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import { Action, Dispatch } from 'redux';
|
||||
import { apiErrorType } from '../../utils/services/ShlinkApiClient';
|
||||
import { buildActionCreator, buildReducer } from '../../utils/helpers/redux';
|
||||
import { ProblemDetailsError, ShlinkApiClientBuilder } from '../../utils/services/types';
|
||||
import { GetState } from '../../container/types';
|
||||
|
@ -12,14 +10,6 @@ export const SHORT_URL_DELETED = 'shlink/deleteShortUrl/SHORT_URL_DELETED';
|
|||
export const RESET_DELETE_SHORT_URL = 'shlink/deleteShortUrl/RESET_DELETE_SHORT_URL';
|
||||
/* eslint-enable padding-line-between-statements */
|
||||
|
||||
/** @deprecated Use ShortUrlDeletion interface */
|
||||
export const shortUrlDeletionType = PropTypes.shape({
|
||||
shortCode: PropTypes.string.isRequired,
|
||||
loading: PropTypes.bool.isRequired,
|
||||
error: PropTypes.bool.isRequired,
|
||||
errorData: apiErrorType.isRequired,
|
||||
});
|
||||
|
||||
export interface ShortUrlDeletion {
|
||||
shortCode: string;
|
||||
loading: boolean;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import { Action, Dispatch } from 'redux';
|
||||
import { buildReducer } from '../../utils/helpers/redux';
|
||||
import { ShlinkApiClientBuilder } from '../../utils/services/types';
|
||||
|
@ -11,14 +10,6 @@ export const EDIT_SHORT_URL_ERROR = 'shlink/shortUrlEdition/EDIT_SHORT_URL_ERROR
|
|||
export const SHORT_URL_EDITED = 'shlink/shortUrlEdition/SHORT_URL_EDITED';
|
||||
/* eslint-enable padding-line-between-statements */
|
||||
|
||||
/** @deprecated Use ShortUrlEdition interface instead */
|
||||
export const ShortUrlEditionType = PropTypes.shape({
|
||||
shortCode: PropTypes.string,
|
||||
longUrl: PropTypes.string,
|
||||
saving: PropTypes.bool.isRequired,
|
||||
error: PropTypes.bool.isRequired,
|
||||
});
|
||||
|
||||
export interface ShortUrlEdition {
|
||||
shortCode: string | null;
|
||||
longUrl: string | null;
|
||||
|
|
|
@ -6,6 +6,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|||
import PropTypes from 'prop-types';
|
||||
import './EditTagModal.scss';
|
||||
import { useToggle } from '../../utils/helpers/hooks';
|
||||
import { handleEventPreventingDefault } from '../../utils/utils';
|
||||
|
||||
const propTypes = {
|
||||
tag: PropTypes.string,
|
||||
|
@ -24,14 +25,10 @@ const EditTagModal = ({ getColorForKey }) => {
|
|||
const [ newTagName, setNewTagName ] = useState(tag);
|
||||
const [ color, setColor ] = useState(getColorForKey(tag));
|
||||
const [ showColorPicker, toggleColorPicker ] = useToggle();
|
||||
const saveTag = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
editTag(tag, newTagName, color)
|
||||
.then(() => tagEdited(tag, newTagName, color))
|
||||
.then(toggle)
|
||||
.catch(() => {});
|
||||
};
|
||||
const saveTag = handleEventPreventingDefault(() => editTag(tag, newTagName, color)
|
||||
.then(() => tagEdited(tag, newTagName, color))
|
||||
.then(toggle)
|
||||
.catch(() => {}));
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} toggle={toggle} centered>
|
||||
|
|
|
@ -1,15 +1,5 @@
|
|||
import qs from 'qs';
|
||||
import { isEmpty, isNil, reject } from 'ramda';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export const apiErrorType = PropTypes.shape({
|
||||
type: PropTypes.string,
|
||||
detail: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
status: PropTypes.number,
|
||||
error: PropTypes.string, // Deprecated
|
||||
message: PropTypes.string, // Deprecated
|
||||
});
|
||||
|
||||
const buildShlinkBaseUrl = (url, apiVersion) => url ? `${url}/rest/v${apiVersion}` : '';
|
||||
const rejectNilProps = reject(isNil);
|
||||
|
|
|
@ -22,4 +22,5 @@ export interface ProblemDetailsError {
|
|||
status: number;
|
||||
error?: string; // Deprecated
|
||||
message?: string; // Deprecated
|
||||
[extraProps: string]: any;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { isEmpty, isNil, range } from 'ramda';
|
||||
import { isEmpty, isNil, pipe, range } from 'ramda';
|
||||
import { SyntheticEvent } from 'react';
|
||||
|
||||
export type OrderDir = 'ASC' | 'DESC' | undefined;
|
||||
|
||||
|
@ -22,6 +23,11 @@ export type Empty = null | undefined | '' | never[];
|
|||
|
||||
export const hasValue = <T>(value: T | Empty): value is T => !isNil(value) && !isEmpty(value);
|
||||
|
||||
export const handleEventPreventingDefault = <T>(handler: () => T) => pipe(
|
||||
(e: SyntheticEvent) => e.preventDefault(),
|
||||
handler,
|
||||
);
|
||||
|
||||
export type Nullable<T> = {
|
||||
[P in keyof T]: T[P] | null
|
||||
};
|
||||
|
|
|
@ -1,35 +1,37 @@
|
|||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
import { identity } from 'ramda';
|
||||
import { Mock } from 'ts-mockery';
|
||||
import DeleteShortUrlModal from '../../../src/short-urls/helpers/DeleteShortUrlModal';
|
||||
import { ShortUrl } from '../../../src/short-urls/data';
|
||||
import { ShortUrlDeletion } from '../../../src/short-urls/reducers/shortUrlDeletion';
|
||||
import { ProblemDetailsError } from '../../../src/utils/services/types';
|
||||
|
||||
describe('<DeleteShortUrlModal />', () => {
|
||||
let wrapper;
|
||||
const shortUrl = {
|
||||
let wrapper: ShallowWrapper;
|
||||
const shortUrl = Mock.of<ShortUrl>({
|
||||
tags: [],
|
||||
shortCode: 'abc123',
|
||||
originalUrl: 'https://long-domain.com/foo/bar',
|
||||
};
|
||||
const deleteShortUrl = jest.fn(() => Promise.resolve());
|
||||
const createWrapper = (shortUrlDeletion) => {
|
||||
longUrl: 'https://long-domain.com/foo/bar',
|
||||
});
|
||||
const deleteShortUrl = jest.fn(async () => Promise.resolve());
|
||||
const createWrapper = (shortUrlDeletion: Partial<ShortUrlDeletion>) => {
|
||||
wrapper = shallow(
|
||||
<DeleteShortUrlModal
|
||||
isOpen
|
||||
shortUrl={shortUrl}
|
||||
shortUrlDeletion={shortUrlDeletion}
|
||||
toggle={identity}
|
||||
shortUrlDeletion={Mock.of<ShortUrlDeletion>(shortUrlDeletion)}
|
||||
toggle={() => {}}
|
||||
deleteShortUrl={deleteShortUrl}
|
||||
resetDeleteShortUrl={identity}
|
||||
resetDeleteShortUrl={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
return wrapper;
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
wrapper && wrapper.unmount();
|
||||
deleteShortUrl.mockClear();
|
||||
});
|
||||
afterEach(() => wrapper?.unmount());
|
||||
afterEach(jest.clearAllMocks);
|
||||
|
||||
it.each([
|
||||
[
|
||||
|
@ -48,12 +50,12 @@ describe('<DeleteShortUrlModal />', () => {
|
|||
{ type: 'INVALID_SHORTCODE_DELETION', threshold: 8 },
|
||||
'This short URL has received more than 8 visits, and therefore, it cannot be deleted.',
|
||||
],
|
||||
])('shows threshold error message when threshold error occurs', (errorData, expectedMessage) => {
|
||||
])('shows threshold error message when threshold error occurs', (errorData: Partial<ProblemDetailsError>, expectedMessage) => {
|
||||
const wrapper = createWrapper({
|
||||
loading: false,
|
||||
error: true,
|
||||
shortCode: 'abc123',
|
||||
errorData,
|
||||
errorData: Mock.of<ProblemDetailsError>(errorData),
|
||||
});
|
||||
const warning = wrapper.find('.bg-warning');
|
||||
|
||||
|
@ -66,7 +68,7 @@ describe('<DeleteShortUrlModal />', () => {
|
|||
loading: false,
|
||||
error: true,
|
||||
shortCode: 'abc123',
|
||||
errorData: { error: 'OTHER_ERROR' },
|
||||
errorData: Mock.of<ProblemDetailsError>({ error: 'OTHER_ERROR' }),
|
||||
});
|
||||
const error = wrapper.find('.bg-danger');
|
||||
|
||||
|
@ -79,7 +81,6 @@ describe('<DeleteShortUrlModal />', () => {
|
|||
loading: true,
|
||||
error: false,
|
||||
shortCode: 'abc123',
|
||||
errorData: {},
|
||||
});
|
||||
const submit = wrapper.find('.btn-danger');
|
||||
|
||||
|
@ -94,7 +95,6 @@ describe('<DeleteShortUrlModal />', () => {
|
|||
loading: false,
|
||||
error: false,
|
||||
shortCode,
|
||||
errorData: {},
|
||||
});
|
||||
const input = wrapper.find('.form-control');
|
||||
|
||||
|
@ -113,7 +113,6 @@ describe('<DeleteShortUrlModal />', () => {
|
|||
loading: false,
|
||||
error: false,
|
||||
shortCode,
|
||||
errorData: {},
|
||||
});
|
||||
const input = wrapper.find('.form-control');
|
||||
|
|
@ -1,18 +1,21 @@
|
|||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { FormGroup, Modal, ModalHeader } from 'reactstrap';
|
||||
import { shallow, ShallowWrapper } from 'enzyme';
|
||||
import { FormGroup } from 'reactstrap';
|
||||
import { Mock } from 'ts-mockery';
|
||||
import EditShortUrlModal from '../../../src/short-urls/helpers/EditShortUrlModal';
|
||||
import { ShortUrl } from '../../../src/short-urls/data';
|
||||
import { ShortUrlEdition } from '../../../src/short-urls/reducers/shortUrlEdition';
|
||||
|
||||
describe('<EditShortUrlModal />', () => {
|
||||
let wrapper;
|
||||
const editShortUrl = jest.fn(() => Promise.resolve());
|
||||
let wrapper: ShallowWrapper;
|
||||
const editShortUrl = jest.fn(async () => Promise.resolve());
|
||||
const toggle = jest.fn();
|
||||
const createWrapper = (shortUrl, shortUrlEdition) => {
|
||||
const createWrapper = (shortUrl: Partial<ShortUrl>, shortUrlEdition: Partial<ShortUrlEdition>) => {
|
||||
wrapper = shallow(
|
||||
<EditShortUrlModal
|
||||
isOpen={true}
|
||||
shortUrl={shortUrl}
|
||||
shortUrlEdition={shortUrlEdition}
|
||||
shortUrl={Mock.of<ShortUrl>(shortUrl)}
|
||||
shortUrlEdition={Mock.of<ShortUrlEdition>(shortUrlEdition)}
|
||||
toggle={toggle}
|
||||
editShortUrl={editShortUrl}
|
||||
/>,
|
||||
|
@ -21,10 +24,8 @@ describe('<EditShortUrlModal />', () => {
|
|||
return wrapper;
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
wrapper && wrapper.unmount();
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
afterEach(() => wrapper?.unmount());
|
||||
afterEach(jest.clearAllMocks);
|
||||
|
||||
it.each([
|
||||
[ false, 0 ],
|
||||
|
@ -66,13 +67,13 @@ describe('<EditShortUrlModal />', () => {
|
|||
|
||||
it.each([
|
||||
[ '[color="link"]', 'onClick' ],
|
||||
[ Modal, 'toggle' ],
|
||||
[ ModalHeader, 'toggle' ],
|
||||
[ 'Modal', 'toggle' ],
|
||||
[ 'ModalHeader', 'toggle' ],
|
||||
])('toggles modal with different mechanisms', (componentToFind, propToCall) => {
|
||||
const wrapper = createWrapper({}, { saving: false, error: false });
|
||||
const component = wrapper.find(componentToFind);
|
||||
|
||||
component.prop(propToCall)();
|
||||
(component.prop(propToCall) as Function)(); // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
|
||||
expect(toggle).toHaveBeenCalled();
|
||||
});
|
Loading…
Reference in a new issue