mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Updated editDomainRedirects action, to expect a payload DTO instead of multiple args
This commit is contained in:
parent
4fa6ae493d
commit
b6d08e2203
8 changed files with 61 additions and 36 deletions
|
@ -8,11 +8,12 @@ import { SelectedServer } from '../servers/data';
|
||||||
import { Domain } from './data';
|
import { Domain } from './data';
|
||||||
import { DomainStatusIcon } from './helpers/DomainStatusIcon';
|
import { DomainStatusIcon } from './helpers/DomainStatusIcon';
|
||||||
import { DomainDropdown } from './helpers/DomainDropdown';
|
import { DomainDropdown } from './helpers/DomainDropdown';
|
||||||
|
import { EditDomainRedirects } from './reducers/domainRedirects';
|
||||||
|
|
||||||
interface DomainRowProps {
|
interface DomainRowProps {
|
||||||
domain: Domain;
|
domain: Domain;
|
||||||
defaultRedirects?: ShlinkDomainRedirects;
|
defaultRedirects?: ShlinkDomainRedirects;
|
||||||
editDomainRedirects: (domain: string, redirects: Partial<ShlinkDomainRedirects>) => Promise<void>;
|
editDomainRedirects: (redirects: EditDomainRedirects) => Promise<void>;
|
||||||
checkDomainHealth: (domain: string) => void;
|
checkDomainHealth: (domain: string) => void;
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Result } from '../utils/Result';
|
||||||
import { ShlinkApiError } from '../api/ShlinkApiError';
|
import { ShlinkApiError } from '../api/ShlinkApiError';
|
||||||
import { SimpleCard } from '../utils/SimpleCard';
|
import { SimpleCard } from '../utils/SimpleCard';
|
||||||
import { SearchField } from '../utils/SearchField';
|
import { SearchField } from '../utils/SearchField';
|
||||||
import { ShlinkDomainRedirects } from '../api/types';
|
import { EditDomainRedirects } from './reducers/domainRedirects';
|
||||||
import { SelectedServer } from '../servers/data';
|
import { SelectedServer } from '../servers/data';
|
||||||
import { DomainsList } from './reducers/domainsList';
|
import { DomainsList } from './reducers/domainsList';
|
||||||
import { DomainRow } from './DomainRow';
|
import { DomainRow } from './DomainRow';
|
||||||
|
@ -12,7 +12,7 @@ import { DomainRow } from './DomainRow';
|
||||||
interface ManageDomainsProps {
|
interface ManageDomainsProps {
|
||||||
listDomains: Function;
|
listDomains: Function;
|
||||||
filterDomains: (searchTerm: string) => void;
|
filterDomains: (searchTerm: string) => void;
|
||||||
editDomainRedirects: (domain: string, redirects: Partial<ShlinkDomainRedirects>) => Promise<void>;
|
editDomainRedirects: (redirects: EditDomainRedirects) => Promise<void>;
|
||||||
checkDomainHealth: (domain: string) => void;
|
checkDomainHealth: (domain: string) => void;
|
||||||
domainsList: DomainsList;
|
domainsList: DomainsList;
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
|
|
|
@ -7,14 +7,14 @@ import { useToggle } from '../../utils/helpers/hooks';
|
||||||
import { DropdownBtnMenu } from '../../utils/DropdownBtnMenu';
|
import { DropdownBtnMenu } from '../../utils/DropdownBtnMenu';
|
||||||
import { EditDomainRedirectsModal } from './EditDomainRedirectsModal';
|
import { EditDomainRedirectsModal } from './EditDomainRedirectsModal';
|
||||||
import { Domain } from '../data';
|
import { Domain } from '../data';
|
||||||
import { ShlinkDomainRedirects } from '../../api/types';
|
import { EditDomainRedirects } from '../reducers/domainRedirects';
|
||||||
import { supportsDefaultDomainRedirectsEdition, supportsDomainVisits } from '../../utils/helpers/features';
|
import { supportsDefaultDomainRedirectsEdition, supportsDomainVisits } from '../../utils/helpers/features';
|
||||||
import { getServerId, SelectedServer } from '../../servers/data';
|
import { getServerId, SelectedServer } from '../../servers/data';
|
||||||
import { DEFAULT_DOMAIN } from '../../visits/reducers/domainVisits';
|
import { DEFAULT_DOMAIN } from '../../visits/reducers/domainVisits';
|
||||||
|
|
||||||
interface DomainDropdownProps {
|
interface DomainDropdownProps {
|
||||||
domain: Domain;
|
domain: Domain;
|
||||||
editDomainRedirects: (domain: string, redirects: Partial<ShlinkDomainRedirects>) => Promise<void>;
|
editDomainRedirects: (redirects: EditDomainRedirects) => Promise<void>;
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import { FC, useState } from 'react';
|
import { FC, useState } from 'react';
|
||||||
import { Button, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
import { Button, Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
||||||
import { ShlinkDomain, ShlinkDomainRedirects } from '../../api/types';
|
import { ShlinkDomain } from '../../api/types';
|
||||||
import { InputFormGroup, InputFormGroupProps } from '../../utils/forms/InputFormGroup';
|
import { InputFormGroup, InputFormGroupProps } from '../../utils/forms/InputFormGroup';
|
||||||
import { handleEventPreventingDefault, nonEmptyValueOrNull } from '../../utils/utils';
|
import { handleEventPreventingDefault, nonEmptyValueOrNull } from '../../utils/utils';
|
||||||
import { InfoTooltip } from '../../utils/InfoTooltip';
|
import { InfoTooltip } from '../../utils/InfoTooltip';
|
||||||
|
import { EditDomainRedirects } from '../reducers/domainRedirects';
|
||||||
|
|
||||||
interface EditDomainRedirectsModalProps {
|
interface EditDomainRedirectsModalProps {
|
||||||
domain: ShlinkDomain;
|
domain: ShlinkDomain;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
toggle: () => void;
|
toggle: () => void;
|
||||||
editDomainRedirects: (domain: string, redirects: Partial<ShlinkDomainRedirects>) => Promise<void>;
|
editDomainRedirects: (redirects: EditDomainRedirects) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FormGroup: FC<InputFormGroupProps & { isLast?: boolean }> = ({ isLast, ...rest }) => (
|
const FormGroup: FC<InputFormGroupProps & { isLast?: boolean }> = ({ isLast, ...rest }) => (
|
||||||
|
@ -30,10 +31,13 @@ export const EditDomainRedirectsModal: FC<EditDomainRedirectsModalProps> = (
|
||||||
const [invalidShortUrlRedirect, setInvalidShortUrlRedirect] = useState(
|
const [invalidShortUrlRedirect, setInvalidShortUrlRedirect] = useState(
|
||||||
domain.redirects?.invalidShortUrlRedirect ?? '',
|
domain.redirects?.invalidShortUrlRedirect ?? '',
|
||||||
);
|
);
|
||||||
const handleSubmit = handleEventPreventingDefault(async () => editDomainRedirects(domain.domain, {
|
const handleSubmit = handleEventPreventingDefault(async () => editDomainRedirects({
|
||||||
baseUrlRedirect: nonEmptyValueOrNull(baseUrlRedirect),
|
domain: domain.domain,
|
||||||
regular404Redirect: nonEmptyValueOrNull(regular404Redirect),
|
redirects: {
|
||||||
invalidShortUrlRedirect: nonEmptyValueOrNull(invalidShortUrlRedirect),
|
baseUrlRedirect: nonEmptyValueOrNull(baseUrlRedirect),
|
||||||
|
regular404Redirect: nonEmptyValueOrNull(regular404Redirect),
|
||||||
|
invalidShortUrlRedirect: nonEmptyValueOrNull(invalidShortUrlRedirect),
|
||||||
|
},
|
||||||
}).then(toggle));
|
}).then(toggle));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -9,15 +9,17 @@ export const EDIT_DOMAIN_REDIRECTS_START = 'shlink/domainRedirects/EDIT_DOMAIN_R
|
||||||
export const EDIT_DOMAIN_REDIRECTS_ERROR = 'shlink/domainRedirects/EDIT_DOMAIN_REDIRECTS_ERROR';
|
export const EDIT_DOMAIN_REDIRECTS_ERROR = 'shlink/domainRedirects/EDIT_DOMAIN_REDIRECTS_ERROR';
|
||||||
export const EDIT_DOMAIN_REDIRECTS = 'shlink/domainRedirects/EDIT_DOMAIN_REDIRECTS';
|
export const EDIT_DOMAIN_REDIRECTS = 'shlink/domainRedirects/EDIT_DOMAIN_REDIRECTS';
|
||||||
|
|
||||||
export interface EditDomainRedirectsAction extends Action<string> {
|
export interface EditDomainRedirects {
|
||||||
domain: string;
|
domain: string;
|
||||||
redirects: ShlinkDomainRedirects;
|
redirects: ShlinkDomainRedirects;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const editDomainRedirects = (buildShlinkApiClient: ShlinkApiClientBuilder) => (
|
export interface EditDomainRedirectsAction extends Action<string>, EditDomainRedirects {}
|
||||||
domain: string,
|
|
||||||
domainRedirects: Partial<ShlinkDomainRedirects>,
|
export const editDomainRedirects = (buildShlinkApiClient: ShlinkApiClientBuilder) => ({
|
||||||
) => async (dispatch: Dispatch, getState: GetState) => {
|
domain,
|
||||||
|
redirects: domainRedirects,
|
||||||
|
}: EditDomainRedirects) => async (dispatch: Dispatch, getState: GetState) => {
|
||||||
dispatch({ type: EDIT_DOMAIN_REDIRECTS_START });
|
dispatch({ type: EDIT_DOMAIN_REDIRECTS_START });
|
||||||
const { editDomainRedirects: shlinkEditDomainRedirects } = buildShlinkApiClient(getState);
|
const { editDomainRedirects: shlinkEditDomainRedirects } = buildShlinkApiClient(getState);
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ describe('<DomainDropdown />', () => {
|
||||||
|
|
||||||
expect(editDomainRedirects).not.toHaveBeenCalled();
|
expect(editDomainRedirects).not.toHaveBeenCalled();
|
||||||
await user.click(screen.getByText('Save'));
|
await user.click(screen.getByText('Save'));
|
||||||
expect(editDomainRedirects).toHaveBeenCalledWith(domain, expect.anything());
|
expect(editDomainRedirects).toHaveBeenCalledWith(expect.objectContaining({ domain }));
|
||||||
|
|
||||||
await waitForElementToBeRemoved(() => screen.queryByRole('dialog'));
|
await waitForElementToBeRemoved(() => screen.queryByRole('dialog'));
|
||||||
});
|
});
|
||||||
|
|
|
@ -40,37 +40,49 @@ describe('<EditDomainRedirectsModal />', () => {
|
||||||
|
|
||||||
expect(editDomainRedirects).not.toHaveBeenCalled();
|
expect(editDomainRedirects).not.toHaveBeenCalled();
|
||||||
submitForm();
|
submitForm();
|
||||||
await waitFor(() => expect(editDomainRedirects).toHaveBeenCalledWith('foo.com', {
|
await waitFor(() => expect(editDomainRedirects).toHaveBeenCalledWith({
|
||||||
baseUrlRedirect: 'baz',
|
domain: 'foo.com',
|
||||||
regular404Redirect: null,
|
redirects: {
|
||||||
invalidShortUrlRedirect: null,
|
baseUrlRedirect: 'baz',
|
||||||
|
regular404Redirect: null,
|
||||||
|
invalidShortUrlRedirect: null,
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await user.clear(screen.getByDisplayValue('baz'));
|
await user.clear(screen.getByDisplayValue('baz'));
|
||||||
await user.type(screen.getAllByPlaceholderText('No redirect')[0], 'new_base_url');
|
await user.type(screen.getAllByPlaceholderText('No redirect')[0], 'new_base_url');
|
||||||
await user.type(screen.getAllByPlaceholderText('No redirect')[2], 'new_invalid_short_url');
|
await user.type(screen.getAllByPlaceholderText('No redirect')[2], 'new_invalid_short_url');
|
||||||
submitForm();
|
submitForm();
|
||||||
await waitFor(() => expect(editDomainRedirects).toHaveBeenCalledWith('foo.com', {
|
await waitFor(() => expect(editDomainRedirects).toHaveBeenCalledWith({
|
||||||
baseUrlRedirect: 'new_base_url',
|
domain: 'foo.com',
|
||||||
regular404Redirect: null,
|
redirects: {
|
||||||
invalidShortUrlRedirect: 'new_invalid_short_url',
|
baseUrlRedirect: 'new_base_url',
|
||||||
|
regular404Redirect: null,
|
||||||
|
invalidShortUrlRedirect: 'new_invalid_short_url',
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await user.type(screen.getAllByPlaceholderText('No redirect')[1], 'new_regular_404');
|
await user.type(screen.getAllByPlaceholderText('No redirect')[1], 'new_regular_404');
|
||||||
await user.clear(screen.getByDisplayValue('new_invalid_short_url'));
|
await user.clear(screen.getByDisplayValue('new_invalid_short_url'));
|
||||||
submitForm();
|
submitForm();
|
||||||
await waitFor(() => expect(editDomainRedirects).toHaveBeenCalledWith('foo.com', {
|
await waitFor(() => expect(editDomainRedirects).toHaveBeenCalledWith({
|
||||||
baseUrlRedirect: 'new_base_url',
|
domain: 'foo.com',
|
||||||
regular404Redirect: 'new_regular_404',
|
redirects: {
|
||||||
invalidShortUrlRedirect: null,
|
baseUrlRedirect: 'new_base_url',
|
||||||
|
regular404Redirect: 'new_regular_404',
|
||||||
|
invalidShortUrlRedirect: null,
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await Promise.all(screen.getAllByPlaceholderText('No redirect').map((element) => user.clear(element)));
|
await Promise.all(screen.getAllByPlaceholderText('No redirect').map((element) => user.clear(element)));
|
||||||
submitForm();
|
submitForm();
|
||||||
await waitFor(() => expect(editDomainRedirects).toHaveBeenCalledWith('foo.com', {
|
await waitFor(() => expect(editDomainRedirects).toHaveBeenCalledWith({
|
||||||
baseUrlRedirect: null,
|
domain: 'foo.com',
|
||||||
regular404Redirect: null,
|
redirects: {
|
||||||
invalidShortUrlRedirect: null,
|
baseUrlRedirect: null,
|
||||||
|
regular404Redirect: null,
|
||||||
|
invalidShortUrlRedirect: null,
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { ShlinkApiClient } from '../../../src/api/services/ShlinkApiClient';
|
||||||
import {
|
import {
|
||||||
EDIT_DOMAIN_REDIRECTS,
|
EDIT_DOMAIN_REDIRECTS,
|
||||||
EDIT_DOMAIN_REDIRECTS_ERROR,
|
EDIT_DOMAIN_REDIRECTS_ERROR,
|
||||||
EDIT_DOMAIN_REDIRECTS_START,
|
EDIT_DOMAIN_REDIRECTS_START, EditDomainRedirects,
|
||||||
editDomainRedirects as editDomainRedirectsAction,
|
editDomainRedirects as editDomainRedirectsAction,
|
||||||
} from '../../../src/domains/reducers/domainRedirects';
|
} from '../../../src/domains/reducers/domainRedirects';
|
||||||
import { ShlinkDomainRedirects } from '../../../src/api/types';
|
import { ShlinkDomainRedirects } from '../../../src/api/types';
|
||||||
|
@ -22,7 +22,10 @@ describe('domainRedirectsReducer', () => {
|
||||||
it('dispatches error when loading domains fails', async () => {
|
it('dispatches error when loading domains fails', async () => {
|
||||||
editDomainRedirects.mockRejectedValue(new Error('error'));
|
editDomainRedirects.mockRejectedValue(new Error('error'));
|
||||||
|
|
||||||
await editDomainRedirectsAction(buildShlinkApiClient)(domain, {})(dispatch, getState);
|
await editDomainRedirectsAction(buildShlinkApiClient)(Mock.of<EditDomainRedirects>({ domain }))(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
);
|
||||||
|
|
||||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_DOMAIN_REDIRECTS_START });
|
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_DOMAIN_REDIRECTS_START });
|
||||||
|
@ -33,7 +36,10 @@ describe('domainRedirectsReducer', () => {
|
||||||
it('dispatches domain and redirects once loaded', async () => {
|
it('dispatches domain and redirects once loaded', async () => {
|
||||||
editDomainRedirects.mockResolvedValue(redirects);
|
editDomainRedirects.mockResolvedValue(redirects);
|
||||||
|
|
||||||
await editDomainRedirectsAction(buildShlinkApiClient)(domain, {})(dispatch, getState);
|
await editDomainRedirectsAction(buildShlinkApiClient)(Mock.of<EditDomainRedirects>({ domain }))(
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
);
|
||||||
|
|
||||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_DOMAIN_REDIRECTS_START });
|
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_DOMAIN_REDIRECTS_START });
|
||||||
|
|
Loading…
Reference in a new issue