mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Ensured all data can be set when editing a short URL
This commit is contained in:
parent
a019bd30df
commit
eea76d88c3
15 changed files with 73 additions and 64 deletions
|
@ -12,7 +12,7 @@ import {
|
|||
ShlinkTagsResponse,
|
||||
ShlinkVisits,
|
||||
ShlinkVisitsParams,
|
||||
ShlinkShortUrlMeta,
|
||||
ShlinkShortUrlData,
|
||||
ShlinkDomain,
|
||||
ShlinkDomainsResponse,
|
||||
ShlinkVisitsOverview,
|
||||
|
@ -67,7 +67,7 @@ export default class ShlinkApiClient {
|
|||
this.performRequest(`/short-urls/${shortCode}`, 'DELETE', { domain })
|
||||
.then(() => {});
|
||||
|
||||
/* @deprecated. If using Shlink 2.6.0 or greater, use updateShortUrlMeta instead */
|
||||
/* @deprecated. If using Shlink 2.6.0 or greater, use updateShortUrl instead */
|
||||
public readonly updateShortUrlTags = async (
|
||||
shortCode: string,
|
||||
domain: OptionalString,
|
||||
|
@ -76,12 +76,12 @@ export default class ShlinkApiClient {
|
|||
this.performRequest<{ tags: string[] }>(`/short-urls/${shortCode}/tags`, 'PUT', { domain }, { tags })
|
||||
.then(({ data }) => data.tags);
|
||||
|
||||
public readonly updateShortUrlMeta = async (
|
||||
public readonly updateShortUrl = async (
|
||||
shortCode: string,
|
||||
domain: OptionalString,
|
||||
meta: ShlinkShortUrlMeta,
|
||||
data: ShlinkShortUrlData,
|
||||
): Promise<ShortUrl> =>
|
||||
this.performRequest<ShortUrl>(`/short-urls/${shortCode}`, 'PATCH', { domain }, meta)
|
||||
this.performRequest<ShortUrl>(`/short-urls/${shortCode}`, 'PATCH', { domain }, data)
|
||||
.then(({ data }) => data);
|
||||
|
||||
public readonly listTags = async (): Promise<ShlinkTags> =>
|
||||
|
|
|
@ -57,8 +57,10 @@ export interface ShlinkVisitsParams {
|
|||
endDate?: string;
|
||||
}
|
||||
|
||||
export interface ShlinkShortUrlMeta extends ShortUrlMeta {
|
||||
export interface ShlinkShortUrlData extends ShortUrlMeta {
|
||||
longUrl?: string;
|
||||
title?: string;
|
||||
validateUrl?: boolean;
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
|
|
|
@ -9,13 +9,14 @@ import { Result } from '../utils/Result';
|
|||
import { ShlinkApiError } from '../api/ShlinkApiError';
|
||||
import { ShortUrlFormProps } from './ShortUrlForm';
|
||||
import { ShortUrlDetail } from './reducers/shortUrlDetail';
|
||||
import { ShortUrl, ShortUrlData } from './data';
|
||||
import { EditShortUrlData, ShortUrl, ShortUrlData } from './data';
|
||||
|
||||
interface EditShortUrlConnectProps extends RouteComponentProps<{ shortCode: string }> {
|
||||
settings: Settings;
|
||||
selectedServer: SelectedServer;
|
||||
shortUrlDetail: ShortUrlDetail;
|
||||
getShortUrlDetail: (shortCode: string, domain: OptionalString) => void;
|
||||
editShortUrl: (shortUrl: string, domain: OptionalString, data: EditShortUrlData) => Promise<void>;
|
||||
}
|
||||
|
||||
const getInitialState = (shortUrl?: ShortUrl, settings?: ShortUrlCreationSettings): ShortUrlData => {
|
||||
|
@ -44,6 +45,7 @@ export const EditShortUrl = (ShortUrlForm: FC<ShortUrlFormProps>) => ({
|
|||
selectedServer,
|
||||
shortUrlDetail,
|
||||
getShortUrlDetail,
|
||||
editShortUrl,
|
||||
}: EditShortUrlConnectProps) => {
|
||||
const { loading, error, errorData, shortUrl } = shortUrlDetail;
|
||||
const { domain } = parseQuery<{ domain?: string }>(search);
|
||||
|
@ -70,7 +72,7 @@ export const EditShortUrl = (ShortUrlForm: FC<ShortUrlFormProps>) => ({
|
|||
saving={false}
|
||||
selectedServer={selectedServer}
|
||||
mode="edit"
|
||||
onSave={async (shortUrlData) => Promise.resolve(console.log(shortUrlData))}
|
||||
onSave={async (shortUrlData) => shortUrl && editShortUrl(shortUrl.shortCode, shortUrl.domain, shortUrlData)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@ import { FC, useEffect, useState } from 'react';
|
|||
import { InputType } from 'reactstrap/lib/Input';
|
||||
import { Button, FormGroup, Input, Row } from 'reactstrap';
|
||||
import { isEmpty, pipe, replace, trim } from 'ramda';
|
||||
import * as m from 'moment';
|
||||
import m from 'moment';
|
||||
import DateInput, { DateInputProps } from '../utils/DateInput';
|
||||
import {
|
||||
supportsListingDomains,
|
||||
|
@ -46,8 +46,9 @@ export const ShortUrlForm = (
|
|||
const reset = () => setShortUrlData(initialState);
|
||||
const submit = handleEventPreventingDefault(async () => onSave({
|
||||
...shortUrlData,
|
||||
validSince: formatIsoDate(shortUrlData.validSince) ?? undefined,
|
||||
validUntil: formatIsoDate(shortUrlData.validUntil) ?? undefined,
|
||||
validSince: formatIsoDate(shortUrlData.validSince) ?? null,
|
||||
validUntil: formatIsoDate(shortUrlData.validUntil) ?? null,
|
||||
maxVisits: !hasValue(shortUrlData.maxVisits) ? null : Number(shortUrlData.maxVisits),
|
||||
}).then(() => !isEdit && reset()).catch(() => {}));
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -69,7 +70,7 @@ export const ShortUrlForm = (
|
|||
const renderDateInput = (id: DateFields, placeholder: string, props: Partial<DateInputProps> = {}) => (
|
||||
<div className="form-group">
|
||||
<DateInput
|
||||
selected={shortUrlData[id] as m.Moment | null}
|
||||
selected={shortUrlData[id] ? m(shortUrlData[id]) : null}
|
||||
placeholderText={placeholder}
|
||||
isClearable
|
||||
onChange={(date) => setShortUrlData({ ...shortUrlData, [id]: date })}
|
||||
|
@ -148,8 +149,8 @@ export const ShortUrlForm = (
|
|||
<div className="col-sm-6 mb-3">
|
||||
<SimpleCard title="Limit access to the short URL">
|
||||
{renderOptionalInput('maxVisits', 'Maximum number of visits allowed', 'number', { min: 1 })}
|
||||
{renderDateInput('validSince', 'Enabled since...', { maxDate: shortUrlData.validUntil as m.Moment | undefined })}
|
||||
{renderDateInput('validUntil', 'Enabled until...', { minDate: shortUrlData.validSince as m.Moment | undefined })}
|
||||
{renderDateInput('validSince', 'Enabled since...', { maxDate: shortUrlData.validUntil ? m(shortUrlData.validUntil) : undefined })}
|
||||
{renderDateInput('validUntil', 'Enabled until...', { minDate: shortUrlData.validSince ? m(shortUrlData.validSince) : undefined })}
|
||||
</SimpleCard>
|
||||
</div>
|
||||
</Row>
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
import * as m from 'moment';
|
||||
import { Nullable, OptionalString } from '../../utils/utils';
|
||||
|
||||
export interface ShortUrlData {
|
||||
longUrl: string;
|
||||
export interface EditShortUrlData {
|
||||
longUrl?: string;
|
||||
tags?: string[];
|
||||
customSlug?: string;
|
||||
title?: string;
|
||||
validSince?: m.Moment | string | null;
|
||||
validUntil?: m.Moment | string | null;
|
||||
maxVisits?: number | null;
|
||||
validateUrl?: boolean;
|
||||
}
|
||||
|
||||
export interface ShortUrlData extends EditShortUrlData {
|
||||
longUrl: string;
|
||||
customSlug?: string;
|
||||
shortCodeLength?: number;
|
||||
domain?: string;
|
||||
validSince?: m.Moment | string;
|
||||
validUntil?: m.Moment | string;
|
||||
maxVisits?: number;
|
||||
findIfExists?: boolean;
|
||||
validateUrl?: boolean;
|
||||
}
|
||||
|
||||
export interface ShortUrl {
|
||||
|
|
|
@ -3,13 +3,13 @@ import { Modal, ModalBody, ModalFooter, ModalHeader, FormGroup, Input, Button }
|
|||
import { ExternalLink } from 'react-external-link';
|
||||
import { ShortUrlEdition } from '../reducers/shortUrlEdition';
|
||||
import { handleEventPreventingDefault, hasValue, OptionalString } from '../../utils/utils';
|
||||
import { ShortUrlModalProps } from '../data';
|
||||
import { EditShortUrlData, ShortUrlModalProps } from '../data';
|
||||
import { Result } from '../../utils/Result';
|
||||
import { ShlinkApiError } from '../../api/ShlinkApiError';
|
||||
|
||||
interface EditShortUrlModalProps extends ShortUrlModalProps {
|
||||
shortUrlEdition: ShortUrlEdition;
|
||||
editShortUrl: (shortUrl: string, domain: OptionalString, longUrl: string) => Promise<void>;
|
||||
editShortUrl: (shortUrl: string, domain: OptionalString, data: EditShortUrlData) => Promise<void>;
|
||||
}
|
||||
|
||||
const EditShortUrlModal = ({ isOpen, toggle, shortUrl, shortUrlEdition, editShortUrl }: EditShortUrlModalProps) => {
|
||||
|
@ -17,7 +17,7 @@ const EditShortUrlModal = ({ isOpen, toggle, shortUrl, shortUrlEdition, editShor
|
|||
const url = shortUrl?.shortUrl ?? '';
|
||||
const [ longUrl, setLongUrl ] = useState(shortUrl.longUrl);
|
||||
|
||||
const doEdit = async () => 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 size="lg">
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Action, Dispatch } from 'redux';
|
|||
import { buildReducer } from '../../utils/helpers/redux';
|
||||
import { GetState } from '../../container/types';
|
||||
import { OptionalString } from '../../utils/utils';
|
||||
import { ShortUrlIdentifier } from '../data';
|
||||
import { EditShortUrlData, ShortUrlIdentifier } from '../data';
|
||||
import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder';
|
||||
import { ProblemDetailsError } from '../../api/types';
|
||||
import { parseApiError } from '../../api/utils';
|
||||
|
@ -45,13 +45,16 @@ export default buildReducer<ShortUrlEdition, ShortUrlEditedAction & ShortUrlEdit
|
|||
export const editShortUrl = (buildShlinkApiClient: ShlinkApiClientBuilder) => (
|
||||
shortCode: string,
|
||||
domain: OptionalString,
|
||||
longUrl: string,
|
||||
data: EditShortUrlData,
|
||||
) => async (dispatch: Dispatch, getState: GetState) => {
|
||||
dispatch({ type: EDIT_SHORT_URL_START });
|
||||
const { updateShortUrlMeta } = buildShlinkApiClient(getState);
|
||||
|
||||
// TODO Pass tags to the updateTags function if server version is lower than 2.6
|
||||
const { updateShortUrl } = buildShlinkApiClient(getState);
|
||||
|
||||
try {
|
||||
await updateShortUrlMeta(shortCode, domain, { longUrl });
|
||||
const { longUrl } = await updateShortUrl(shortCode, domain, data as any); // FIXME Parse dates
|
||||
|
||||
dispatch<ShortUrlEditedAction>({ shortCode, longUrl, domain, type: SHORT_URL_EDITED });
|
||||
} catch (e) {
|
||||
dispatch<ShortUrlEditionFailedAction>({ type: EDIT_SHORT_URL_ERROR, errorData: parseApiError(e) });
|
||||
|
|
|
@ -50,10 +50,10 @@ export const editShortUrlMeta = (buildShlinkApiClient: ShlinkApiClientBuilder) =
|
|||
meta: ShortUrlMeta,
|
||||
) => async (dispatch: Dispatch, getState: GetState) => {
|
||||
dispatch({ type: EDIT_SHORT_URL_META_START });
|
||||
const { updateShortUrlMeta } = buildShlinkApiClient(getState);
|
||||
const { updateShortUrl } = buildShlinkApiClient(getState);
|
||||
|
||||
try {
|
||||
await updateShortUrlMeta(shortCode, domain, meta);
|
||||
await updateShortUrl(shortCode, domain, meta);
|
||||
dispatch<ShortUrlMetaEditedAction>({ shortCode, meta, domain, type: SHORT_URL_META_EDITED });
|
||||
} catch (e) {
|
||||
dispatch<ShortUrlMetaEditionFailedAction>({ type: EDIT_SHORT_URL_META_ERROR, errorData: parseApiError(e) });
|
||||
|
|
|
@ -54,12 +54,12 @@ export const editShortUrlTags = (buildShlinkApiClient: ShlinkApiClientBuilder) =
|
|||
dispatch({ type: EDIT_SHORT_URL_TAGS_START });
|
||||
const { selectedServer } = getState();
|
||||
const tagsInPatch = supportsTagsInPatch(selectedServer);
|
||||
const { updateShortUrlTags, updateShortUrlMeta } = buildShlinkApiClient(getState);
|
||||
const { updateShortUrlTags, updateShortUrl } = buildShlinkApiClient(getState);
|
||||
|
||||
try {
|
||||
const normalizedTags = await (
|
||||
tagsInPatch
|
||||
? updateShortUrlMeta(shortCode, domain, { tags }).then(prop('tags'))
|
||||
? updateShortUrl(shortCode, domain, { tags }).then(prop('tags'))
|
||||
: updateShortUrlTags(shortCode, domain, tags)
|
||||
);
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
|||
bottle.serviceFactory('EditShortUrl', EditShortUrl, 'ShortUrlForm');
|
||||
bottle.decorator(
|
||||
'EditShortUrl',
|
||||
connect([ 'shortUrlDetail', 'selectedServer', 'settings' ], [ 'getShortUrlDetail' ]),
|
||||
connect([ 'shortUrlDetail', 'selectedServer', 'settings' ], [ 'getShortUrlDetail', 'editShortUrl' ]),
|
||||
);
|
||||
|
||||
bottle.serviceFactory('DeleteShortUrlModal', () => DeleteShortUrlModal);
|
||||
|
|
|
@ -48,10 +48,7 @@ describe('ShlinkApiClient', () => {
|
|||
const axiosSpy = createAxiosMock({ data: shortUrl });
|
||||
const { createShortUrl } = new ShlinkApiClient(axiosSpy, '', '');
|
||||
|
||||
await createShortUrl(
|
||||
// @ts-expect-error in case maxVisits is null, it needs to be ignored as if it was undefined
|
||||
{ longUrl: 'bar', customSlug: undefined, maxVisits: null },
|
||||
);
|
||||
await createShortUrl({ longUrl: 'bar', customSlug: undefined, maxVisits: null });
|
||||
|
||||
expect(axiosSpy).toHaveBeenCalledWith(expect.objectContaining({ data: { longUrl: 'bar' } }));
|
||||
});
|
||||
|
@ -139,7 +136,7 @@ describe('ShlinkApiClient', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('updateShortUrlMeta', () => {
|
||||
describe('updateShortUrl', () => {
|
||||
it.each(shortCodesWithDomainCombinations)('properly updates short URL meta', async (shortCode, domain) => {
|
||||
const meta = {
|
||||
maxVisits: 50,
|
||||
|
@ -147,9 +144,9 @@ describe('ShlinkApiClient', () => {
|
|||
};
|
||||
const expectedResp = Mock.of<ShortUrl>();
|
||||
const axiosSpy = createAxiosMock({ data: expectedResp });
|
||||
const { updateShortUrlMeta } = new ShlinkApiClient(axiosSpy, '', '');
|
||||
const { updateShortUrl } = new ShlinkApiClient(axiosSpy, '', '');
|
||||
|
||||
const result = await updateShortUrlMeta(shortCode, domain, meta);
|
||||
const result = await updateShortUrl(shortCode, domain, meta);
|
||||
|
||||
expect(expectedResp).toEqual(result);
|
||||
expect(axiosSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||
|
|
|
@ -50,7 +50,7 @@ describe('<ShortUrlForm />', () => {
|
|||
domain: 'example.com',
|
||||
validSince: validSince.format(),
|
||||
validUntil: validUntil.format(),
|
||||
maxVisits: '20',
|
||||
maxVisits: 20,
|
||||
findIfExists: false,
|
||||
shortCodeLength: 15,
|
||||
validateUrl: true,
|
||||
|
|
|
@ -42,19 +42,19 @@ describe('shortUrlEditionReducer', () => {
|
|||
});
|
||||
|
||||
describe('editShortUrl', () => {
|
||||
const updateShortUrlMeta = jest.fn().mockResolvedValue({});
|
||||
const buildShlinkApiClient = jest.fn().mockReturnValue({ updateShortUrlMeta });
|
||||
const updateShortUrl = jest.fn().mockResolvedValue({ longUrl });
|
||||
const buildShlinkApiClient = jest.fn().mockReturnValue({ updateShortUrl });
|
||||
const dispatch = jest.fn();
|
||||
const getState = () => Mock.of<ShlinkState>();
|
||||
|
||||
afterEach(jest.clearAllMocks);
|
||||
|
||||
it.each([[ undefined ], [ null ], [ 'example.com' ]])('dispatches long URL on success', async (domain) => {
|
||||
await editShortUrl(buildShlinkApiClient)(shortCode, domain, longUrl)(dispatch, getState);
|
||||
await editShortUrl(buildShlinkApiClient)(shortCode, domain, { longUrl })(dispatch, getState);
|
||||
|
||||
expect(buildShlinkApiClient).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlMeta).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlMeta).toHaveBeenCalledWith(shortCode, domain, { longUrl });
|
||||
expect(updateShortUrl).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrl).toHaveBeenCalledWith(shortCode, domain, { longUrl });
|
||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_SHORT_URL_START });
|
||||
expect(dispatch).toHaveBeenNthCalledWith(2, { type: SHORT_URL_EDITED, longUrl, shortCode, domain });
|
||||
|
@ -63,17 +63,17 @@ describe('shortUrlEditionReducer', () => {
|
|||
it('dispatches error on failure', async () => {
|
||||
const error = new Error();
|
||||
|
||||
updateShortUrlMeta.mockRejectedValue(error);
|
||||
updateShortUrl.mockRejectedValue(error);
|
||||
|
||||
try {
|
||||
await editShortUrl(buildShlinkApiClient)(shortCode, undefined, longUrl)(dispatch, getState);
|
||||
await editShortUrl(buildShlinkApiClient)(shortCode, undefined, { longUrl })(dispatch, getState);
|
||||
} catch (e) {
|
||||
expect(e).toBe(error);
|
||||
}
|
||||
|
||||
expect(buildShlinkApiClient).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlMeta).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlMeta).toHaveBeenCalledWith(shortCode, undefined, { longUrl });
|
||||
expect(updateShortUrl).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrl).toHaveBeenCalledWith(shortCode, undefined, { longUrl });
|
||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_SHORT_URL_START });
|
||||
expect(dispatch).toHaveBeenNthCalledWith(2, { type: EDIT_SHORT_URL_ERROR });
|
||||
|
|
|
@ -56,8 +56,8 @@ describe('shortUrlMetaReducer', () => {
|
|||
});
|
||||
|
||||
describe('editShortUrlMeta', () => {
|
||||
const updateShortUrlMeta = jest.fn().mockResolvedValue({});
|
||||
const buildShlinkApiClient = jest.fn().mockReturnValue({ updateShortUrlMeta });
|
||||
const updateShortUrl = jest.fn().mockResolvedValue({});
|
||||
const buildShlinkApiClient = jest.fn().mockReturnValue({ updateShortUrl });
|
||||
const dispatch = jest.fn();
|
||||
const getState = () => Mock.all<ShlinkState>();
|
||||
|
||||
|
@ -67,8 +67,8 @@ describe('shortUrlMetaReducer', () => {
|
|||
await editShortUrlMeta(buildShlinkApiClient)(shortCode, domain, meta)(dispatch, getState);
|
||||
|
||||
expect(buildShlinkApiClient).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlMeta).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlMeta).toHaveBeenCalledWith(shortCode, domain, meta);
|
||||
expect(updateShortUrl).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrl).toHaveBeenCalledWith(shortCode, domain, meta);
|
||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_SHORT_URL_META_START });
|
||||
expect(dispatch).toHaveBeenNthCalledWith(2, { type: SHORT_URL_META_EDITED, meta, shortCode, domain });
|
||||
|
@ -77,7 +77,7 @@ describe('shortUrlMetaReducer', () => {
|
|||
it('dispatches error on failure', async () => {
|
||||
const error = new Error();
|
||||
|
||||
updateShortUrlMeta.mockRejectedValue(error);
|
||||
updateShortUrl.mockRejectedValue(error);
|
||||
|
||||
try {
|
||||
await editShortUrlMeta(buildShlinkApiClient)(shortCode, undefined, meta)(dispatch, getState);
|
||||
|
@ -86,8 +86,8 @@ describe('shortUrlMetaReducer', () => {
|
|||
}
|
||||
|
||||
expect(buildShlinkApiClient).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlMeta).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlMeta).toHaveBeenCalledWith(shortCode, undefined, meta);
|
||||
expect(updateShortUrl).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrl).toHaveBeenCalledWith(shortCode, undefined, meta);
|
||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_SHORT_URL_META_START });
|
||||
expect(dispatch).toHaveBeenNthCalledWith(2, { type: EDIT_SHORT_URL_META_ERROR });
|
||||
|
|
|
@ -61,8 +61,8 @@ describe('shortUrlTagsReducer', () => {
|
|||
|
||||
describe('editShortUrlTags', () => {
|
||||
const updateShortUrlTags = jest.fn();
|
||||
const updateShortUrlMeta = jest.fn();
|
||||
const buildShlinkApiClient = jest.fn().mockReturnValue({ updateShortUrlTags, updateShortUrlMeta });
|
||||
const updateShortUrl = jest.fn();
|
||||
const buildShlinkApiClient = jest.fn().mockReturnValue({ updateShortUrlTags, updateShortUrl });
|
||||
const dispatch = jest.fn();
|
||||
const buildGetState = (selectedServer?: SelectedServer) => () => Mock.of<ShlinkState>({ selectedServer });
|
||||
|
||||
|
@ -78,7 +78,7 @@ describe('shortUrlTagsReducer', () => {
|
|||
expect(buildShlinkApiClient).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlTags).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlTags).toHaveBeenCalledWith(shortCode, domain, tags);
|
||||
expect(updateShortUrlMeta).not.toHaveBeenCalled();
|
||||
expect(updateShortUrl).not.toHaveBeenCalled();
|
||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_SHORT_URL_TAGS_START });
|
||||
expect(dispatch).toHaveBeenNthCalledWith(
|
||||
|
@ -87,10 +87,10 @@ describe('shortUrlTagsReducer', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('calls updateShortUrlMeta when server is version 2.6.0 or above', async () => {
|
||||
it('calls updateShortUrl when server is version 2.6.0 or above', async () => {
|
||||
const normalizedTags = [ 'bar', 'foo' ];
|
||||
|
||||
updateShortUrlMeta.mockResolvedValue({ tags: normalizedTags });
|
||||
updateShortUrl.mockResolvedValue({ tags: normalizedTags });
|
||||
|
||||
await editShortUrlTags(buildShlinkApiClient)(shortCode, undefined, tags)(
|
||||
dispatch,
|
||||
|
@ -98,8 +98,8 @@ describe('shortUrlTagsReducer', () => {
|
|||
);
|
||||
|
||||
expect(buildShlinkApiClient).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlMeta).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrlMeta).toHaveBeenCalledWith(shortCode, undefined, { tags });
|
||||
expect(updateShortUrl).toHaveBeenCalledTimes(1);
|
||||
expect(updateShortUrl).toHaveBeenCalledWith(shortCode, undefined, { tags });
|
||||
expect(updateShortUrlTags).not.toHaveBeenCalled();
|
||||
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_SHORT_URL_TAGS_START });
|
||||
|
|
Loading…
Reference in a new issue