From 54e5eff61accca4e6d186fb5cfa9447802425ea6 Mon Sep 17 00:00:00 2001 From: Yury Saukou Date: Mon, 19 Aug 2024 09:58:25 +0400 Subject: [PATCH] STCOR-873 Ensure support for the passed `tenantId` value by `useChunkedCQLFetch` for manipulations in the context of a specific tenant (#1519) * STCOR-873 Ensure support for the passed 'tenantId' value by 'useChunkedCQLFetch' for manipulations in the context of a specific tenant * resolve description issues * tests --- CHANGELOG.md | 1 + src/queries/useChunkedCQLFetch.js | 13 +++--- src/queries/useChunkedCQLFetch.test.js | 61 +++++++++++++++++++++----- 3 files changed, 59 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d90281e0d..fe0fc0bd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ * Correctly evaluate `stripes.okapi` before rendering ``. Refs STCOR-864. * `/users-keycloak/_self` is an authentication request. Refs STCOR-866. * Terminate the session when the fixed-length session expires. Refs STCOR-862. +* Ensure support for the passed `tenantId` value by `useChunkedCQLFetch` for manipulations in the context of a specific tenant. Refs STCOR-873. * Provide `key` to elements in ``. Refs STCOR-874. ## [10.1.1](https://github.com/folio-org/stripes-core/tree/v10.1.1) (2024-03-25) diff --git a/src/queries/useChunkedCQLFetch.js b/src/queries/useChunkedCQLFetch.js index 79ed6876b..9b13ee177 100644 --- a/src/queries/useChunkedCQLFetch.js +++ b/src/queries/useChunkedCQLFetch.js @@ -38,9 +38,10 @@ const useChunkedCQLFetch = ({ limit = 1000, // Item limit to fetch on each request queryOptions: passedQueryOptions = {}, // Options to pass to each query reduceFunction, // Function to reduce fetched objects at the end into single array - STEP_SIZE = STEP_SIZE_DEFAULT // Number of IDs fetch per request + STEP_SIZE = STEP_SIZE_DEFAULT, // Number of IDs fetch per request + tenantId, // Tenant ID to which requests should be directed }) => { - const ky = useOkapiKy(); + const ky = useOkapiKy({ tenant: tenantId }); // Destructure passed query options to grab enabled const { enabled: queryEnabled = true, ...queryOptions } = passedQueryOptions; @@ -69,9 +70,10 @@ const useChunkedCQLFetch = ({ endpoint, ids, queryOptions, - STEP_SIZE + STEP_SIZE, + tenantId, }) : - ['stripes-core', endpoint, chunkedItem]; + ['stripes-core', endpoint, chunkedItem, tenantId]; queryArray.push({ queryKey, queryFn: () => ky.get(`${endpoint}?limit=${limit}&query=${query}`).json(), @@ -93,7 +95,8 @@ const useChunkedCQLFetch = ({ ky, queryEnabled, queryOptions, - STEP_SIZE + STEP_SIZE, + tenantId, ]); const queryArray = getQueryArray(); diff --git a/src/queries/useChunkedCQLFetch.test.js b/src/queries/useChunkedCQLFetch.test.js index 31c150790..a742a3537 100644 --- a/src/queries/useChunkedCQLFetch.test.js +++ b/src/queries/useChunkedCQLFetch.test.js @@ -42,6 +42,15 @@ const baseOptions = { // Set these up in beforeEach so it's fresh for each describe -- otherwise get improper test component changes(?) let queryClient; let wrapper; + +const response = [{ dummy: 'result' }]; +const mockUseOkapiKyValue = { + get: jest.fn(() => ({ + json: () => Promise.resolve(response), + })), +}; +const mockUseOkapiKy = useOkapiKy; + describe('Given useChunkedCQLFetch', () => { beforeEach(() => { queryClient = new QueryClient({ @@ -57,14 +66,10 @@ describe('Given useChunkedCQLFetch', () => { {children} ); - const response = [{ dummy: 'result' }]; - const mockUseOkapiKy = useOkapiKy; - mockUseOkapiKy.mockReturnValue({ - get: () => ({ - json: () => Promise.resolve(response), - }), - }); + mockUseOkapiKy.mockClear(); + mockUseOkapiKyValue.get.mockClear(); + mockUseOkapiKy.mockReturnValue(mockUseOkapiKyValue); }); describe('sets up correct number of fetches', () => { @@ -197,7 +202,8 @@ describe('Given useChunkedCQLFetch', () => { it('expose queryKeys based on given ids and endpoint', async () => { const { result } = renderHook(() => useChunkedCQLFetch({ ...baseOptions, - STEP_SIZE: 2 + STEP_SIZE: 2, + tenantId: 'central', }), { wrapper }); await waitFor(() => { @@ -208,10 +214,43 @@ describe('Given useChunkedCQLFetch', () => { expect(result.current.queryKeys).toHaveLength(3); expect(result.current.queryKeys).toStrictEqual([ - ['stripes-core', 'users', ['1234-5678-a', '1234-5678-b']], - ['stripes-core', 'users', ['1234-5678-c', '1234-5678-d']], - ['stripes-core', 'users', ['1234-5678-e']] + ['stripes-core', 'users', ['1234-5678-a', '1234-5678-b'], 'central'], + ['stripes-core', 'users', ['1234-5678-c', '1234-5678-d'], 'central'], + ['stripes-core', 'users', ['1234-5678-e'], 'central'] ]); }); }); + + describe('allows work in provided tenant', () => { + const providedTenantId = 'providedTenantId'; + + it('sets up 1 fetch using alternate tenant ID', async () => { + const { result } = renderHook(() => useChunkedCQLFetch({ + ...baseOptions, + tenantId: providedTenantId, + }), { wrapper }); + + await waitFor(() => { + return result.current.itemQueries?.filter(iq => iq.isLoading)?.length === 0; + }); + + expect(mockUseOkapiKy).toHaveBeenCalledWith({ tenant: providedTenantId }); + }); + + it('includes tenantId in the generateQueryKey function', async () => { + const generateQueryKey = jest.fn(); + + const { result } = renderHook(() => useChunkedCQLFetch({ + ...baseOptions, + generateQueryKey, + tenantId: providedTenantId, + }), { wrapper }); + + await waitFor(() => { + return result.current.itemQueries?.filter(iq => iq.isLoading)?.length === 0; + }); + + expect(generateQueryKey).toHaveBeenCalledWith(expect.objectContaining({ tenantId: providedTenantId })); + }); + }); });