diff --git a/src/utils/helpers/redux.ts b/src/utils/helpers/redux.ts index 8ae09e05..238d0fa2 100644 --- a/src/utils/helpers/redux.ts +++ b/src/utils/helpers/redux.ts @@ -17,9 +17,6 @@ export const buildReducer = (map: ActionHandlerMap(type: T) => (): Action => ({ type }); - export const createAsyncThunk = ( typePrefix: string, payloadCreator: AsyncThunkPayloadCreator, diff --git a/src/visits/TagVisits.tsx b/src/visits/TagVisits.tsx index a7ce5ba1..ff70f1bf 100644 --- a/src/visits/TagVisits.tsx +++ b/src/visits/TagVisits.tsx @@ -5,7 +5,7 @@ import { ShlinkVisitsParams } from '../api/types'; import { Topics } from '../mercure/helpers/Topics'; import { useGoBack } from '../utils/helpers/hooks'; import { ReportExporter } from '../common/services/ReportExporter'; -import { TagVisits as TagVisitsState } from './reducers/tagVisits'; +import { LoadTagVisits, TagVisits as TagVisitsState } from './reducers/tagVisits'; import { TagVisitsHeader } from './TagVisitsHeader'; import { VisitsStats } from './VisitsStats'; import { NormalizedVisit } from './types'; @@ -13,7 +13,7 @@ import { CommonVisitsProps } from './types/CommonVisitsProps'; import { toApiParams } from './types/helpers'; export interface TagVisitsProps extends CommonVisitsProps { - getTagVisits: (tag: string, query?: ShlinkVisitsParams, doIntervalFallback?: boolean) => void; + getTagVisits: (params: LoadTagVisits) => void; tagVisits: TagVisitsState; cancelGetTagVisits: () => void; } @@ -28,7 +28,7 @@ export const TagVisits = (colorGenerator: ColorGenerator, { exportVisits }: Repo const goBack = useGoBack(); const { tag = '' } = useParams(); const loadVisits = (params: ShlinkVisitsParams, doIntervalFallback?: boolean) => - getTagVisits(tag, toApiParams(params), doIntervalFallback); + getTagVisits({ tag, query: toApiParams(params), doIntervalFallback }); const exportCsv = (visits: NormalizedVisit[]) => exportVisits(`tag_${tag}_visits.csv`, visits); return ( diff --git a/src/visits/reducers/common.ts b/src/visits/reducers/common.ts index 52544b69..1f888413 100644 --- a/src/visits/reducers/common.ts +++ b/src/visits/reducers/common.ts @@ -1,11 +1,11 @@ import { flatten, prop, range, splitEvery } from 'ramda'; -import { Action, Dispatch } from 'redux'; +import { Dispatch } from '@reduxjs/toolkit'; import { ShlinkPaginator, ShlinkVisits, ShlinkVisitsParams } from '../../api/types'; import { Visit } from '../types'; import { parseApiError } from '../../api/utils'; import { ApiErrorAction } from '../../api/types/actions'; import { dateToMatchingInterval } from '../../utils/dates/types'; -import { VisitsLoadProgressChangedAction } from './types'; +import { VisitsLoaded, VisitsLoadProgressChangedAction } from './types'; const ITEMS_PER_PAGE = 5000; const PARALLEL_REQUESTS_COUNT = 4; @@ -17,10 +17,10 @@ const calcProgress = (total: number, current: number): number => (current * 100) type VisitsLoader = (page: number, itemsPerPage: number) => Promise; type LastVisitLoader = () => Promise; -export const getVisitsWithLoader = async & { visits: Visit[] }>( +export const getVisitsWithLoader = async ( visitsLoader: VisitsLoader, lastVisitLoader: LastVisitLoader, - extraFinishActionData: Partial, + extraFulfilledPayload: Partial, actionsPrefix: string, dispatch: Dispatch, shouldCancel: () => boolean, @@ -74,7 +74,7 @@ export const getVisitsWithLoader = async & { visits: V dispatch( !visits.length && lastVisit ? { type: `${actionsPrefix}/fallbackToInterval`, payload: dateToMatchingInterval(lastVisit.date) } - : { ...extraFinishActionData, visits, type: `${actionsPrefix}/fulfilled` }, + : { type: `${actionsPrefix}/fulfilled`, payload: { ...extraFulfilledPayload, visits } }, ); } catch (e: any) { dispatch({ type: `${actionsPrefix}/rejected`, errorData: parseApiError(e) }); @@ -89,5 +89,5 @@ export const lastVisitLoaderForLoader = ( return async () => Promise.resolve(undefined); } - return async () => loader({ page: 1, itemsPerPage: 1 }).then((result) => result.data[0]); + return async () => loader({ page: 1, itemsPerPage: 1 }).then(({ data }) => data[0]); }; diff --git a/src/visits/reducers/domainVisits.ts b/src/visits/reducers/domainVisits.ts index 42e1f371..1fd46a0e 100644 --- a/src/visits/reducers/domainVisits.ts +++ b/src/visits/reducers/domainVisits.ts @@ -1,16 +1,21 @@ import { createAction } from '@reduxjs/toolkit'; -import { Action, Dispatch } from 'redux'; -import { Visit } from '../types'; +import { Dispatch } from 'redux'; import { buildReducer } from '../../utils/helpers/redux'; import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; import { GetState } from '../../container/types'; -import { ShlinkVisitsParams } from '../../api/types'; import { ApiErrorAction } from '../../api/types/actions'; import { isBetween } from '../../utils/helpers/date'; import { getVisitsWithLoader, lastVisitLoaderForLoader } from './common'; import { createNewVisits, CreateVisitsAction } from './visitCreation'; import { domainMatches } from '../../short-urls/helpers'; -import { LoadVisits, VisitsFallbackIntervalAction, VisitsInfo, VisitsLoadProgressChangedAction } from './types'; +import { + LoadVisits, + VisitsFallbackIntervalAction, + VisitsInfo, + VisitsLoaded, + VisitsLoadedAction, + VisitsLoadProgressChangedAction, +} from './types'; const REDUCER_PREFIX = 'shlink/domainVisits'; export const GET_DOMAIN_VISITS_START = `${REDUCER_PREFIX}/getDomainVisits/pending`; @@ -23,19 +28,15 @@ export const GET_DOMAIN_VISITS_FALLBACK_TO_INTERVAL = `${REDUCER_PREFIX}/getDoma export const DEFAULT_DOMAIN = 'DEFAULT'; -export interface DomainVisits extends VisitsInfo { +interface WithDomain { domain: string; } -export interface LoadDomainVisits extends LoadVisits { - domain: string; -} +export interface DomainVisits extends VisitsInfo, WithDomain {} -export interface DomainVisitsAction extends Action { - visits: Visit[]; - domain: string; - query?: ShlinkVisitsParams; -} +export interface LoadDomainVisits extends LoadVisits, WithDomain {} + +type DomainVisitsAction = VisitsLoadedAction; type DomainVisitsCombinedAction = DomainVisitsAction & VisitsLoadProgressChangedAction @@ -56,8 +57,8 @@ const initialState: DomainVisits = { export default buildReducer({ [`${REDUCER_PREFIX}/getDomainVisits/pending`]: () => ({ ...initialState, loading: true }), [`${REDUCER_PREFIX}/getDomainVisits/rejected`]: (_, { errorData }) => ({ ...initialState, error: true, errorData }), - [`${REDUCER_PREFIX}/getDomainVisits/fulfilled`]: (state, { visits, domain, query }) => ( - { ...state, visits, domain, query, loading: false, loadingLarge: false, error: false } + [`${REDUCER_PREFIX}/getDomainVisits/fulfilled`]: (state, { payload }: DomainVisitsAction) => ( + { ...state, ...payload, loading: false, loadingLarge: false, error: false } ), [`${REDUCER_PREFIX}/getDomainVisits/large`]: (state) => ({ ...state, loadingLarge: true }), [`${REDUCER_PREFIX}/getDomainVisits/cancel`]: (state) => ({ ...state, cancelLoad: true }), @@ -87,7 +88,7 @@ export const getDomainVisits = (buildShlinkApiClient: ShlinkApiClientBuilder) => ); const lastVisitLoader = lastVisitLoaderForLoader(doIntervalFallback, async (params) => getVisits(domain, params)); const shouldCancel = () => getState().domainVisits.cancelLoad; - const extraFinishActionData: Partial = { domain, query }; + const extraFinishActionData: Partial> = { domain, query }; const prefix = `${REDUCER_PREFIX}/getDomainVisits`; return getVisitsWithLoader(visitsLoader, lastVisitLoader, extraFinishActionData, prefix, dispatch, shouldCancel); diff --git a/src/visits/reducers/nonOrphanVisits.ts b/src/visits/reducers/nonOrphanVisits.ts index 8db3e519..632b78e9 100644 --- a/src/visits/reducers/nonOrphanVisits.ts +++ b/src/visits/reducers/nonOrphanVisits.ts @@ -1,15 +1,20 @@ import { createAction } from '@reduxjs/toolkit'; -import { Action, Dispatch } from 'redux'; -import { Visit } from '../types'; +import { Dispatch } from 'redux'; import { buildReducer } from '../../utils/helpers/redux'; import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; import { GetState } from '../../container/types'; -import { ShlinkVisitsParams } from '../../api/types'; import { ApiErrorAction } from '../../api/types/actions'; import { isBetween } from '../../utils/helpers/date'; import { getVisitsWithLoader, lastVisitLoaderForLoader } from './common'; import { createNewVisits, CreateVisitsAction } from './visitCreation'; -import { LoadVisits, VisitsFallbackIntervalAction, VisitsInfo, VisitsLoadProgressChangedAction } from './types'; +import { + LoadVisits, + VisitsFallbackIntervalAction, + VisitsInfo, + VisitsLoaded, + VisitsLoadedAction, + VisitsLoadProgressChangedAction, +} from './types'; const REDUCER_PREFIX = 'shlink/orphanVisits'; export const GET_NON_ORPHAN_VISITS_START = `${REDUCER_PREFIX}/getNonOrphanVisits/pending`; @@ -20,12 +25,7 @@ export const GET_NON_ORPHAN_VISITS_CANCEL = `${REDUCER_PREFIX}/getNonOrphanVisit export const GET_NON_ORPHAN_VISITS_PROGRESS_CHANGED = `${REDUCER_PREFIX}/getNonOrphanVisits/progressChanged`; export const GET_NON_ORPHAN_VISITS_FALLBACK_TO_INTERVAL = `${REDUCER_PREFIX}/getNonOrphanVisits/fallbackToInterval`; -export interface NonOrphanVisitsAction extends Action { - visits: Visit[]; - query?: ShlinkVisitsParams; -} - -type NonOrphanVisitsCombinedAction = NonOrphanVisitsAction +type NonOrphanVisitsCombinedAction = VisitsLoadedAction & VisitsLoadProgressChangedAction & VisitsFallbackIntervalAction & CreateVisitsAction @@ -45,8 +45,8 @@ export default buildReducer({ [`${REDUCER_PREFIX}/getNonOrphanVisits/rejected`]: (_, { errorData }) => ( { ...initialState, error: true, errorData } ), - [`${REDUCER_PREFIX}/getNonOrphanVisits/fulfilled`]: (state, { visits, query }) => ( - { ...state, visits, query, loading: false, loadingLarge: false, error: false } + [`${REDUCER_PREFIX}/getNonOrphanVisits/fulfilled`]: (state, { payload }: VisitsLoadedAction) => ( + { ...state, ...payload, loading: false, loadingLarge: false, error: false } ), [`${REDUCER_PREFIX}/getNonOrphanVisits/large`]: (state) => ({ ...state, loadingLarge: true }), [`${REDUCER_PREFIX}/getNonOrphanVisits/cancel`]: (state) => ({ ...state, cancelLoad: true }), @@ -73,7 +73,7 @@ export const getNonOrphanVisits = (buildShlinkApiClient: ShlinkApiClientBuilder) shlinkGetNonOrphanVisits({ ...query, page, itemsPerPage }); const lastVisitLoader = lastVisitLoaderForLoader(doIntervalFallback, shlinkGetNonOrphanVisits); const shouldCancel = () => getState().orphanVisits.cancelLoad; - const extraFinishActionData: Partial = { query }; + const extraFinishActionData: Partial = { query }; const prefix = `${REDUCER_PREFIX}/getNonOrphanVisits`; return getVisitsWithLoader(visitsLoader, lastVisitLoader, extraFinishActionData, prefix, dispatch, shouldCancel); diff --git a/src/visits/reducers/orphanVisits.ts b/src/visits/reducers/orphanVisits.ts index 206f7d79..102f9c0c 100644 --- a/src/visits/reducers/orphanVisits.ts +++ b/src/visits/reducers/orphanVisits.ts @@ -1,16 +1,22 @@ import { createAction } from '@reduxjs/toolkit'; -import { Action, Dispatch } from 'redux'; -import { OrphanVisit, OrphanVisitType, Visit } from '../types'; +import { Dispatch } from 'redux'; +import { OrphanVisit, OrphanVisitType } from '../types'; import { buildReducer } from '../../utils/helpers/redux'; import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; import { GetState } from '../../container/types'; -import { ShlinkVisitsParams } from '../../api/types'; import { isOrphanVisit } from '../types/helpers'; import { ApiErrorAction } from '../../api/types/actions'; import { isBetween } from '../../utils/helpers/date'; import { getVisitsWithLoader, lastVisitLoaderForLoader } from './common'; import { createNewVisits, CreateVisitsAction } from './visitCreation'; -import { LoadVisits, VisitsFallbackIntervalAction, VisitsInfo, VisitsLoadProgressChangedAction } from './types'; +import { + LoadVisits, + VisitsFallbackIntervalAction, + VisitsInfo, + VisitsLoaded, + VisitsLoadedAction, + VisitsLoadProgressChangedAction, +} from './types'; const REDUCER_PREFIX = 'shlink/orphanVisits'; export const GET_ORPHAN_VISITS_START = `${REDUCER_PREFIX}/getOrphanVisits/pending`; @@ -21,16 +27,11 @@ export const GET_ORPHAN_VISITS_CANCEL = `${REDUCER_PREFIX}/getOrphanVisits/cance export const GET_ORPHAN_VISITS_PROGRESS_CHANGED = `${REDUCER_PREFIX}/getOrphanVisits/progressChanged`; export const GET_ORPHAN_VISITS_FALLBACK_TO_INTERVAL = `${REDUCER_PREFIX}/getOrphanVisits/fallbackToInterval`; -export interface OrphanVisitsAction extends Action { - visits: Visit[]; - query?: ShlinkVisitsParams; -} - export interface LoadOrphanVisits extends LoadVisits { orphanVisitsType?: OrphanVisitType; } -type OrphanVisitsCombinedAction = OrphanVisitsAction +type OrphanVisitsCombinedAction = VisitsLoadedAction & VisitsLoadProgressChangedAction & VisitsFallbackIntervalAction & CreateVisitsAction @@ -48,8 +49,8 @@ const initialState: VisitsInfo = { export default buildReducer({ [`${REDUCER_PREFIX}/getOrphanVisits/pending`]: () => ({ ...initialState, loading: true }), [`${REDUCER_PREFIX}/getOrphanVisits/rejected`]: (_, { errorData }) => ({ ...initialState, error: true, errorData }), - [`${REDUCER_PREFIX}/getOrphanVisits/fulfilled`]: (state, { visits, query }) => ( - { ...state, visits, query, loading: false, loadingLarge: false, error: false } + [`${REDUCER_PREFIX}/getOrphanVisits/fulfilled`]: (state, { payload }: VisitsLoadedAction) => ( + { ...state, ...payload, loading: false, loadingLarge: false, error: false } ), [`${REDUCER_PREFIX}/getOrphanVisits/large`]: (state) => ({ ...state, loadingLarge: true }), [`${REDUCER_PREFIX}/getOrphanVisits/cancel`]: (state) => ({ ...state, cancelLoad: true }), @@ -83,7 +84,7 @@ export const getOrphanVisits = (buildShlinkApiClient: ShlinkApiClientBuilder) => }); const lastVisitLoader = lastVisitLoaderForLoader(doIntervalFallback, getVisits); const shouldCancel = () => getState().orphanVisits.cancelLoad; - const extraFinishActionData: Partial = { query }; + const extraFinishActionData: Partial = { query }; const prefix = `${REDUCER_PREFIX}/getOrphanVisits`; return getVisitsWithLoader(visitsLoader, lastVisitLoader, extraFinishActionData, prefix, dispatch, shouldCancel); diff --git a/src/visits/reducers/shortUrlVisits.ts b/src/visits/reducers/shortUrlVisits.ts index 9c2a9e9c..fd720a88 100644 --- a/src/visits/reducers/shortUrlVisits.ts +++ b/src/visits/reducers/shortUrlVisits.ts @@ -1,17 +1,22 @@ import { createAction } from '@reduxjs/toolkit'; -import { Action, Dispatch } from 'redux'; +import { Dispatch } from 'redux'; import { shortUrlMatches } from '../../short-urls/helpers'; -import { Visit } from '../types'; import { ShortUrlIdentifier } from '../../short-urls/data'; import { buildReducer } from '../../utils/helpers/redux'; import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; import { GetState } from '../../container/types'; -import { ShlinkVisitsParams } from '../../api/types'; import { ApiErrorAction } from '../../api/types/actions'; import { isBetween } from '../../utils/helpers/date'; import { getVisitsWithLoader, lastVisitLoaderForLoader } from './common'; import { createNewVisits, CreateVisitsAction } from './visitCreation'; -import { LoadVisits, VisitsFallbackIntervalAction, VisitsInfo, VisitsLoadProgressChangedAction } from './types'; +import { + LoadVisits, + VisitsFallbackIntervalAction, + VisitsInfo, + VisitsLoaded, + VisitsLoadedAction, + VisitsLoadProgressChangedAction, +} from './types'; const REDUCER_PREFIX = 'shlink/shortUrlVisits'; export const GET_SHORT_URL_VISITS_START = `${REDUCER_PREFIX}/getShortUrlVisits/pending`; @@ -24,10 +29,7 @@ export const GET_SHORT_URL_VISITS_FALLBACK_TO_INTERVAL = `${REDUCER_PREFIX}/getS export interface ShortUrlVisits extends VisitsInfo, ShortUrlIdentifier {} -interface ShortUrlVisitsAction extends Action, ShortUrlIdentifier { - visits: Visit[]; - query?: ShlinkVisitsParams; -} +type ShortUrlVisitsAction = VisitsLoadedAction; export interface LoadShortUrlVisits extends LoadVisits { shortCode: string; @@ -53,12 +55,9 @@ const initialState: ShortUrlVisits = { export default buildReducer({ [`${REDUCER_PREFIX}/getShortUrlVisits/pending`]: () => ({ ...initialState, loading: true }), [`${REDUCER_PREFIX}/getShortUrlVisits/rejected`]: (_, { errorData }) => ({ ...initialState, error: true, errorData }), - [`${REDUCER_PREFIX}/getShortUrlVisits/fulfilled`]: (state, { visits, query, shortCode, domain }) => ({ + [`${REDUCER_PREFIX}/getShortUrlVisits/fulfilled`]: (state, { payload }: ShortUrlVisitsAction) => ({ ...state, - visits, - shortCode, - domain, - query, + ...payload, loading: false, loadingLarge: false, error: false, @@ -96,7 +95,7 @@ export const getShortUrlVisits = (buildShlinkApiClient: ShlinkApiClientBuilder) async (params) => shlinkGetShortUrlVisits(shortCode, { ...params, domain: query.domain }), ); const shouldCancel = () => getState().shortUrlVisits.cancelLoad; - const extraFinishActionData: Partial = { shortCode, query, domain: query.domain }; + const extraFinishActionData: Partial> = { shortCode, query, domain: query.domain }; const prefix = `${REDUCER_PREFIX}/getShortUrlVisits`; return getVisitsWithLoader(visitsLoader, lastVisitLoader, extraFinishActionData, prefix, dispatch, shouldCancel); diff --git a/src/visits/reducers/tagVisits.ts b/src/visits/reducers/tagVisits.ts index 0b173613..ff7d2bb7 100644 --- a/src/visits/reducers/tagVisits.ts +++ b/src/visits/reducers/tagVisits.ts @@ -1,15 +1,20 @@ import { createAction } from '@reduxjs/toolkit'; -import { Action, Dispatch } from 'redux'; -import { Visit } from '../types'; +import { Dispatch } from 'redux'; import { buildReducer } from '../../utils/helpers/redux'; import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; import { GetState } from '../../container/types'; -import { ShlinkVisitsParams } from '../../api/types'; import { ApiErrorAction } from '../../api/types/actions'; import { isBetween } from '../../utils/helpers/date'; import { getVisitsWithLoader, lastVisitLoaderForLoader } from './common'; import { createNewVisits, CreateVisitsAction } from './visitCreation'; -import { VisitsFallbackIntervalAction, VisitsInfo, VisitsLoadProgressChangedAction } from './types'; +import { + LoadVisits, + VisitsFallbackIntervalAction, + VisitsInfo, + VisitsLoaded, + VisitsLoadedAction, + VisitsLoadProgressChangedAction, +} from './types'; const REDUCER_PREFIX = 'shlink/tagVisits'; export const GET_TAG_VISITS_START = `${REDUCER_PREFIX}/getTagVisits/pending`; @@ -24,12 +29,12 @@ export interface TagVisits extends VisitsInfo { tag: string; } -export interface TagVisitsAction extends Action { - visits: Visit[]; +export interface LoadTagVisits extends LoadVisits { tag: string; - query?: ShlinkVisitsParams; } +export type TagVisitsAction = VisitsLoadedAction<{ tag: string }>; + type TagsVisitsCombinedAction = TagVisitsAction & VisitsLoadProgressChangedAction & VisitsFallbackIntervalAction @@ -49,8 +54,8 @@ const initialState: TagVisits = { export default buildReducer({ [`${REDUCER_PREFIX}/getTagVisits/pending`]: () => ({ ...initialState, loading: true }), [`${REDUCER_PREFIX}/getTagVisits/rejected`]: (_, { errorData }) => ({ ...initialState, error: true, errorData }), - [`${REDUCER_PREFIX}/getTagVisits/fulfilled`]: (state, { visits, tag, query }) => ( - { ...state, visits, tag, query, loading: false, loadingLarge: false, error: false } + [`${REDUCER_PREFIX}/getTagVisits/fulfilled`]: (state, { payload }: TagVisitsAction) => ( + { ...state, ...payload, loading: false, loadingLarge: false, error: false } ), [`${REDUCER_PREFIX}/getTagVisits/large`]: (state) => ({ ...state, loadingLarge: true }), [`${REDUCER_PREFIX}/getTagVisits/cancel`]: (state) => ({ ...state, cancelLoad: true }), @@ -70,9 +75,7 @@ export default buildReducer({ }, initialState); export const getTagVisits = (buildShlinkApiClient: ShlinkApiClientBuilder) => ( - tag: string, - query: ShlinkVisitsParams = {}, - doIntervalFallback = false, + { tag, query = {}, doIntervalFallback = false }: LoadTagVisits, ) => async (dispatch: Dispatch, getState: GetState) => { const { getTagVisits: getVisits } = buildShlinkApiClient(getState); const visitsLoader = async (page: number, itemsPerPage: number) => getVisits( @@ -81,7 +84,7 @@ export const getTagVisits = (buildShlinkApiClient: ShlinkApiClientBuilder) => ( ); const lastVisitLoader = lastVisitLoaderForLoader(doIntervalFallback, async (params) => getVisits(tag, params)); const shouldCancel = () => getState().tagVisits.cancelLoad; - const extraFinishActionData: Partial = { tag, query }; + const extraFinishActionData: Partial> = { tag, query }; const prefix = `${REDUCER_PREFIX}/getTagVisits`; return getVisitsWithLoader(visitsLoader, lastVisitLoader, extraFinishActionData, prefix, dispatch, shouldCancel); diff --git a/src/visits/reducers/types/index.ts b/src/visits/reducers/types/index.ts index a14920c0..692b4591 100644 --- a/src/visits/reducers/types/index.ts +++ b/src/visits/reducers/types/index.ts @@ -21,6 +21,13 @@ export interface LoadVisits { doIntervalFallback?: boolean; } +export type VisitsLoaded = T & { + visits: Visit[]; + query?: ShlinkVisitsParams; +}; + +export type VisitsLoadedAction = PayloadAction>; + export type VisitsLoadProgressChangedAction = PayloadAction; export type VisitsFallbackIntervalAction = PayloadAction; diff --git a/test/utils/helpers/redux.test.ts b/test/utils/helpers/redux.test.ts index 69c0bc82..472afa7b 100644 --- a/test/utils/helpers/redux.test.ts +++ b/test/utils/helpers/redux.test.ts @@ -1,22 +1,9 @@ import { Action } from 'redux'; -import { buildActionCreator, buildReducer } from '../../../src/utils/helpers/redux'; +import { buildReducer } from '../../../src/utils/helpers/redux'; describe('redux', () => { beforeEach(jest.clearAllMocks); - describe('buildActionCreator', () => { - it.each([ - ['foo', { type: 'foo' }], - ['bar', { type: 'bar' }], - ['something', { type: 'something' }], - ])('returns an action creator', (type, expected) => { - const actionCreator = buildActionCreator(type); - - expect(actionCreator).toBeInstanceOf(Function); - expect(actionCreator()).toEqual(expected); - }); - }); - describe('buildReducer', () => { const fooActionHandler = jest.fn(() => 'foo result'); const barActionHandler = jest.fn(() => 'bar result'); diff --git a/test/visits/reducers/domainVisits.test.ts b/test/visits/reducers/domainVisits.test.ts index 8564fd76..4a8cc825 100644 --- a/test/visits/reducers/domainVisits.test.ts +++ b/test/visits/reducers/domainVisits.test.ts @@ -61,10 +61,10 @@ describe('domainVisitsReducer', () => { it('return visits on GET_DOMAIN_VISITS', () => { const actionVisits = [{}, {}]; - const state = reducer( - buildState({ loading: true, error: false }), - { type: GET_DOMAIN_VISITS, visits: actionVisits } as any, - ); + const state = reducer(buildState({ loading: true, error: false }), { + type: GET_DOMAIN_VISITS, + payload: { visits: actionVisits }, + } as any); const { loading, error, visits } = state; expect(loading).toEqual(false); @@ -201,7 +201,10 @@ describe('domainVisitsReducer', () => { expect(dispatchMock).toHaveBeenCalledTimes(2); expect(dispatchMock).toHaveBeenNthCalledWith(1, { type: GET_DOMAIN_VISITS_START }); - expect(dispatchMock).toHaveBeenNthCalledWith(2, { type: GET_DOMAIN_VISITS, visits, domain, query: query ?? {} }); + expect(dispatchMock).toHaveBeenNthCalledWith(2, { + type: GET_DOMAIN_VISITS, + payload: { visits, domain, query: query ?? {} }, + }); expect(shlinkApiClient.getDomainVisits).toHaveBeenCalledTimes(1); }); diff --git a/test/visits/reducers/nonOrphanVisits.test.ts b/test/visits/reducers/nonOrphanVisits.test.ts index 0afde97e..b9beb629 100644 --- a/test/visits/reducers/nonOrphanVisits.test.ts +++ b/test/visits/reducers/nonOrphanVisits.test.ts @@ -59,10 +59,10 @@ describe('nonOrphanVisitsReducer', () => { it('return visits on GET_NON_ORPHAN_VISITS', () => { const actionVisits = [{}, {}]; - const state = reducer( - buildState({ loading: true, error: false }), - { type: GET_NON_ORPHAN_VISITS, visits: actionVisits } as any, - ); + const state = reducer(buildState({ loading: true, error: false }), { + type: GET_NON_ORPHAN_VISITS, + payload: { visits: actionVisits }, + } as any); const { loading, error, visits } = state; expect(loading).toEqual(false); @@ -173,7 +173,10 @@ describe('nonOrphanVisitsReducer', () => { expect(dispatchMock).toHaveBeenCalledTimes(2); expect(dispatchMock).toHaveBeenNthCalledWith(1, { type: GET_NON_ORPHAN_VISITS_START }); - expect(dispatchMock).toHaveBeenNthCalledWith(2, { type: GET_NON_ORPHAN_VISITS, visits, query: query ?? {} }); + expect(dispatchMock).toHaveBeenNthCalledWith(2, { + type: GET_NON_ORPHAN_VISITS, + payload: { visits, query: query ?? {} }, + }); expect(ShlinkApiClient.getNonOrphanVisits).toHaveBeenCalledTimes(1); }); diff --git a/test/visits/reducers/orphanVisits.test.ts b/test/visits/reducers/orphanVisits.test.ts index 9ef91e74..e763d3ad 100644 --- a/test/visits/reducers/orphanVisits.test.ts +++ b/test/visits/reducers/orphanVisits.test.ts @@ -59,10 +59,10 @@ describe('orphanVisitsReducer', () => { it('return visits on GET_ORPHAN_VISITS', () => { const actionVisits = [{}, {}]; - const state = reducer( - buildState({ loading: true, error: false }), - { type: GET_ORPHAN_VISITS, visits: actionVisits } as any, - ); + const state = reducer(buildState({ loading: true, error: false }), { + type: GET_ORPHAN_VISITS, + payload: { visits: actionVisits }, + } as any); const { loading, error, visits } = state; expect(loading).toEqual(false); @@ -173,7 +173,10 @@ describe('orphanVisitsReducer', () => { expect(dispatchMock).toHaveBeenCalledTimes(2); expect(dispatchMock).toHaveBeenNthCalledWith(1, { type: GET_ORPHAN_VISITS_START }); - expect(dispatchMock).toHaveBeenNthCalledWith(2, { type: GET_ORPHAN_VISITS, visits, query: query ?? {} }); + expect(dispatchMock).toHaveBeenNthCalledWith(2, { + type: GET_ORPHAN_VISITS, + payload: { visits, query: query ?? {} }, + }); expect(ShlinkApiClient.getOrphanVisits).toHaveBeenCalledTimes(1); }); diff --git a/test/visits/reducers/shortUrlVisits.test.ts b/test/visits/reducers/shortUrlVisits.test.ts index 9f5d017b..b7afd964 100644 --- a/test/visits/reducers/shortUrlVisits.test.ts +++ b/test/visits/reducers/shortUrlVisits.test.ts @@ -59,10 +59,10 @@ describe('shortUrlVisitsReducer', () => { it('return visits on GET_SHORT_URL_VISITS', () => { const actionVisits = [{}, {}]; - const state = reducer( - buildState({ loading: true, error: false }), - { type: GET_SHORT_URL_VISITS, visits: actionVisits } as any, - ); + const state = reducer(buildState({ loading: true, error: false }), { + type: GET_SHORT_URL_VISITS, + payload: { visits: actionVisits }, + } as any); const { loading, error, visits } = state; expect(loading).toEqual(false); @@ -195,10 +195,10 @@ describe('shortUrlVisitsReducer', () => { expect(dispatchMock).toHaveBeenCalledTimes(2); expect(dispatchMock).toHaveBeenNthCalledWith(1, { type: GET_SHORT_URL_VISITS_START }); - expect(dispatchMock).toHaveBeenNthCalledWith( - 2, - { type: GET_SHORT_URL_VISITS, visits, shortCode, domain, query: query ?? {} }, - ); + expect(dispatchMock).toHaveBeenNthCalledWith(2, { + type: GET_SHORT_URL_VISITS, + payload: { visits, shortCode, domain, query: query ?? {} }, + }); expect(ShlinkApiClient.getShortUrlVisits).toHaveBeenCalledTimes(1); }); @@ -218,7 +218,9 @@ describe('shortUrlVisitsReducer', () => { expect(ShlinkApiClient.getShortUrlVisits).toHaveBeenCalledTimes(expectedRequests); expect(dispatchMock).toHaveBeenNthCalledWith(3, expect.objectContaining({ - visits: [...visitsMocks, ...visitsMocks, ...visitsMocks], + payload: expect.objectContaining({ + visits: [...visitsMocks, ...visitsMocks, ...visitsMocks], + }), })); }); diff --git a/test/visits/reducers/tagVisits.test.ts b/test/visits/reducers/tagVisits.test.ts index 7292dc28..0d91406e 100644 --- a/test/visits/reducers/tagVisits.test.ts +++ b/test/visits/reducers/tagVisits.test.ts @@ -59,10 +59,10 @@ describe('tagVisitsReducer', () => { it('return visits on GET_TAG_VISITS', () => { const actionVisits = [{}, {}]; - const state = reducer( - buildState({ loading: true, error: false }), - { type: GET_TAG_VISITS, visits: actionVisits } as any, - ); + const state = reducer(buildState({ loading: true, error: false }), { + type: GET_TAG_VISITS, + payload: { visits: actionVisits }, + } as any); const { loading, error, visits } = state; expect(loading).toEqual(false); @@ -165,7 +165,7 @@ describe('tagVisitsReducer', () => { it('dispatches start and error when promise is rejected', async () => { const shlinkApiClient = buildApiClientMock(Promise.reject(new Error())); - await getTagVisits(() => shlinkApiClient)('foo')(dispatchMock, getState); + await getTagVisits(() => shlinkApiClient)({ tag })(dispatchMock, getState); expect(dispatchMock).toHaveBeenCalledTimes(2); expect(dispatchMock).toHaveBeenNthCalledWith(1, { type: GET_TAG_VISITS_START }); @@ -187,11 +187,14 @@ describe('tagVisitsReducer', () => { }, })); - await getTagVisits(() => shlinkApiClient)(tag, query)(dispatchMock, getState); + await getTagVisits(() => shlinkApiClient)({ tag, query })(dispatchMock, getState); expect(dispatchMock).toHaveBeenCalledTimes(2); expect(dispatchMock).toHaveBeenNthCalledWith(1, { type: GET_TAG_VISITS_START }); - expect(dispatchMock).toHaveBeenNthCalledWith(2, { type: GET_TAG_VISITS, visits, tag, query: query ?? {} }); + expect(dispatchMock).toHaveBeenNthCalledWith(2, { + type: GET_TAG_VISITS, + payload: { visits, tag, query: query ?? {} }, + }); expect(shlinkApiClient.getTagVisits).toHaveBeenCalledTimes(1); }); @@ -219,7 +222,7 @@ describe('tagVisitsReducer', () => { .mockResolvedValueOnce(buildVisitsResult(lastVisits)); const ShlinkApiClient = Mock.of({ getTagVisits: getShlinkTagVisits }); - await getTagVisits(() => ShlinkApiClient)(tag, {}, true)(dispatchMock, getState); + await getTagVisits(() => ShlinkApiClient)({ tag, doIntervalFallback: true })(dispatchMock, getState); expect(dispatchMock).toHaveBeenCalledTimes(2); expect(dispatchMock).toHaveBeenNthCalledWith(1, { type: GET_TAG_VISITS_START });