diff --git a/packages/toolkit/src/query/baseQueryTypes.ts b/packages/toolkit/src/query/baseQueryTypes.ts index 2b693b4bd8..8916d94a22 100644 --- a/packages/toolkit/src/query/baseQueryTypes.ts +++ b/packages/toolkit/src/query/baseQueryTypes.ts @@ -6,6 +6,17 @@ export interface BaseQueryApi { dispatch: ThunkDispatch getState: () => unknown extra: unknown + endpoint: string + type: 'query' | 'mutation' + /** + * Only available for queries: indicates if a query has been forced, + * i.e. it would have been fetched even if there would already be a cache entry + * (this does not mean that there is already a cache entry though!) + * + * This can be used to for example add a `Cache-Control: no-cache` header for + * invalidated queries. + */ + forced?: boolean } export type QueryReturnValue = diff --git a/packages/toolkit/src/query/core/buildInitiate.ts b/packages/toolkit/src/query/core/buildInitiate.ts index 2a3c6b1b17..af748cce6c 100644 --- a/packages/toolkit/src/query/core/buildInitiate.ts +++ b/packages/toolkit/src/query/core/buildInitiate.ts @@ -232,6 +232,7 @@ Features like automatic cache collection, automatic refetching etc. will not be endpointName, }) const thunk = queryThunk({ + type: 'query', subscribe, forceRefetch, subscriptionOptions, @@ -292,6 +293,7 @@ Features like automatic cache collection, automatic refetching etc. will not be return (arg, { track = true, fixedCacheKey } = {}) => (dispatch, getState) => { const thunk = mutationThunk({ + type: 'mutation', endpointName, originalArgs: arg, track, diff --git a/packages/toolkit/src/query/core/buildMiddleware/index.ts b/packages/toolkit/src/query/core/buildMiddleware/index.ts index 06494fc61e..c7a9ed1330 100644 --- a/packages/toolkit/src/query/core/buildMiddleware/index.ts +++ b/packages/toolkit/src/query/core/buildMiddleware/index.ts @@ -75,6 +75,7 @@ export function buildMiddleware< override: Partial = {} ) { return queryThunk({ + type: 'query', endpointName: querySubState.endpointName, originalArgs: querySubState.originalArgs, subscribe: false, diff --git a/packages/toolkit/src/query/core/buildThunks.ts b/packages/toolkit/src/query/core/buildThunks.ts index b5a92ebcc8..8a5dcc38ba 100644 --- a/packages/toolkit/src/query/core/buildThunks.ts +++ b/packages/toolkit/src/query/core/buildThunks.ts @@ -103,11 +103,13 @@ export interface Matchers< export interface QueryThunkArg extends QuerySubstateIdentifier, StartQueryActionCreatorOptions { + type: 'query' originalArgs: unknown endpointName: string } export interface MutationThunkArg { + type: 'mutation' originalArgs: unknown endpointName: string track?: boolean @@ -276,6 +278,10 @@ export function buildThunks< dispatch, getState, extra, + endpoint: arg.endpointName, + type: arg.type, + forced: + arg.type === 'query' ? isForcedQuery(arg, getState()) : undefined, } if (endpointDefinition.query) { result = await baseQuery( @@ -325,6 +331,28 @@ In the case of an unhandled error, no tags will be "provided" or "invalidated".` } } + function isForcedQuery( + arg: QueryThunkArg, + state: RootState + ) { + const requestState = state[reducerPath]?.queries?.[arg.queryCacheKey] + const baseFetchOnMountOrArgChange = + state[reducerPath]?.config.refetchOnMountOrArgChange + + const fulfilledVal = requestState?.fulfilledTimeStamp + const refetchVal = + arg.forceRefetch ?? (arg.subscribe && baseFetchOnMountOrArgChange) + + if (refetchVal) { + // Return if its true or compare the dates because it must be a number + return ( + refetchVal === true || + (Number(new Date()) - Number(fulfilledVal)) / 1000 >= refetchVal + ) + } + return false + } + const queryThunk = createAsyncThunk< ThunkResult, QueryThunkArg, @@ -334,29 +362,20 @@ In the case of an unhandled error, no tags will be "provided" or "invalidated".` return { startedTimeStamp: Date.now() } }, condition(arg, { getState }) { - const state = getState()[reducerPath] - const requestState = state?.queries?.[arg.queryCacheKey] - const baseFetchOnMountOrArgChange = state.config.refetchOnMountOrArgChange - + const state = getState() + const requestState = state[reducerPath]?.queries?.[arg.queryCacheKey] const fulfilledVal = requestState?.fulfilledTimeStamp - const refetchVal = - arg.forceRefetch ?? (arg.subscribe && baseFetchOnMountOrArgChange) // Don't retry a request that's currently in-flight if (requestState?.status === 'pending') return false + // if this is forced, continue + if (isForcedQuery(arg, state)) return true + // Pull from the cache unless we explicitly force refetch or qualify based on time - if (fulfilledVal) { - if (refetchVal) { - // Return if its true or compare the dates because it must be a number - return ( - refetchVal === true || - (Number(new Date()) - Number(fulfilledVal)) / 1000 >= refetchVal - ) - } + if (fulfilledVal) // Value is cached and we didn't specify to refresh, skip it. return false - } return true }, diff --git a/packages/toolkit/src/query/fetchBaseQuery.ts b/packages/toolkit/src/query/fetchBaseQuery.ts index 4bb225864f..5349ca3770 100644 --- a/packages/toolkit/src/query/fetchBaseQuery.ts +++ b/packages/toolkit/src/query/fetchBaseQuery.ts @@ -1,6 +1,6 @@ import { joinUrls } from './utils' import { isPlainObject } from '@reduxjs/toolkit' -import type { BaseQueryFn } from './baseQueryTypes' +import type { BaseQueryApi, BaseQueryFn } from './baseQueryTypes' import type { MaybePromise, Override } from './tsHelpers' export type ResponseHandler = @@ -113,7 +113,7 @@ export type FetchBaseQueryArgs = { baseUrl?: string prepareHeaders?: ( headers: Headers, - api: { getState: () => unknown } + api: Pick ) => MaybePromise fetchFn?: ( input: RequestInfo, @@ -178,7 +178,7 @@ export function fetchBaseQuery({ 'Warning: `fetch` is not available. Please supply a custom `fetchFn` property to use `fetchBaseQuery` on SSR environments.' ) } - return async (arg, { signal, getState }) => { + return async (arg, { signal, getState, endpoint, forced, type }) => { let meta: FetchBaseQueryMeta | undefined let { url, @@ -200,7 +200,7 @@ export function fetchBaseQuery({ config.headers = await prepareHeaders( new Headers(stripUndefined(headers)), - { getState } + { getState, endpoint, forced, type } ) // Only set the content-type to json if appropriate. Will not be true for FormData, ArrayBuffer, Blob, etc. diff --git a/packages/toolkit/src/query/tests/createApi.test.ts b/packages/toolkit/src/query/tests/createApi.test.ts index 8ca61c32e4..dcce29815e 100644 --- a/packages/toolkit/src/query/tests/createApi.test.ts +++ b/packages/toolkit/src/query/tests/createApi.test.ts @@ -305,10 +305,14 @@ describe('endpoint definition typings', () => { describe('enhancing endpoint definitions', () => { const baseQuery = jest.fn((x: string) => ({ data: 'success' })) - const baseQueryApiMatcher = { + const commonBaseQueryApi = { dispatch: expect.any(Function), + endpoint: expect.any(String), + extra: undefined, + forced: expect.any(Boolean), getState: expect.any(Function), signal: expect.any(Object), + type: expect.any(String), } beforeEach(() => { baseQuery.mockClear() @@ -337,11 +341,56 @@ describe('endpoint definition typings', () => { storeRef.store.dispatch(api.endpoints.query2.initiate('in2')) storeRef.store.dispatch(api.endpoints.mutation1.initiate('in1')) storeRef.store.dispatch(api.endpoints.mutation2.initiate('in2')) + expect(baseQuery.mock.calls).toEqual([ - ['in1', baseQueryApiMatcher, undefined], - ['in2', baseQueryApiMatcher, undefined], - ['in1', baseQueryApiMatcher, undefined], - ['in2', baseQueryApiMatcher, undefined], + [ + 'in1', + { + dispatch: expect.any(Function), + endpoint: expect.any(String), + getState: expect.any(Function), + signal: expect.any(Object), + forced: expect.any(Boolean), + type: expect.any(String), + }, + undefined, + ], + [ + 'in2', + { + dispatch: expect.any(Function), + endpoint: expect.any(String), + getState: expect.any(Function), + signal: expect.any(Object), + forced: expect.any(Boolean), + type: expect.any(String), + }, + undefined, + ], + [ + 'in1', + { + dispatch: expect.any(Function), + endpoint: expect.any(String), + getState: expect.any(Function), + signal: expect.any(Object), + // forced: undefined, + type: expect.any(String), + }, + undefined, + ], + [ + 'in2', + { + dispatch: expect.any(Function), + endpoint: expect.any(String), + getState: expect.any(Function), + signal: expect.any(Object), + // forced: undefined, + type: expect.any(String), + }, + undefined, + ], ]) }) @@ -439,11 +488,12 @@ describe('endpoint definition typings', () => { storeRef.store.dispatch(api.endpoints.query2.initiate('in2')) storeRef.store.dispatch(api.endpoints.mutation1.initiate('in1')) storeRef.store.dispatch(api.endpoints.mutation2.initiate('in2')) + expect(baseQuery.mock.calls).toEqual([ - ['modified1', baseQueryApiMatcher, undefined], - ['modified2', baseQueryApiMatcher, undefined], - ['modified1', baseQueryApiMatcher, undefined], - ['modified2', baseQueryApiMatcher, undefined], + ['modified1', commonBaseQueryApi, undefined], + ['modified2', commonBaseQueryApi, undefined], + ['modified1', { ...commonBaseQueryApi, forced: undefined }, undefined], + ['modified2', { ...commonBaseQueryApi, forced: undefined }, undefined], ]) }) }) diff --git a/packages/toolkit/src/query/tests/errorHandling.test.tsx b/packages/toolkit/src/query/tests/errorHandling.test.tsx index 26343c2d14..6b59998174 100644 --- a/packages/toolkit/src/query/tests/errorHandling.test.tsx +++ b/packages/toolkit/src/query/tests/errorHandling.test.tsx @@ -11,6 +11,7 @@ import { server } from './mocks/server' import { fireEvent, render, waitFor, screen } from '@testing-library/react' import { useDispatch } from 'react-redux' import type { AnyAction, ThunkDispatch } from '@reduxjs/toolkit' +import type { BaseQueryApi } from '../baseQueryTypes' const baseQuery = fetchBaseQuery({ baseUrl: 'http://example.com' }) @@ -33,18 +34,20 @@ const failQueryOnce = rest.get('/query', (_, req, ctx) => ) describe('fetchBaseQuery', () => { + let commonBaseQueryApiArgs: BaseQueryApi = {} as any + beforeEach(() => { + commonBaseQueryApiArgs = { + signal: new AbortController().signal, + dispatch: storeRef.store.dispatch, + getState: storeRef.store.getState, + extra: undefined, + type: 'query', + endpoint: 'doesntmatterhere', + } + }) test('success', async () => { await expect( - baseQuery( - '/success', - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, - {} - ) + baseQuery('/success', commonBaseQueryApiArgs, {}) ).resolves.toEqual({ data: { value: 'success' }, meta: { @@ -56,16 +59,7 @@ describe('fetchBaseQuery', () => { test('error', async () => { server.use(failQueryOnce) await expect( - baseQuery( - '/error', - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, - {} - ) + baseQuery('/error', commonBaseQueryApiArgs, {}) ).resolves.toEqual({ error: { data: { value: 'error' }, diff --git a/packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx b/packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx index bf9c0bd60a..eb6b6bbc2a 100644 --- a/packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx +++ b/packages/toolkit/src/query/tests/fetchBaseQuery.test.tsx @@ -5,6 +5,7 @@ import { server } from './mocks/server' import { default as crossFetch } from 'cross-fetch' import { rest } from 'msw' import queryString from 'query-string' +import type { BaseQueryApi } from '../baseQueryTypes' const defaultHeaders: Record = { fake: 'header', @@ -71,19 +72,22 @@ const authSlice = createSlice({ const storeRef = setupApiStore(api, { auth: authSlice.reducer }) type RootState = ReturnType +let commonBaseQueryApi: BaseQueryApi = {} as any +beforeEach(() => { + commonBaseQueryApi = { + signal: new AbortController().signal, + dispatch: storeRef.store.dispatch, + getState: storeRef.store.getState, + extra: undefined, + type: 'query', + endpoint: 'doesntmatterhere', + } +}) + describe('fetchBaseQuery', () => { describe('basic functionality', () => { it('should return an object for a simple GET request when it is json data', async () => { - const req = baseQuery( - '/success', - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, - {} - ) + const req = baseQuery('/success', commonBaseQueryApi, {}) expect(req).toBeInstanceOf(Promise) const res = await req expect(res).toBeInstanceOf(Object) @@ -91,16 +95,7 @@ describe('fetchBaseQuery', () => { }) it('should return undefined for a simple GET request when the response is empty', async () => { - const req = baseQuery( - '/empty', - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, - {} - ) + const req = baseQuery('/empty', commonBaseQueryApi, {}) expect(req).toBeInstanceOf(Promise) const res = await req expect(res).toBeInstanceOf(Object) @@ -110,16 +105,7 @@ describe('fetchBaseQuery', () => { }) it('should return an error and status for error responses', async () => { - const req = baseQuery( - '/error', - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, - {} - ) + const req = baseQuery('/error', commonBaseQueryApi, {}) expect(req).toBeInstanceOf(Promise) const res = await req expect(res).toBeInstanceOf(Object) @@ -134,16 +120,7 @@ describe('fetchBaseQuery', () => { it('should handle a connection loss semi-gracefully', async () => { fetchFn.mockRejectedValueOnce(new TypeError('Failed to fetch')) - const req = baseQuery( - '/success', - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, - {} - ) + const req = baseQuery('/success', commonBaseQueryApi, {}) expect(req).toBeInstanceOf(Promise) const res = await req expect(res).toBeInstanceOf(Object) @@ -166,12 +143,7 @@ describe('fetchBaseQuery', () => { const req = baseQuery( { url: '/success', responseHandler: 'text' }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} ) expect(req).toBeInstanceOf(Promise) @@ -189,16 +161,7 @@ describe('fetchBaseQuery', () => { ) ) - const req = baseQuery( - '/success', - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, - {} - ) + const req = baseQuery('/success', commonBaseQueryApi, {}) expect(req).toBeInstanceOf(Promise) const res = await req expect(res).toBeInstanceOf(Object) @@ -221,12 +184,7 @@ describe('fetchBaseQuery', () => { const req = baseQuery( { url: '/error', responseHandler: 'text' }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} ) expect(req).toBeInstanceOf(Promise) @@ -247,16 +205,7 @@ describe('fetchBaseQuery', () => { ) ) - const req = baseQuery( - '/error', - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, - {} - ) + const req = baseQuery('/error', commonBaseQueryApi, {}) expect(req).toBeInstanceOf(Promise) const res = await req expect(res).toBeInstanceOf(Object) @@ -280,12 +229,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', body: data, method: 'POST' }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + { ...commonBaseQueryApi, type: 'mutation' }, {} )) @@ -299,12 +243,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', body: data, method: 'POST' }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -325,12 +264,7 @@ describe('fetchBaseQuery', () => { method: 'POST', headers: { 'content-type': 'text/html' }, }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -349,12 +283,7 @@ describe('fetchBaseQuery', () => { method: 'POST', headers: { 'content-type': 'text/html' }, }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -368,12 +297,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo' }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -386,12 +310,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', params }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -404,12 +323,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo?banana=pudding', params }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -422,12 +336,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', params }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -440,12 +349,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', params }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -485,12 +389,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', params }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -509,12 +408,7 @@ describe('fetchBaseQuery', () => { validateStatus: (response, body) => response.status === 200 && body.success === false ? false : true, }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} ) @@ -533,12 +427,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo' }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -551,12 +440,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', headers: { authorization: 'Bearer banana' } }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -576,12 +460,7 @@ describe('fetchBaseQuery', () => { 'content-type': 'custom-content-type', }, }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -598,12 +477,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', headers: { fake, delete: '', delete2: '' } }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -627,16 +501,7 @@ describe('fetchBaseQuery', () => { }) const doRequest = async () => - _baseQuery( - { url: '/echo' }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, - {} - ) + _baseQuery({ url: '/echo' }, commonBaseQueryApi, {}) ;({ data: request } = await doRequest()) @@ -654,6 +519,8 @@ describe('fetchBaseQuery', () => { dispatch: storeRef.store.dispatch, getState: storeRef.store.getState, extra: undefined, + type: 'query', + endpoint: '', }, {} ) @@ -675,12 +542,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', headers: undefined }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -694,12 +556,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', headers: { banana } }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -714,12 +571,7 @@ describe('fetchBaseQuery', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', headers: { banana } }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -743,12 +595,7 @@ describe('fetchFn', () => { let request: any ;({ data: request } = await baseQuery( { url: '/echo', params }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} )) @@ -769,16 +616,7 @@ describe('fetchFn', () => { const spiedFetch = jest.spyOn(window, 'fetch') spiedFetch.mockResolvedValueOnce(fakeResponse as any) - const { data } = await baseQuery( - { url: '/echo' }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, - {} - ) + const { data } = await baseQuery({ url: '/echo' }, commonBaseQueryApi, {}) expect(data).toEqual({ url: 'mock-return-url' }) spiedFetch.mockClear() @@ -798,12 +636,7 @@ describe('FormData', () => { const res = await baseQuery( { url: '/echo', method: 'POST', body }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} ) const request: any = res.data @@ -821,12 +654,7 @@ describe('still throws on completely unexpected errors', () => { throw error }, }, - { - signal: new AbortController().signal, - dispatch: storeRef.store.dispatch, - getState: storeRef.store.getState, - extra: undefined, - }, + commonBaseQueryApi, {} ) expect(req).toBeInstanceOf(Promise)