mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 17:40:23 +03:00
Enhanced visits async thunk so that it wraps both standard async thunk actions and extra ones
This commit is contained in:
parent
9b19113262
commit
85452cde23
6 changed files with 58 additions and 56 deletions
|
@ -29,11 +29,11 @@ interface VisitsAsyncThunkOptions<T extends LoadVisits = LoadVisits, R extends V
|
||||||
export const createVisitsAsyncThunk = <T extends LoadVisits = LoadVisits, R extends VisitsLoaded = VisitsLoaded>(
|
export const createVisitsAsyncThunk = <T extends LoadVisits = LoadVisits, R extends VisitsLoaded = VisitsLoaded>(
|
||||||
{ typePrefix, createLoaders, getExtraFulfilledPayload, shouldCancel }: VisitsAsyncThunkOptions<T, R>,
|
{ typePrefix, createLoaders, getExtraFulfilledPayload, shouldCancel }: VisitsAsyncThunkOptions<T, R>,
|
||||||
) => {
|
) => {
|
||||||
const progressChangedAction = createAction<number>(`${typePrefix}/progressChanged`);
|
const progressChanged = createAction<number>(`${typePrefix}/progressChanged`);
|
||||||
const largeAction = createAction<void>(`${typePrefix}/large`);
|
const large = createAction<void>(`${typePrefix}/large`);
|
||||||
const fallbackToIntervalAction = createAction<DateInterval>(`${typePrefix}/fallbackToInterval`);
|
const fallbackToInterval = createAction<DateInterval>(`${typePrefix}/fallbackToInterval`);
|
||||||
|
|
||||||
const asyncThunk = createAsyncThunk(typePrefix, async (params: T, { getState, dispatch }): Promise<R> => {
|
const asyncThunk = createAsyncThunk(typePrefix, async (params: T, { getState, dispatch }): Promise<Partial<R>> => {
|
||||||
const [visitsLoader, lastVisitLoader] = createLoaders(params, getState);
|
const [visitsLoader, lastVisitLoader] = createLoaders(params, getState);
|
||||||
|
|
||||||
const loadVisitsInParallel = async (pages: number[]): Promise<Visit[]> =>
|
const loadVisitsInParallel = async (pages: number[]): Promise<Visit[]> =>
|
||||||
|
@ -46,7 +46,7 @@ export const createVisitsAsyncThunk = <T extends LoadVisits = LoadVisits, R exte
|
||||||
|
|
||||||
const data = await loadVisitsInParallel(pagesBlocks[index]);
|
const data = await loadVisitsInParallel(pagesBlocks[index]);
|
||||||
|
|
||||||
dispatch(progressChangedAction(calcProgress(pagesBlocks.length, index + PARALLEL_STARTING_PAGE)));
|
dispatch(progressChanged(calcProgress(pagesBlocks.length, index + PARALLEL_STARTING_PAGE)));
|
||||||
|
|
||||||
if (index < pagesBlocks.length - 1) {
|
if (index < pagesBlocks.length - 1) {
|
||||||
return data.concat(await loadPagesBlocks(pagesBlocks, index + 1));
|
return data.concat(await loadPagesBlocks(pagesBlocks, index + 1));
|
||||||
|
@ -68,7 +68,7 @@ export const createVisitsAsyncThunk = <T extends LoadVisits = LoadVisits, R exte
|
||||||
const pagesBlocks = splitEvery(PARALLEL_REQUESTS_COUNT, pagesRange);
|
const pagesBlocks = splitEvery(PARALLEL_REQUESTS_COUNT, pagesRange);
|
||||||
|
|
||||||
if (pagination.pagesCount - 1 > PARALLEL_REQUESTS_COUNT) {
|
if (pagination.pagesCount - 1 > PARALLEL_REQUESTS_COUNT) {
|
||||||
dispatch(largeAction());
|
dispatch(large());
|
||||||
}
|
}
|
||||||
|
|
||||||
return data.concat(await loadPagesBlocks(pagesBlocks));
|
return data.concat(await loadPagesBlocks(pagesBlocks));
|
||||||
|
@ -77,13 +77,14 @@ export const createVisitsAsyncThunk = <T extends LoadVisits = LoadVisits, R exte
|
||||||
const [visits, lastVisit] = await Promise.all([loadVisits(), lastVisitLoader()]);
|
const [visits, lastVisit] = await Promise.all([loadVisits(), lastVisitLoader()]);
|
||||||
|
|
||||||
if (!visits.length && lastVisit) {
|
if (!visits.length && lastVisit) {
|
||||||
dispatch(fallbackToIntervalAction(dateToMatchingInterval(lastVisit.date)));
|
dispatch(fallbackToInterval(dateToMatchingInterval(lastVisit.date)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return { ...getExtraFulfilledPayload(params), visits } as any; // TODO Get rid of this casting
|
return { ...getExtraFulfilledPayload(params), visits };
|
||||||
});
|
});
|
||||||
|
|
||||||
return { asyncThunk, progressChangedAction, largeAction, fallbackToIntervalAction };
|
// Enhance the async thunk with extra actions
|
||||||
|
return Object.assign(asyncThunk, { progressChanged, large, fallbackToInterval });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const lastVisitLoaderForLoader = (
|
export const lastVisitLoaderForLoader = (
|
||||||
|
@ -107,7 +108,7 @@ interface VisitsReducerOptions<State extends VisitsInfo, AT extends ReturnType<t
|
||||||
export const createVisitsReducer = <State extends VisitsInfo, AT extends ReturnType<typeof createVisitsAsyncThunk>>(
|
export const createVisitsReducer = <State extends VisitsInfo, AT extends ReturnType<typeof createVisitsAsyncThunk>>(
|
||||||
{ name, asyncThunkCreator, initialState, filterCreatedVisits }: VisitsReducerOptions<State, AT>,
|
{ name, asyncThunkCreator, initialState, filterCreatedVisits }: VisitsReducerOptions<State, AT>,
|
||||||
) => {
|
) => {
|
||||||
const { asyncThunk, largeAction, fallbackToIntervalAction, progressChangedAction } = asyncThunkCreator;
|
const { pending, rejected, fulfilled, large, progressChanged, fallbackToInterval } = asyncThunkCreator;
|
||||||
const { reducer, actions } = createSlice({
|
const { reducer, actions } = createSlice({
|
||||||
name,
|
name,
|
||||||
initialState,
|
initialState,
|
||||||
|
@ -115,17 +116,17 @@ export const createVisitsReducer = <State extends VisitsInfo, AT extends ReturnT
|
||||||
cancelGetVisits: (state) => ({ ...state, cancelLoad: true }),
|
cancelGetVisits: (state) => ({ ...state, cancelLoad: true }),
|
||||||
},
|
},
|
||||||
extraReducers: (builder) => {
|
extraReducers: (builder) => {
|
||||||
builder.addCase(asyncThunk.pending, () => ({ ...initialState, loading: true }));
|
builder.addCase(pending, () => ({ ...initialState, loading: true }));
|
||||||
builder.addCase(asyncThunk.rejected, (_, { error }) => (
|
builder.addCase(rejected, (_, { error }) => (
|
||||||
{ ...initialState, error: true, errorData: parseApiError(error) }
|
{ ...initialState, error: true, errorData: parseApiError(error) }
|
||||||
));
|
));
|
||||||
builder.addCase(asyncThunk.fulfilled, (state, { payload }) => (
|
builder.addCase(fulfilled, (state, { payload }) => (
|
||||||
{ ...state, ...payload, loading: false, loadingLarge: false, error: false }
|
{ ...state, ...payload, loading: false, loadingLarge: false, error: false }
|
||||||
));
|
));
|
||||||
|
|
||||||
builder.addCase(largeAction, (state) => ({ ...state, loadingLarge: true }));
|
builder.addCase(large, (state) => ({ ...state, loadingLarge: true }));
|
||||||
builder.addCase(progressChangedAction, (state, { payload: progress }) => ({ ...state, progress }));
|
builder.addCase(progressChanged, (state, { payload: progress }) => ({ ...state, progress }));
|
||||||
builder.addCase(fallbackToIntervalAction, (state, { payload: fallbackInterval }) => (
|
builder.addCase(fallbackToInterval, (state, { payload: fallbackInterval }) => (
|
||||||
{ ...state, fallbackInterval }
|
{ ...state, fallbackInterval }
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,8 @@ describe('domainVisitsReducer', () => {
|
||||||
const visitsMocks = rangeOf(2, () => Mock.all<Visit>());
|
const visitsMocks = rangeOf(2, () => Mock.all<Visit>());
|
||||||
const getDomainVisitsCall = jest.fn();
|
const getDomainVisitsCall = jest.fn();
|
||||||
const buildApiClientMock = () => Mock.of<ShlinkApiClient>({ getDomainVisits: getDomainVisitsCall });
|
const buildApiClientMock = () => Mock.of<ShlinkApiClient>({ getDomainVisits: getDomainVisitsCall });
|
||||||
const creator = getDomainVisitsCreator(buildApiClientMock);
|
const getDomainVisits = getDomainVisitsCreator(buildApiClientMock);
|
||||||
const { asyncThunk: getDomainVisits, progressChangedAction, largeAction, fallbackToIntervalAction } = creator;
|
const { reducer, cancelGetVisits: cancelGetDomainVisits } = domainVisitsReducerCreator(getDomainVisits);
|
||||||
const { reducer, cancelGetVisits: cancelGetDomainVisits } = domainVisitsReducerCreator(creator);
|
|
||||||
|
|
||||||
beforeEach(jest.clearAllMocks);
|
beforeEach(jest.clearAllMocks);
|
||||||
|
|
||||||
|
@ -36,7 +35,7 @@ describe('domainVisitsReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns loadingLarge on GET_DOMAIN_VISITS_LARGE', () => {
|
it('returns loadingLarge on GET_DOMAIN_VISITS_LARGE', () => {
|
||||||
const { loadingLarge } = reducer(buildState({ loadingLarge: false }), { type: largeAction.toString() });
|
const { loadingLarge } = reducer(buildState({ loadingLarge: false }), { type: getDomainVisits.large.toString() });
|
||||||
expect(loadingLarge).toEqual(true);
|
expect(loadingLarge).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -130,7 +129,7 @@ describe('domainVisitsReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns new progress on GET_DOMAIN_VISITS_PROGRESS_CHANGED', () => {
|
it('returns new progress on GET_DOMAIN_VISITS_PROGRESS_CHANGED', () => {
|
||||||
const state = reducer(undefined, { type: progressChangedAction.toString(), payload: 85 });
|
const state = reducer(undefined, { type: getDomainVisits.progressChanged.toString(), payload: 85 });
|
||||||
|
|
||||||
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
|
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
|
||||||
});
|
});
|
||||||
|
@ -139,7 +138,7 @@ describe('domainVisitsReducer', () => {
|
||||||
const fallbackInterval: DateInterval = 'last30Days';
|
const fallbackInterval: DateInterval = 'last30Days';
|
||||||
const state = reducer(
|
const state = reducer(
|
||||||
undefined,
|
undefined,
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: fallbackInterval },
|
{ type: getDomainVisits.fallbackToInterval.toString(), payload: fallbackInterval },
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
|
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
|
||||||
|
@ -198,12 +197,12 @@ describe('domainVisitsReducer', () => {
|
||||||
it.each([
|
it.each([
|
||||||
[
|
[
|
||||||
[Mock.of<Visit>({ date: formatISO(subDays(now, 20)) })],
|
[Mock.of<Visit>({ date: formatISO(subDays(now, 20)) })],
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: 'last30Days' },
|
{ type: getDomainVisits.fallbackToInterval.toString(), payload: 'last30Days' },
|
||||||
3,
|
3,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[Mock.of<Visit>({ date: formatISO(subDays(now, 100)) })],
|
[Mock.of<Visit>({ date: formatISO(subDays(now, 100)) })],
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: 'last180Days' },
|
{ type: getDomainVisits.fallbackToInterval.toString(), payload: 'last180Days' },
|
||||||
3,
|
3,
|
||||||
],
|
],
|
||||||
[[], expect.objectContaining({ type: getDomainVisits.fulfilled.toString() }), 2],
|
[[], expect.objectContaining({ type: getDomainVisits.fulfilled.toString() }), 2],
|
||||||
|
|
|
@ -19,9 +19,8 @@ describe('nonOrphanVisitsReducer', () => {
|
||||||
const visitsMocks = rangeOf(2, () => Mock.all<Visit>());
|
const visitsMocks = rangeOf(2, () => Mock.all<Visit>());
|
||||||
const getNonOrphanVisitsCall = jest.fn();
|
const getNonOrphanVisitsCall = jest.fn();
|
||||||
const buildShlinkApiClient = () => Mock.of<ShlinkApiClient>({ getNonOrphanVisits: getNonOrphanVisitsCall });
|
const buildShlinkApiClient = () => Mock.of<ShlinkApiClient>({ getNonOrphanVisits: getNonOrphanVisitsCall });
|
||||||
const creator = getNonOrphanVisitsCreator(buildShlinkApiClient);
|
const getNonOrphanVisits = getNonOrphanVisitsCreator(buildShlinkApiClient);
|
||||||
const { asyncThunk: getNonOrphanVisits, progressChangedAction, largeAction, fallbackToIntervalAction } = creator;
|
const { reducer, cancelGetVisits: cancelGetNonOrphanVisits } = nonOrphanVisitsReducerCreator(getNonOrphanVisits);
|
||||||
const { reducer, cancelGetVisits: cancelGetNonOrphanVisits } = nonOrphanVisitsReducerCreator(creator);
|
|
||||||
|
|
||||||
beforeEach(jest.clearAllMocks);
|
beforeEach(jest.clearAllMocks);
|
||||||
|
|
||||||
|
@ -34,7 +33,10 @@ describe('nonOrphanVisitsReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns loadingLarge on GET_NON_ORPHAN_VISITS_LARGE', () => {
|
it('returns loadingLarge on GET_NON_ORPHAN_VISITS_LARGE', () => {
|
||||||
const { loadingLarge } = reducer(buildState({ loadingLarge: false }), { type: largeAction.toString() });
|
const { loadingLarge } = reducer(
|
||||||
|
buildState({ loadingLarge: false }),
|
||||||
|
{ type: getNonOrphanVisits.large.toString() },
|
||||||
|
);
|
||||||
expect(loadingLarge).toEqual(true);
|
expect(loadingLarge).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -110,7 +112,7 @@ describe('nonOrphanVisitsReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns new progress on GET_NON_ORPHAN_VISITS_PROGRESS_CHANGED', () => {
|
it('returns new progress on GET_NON_ORPHAN_VISITS_PROGRESS_CHANGED', () => {
|
||||||
const state = reducer(undefined, { type: progressChangedAction.toString(), payload: 85 });
|
const state = reducer(undefined, { type: getNonOrphanVisits.progressChanged.toString(), payload: 85 });
|
||||||
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
|
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -118,7 +120,7 @@ describe('nonOrphanVisitsReducer', () => {
|
||||||
const fallbackInterval: DateInterval = 'last30Days';
|
const fallbackInterval: DateInterval = 'last30Days';
|
||||||
const state = reducer(
|
const state = reducer(
|
||||||
undefined,
|
undefined,
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: fallbackInterval },
|
{ type: getNonOrphanVisits.fallbackToInterval.toString(), payload: fallbackInterval },
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
|
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
|
||||||
|
@ -178,12 +180,12 @@ describe('nonOrphanVisitsReducer', () => {
|
||||||
it.each([
|
it.each([
|
||||||
[
|
[
|
||||||
[Mock.of<Visit>({ date: formatISO(subDays(now, 5)) })],
|
[Mock.of<Visit>({ date: formatISO(subDays(now, 5)) })],
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: 'last7Days' },
|
{ type: getNonOrphanVisits.fallbackToInterval.toString(), payload: 'last7Days' },
|
||||||
3,
|
3,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[Mock.of<Visit>({ date: formatISO(subDays(now, 200)) })],
|
[Mock.of<Visit>({ date: formatISO(subDays(now, 200)) })],
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: 'last365Days' },
|
{ type: getNonOrphanVisits.fallbackToInterval.toString(), payload: 'last365Days' },
|
||||||
3,
|
3,
|
||||||
],
|
],
|
||||||
[[], expect.objectContaining({ type: getNonOrphanVisits.fulfilled.toString() }), 2],
|
[[], expect.objectContaining({ type: getNonOrphanVisits.fulfilled.toString() }), 2],
|
||||||
|
|
|
@ -19,9 +19,8 @@ describe('orphanVisitsReducer', () => {
|
||||||
const visitsMocks = rangeOf(2, () => Mock.all<Visit>());
|
const visitsMocks = rangeOf(2, () => Mock.all<Visit>());
|
||||||
const getOrphanVisitsCall = jest.fn();
|
const getOrphanVisitsCall = jest.fn();
|
||||||
const buildShlinkApiClientMock = () => Mock.of<ShlinkApiClient>({ getOrphanVisits: getOrphanVisitsCall });
|
const buildShlinkApiClientMock = () => Mock.of<ShlinkApiClient>({ getOrphanVisits: getOrphanVisitsCall });
|
||||||
const creator = getOrphanVisitsCreator(buildShlinkApiClientMock);
|
const getOrphanVisits = getOrphanVisitsCreator(buildShlinkApiClientMock);
|
||||||
const { asyncThunk: getOrphanVisits, largeAction, progressChangedAction, fallbackToIntervalAction } = creator;
|
const { reducer, cancelGetVisits: cancelGetOrphanVisits } = orphanVisitsReducerCreator(getOrphanVisits);
|
||||||
const { reducer, cancelGetVisits: cancelGetOrphanVisits } = orphanVisitsReducerCreator(creator);
|
|
||||||
|
|
||||||
beforeEach(jest.clearAllMocks);
|
beforeEach(jest.clearAllMocks);
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ describe('orphanVisitsReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns loadingLarge on GET_ORPHAN_VISITS_LARGE', () => {
|
it('returns loadingLarge on GET_ORPHAN_VISITS_LARGE', () => {
|
||||||
const { loadingLarge } = reducer(buildState({ loadingLarge: false }), { type: largeAction.toString() });
|
const { loadingLarge } = reducer(buildState({ loadingLarge: false }), { type: getOrphanVisits.large.toString() });
|
||||||
expect(loadingLarge).toEqual(true);
|
expect(loadingLarge).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -110,7 +109,7 @@ describe('orphanVisitsReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns new progress on GET_ORPHAN_VISITS_PROGRESS_CHANGED', () => {
|
it('returns new progress on GET_ORPHAN_VISITS_PROGRESS_CHANGED', () => {
|
||||||
const state = reducer(undefined, { type: progressChangedAction.toString(), payload: 85 });
|
const state = reducer(undefined, { type: getOrphanVisits.progressChanged.toString(), payload: 85 });
|
||||||
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
|
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -118,7 +117,7 @@ describe('orphanVisitsReducer', () => {
|
||||||
const fallbackInterval: DateInterval = 'last30Days';
|
const fallbackInterval: DateInterval = 'last30Days';
|
||||||
const state = reducer(
|
const state = reducer(
|
||||||
undefined,
|
undefined,
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: fallbackInterval },
|
{ type: getOrphanVisits.fallbackToInterval.toString(), payload: fallbackInterval },
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
|
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
|
||||||
|
@ -176,12 +175,12 @@ describe('orphanVisitsReducer', () => {
|
||||||
it.each([
|
it.each([
|
||||||
[
|
[
|
||||||
[Mock.of<Visit>({ date: formatISO(subDays(now, 5)) })],
|
[Mock.of<Visit>({ date: formatISO(subDays(now, 5)) })],
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: 'last7Days' },
|
{ type: getOrphanVisits.fallbackToInterval.toString(), payload: 'last7Days' },
|
||||||
3,
|
3,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[Mock.of<Visit>({ date: formatISO(subDays(now, 200)) })],
|
[Mock.of<Visit>({ date: formatISO(subDays(now, 200)) })],
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: 'last365Days' },
|
{ type: getOrphanVisits.fallbackToInterval.toString(), payload: 'last365Days' },
|
||||||
3,
|
3,
|
||||||
],
|
],
|
||||||
[[], expect.objectContaining({ type: getOrphanVisits.fulfilled.toString() }), 2],
|
[[], expect.objectContaining({ type: getOrphanVisits.fulfilled.toString() }), 2],
|
||||||
|
|
|
@ -19,9 +19,8 @@ describe('shortUrlVisitsReducer', () => {
|
||||||
const visitsMocks = rangeOf(2, () => Mock.all<Visit>());
|
const visitsMocks = rangeOf(2, () => Mock.all<Visit>());
|
||||||
const getShortUrlVisitsCall = jest.fn();
|
const getShortUrlVisitsCall = jest.fn();
|
||||||
const buildApiClientMock = () => Mock.of<ShlinkApiClient>({ getShortUrlVisits: getShortUrlVisitsCall });
|
const buildApiClientMock = () => Mock.of<ShlinkApiClient>({ getShortUrlVisits: getShortUrlVisitsCall });
|
||||||
const creator = getShortUrlVisitsCreator(buildApiClientMock);
|
const getShortUrlVisits = getShortUrlVisitsCreator(buildApiClientMock);
|
||||||
const { asyncThunk: getShortUrlVisits, largeAction, progressChangedAction, fallbackToIntervalAction } = creator;
|
const { reducer, cancelGetVisits: cancelGetShortUrlVisits } = shortUrlVisitsReducerCreator(getShortUrlVisits);
|
||||||
const { reducer, cancelGetVisits: cancelGetShortUrlVisits } = shortUrlVisitsReducerCreator(creator);
|
|
||||||
|
|
||||||
beforeEach(jest.clearAllMocks);
|
beforeEach(jest.clearAllMocks);
|
||||||
|
|
||||||
|
@ -34,7 +33,10 @@ describe('shortUrlVisitsReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns loadingLarge on GET_SHORT_URL_VISITS_LARGE', () => {
|
it('returns loadingLarge on GET_SHORT_URL_VISITS_LARGE', () => {
|
||||||
const { loadingLarge } = reducer(buildState({ loadingLarge: false }), { type: largeAction.toString() });
|
const { loadingLarge } = reducer(
|
||||||
|
buildState({ loadingLarge: false }),
|
||||||
|
{ type: getShortUrlVisits.large.toString() },
|
||||||
|
);
|
||||||
expect(loadingLarge).toEqual(true);
|
expect(loadingLarge).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -130,7 +132,7 @@ describe('shortUrlVisitsReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns new progress on GET_SHORT_URL_VISITS_PROGRESS_CHANGED', () => {
|
it('returns new progress on GET_SHORT_URL_VISITS_PROGRESS_CHANGED', () => {
|
||||||
const state = reducer(undefined, { type: progressChangedAction.toString(), payload: 85 });
|
const state = reducer(undefined, { type: getShortUrlVisits.progressChanged.toString(), payload: 85 });
|
||||||
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
|
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -138,7 +140,7 @@ describe('shortUrlVisitsReducer', () => {
|
||||||
const fallbackInterval: DateInterval = 'last30Days';
|
const fallbackInterval: DateInterval = 'last30Days';
|
||||||
const state = reducer(
|
const state = reducer(
|
||||||
undefined,
|
undefined,
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: fallbackInterval },
|
{ type: getShortUrlVisits.fallbackToInterval.toString(), payload: fallbackInterval },
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
|
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
|
||||||
|
@ -220,12 +222,12 @@ describe('shortUrlVisitsReducer', () => {
|
||||||
it.each([
|
it.each([
|
||||||
[
|
[
|
||||||
[Mock.of<Visit>({ date: formatISO(subDays(now, 5)) })],
|
[Mock.of<Visit>({ date: formatISO(subDays(now, 5)) })],
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: 'last7Days' },
|
{ type: getShortUrlVisits.fallbackToInterval.toString(), payload: 'last7Days' },
|
||||||
3,
|
3,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[Mock.of<Visit>({ date: formatISO(subDays(now, 200)) })],
|
[Mock.of<Visit>({ date: formatISO(subDays(now, 200)) })],
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: 'last365Days' },
|
{ type: getShortUrlVisits.fallbackToInterval.toString(), payload: 'last365Days' },
|
||||||
3,
|
3,
|
||||||
],
|
],
|
||||||
[[], expect.objectContaining({ type: getShortUrlVisits.fulfilled.toString() }), 2],
|
[[], expect.objectContaining({ type: getShortUrlVisits.fulfilled.toString() }), 2],
|
||||||
|
|
|
@ -19,9 +19,8 @@ describe('tagVisitsReducer', () => {
|
||||||
const visitsMocks = rangeOf(2, () => Mock.all<Visit>());
|
const visitsMocks = rangeOf(2, () => Mock.all<Visit>());
|
||||||
const getTagVisitsCall = jest.fn();
|
const getTagVisitsCall = jest.fn();
|
||||||
const buildShlinkApiClientMock = () => Mock.of<ShlinkApiClient>({ getTagVisits: getTagVisitsCall });
|
const buildShlinkApiClientMock = () => Mock.of<ShlinkApiClient>({ getTagVisits: getTagVisitsCall });
|
||||||
const creator = getTagVisitsCreator(buildShlinkApiClientMock);
|
const getTagVisits = getTagVisitsCreator(buildShlinkApiClientMock);
|
||||||
const { asyncThunk: getTagVisits, fallbackToIntervalAction, largeAction, progressChangedAction } = creator;
|
const { reducer, cancelGetVisits: cancelGetTagVisits } = tagVisitsReducerCreator(getTagVisits);
|
||||||
const { reducer, cancelGetVisits: cancelGetTagVisits } = tagVisitsReducerCreator(creator);
|
|
||||||
|
|
||||||
beforeEach(jest.clearAllMocks);
|
beforeEach(jest.clearAllMocks);
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ describe('tagVisitsReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns loadingLarge on GET_TAG_VISITS_LARGE', () => {
|
it('returns loadingLarge on GET_TAG_VISITS_LARGE', () => {
|
||||||
const { loadingLarge } = reducer(buildState({ loadingLarge: false }), { type: largeAction.toString() });
|
const { loadingLarge } = reducer(buildState({ loadingLarge: false }), { type: getTagVisits.large.toString() });
|
||||||
expect(loadingLarge).toEqual(true);
|
expect(loadingLarge).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -130,13 +129,13 @@ describe('tagVisitsReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns new progress on GET_TAG_VISITS_PROGRESS_CHANGED', () => {
|
it('returns new progress on GET_TAG_VISITS_PROGRESS_CHANGED', () => {
|
||||||
const state = reducer(undefined, { type: progressChangedAction.toString(), payload: 85 });
|
const state = reducer(undefined, { type: getTagVisits.progressChanged.toString(), payload: 85 });
|
||||||
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
|
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns fallbackInterval on GET_TAG_VISITS_FALLBACK_TO_INTERVAL', () => {
|
it('returns fallbackInterval on GET_TAG_VISITS_FALLBACK_TO_INTERVAL', () => {
|
||||||
const fallbackInterval: DateInterval = 'last30Days';
|
const fallbackInterval: DateInterval = 'last30Days';
|
||||||
const state = reducer(undefined, { type: fallbackToIntervalAction.toString(), payload: fallbackInterval });
|
const state = reducer(undefined, { type: getTagVisits.fallbackToInterval.toString(), payload: fallbackInterval });
|
||||||
|
|
||||||
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
|
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
|
||||||
});
|
});
|
||||||
|
@ -194,12 +193,12 @@ describe('tagVisitsReducer', () => {
|
||||||
it.each([
|
it.each([
|
||||||
[
|
[
|
||||||
[Mock.of<Visit>({ date: formatISO(subDays(now, 20)) })],
|
[Mock.of<Visit>({ date: formatISO(subDays(now, 20)) })],
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: 'last30Days' },
|
{ type: getTagVisits.fallbackToInterval.toString(), payload: 'last30Days' },
|
||||||
3,
|
3,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[Mock.of<Visit>({ date: formatISO(subDays(now, 100)) })],
|
[Mock.of<Visit>({ date: formatISO(subDays(now, 100)) })],
|
||||||
{ type: fallbackToIntervalAction.toString(), payload: 'last180Days' },
|
{ type: getTagVisits.fallbackToInterval.toString(), payload: 'last180Days' },
|
||||||
3,
|
3,
|
||||||
],
|
],
|
||||||
[[], expect.objectContaining({ type: getTagVisits.fulfilled.toString() }), 2],
|
[[], expect.objectContaining({ type: getTagVisits.fulfilled.toString() }), 2],
|
||||||
|
|
Loading…
Reference in a new issue