diff --git a/src/short-urls/helpers/CreateShortUrlResult.tsx b/src/short-urls/helpers/CreateShortUrlResult.tsx index d37b511c..220eb42f 100644 --- a/src/short-urls/helpers/CreateShortUrlResult.tsx +++ b/src/short-urls/helpers/CreateShortUrlResult.tsx @@ -20,7 +20,7 @@ export const CreateShortUrlResult = (useTimeoutToggle: TimeoutToggle) => ( { creation, resetCreateShortUrl, canBeClosed = false }: CreateShortUrlResultProps, ) => { const [showCopyTooltip, setShowCopyTooltip] = useTimeoutToggle(); - const { error, errorData, result } = creation; + const { error, saved } = creation; useEffect(() => { resetCreateShortUrl(); @@ -30,16 +30,16 @@ export const CreateShortUrlResult = (useTimeoutToggle: TimeoutToggle) => ( return ( {canBeClosed && } - + ); } - if (!result) { + if (!saved) { return null; } - const { shortUrl } = result; + const { shortUrl } = creation.result; return ( diff --git a/src/short-urls/reducers/shortUrlCreation.ts b/src/short-urls/reducers/shortUrlCreation.ts index 5124701d..f30cdcd3 100644 --- a/src/short-urls/reducers/shortUrlCreation.ts +++ b/src/short-urls/reducers/shortUrlCreation.ts @@ -7,13 +7,25 @@ import { ProblemDetailsError } from '../../api/types/errors'; export const CREATE_SHORT_URL = 'shlink/createShortUrl/CREATE_SHORT_URL'; -export interface ShortUrlCreation { - result?: ShortUrl; - saving: boolean; - saved: boolean; - error: boolean; +export type ShortUrlCreation = { + saving: false; + saved: false; + error: false; +} | { + saving: true; + saved: false; + error: false; +} | { + saving: false; + saved: false; + error: true; errorData?: ProblemDetailsError; -} +} | { + result: ShortUrl; + saving: false; + saved: true; + error: false; +}; export type CreateShortUrlAction = PayloadAction; @@ -31,15 +43,15 @@ export const shortUrlCreationReducerCreator = (buildShlinkApiClient: ShlinkApiCl const { reducer, actions } = createSlice({ name: 'shortUrlCreationReducer', - initialState, + initialState: initialState as ShortUrlCreation, // Without this casting it infers type ShortUrlCreationWaiting reducers: { resetCreateShortUrl: () => initialState, }, extraReducers: (builder) => { - builder.addCase(createShortUrl.pending, (state) => ({ ...state, saving: true, saved: false, error: false })); + builder.addCase(createShortUrl.pending, () => ({ saving: true, saved: false, error: false })); builder.addCase( createShortUrl.rejected, - (state, { error }) => ({ ...state, saving: false, saved: false, error: true, errorData: parseApiError(error) }), + (_, { error }) => ({ saving: false, saved: false, error: true, errorData: parseApiError(error) }), ); builder.addCase( createShortUrl.fulfilled, diff --git a/test/short-urls/helpers/CreateShortUrlResult.test.tsx b/test/short-urls/helpers/CreateShortUrlResult.test.tsx index 55b46e13..d9cbba96 100644 --- a/test/short-urls/helpers/CreateShortUrlResult.test.tsx +++ b/test/short-urls/helpers/CreateShortUrlResult.test.tsx @@ -4,34 +4,39 @@ import { CreateShortUrlResult as createResult } from '../../../src/short-urls/he import { ShortUrl } from '../../../src/short-urls/data'; import { TimeoutToggle } from '../../../src/utils/helpers/hooks'; import { renderWithEvents } from '../../__helpers__/setUpTest'; +import { ShortUrlCreation } from '../../../src/short-urls/reducers/shortUrlCreation'; describe('', () => { const copyToClipboard = jest.fn(); const useTimeoutToggle = jest.fn(() => [false, copyToClipboard]) as TimeoutToggle; const CreateShortUrlResult = createResult(useTimeoutToggle); - const setUp = (result?: ShortUrl, error = false) => renderWithEvents( - {}} creation={{ result, saving: false, error, saved: false }} />, + const setUp = (creation: ShortUrlCreation) => renderWithEvents( + {}} creation={creation} />, ); afterEach(jest.clearAllMocks); it('renders an error when error is true', () => { - setUp(Mock.all(), true); + setUp({ error: true, saved: false, saving: false }); expect(screen.getByText('An error occurred while creating the URL :(')).toBeInTheDocument(); }); - it('renders nothing when no result is provided', () => { - const { container } = setUp(); + it.each([[true], [false]])('renders nothing when not saved yet', (saving) => { + const { container } = setUp({ error: false, saved: false, saving }); expect(container.firstChild).toBeNull(); }); it('renders a result message when result is provided', () => { - setUp(Mock.of({ shortUrl: 'https://doma.in/abc123' })); + setUp( + { result: Mock.of({ shortUrl: 'https://doma.in/abc123' }), saving: false, saved: true, error: false }, + ); expect(screen.getByText(/The short URL is/)).toHaveTextContent('Great! The short URL is https://doma.in/abc123'); }); it('Invokes tooltip timeout when copy to clipboard button is clicked', async () => { - const { user } = setUp(Mock.of({ shortUrl: 'https://doma.in/abc123' })); + const { user } = setUp( + { result: Mock.of({ shortUrl: 'https://doma.in/abc123' }), saving: false, saved: true, error: false }, + ); expect(copyToClipboard).not.toHaveBeenCalled(); await user.click(screen.getByRole('button'));