diff --git a/src/api/item.test.ts b/src/api/item.test.ts new file mode 100644 index 00000000..43eb241c --- /dev/null +++ b/src/api/item.test.ts @@ -0,0 +1,48 @@ +import { ItemType } from '@graasp/sdk'; + +import { AxiosInstance } from 'axios'; +import { v4 } from 'uuid'; +import { describe, expect, it, vi } from 'vitest'; + +import { getDescendants } from './item.js'; + +const API_HOST = 'https://localhost:3000'; + +describe('getDescendants', () => { + it('without parameters', async () => { + const mockGet = vi.fn().mockResolvedValue({ data: { value: 'hello' } }); + const axios = { + get: mockGet, + } as unknown as AxiosInstance; + await getDescendants({ id: v4() }, { API_HOST, axios }); + expect(mockGet).toHaveBeenCalledWith(expect.not.stringContaining('types')); + }); + + it.each([ + { inputs: { showHidden: true }, query: 'showHidden=true' }, + { inputs: { showHidden: false }, query: 'showHidden=false' }, + { + inputs: { types: [ItemType.FOLDER], showHidden: false }, + query: 'types=folder&showHidden=false', + }, + { + inputs: { types: [ItemType.FOLDER], showHidden: true }, + query: 'types=folder&showHidden=true', + }, + { + inputs: { types: [ItemType.FOLDER, ItemType.APP], showHidden: false }, + query: 'types=folder&types=app&showHidden=false', + }, + { + inputs: { types: [ItemType.FOLDER, ItemType.APP], showHidden: true }, + query: 'types=folder&types=app&showHidden=true', + }, + ])('With parameters: $inputs', async ({ inputs, query }) => { + const mockGet = vi.fn().mockResolvedValue({ data: { value: 'hello' } }); + const axios = { + get: mockGet, + } as unknown as AxiosInstance; + await getDescendants({ id: v4(), ...inputs }, { API_HOST, axios }); + expect(mockGet).toHaveBeenCalledWith(expect.stringContaining(query)); + }); +}); diff --git a/src/api/item.ts b/src/api/item.ts index 2c11b81d..78cf8770 100644 --- a/src/api/item.ts +++ b/src/api/item.ts @@ -1,6 +1,7 @@ import { DiscriminatedItem, ItemGeolocation, + ItemTypeUnion, PackedItem, PackedRecycledItemData, ResultOf, @@ -227,12 +228,23 @@ export const getParents = async ( }; export const getDescendants = async ( - { id }: { id: UUID }, + { + id, + types, + showHidden, + }: { id: UUID; types?: ItemTypeUnion[]; showHidden?: boolean }, { API_HOST, axios }: PartialQueryConfigForApi, -) => - axios - .get(`${API_HOST}/${buildGetItemDescendants(id)}`) - .then(({ data }) => data); +) => { + const url = new URL(`${API_HOST}/${buildGetItemDescendants(id)}`); + // add item types to the query as repeating parameters + types?.forEach((itemType) => { + url.searchParams.append('types', itemType); + }); + if (showHidden !== undefined) { + url.searchParams.set('showHidden', showHidden.toString()); + } + return axios.get(url.toString()).then(({ data }) => data); +}; export const moveItems = async ( { diff --git a/src/config/keys.ts b/src/config/keys.ts index 69bbfa0f..1e303f43 100644 --- a/src/config/keys.ts +++ b/src/config/keys.ts @@ -4,6 +4,7 @@ import { DiscriminatedItem, ItemGeolocation, ItemType, + ItemTypeUnion, UUID, UnionOfConst, } from '@graasp/sdk'; @@ -60,7 +61,10 @@ export const itemKeys = { paginatedChildren: [...allChildren, 'paginated'] as const, // descendants - descendants: [...singleBaseKey, 'descendants'] as const, + descendants: (options?: { + types?: ItemTypeUnion[]; + showHidden?: boolean; + }) => [...singleBaseKey, 'descendants', options].filter(Boolean), // parents parents: [...singleBaseKey, 'parents'] as const, @@ -137,9 +141,6 @@ export const itemKeys = { accessiblePage: (params: ItemSearchParams, pagination: PaginationParams) => [...itemKeys.allAccessible(), params, pagination] as const, - // shared items - shared: () => [...itemKeys.all, 'shared'] as const, - search: (args: { query?: string; categories?: Category['id'][][]; diff --git a/src/hooks/item.test.ts b/src/hooks/item.test.ts index d86e92f2..1723dae6 100644 --- a/src/hooks/item.test.ts +++ b/src/hooks/item.test.ts @@ -28,11 +28,11 @@ import { } from '../../test/utils.js'; import { GET_OWN_ITEMS_ROUTE, - SHARED_ITEM_WITH_ROUTE, buildDownloadFilesRoute, buildDownloadItemThumbnailRoute, buildGetAccessibleItems, buildGetChildrenRoute, + buildGetItemDescendants, buildGetItemParents, buildGetItemRoute, buildGetItemsRoute, @@ -41,819 +41,887 @@ import { OWN_ITEMS_KEY, itemKeys } from '../config/keys.js'; const { hooks, wrapper, queryClient } = setUpTest(); -describe('Items Hooks', () => { +describe('useOwnItems', () => { afterEach(() => { nock.cleanAll(); queryClient.clear(); }); + const route = `/${GET_OWN_ITEMS_ROUTE}`; + const hook = () => hooks.useOwnItems(); + + it(`Receive own items`, async () => { + const response = [ + FolderItemFactory(), + FolderItemFactory(), + FolderItemFactory(), + ]; + const endpoints = [{ route, response }]; + const { data } = await mockHook({ endpoints, hook, wrapper }); + + expect(data).toMatchObject(response); + + // verify cache keys + expect( + queryClient.getQueryData(OWN_ITEMS_KEY), + ).toEqual(response); + }); - describe('useOwnItems', () => { - const route = `/${GET_OWN_ITEMS_ROUTE}`; - const hook = () => hooks.useOwnItems(); + it(`Unauthorized`, async () => { + const endpoints = [ + { + route, + response: UNAUTHORIZED_RESPONSE, + statusCode: StatusCodes.UNAUTHORIZED, + }, + ]; + const { data, isError } = await mockHook({ + hook, + wrapper, + endpoints, + }); + + expect(data).toBeFalsy(); + expect(isError).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(OWN_ITEMS_KEY)).toBeFalsy(); + }); +}); - it(`Receive own items`, async () => { - const response = [ - FolderItemFactory(), - FolderItemFactory(), - FolderItemFactory(), - ]; - const endpoints = [{ route, response }]; - const { data } = await mockHook({ endpoints, hook, wrapper }); +describe('useChildren', () => { + afterEach(() => { + nock.cleanAll(); + queryClient.clear(); + }); + const id = 'item-id'; + const params = { ordered: true }; + const route = `/${buildGetChildrenRoute(id, params)}`; + const response = generateFolders(); + const key = itemKeys.single(id).children(); + + it(`Receive children of item by id`, async () => { + const hook = () => hooks.useChildren(id); + const endpoints = [{ route, response }]; + const { data, isSuccess } = await mockHook({ + endpoints, + hook, + wrapper, + }); + + expect(data).toMatchObject(response); + expect(isSuccess).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toEqual(response); + for (const item of response) { + expect( + queryClient.getQueryData(itemKeys.single(item.id).content), + ).toEqual(item); + } + }); - expect(data).toMatchObject(response); + it(`Route constructed correctly for children folders`, async () => { + const typesParams = { types: [ItemType.FOLDER] }; + const url = `/${buildGetChildrenRoute(id, typesParams)}`; + const urlObject = new URL(url, 'https://no-existing-url.tmp'); + const queryParams = urlObject.searchParams; + const typesValue = queryParams.get('types'); + + expect(typesValue).toEqual(ItemType.FOLDER); + }); - // verify cache keys + it(`Undefined id does not fetch`, async () => { + const hook = () => hooks.useChildren(undefined); + const endpoints = [{ route, response }]; + const { data, isFetched } = await mockHook({ + endpoints, + hook, + wrapper, + enabled: false, + }); + + expect(isFetched).toBeFalsy(); + expect(data).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); + for (const item of response) { expect( - queryClient.getQueryData(OWN_ITEMS_KEY), - ).toEqual(response); - }); + queryClient.getQueryData(itemKeys.single(item.id).content), + ).toBeFalsy(); + } + }); - it(`Unauthorized`, async () => { - const endpoints = [ - { - route, - response: UNAUTHORIZED_RESPONSE, - statusCode: StatusCodes.UNAUTHORIZED, - }, - ]; - const { data, isError } = await mockHook({ - hook, - wrapper, - endpoints, - }); - - expect(data).toBeFalsy(); - expect(isError).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(OWN_ITEMS_KEY)).toBeFalsy(); - }); + it(`enabled=false does not fetch`, async () => { + const hook = () => hooks.useChildren(id, {}, { enabled: false }); + const endpoints = [{ route, response }]; + const { data, isFetched } = await mockHook({ + endpoints, + hook, + wrapper, + enabled: false, + }); + + expect(isFetched).toBeFalsy(); + expect(data).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); + for (const item of response) { + expect( + queryClient.getQueryData(itemKeys.single(item.id).content), + ).toBeFalsy(); + } }); - describe('useChildren', () => { - const id = 'item-id'; - const params = { ordered: true }; - const route = `/${buildGetChildrenRoute(id, params)}`; - const response = generateFolders(); - const key = itemKeys.single(id).children(); - - it(`Receive children of item by id`, async () => { - const hook = () => hooks.useChildren(id); - const endpoints = [{ route, response }]; - const { data, isSuccess } = await mockHook({ - endpoints, - hook, - wrapper, - }); - - expect(data).toMatchObject(response); - expect(isSuccess).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toEqual(response); - for (const item of response) { - expect( - queryClient.getQueryData(itemKeys.single(item.id).content), - ).toEqual(item); - } - }); + it(`ordered=false fetch children`, async () => { + const unorderedRoute = `/${buildGetChildrenRoute(id, { + ordered: false, + })}`; + const hook = () => hooks.useChildren(id, { ordered: false }); + const endpoints = [{ route: unorderedRoute, response }]; + const { data, isSuccess } = await mockHook({ + endpoints, + hook, + wrapper, + }); + + expect(isSuccess).toBeTruthy(); + expect(data).toMatchObject(response); + // verify cache keys + expect(queryClient.getQueryData(key)).toMatchObject(response); + for (const item of response) { + expect( + queryClient.getQueryData(itemKeys.single(item.id).content), + ).toMatchObject(item); + } + }); - it(`Route constructed correctly for children folders`, async () => { - const typesParams = { types: [ItemType.FOLDER] }; - const url = `/${buildGetChildrenRoute(id, typesParams)}`; - const urlObject = new URL(url, 'https://no-existing-url.tmp'); - const queryParams = urlObject.searchParams; - const typesValue = queryParams.get('types'); + it(`Unauthorized`, async () => { + const endpoints = [ + { + route: `/${buildGetChildrenRoute(id, { ordered: true })}`, + response: UNAUTHORIZED_RESPONSE, + statusCode: StatusCodes.UNAUTHORIZED, + }, + ]; + const { data, isError } = await mockHook({ + endpoints, + hook: () => hooks.useChildren(id), + wrapper, + }); + + expect(data).toBeFalsy(); + expect(isError).toBeTruthy(); + // verify cache keys + expect( + queryClient.getQueryData(itemKeys.single(id).children()), + ).toBeFalsy(); + }); +}); - expect(typesValue).toEqual(ItemType.FOLDER); - }); +describe('useParents', () => { + afterEach(() => { + nock.cleanAll(); + queryClient.clear(); + }); - it(`Undefined id does not fetch`, async () => { - const hook = () => hooks.useChildren(undefined); - const endpoints = [{ route, response }]; - const { data, isFetched } = await mockHook({ - endpoints, - hook, - wrapper, - enabled: false, - }); - - expect(isFetched).toBeFalsy(); - expect(data).toBeFalsy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - for (const item of response) { - expect( - queryClient.getQueryData(itemKeys.single(item.id).content), - ).toBeFalsy(); - } - }); + const response = generateFolders(); + const childItem: FolderItemType = FolderItemFactory({ + id: 'child-item-id', + path: [...response.map(({ id }) => id), 'child_item_id'].join('.'), + }); - it(`enabled=false does not fetch`, async () => { - const hook = () => hooks.useChildren(id, {}, { enabled: false }); - const endpoints = [{ route, response }]; - const { data, isFetched } = await mockHook({ - endpoints, - hook, - wrapper, - enabled: false, - }); - - expect(isFetched).toBeFalsy(); - expect(data).toBeFalsy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - for (const item of response) { - expect( - queryClient.getQueryData(itemKeys.single(item.id).content), - ).toBeFalsy(); - } - }); + it(`Receive parents of item by id`, async () => { + const hook = () => hooks.useParents({ id: childItem.id, enabled: true }); - it(`ordered=false fetch children`, async () => { - const unorderedRoute = `/${buildGetChildrenRoute(id, { - ordered: false, - })}`; - const hook = () => hooks.useChildren(id, { ordered: false }); - const endpoints = [{ route: unorderedRoute, response }]; - const { data, isSuccess } = await mockHook({ - endpoints, - hook, - wrapper, - }); - - expect(isSuccess).toBeTruthy(); - expect(data).toMatchObject(response); - // verify cache keys - expect(queryClient.getQueryData(key)).toMatchObject(response); - for (const item of response) { - expect( - queryClient.getQueryData(itemKeys.single(item.id).content), - ).toMatchObject(item); - } - }); + // build endpoint for each item + const endpoints = [ + { + route: `/${buildGetItemParents(childItem.id)}`, + response, + }, + ]; + const { data } = await mockHook({ endpoints, hook, wrapper }); + + expect(data).toMatchObject(response); + // verify cache keys + expect( + queryClient.getQueryData(itemKeys.single(childItem.id).parents), + ).toMatchObject(response); + for (const i of response) { + expect( + queryClient.getQueryData(itemKeys.single(i.id).content), + ).toMatchObject(i); + } + }); - it(`Unauthorized`, async () => { - const endpoints = [ - { - route: `/${buildGetChildrenRoute(id, { ordered: true })}`, - response: UNAUTHORIZED_RESPONSE, - statusCode: StatusCodes.UNAUTHORIZED, - }, - ]; - const { data, isError } = await mockHook({ - endpoints, - hook: () => hooks.useChildren(id), - wrapper, - }); - - expect(data).toBeFalsy(); - expect(isError).toBeTruthy(); - // verify cache keys + it(`enabled=false does not fetch parents`, async () => { + // build endpoint for each item + const endpoints = [ + { + route: `/${buildGetItemParents(childItem.id)}`, + response, + }, + ]; + const { data, isFetched } = await mockHook({ + hook: () => hooks.useParents({ id: childItem.id, enabled: false }), + endpoints, + wrapper, + enabled: false, + }); + + expect(data).toBeFalsy(); + expect(isFetched).toBeFalsy(); + expect( + queryClient.getQueryData(itemKeys.single(childItem.id).parents), + ).toBeFalsy(); + // verify cache keys + for (const i of response) { expect( - queryClient.getQueryData(itemKeys.single(id).children()), + queryClient.getQueryData(itemKeys.single(i.id).content), ).toBeFalsy(); - }); + } }); - describe('useParents', () => { - const response = generateFolders(); - const childItem: FolderItemType = FolderItemFactory({ - id: 'child-item-id', - path: [...response.map(({ id }) => id), 'child_item_id'].join('.'), + it(`providing path can deduce empty array`, async () => { + const { data, isFetched } = await mockHook({ + hook: () => hooks.useParents({ id: childItem.id, path: 'some-id' }), + endpoints: [], + wrapper, }); - it(`Receive parents of item by id`, async () => { - const hook = () => hooks.useParents({ id: childItem.id, enabled: true }); - - // build endpoint for each item - const endpoints = [ - { - route: `/${buildGetItemParents(childItem.id)}`, - response, - }, - ]; - const { data } = await mockHook({ endpoints, hook, wrapper }); - expect(data).toMatchObject(response); - // verify cache keys - expect( - queryClient.getQueryData(itemKeys.single(childItem.id).parents), - ).toMatchObject(response); - for (const i of response) { - expect( - queryClient.getQueryData(itemKeys.single(i.id).content), - ).toMatchObject(i); - } - }); + expect(data).toHaveLength(0); + expect(isFetched).toBeTruthy(); + expect( + queryClient.getQueryData(itemKeys.single(childItem.id).parents), + ).toHaveLength(0); + }); - it(`enabled=false does not fetch parents`, async () => { - // build endpoint for each item - const endpoints = [ - { - route: `/${buildGetItemParents(childItem.id)}`, - response, - }, - ]; - const { data, isFetched } = await mockHook({ - hook: () => hooks.useParents({ id: childItem.id, enabled: false }), - endpoints, - wrapper, - enabled: false, - }); - - expect(data).toBeFalsy(); - expect(isFetched).toBeFalsy(); + it(`Unauthorized`, async () => { + // build endpoint for each item + const endpoints = [ + { + route: `/${buildGetItemParents(childItem.id)}`, + response: UNAUTHORIZED_RESPONSE, + statusCode: StatusCodes.UNAUTHORIZED, + }, + ]; + const { data, isError } = await mockHook({ + hook: () => hooks.useParents({ id: childItem.id, enabled: true }), + endpoints, + wrapper, + }); + + expect(data).toBeFalsy(); + expect(isError).toBeTruthy(); + expect( + queryClient.getQueryData(itemKeys.single(childItem.id).parents), + ).toBeFalsy(); + // verify cache keys + for (const i of response) { expect( - queryClient.getQueryData(itemKeys.single(childItem.id).parents), + queryClient.getQueryData(itemKeys.single(i.id).content), ).toBeFalsy(); - // verify cache keys - for (const i of response) { - expect( - queryClient.getQueryData(itemKeys.single(i.id).content), - ).toBeFalsy(); - } - }); - - it(`providing path can deduce empty array`, async () => { - const { data, isFetched } = await mockHook({ - hook: () => hooks.useParents({ id: childItem.id, path: 'some-id' }), - endpoints: [], - wrapper, - }); + } + }); +}); - expect(data).toHaveLength(0); - expect(isFetched).toBeTruthy(); - expect( - queryClient.getQueryData(itemKeys.single(childItem.id).parents), - ).toHaveLength(0); - }); +describe('useAccessibleItems', () => { + afterEach(() => { + nock.cleanAll(); + queryClient.clear(); + }); - it(`Unauthorized`, async () => { - // build endpoint for each item - const endpoints = [ - { - route: `/${buildGetItemParents(childItem.id)}`, - response: UNAUTHORIZED_RESPONSE, - statusCode: StatusCodes.UNAUTHORIZED, - }, - ]; - const { data, isError } = await mockHook({ - hook: () => hooks.useParents({ id: childItem.id, enabled: true }), - endpoints, - wrapper, - }); - - expect(data).toBeFalsy(); - expect(isError).toBeTruthy(); - expect( - queryClient.getQueryData(itemKeys.single(childItem.id).parents), - ).toBeFalsy(); - // verify cache keys - for (const i of response) { - expect( - queryClient.getQueryData(itemKeys.single(i.id).content), - ).toBeFalsy(); - } - }); + const params = {}; + const pagination = {}; + const route = `/${buildGetAccessibleItems(params, pagination)}`; + const items = generateFolders(); + const response = { data: items, totalCount: items.length }; + const hook = () => hooks.useAccessibleItems(); + const key = itemKeys.accessiblePage(params, pagination); + + it(`Receive accessible items`, async () => { + const endpoints = [{ route, response }]; + const { data } = await mockHook({ endpoints, hook, wrapper }); + + expect(data).toMatchObject(response); + // verify cache keys + expect(queryClient.getQueryData(key)).toMatchObject(response); }); - describe('useSharedItems', () => { - const route = `/${SHARED_ITEM_WITH_ROUTE}`; - const response = generateFolders(); - const hook = () => hooks.useSharedItems(); - it(`Receive shared items`, async () => { - const endpoints = [{ route, response }]; - const { data } = await mockHook({ endpoints, hook, wrapper }); + it(`Route constructed correctly for accessible folders`, async () => { + const typesParams = { types: [ItemType.FOLDER] }; + const url = `/${buildGetAccessibleItems(typesParams, {})}`; + const urlObject = new URL(url, 'https://no-existing-url.tmp'); + const queryParams = urlObject.searchParams; + const typesValue = queryParams.get('types'); - expect(data).toMatchObject(response); - // verify cache keys - expect(queryClient.getQueryData(itemKeys.shared())).toMatchObject( - response, - ); - }); + expect(typesValue).toEqual(ItemType.FOLDER); + }); - it(`Unauthorized`, async () => { - const endpoints = [ - { - route, - response: UNAUTHORIZED_RESPONSE, - statusCode: StatusCodes.UNAUTHORIZED, - }, - ]; - const { data, isError } = await mockHook({ - hook, - endpoints, - wrapper, - }); - - expect(data).toBeFalsy(); - expect(isError).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(itemKeys.shared())).toBeFalsy(); - }); + it(`Unauthorized`, async () => { + const endpoints = [ + { + route, + response: UNAUTHORIZED_RESPONSE, + statusCode: StatusCodes.UNAUTHORIZED, + }, + ]; + const { data, isError } = await mockHook({ + hook, + endpoints, + wrapper, + }); + + expect(data).toBeFalsy(); + expect(isError).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); }); +}); - describe('useAccessibleItems', () => { - const params = {}; - const pagination = {}; - const route = `/${buildGetAccessibleItems(params, pagination)}`; - const items = generateFolders(); - const response = { data: items, totalCount: items.length }; - const hook = () => hooks.useAccessibleItems(); - const key = itemKeys.accessiblePage(params, pagination); +describe('useItem', () => { + afterEach(() => { + nock.cleanAll(); + queryClient.clear(); + }); - it(`Receive accessible items`, async () => { - const endpoints = [{ route, response }]; - const { data } = await mockHook({ endpoints, hook, wrapper }); + const response = FolderItemFactory(); + const { id } = response; + const route = `/${buildGetItemRoute(id)}`; + const hook = () => hooks.useItem(id); + const key = itemKeys.single(id).content; - expect(data).toMatchObject(response); - // verify cache keys - expect(queryClient.getQueryData(key)).toMatchObject(response); - }); + it(`Receive item by id`, async () => { + const endpoints = [{ route, response }]; + const { data } = await mockHook({ endpoints, hook, wrapper }); - it(`Route constrcuted correctly for accessible folders`, async () => { - const typesParams = { types: [ItemType.FOLDER] }; - const url = `/${buildGetAccessibleItems(typesParams, {})}`; - const urlObject = new URL(url, 'https://no-existing-url.tmp'); - const queryParams = urlObject.searchParams; - const typesValue = queryParams.get('types'); + expect(data).toMatchObject(response); + // verify cache keys + expect(queryClient.getQueryData(key)).toMatchObject(response); + }); - expect(typesValue).toEqual(ItemType.FOLDER); + it(`Undefined id does not fetch`, async () => { + const endpoints = [{ route, response }]; + const { data, isFetched } = await mockHook({ + endpoints, + hook: () => hooks.useItem(undefined), + wrapper, + enabled: false, }); - it(`Unauthorized`, async () => { - const endpoints = [ - { - route, - response: UNAUTHORIZED_RESPONSE, - statusCode: StatusCodes.UNAUTHORIZED, - }, - ]; - const { data, isError } = await mockHook({ - hook, - endpoints, - wrapper, - }); - - expect(data).toBeFalsy(); - expect(isError).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - }); + expect(data).toBeFalsy(); + expect(isFetched).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); }); - describe('useItem', () => { - const response = FolderItemFactory(); - const { id } = response; - const route = `/${buildGetItemRoute(id)}`; - const hook = () => hooks.useItem(id); - const key = itemKeys.single(id).content; - - it(`Receive item by id`, async () => { - const endpoints = [{ route, response }]; - const { data } = await mockHook({ endpoints, hook, wrapper }); - - expect(data).toMatchObject(response); - // verify cache keys - expect(queryClient.getQueryData(key)).toMatchObject(response); - }); - - it(`Undefined id does not fetch`, async () => { - const endpoints = [{ route, response }]; - const { data, isFetched } = await mockHook({ - endpoints, - hook: () => hooks.useItem(undefined), - wrapper, - enabled: false, - }); - - expect(data).toBeFalsy(); - expect(isFetched).toBeFalsy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - }); + it(`Unauthorized`, async () => { + const endpoints = [ + { + route, + response: UNAUTHORIZED_RESPONSE, + statusCode: StatusCodes.UNAUTHORIZED, + }, + ]; + const { data, isError } = await mockHook({ + hook, + endpoints, + wrapper, + }); + + expect(isError).toBeTruthy(); + expect(data).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); + }); +}); - it(`Unauthorized`, async () => { - const endpoints = [ - { - route, - response: UNAUTHORIZED_RESPONSE, - statusCode: StatusCodes.UNAUTHORIZED, - }, - ]; - const { data, isError } = await mockHook({ - hook, - endpoints, - wrapper, - }); - - expect(isError).toBeTruthy(); - expect(data).toBeFalsy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - }); +describe('useItems', () => { + afterEach(() => { + nock.cleanAll(); + queryClient.clear(); }); - describe('useItems', () => { - const dataItems = generateFolders(); - it(`Receive one item`, async () => { - const oneItem = FolderItemFactory(); - const { id } = dataItems[0]; - const response = buildResultOfData([oneItem]); - // use single item call - const route = `/${buildGetItemsRoute([id])}`; - const endpoints = [{ route, response }]; - const hook = () => hooks.useItems([id]); - const { data } = await mockHook({ endpoints, hook, wrapper }); - expect(data).toEqual(response); - // verify cache keys - const item = queryClient.getQueryData( - itemKeys.single(id).content, - ); - expect(item).toEqual(response.data[id]); - const items = queryClient.getQueryData( - itemKeys.many([id]).content, - ); - expect(items).toEqual(response); - }); + const dataItems = generateFolders(); + + it(`Receive one item`, async () => { + const oneItem = FolderItemFactory(); + const { id } = dataItems[0]; + const response = buildResultOfData([oneItem]); + // use single item call + const route = `/${buildGetItemsRoute([id])}`; + const endpoints = [{ route, response }]; + const hook = () => hooks.useItems([id]); + const { data } = await mockHook({ endpoints, hook, wrapper }); + expect(data).toEqual(response); + // verify cache keys + const item = queryClient.getQueryData( + itemKeys.single(id).content, + ); + expect(item).toEqual(response.data[id]); + const items = queryClient.getQueryData( + itemKeys.many([id]).content, + ); + expect(items).toEqual(response); + }); - it(`Receive two items`, async () => { - const items = dataItems.slice(0, 2); - const response = buildResultOfData(items); - const ids: string[] = items.map(({ id }) => id); - const hook = () => hooks.useItems(ids); - const route = `/${buildGetItemsRoute(ids)}`; - const endpoints = [{ route, response }]; - const { data } = await mockHook({ endpoints, hook, wrapper }); - - expect(data).toEqual(response); - // verify cache keys + it(`Receive two items`, async () => { + const items = dataItems.slice(0, 2); + const response = buildResultOfData(items); + const ids: string[] = items.map(({ id }) => id); + const hook = () => hooks.useItems(ids); + const route = `/${buildGetItemsRoute(ids)}`; + const endpoints = [{ route, response }]; + const { data } = await mockHook({ endpoints, hook, wrapper }); + + expect(data).toEqual(response); + // verify cache keys + expect(queryClient.getQueryData(itemKeys.many(ids).content)).toMatchObject( + data!, + ); + for (const item of items) { + const itemById = items.find(({ id }) => id === item.id); expect( - queryClient.getQueryData(itemKeys.many(ids).content), - ).toMatchObject(data!); - for (const item of items) { - const itemById = items.find(({ id }) => id === item.id); - expect( - queryClient.getQueryData(itemKeys.single(item.id).content), - ).toMatchObject(itemById!); - } - }); + queryClient.getQueryData(itemKeys.single(item.id).content), + ).toMatchObject(itemById!); + } + }); - it(`Receive many items`, async () => { - const items = generateFolders(MAX_TARGETS_FOR_READ_REQUEST + 1); - const response = buildResultOfData(items); - const ids: string[] = items.map(({ id }) => id); - const hook = () => hooks.useItems(ids); - const endpoints = splitEndpointByIds( - ids, - MAX_TARGETS_FOR_READ_REQUEST, - (chunk) => `/${buildGetItemsRoute(chunk)}`, - items, - ); - const { data } = await mockHook({ endpoints, hook, wrapper }); - expect(data).toEqual(response); - // verify cache keys + it(`Receive many items`, async () => { + const items = generateFolders(MAX_TARGETS_FOR_READ_REQUEST + 1); + const response = buildResultOfData(items); + const ids: string[] = items.map(({ id }) => id); + const hook = () => hooks.useItems(ids); + const endpoints = splitEndpointByIds( + ids, + MAX_TARGETS_FOR_READ_REQUEST, + (chunk) => `/${buildGetItemsRoute(chunk)}`, + items, + ); + const { data } = await mockHook({ endpoints, hook, wrapper }); + expect(data).toEqual(response); + // verify cache keys + expect(queryClient.getQueryData(itemKeys.many(ids).content)).toMatchObject( + data!, + ); + for (const item of items) { + const itemById = items.find(({ id }) => id === item.id); expect( - queryClient.getQueryData(itemKeys.many(ids).content), - ).toMatchObject(data!); - for (const item of items) { - const itemById = items.find(({ id }) => id === item.id); - expect( - queryClient.getQueryData(itemKeys.single(item.id).content), - ).toMatchObject(itemById!); - } - }); + queryClient.getQueryData(itemKeys.single(item.id).content), + ).toMatchObject(itemById!); + } + }); - it(`Unauthorized`, async () => { - const requestedItems = dataItems; - const ids: string[] = requestedItems.map(({ id }) => id); - const hook = () => hooks.useItems(ids); - const route = `/${buildGetItemsRoute(ids)}`; - const endpoints = [ - { - route, - response: UNAUTHORIZED_RESPONSE, - statusCode: StatusCodes.UNAUTHORIZED, - }, - ]; - const { data, isError } = await mockHook({ - hook, - endpoints, - wrapper, - }); - - expect(data).toBeFalsy(); - expect(isError).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(itemKeys.many(ids).content)).toBeFalsy(); - }); + it(`Unauthorized`, async () => { + const requestedItems = dataItems; + const ids: string[] = requestedItems.map(({ id }) => id); + const hook = () => hooks.useItems(ids); + const route = `/${buildGetItemsRoute(ids)}`; + const endpoints = [ + { + route, + response: UNAUTHORIZED_RESPONSE, + statusCode: StatusCodes.UNAUTHORIZED, + }, + ]; + const { data, isError } = await mockHook({ + hook, + endpoints, + wrapper, + }); + + expect(data).toBeFalsy(); + expect(isError).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(itemKeys.many(ids).content)).toBeFalsy(); + }); - // TODO: errors, contains errors, full errors + // TODO: errors, contains errors, full errors +}); + +describe('useFileContent', () => { + afterEach(() => { + nock.cleanAll(); + queryClient.clear(); }); - describe('useFileContent', () => { - const response = FILE_RESPONSE; - const { id } = LocalFileItemFactory(); - const route = `/${buildDownloadFilesRoute(id)}`; - const hook = () => hooks.useFileContent(id); - const key = itemKeys.single(id).file({ replyUrl: false }); + const response = FILE_RESPONSE; + const { id } = LocalFileItemFactory(); + const route = `/${buildDownloadFilesRoute(id)}`; + const hook = () => hooks.useFileContent(id); + const key = itemKeys.single(id).file({ replyUrl: false }); - it(`Receive file content`, async () => { - const endpoints = [{ route, response }]; - const { data } = await mockHook({ endpoints, hook, wrapper }); + it(`Receive file content`, async () => { + const endpoints = [{ route, response }]; + const { data } = await mockHook({ endpoints, hook, wrapper }); - expect(data).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeTruthy(); - }); + expect(data).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeTruthy(); + }); - it(`Undefined id does not fetch`, async () => { - const endpoints = [{ route, response }]; - const { data, isFetched } = await mockHook({ - endpoints, - hook: () => hooks.useFileContent(undefined), - wrapper, - enabled: false, - }); - - expect(data).toBeFalsy(); - expect(isFetched).toBeFalsy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); + it(`Undefined id does not fetch`, async () => { + const endpoints = [{ route, response }]; + const { data, isFetched } = await mockHook({ + endpoints, + hook: () => hooks.useFileContent(undefined), + wrapper, + enabled: false, }); - it(`enabled=false does not fetch file`, async () => { - // build endpoint for each item - const endpoints: Endpoint[] = []; - const { data, isFetched } = await mockHook({ - hook: () => hooks.useFileContent(id, { enabled: false }), - endpoints, - wrapper, - enabled: false, - }); - - expect(data).toBeFalsy(); - expect(isFetched).toBeFalsy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); + expect(data).toBeFalsy(); + expect(isFetched).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); + }); + + it(`enabled=false does not fetch file`, async () => { + // build endpoint for each item + const endpoints: Endpoint[] = []; + const { data, isFetched } = await mockHook({ + hook: () => hooks.useFileContent(id, { enabled: false }), + endpoints, + wrapper, + enabled: false, }); - it(`Unauthorized`, async () => { - const endpoints = [ - { - route, - response: UNAUTHORIZED_RESPONSE, - statusCode: StatusCodes.UNAUTHORIZED, + expect(data).toBeFalsy(); + expect(isFetched).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); + }); + + it(`Unauthorized`, async () => { + const endpoints = [ + { + route, + response: UNAUTHORIZED_RESPONSE, + statusCode: StatusCodes.UNAUTHORIZED, + }, + ]; + const { data, isError } = await mockHook({ + hook, + endpoints, + wrapper, + }); + + expect(isError).toBeTruthy(); + expect(data).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); + }); +}); + +describe('useItemThumbnail', () => { + afterEach(() => { + nock.cleanAll(); + queryClient.clear(); + }); + + const item = FolderItemFactory(); + const replyUrl = false; + const key = itemKeys.single(item.id).thumbnail({ replyUrl }); + const response = THUMBNAIL_BLOB_RESPONSE; + const route = `/${buildDownloadItemThumbnailRoute({ + id: item.id, + replyUrl, + })}`; + const hook = () => hooks.useItemThumbnail({ id: item.id }); + + it(`Receive default thumbnail`, async () => { + const endpoints = [ + { + route, + response, + headers: { + 'Content-Type': 'image/jpeg', }, - ]; - const { data, isError } = await mockHook({ - hook, - endpoints, - wrapper, - }); - - expect(isError).toBeTruthy(); - expect(data).toBeFalsy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - }); + }, + ]; + const { data } = await mockHook({ endpoints, hook, wrapper }); + + expect(data).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeTruthy(); }); - describe('useItemThumbnail', () => { - const item = FolderItemFactory(); - const replyUrl = false; - const key = itemKeys.single(item.id).thumbnail({ replyUrl }); - const response = THUMBNAIL_BLOB_RESPONSE; - const route = `/${buildDownloadItemThumbnailRoute({ + it(`Receive large thumbnail`, async () => { + const size = ThumbnailSize.Large; + const routeLarge = `/${buildDownloadItemThumbnailRoute({ id: item.id, + size, replyUrl, })}`; - const hook = () => hooks.useItemThumbnail({ id: item.id }); - - it(`Receive default thumbnail`, async () => { - const endpoints = [ - { - route, - response, - headers: { - 'Content-Type': 'image/jpeg', - }, - }, - ]; - const { data } = await mockHook({ endpoints, hook, wrapper }); + const hookLarge = () => hooks.useItemThumbnail({ id: item.id, size }); + const keyLarge = itemKeys.single(item.id).thumbnail({ size }); - expect(data).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeTruthy(); - }); - - it(`Receive large thumbnail`, async () => { - const size = ThumbnailSize.Large; - const routeLarge = `/${buildDownloadItemThumbnailRoute({ - id: item.id, - size, - replyUrl, - })}`; - const hookLarge = () => hooks.useItemThumbnail({ id: item.id, size }); - const keyLarge = itemKeys.single(item.id).thumbnail({ size }); - - const endpoints = [ - { - route: routeLarge, - response, - headers: { - 'Content-Type': 'image/jpeg', - }, + const endpoints = [ + { + route: routeLarge, + response, + headers: { + 'Content-Type': 'image/jpeg', }, - ]; - const { data } = await mockHook({ - endpoints, - hook: hookLarge, - wrapper, - }); - - expect(data).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(keyLarge)).toBeTruthy(); + }, + ]; + const { data } = await mockHook({ + endpoints, + hook: hookLarge, + wrapper, }); - it(`Undefined id does not fetch`, async () => { - const endpoints = [ - { - route, - response, - }, - ]; - const { data, isFetched } = await mockHook({ - endpoints, - hook: () => hooks.useItemThumbnail({ id: undefined }), - wrapper, - enabled: false, - }); - - expect(data).toBeFalsy(); - expect(isFetched).toBeFalsy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - }); + expect(data).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(keyLarge)).toBeTruthy(); + }); - it(`Does not fetch if item has no thumbnail`, async () => { - const itemWithoutThumbnail = { - ...item, - settings: { hasThumbnail: false }, - }; - queryClient.setQueryData( - itemKeys.single(itemWithoutThumbnail.id).content, - itemWithoutThumbnail, - ); - const endpoints = [ - { - route, - response, - }, - ]; - const { data, isFetched } = await mockHook({ - endpoints, - hook: () => hooks.useItemThumbnail({ id: itemWithoutThumbnail.id }), - wrapper, - enabled: false, - }); - - expect(data).toBeFalsy(); - expect(isFetched).toBeFalsy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - }); + it(`Undefined id does not fetch`, async () => { + const endpoints = [ + { + route, + response, + }, + ]; + const { data, isFetched } = await mockHook({ + endpoints, + hook: () => hooks.useItemThumbnail({ id: undefined }), + wrapper, + enabled: false, + }); + + expect(data).toBeFalsy(); + expect(isFetched).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); + }); - it(`Unauthorized`, async () => { - const endpoints = [ - { - route, - response: UNAUTHORIZED_RESPONSE, - statusCode: StatusCodes.UNAUTHORIZED, - }, - ]; - const { data, isError } = await mockHook({ endpoints, hook, wrapper }); + it(`Does not fetch if item has no thumbnail`, async () => { + const itemWithoutThumbnail = { + ...item, + settings: { hasThumbnail: false }, + }; + queryClient.setQueryData( + itemKeys.single(itemWithoutThumbnail.id).content, + itemWithoutThumbnail, + ); + const endpoints = [ + { + route, + response, + }, + ]; + const { data, isFetched } = await mockHook({ + endpoints, + hook: () => hooks.useItemThumbnail({ id: itemWithoutThumbnail.id }), + wrapper, + enabled: false, + }); + + expect(data).toBeFalsy(); + expect(isFetched).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); + }); - expect(data).toBeFalsy(); - expect(isError).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - }); + it(`Unauthorized`, async () => { + const endpoints = [ + { + route, + response: UNAUTHORIZED_RESPONSE, + statusCode: StatusCodes.UNAUTHORIZED, + }, + ]; + const { data, isError } = await mockHook({ endpoints, hook, wrapper }); + + expect(data).toBeFalsy(); + expect(isError).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); }); +}); + +describe('useItemThumbnailUrl', () => { + afterEach(() => { + nock.cleanAll(); + queryClient.clear(); + }); + + const item = FolderItemFactory(); + const replyUrl = true; + const key = itemKeys.single(item.id).thumbnail({ replyUrl }); + const response = THUMBNAIL_URL_RESPONSE; + const route = `/${buildDownloadItemThumbnailRoute({ + id: item.id, + replyUrl, + })}`; + const hook = () => hooks.useItemThumbnailUrl({ id: item.id }); + + it(`Receive default thumbnail`, async () => { + const endpoints = [ + { + route, + response, + }, + ]; + const { data } = await mockHook({ endpoints, hook, wrapper }); - describe('useItemThumbnailUrl', () => { - const item = FolderItemFactory(); - const replyUrl = true; - const key = itemKeys.single(item.id).thumbnail({ replyUrl }); - const response = THUMBNAIL_URL_RESPONSE; - const route = `/${buildDownloadItemThumbnailRoute({ + expect(data).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeTruthy(); + }); + + it(`Receive large thumbnail`, async () => { + const size = ThumbnailSize.Large; + const routeLarge = `/${buildDownloadItemThumbnailRoute({ id: item.id, + size, replyUrl, })}`; - const hook = () => hooks.useItemThumbnailUrl({ id: item.id }); + const hookLarge = () => hooks.useItemThumbnailUrl({ id: item.id, size }); + const keyLarge = itemKeys.single(item.id).thumbnail({ size, replyUrl }); - it(`Receive default thumbnail`, async () => { - const endpoints = [ - { - route, - response, - }, - ]; - const { data } = await mockHook({ endpoints, hook, wrapper }); - - expect(data).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeTruthy(); + const endpoints = [ + { + route: routeLarge, + response, + }, + ]; + const { data } = await mockHook({ + endpoints, + hook: hookLarge, + wrapper, }); - it(`Receive large thumbnail`, async () => { - const size = ThumbnailSize.Large; - const routeLarge = `/${buildDownloadItemThumbnailRoute({ - id: item.id, - size, - replyUrl, - })}`; - const hookLarge = () => hooks.useItemThumbnailUrl({ id: item.id, size }); - const keyLarge = itemKeys.single(item.id).thumbnail({ size, replyUrl }); - - const endpoints = [ - { - route: routeLarge, - response, - }, - ]; - const { data } = await mockHook({ - endpoints, - hook: hookLarge, - wrapper, - }); - - expect(data).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(keyLarge)).toBeTruthy(); - }); + expect(data).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(keyLarge)).toBeTruthy(); + }); - it(`Undefined id does not fetch`, async () => { - const endpoints = [ - { - route, - response, - }, - ]; - const { data, isFetched } = await mockHook({ - endpoints, - hook: () => hooks.useItemThumbnail({ id: undefined }), - wrapper, - enabled: false, - }); - - expect(data).toBeFalsy(); - expect(isFetched).toBeFalsy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - }); + it(`Undefined id does not fetch`, async () => { + const endpoints = [ + { + route, + response, + }, + ]; + const { data, isFetched } = await mockHook({ + endpoints, + hook: () => hooks.useItemThumbnail({ id: undefined }), + wrapper, + enabled: false, + }); + + expect(data).toBeFalsy(); + expect(isFetched).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); + }); - it(`Does not fetch if item has no thumbnail`, async () => { - const itemWithoutThumbnail = { - ...item, - settings: { hasThumbnail: false }, - }; - queryClient.setQueryData( - itemKeys.single(itemWithoutThumbnail.id).content, - itemWithoutThumbnail, - ); - const endpoints = [ - { - route, - response, - }, - ]; - const { data, isFetched } = await mockHook({ - endpoints, - hook: () => hooks.useItemThumbnail({ id: itemWithoutThumbnail.id }), - wrapper, - enabled: false, - }); - - expect(data).toBeFalsy(); - expect(isFetched).toBeFalsy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - }); + it(`Does not fetch if item has no thumbnail`, async () => { + const itemWithoutThumbnail = { + ...item, + settings: { hasThumbnail: false }, + }; + queryClient.setQueryData( + itemKeys.single(itemWithoutThumbnail.id).content, + itemWithoutThumbnail, + ); + const endpoints = [ + { + route, + response, + }, + ]; + const { data, isFetched } = await mockHook({ + endpoints, + hook: () => hooks.useItemThumbnail({ id: itemWithoutThumbnail.id }), + wrapper, + enabled: false, + }); + + expect(data).toBeFalsy(); + expect(isFetched).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); + }); - it(`Unauthorized`, async () => { - const endpoints = [ - { - route, - response: UNAUTHORIZED_RESPONSE, - statusCode: StatusCodes.UNAUTHORIZED, - }, - ]; - const { data, isError } = await mockHook({ endpoints, hook, wrapper }); + it(`Unauthorized`, async () => { + const endpoints = [ + { + route, + response: UNAUTHORIZED_RESPONSE, + statusCode: StatusCodes.UNAUTHORIZED, + }, + ]; + const { data, isError } = await mockHook({ endpoints, hook, wrapper }); + + expect(data).toBeFalsy(); + expect(isError).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); + }); +}); - expect(data).toBeFalsy(); - expect(isError).toBeTruthy(); - // verify cache keys - expect(queryClient.getQueryData(key)).toBeFalsy(); - }); +describe('useDescendants', () => { + afterEach(() => { + nock.cleanAll(); + queryClient.clear(); + }); + + const item = FolderItemFactory(); + const response = { item, ...generateFolders(3) }; + + it('Gets descendants with type filter', async () => { + const types = [ItemType.FOLDER, ItemType.APP]; + const key = itemKeys.single(item.id).descendants({ types }); + const hook = () => hooks.useDescendants({ id: item.id, types }); + const route = `/${buildGetItemDescendants(item.id)}?${types.map((t) => `types=${t}`).join('&')}`; + const endpoints = [ + { + route, + response, + }, + ]; + const { data, isError } = await mockHook({ endpoints, hook, wrapper }); + + expect(data).toBeTruthy(); + expect(isError).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeTruthy(); + }); + + it('Gets descendants with showHidden disabled', async () => { + const key = itemKeys.single(item.id).descendants({ showHidden: false }); + const hook = () => hooks.useDescendants({ id: item.id, showHidden: false }); + const route = `/${buildGetItemDescendants(item.id)}?showHidden=false`; + const endpoints = [ + { + route, + response, + }, + ]; + const { data, isError } = await mockHook({ endpoints, hook, wrapper }); + + expect(data).toBeTruthy(); + expect(isError).toBeFalsy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeTruthy(); + }); + + it(`Unauthorized`, async () => { + const key = itemKeys.single(item.id).descendants(); + const hook = () => hooks.useDescendants({ id: item.id }); + const route = `/${buildGetItemDescendants(item.id)}`; + const endpoints = [ + { + route, + response: UNAUTHORIZED_RESPONSE, + statusCode: StatusCodes.UNAUTHORIZED, + }, + ]; + const { data, isError } = await mockHook({ endpoints, hook, wrapper }); + + expect(data).toBeFalsy(); + expect(isError).toBeTruthy(); + // verify cache keys + expect(queryClient.getQueryData(key)).toBeFalsy(); }); }); diff --git a/src/hooks/item.ts b/src/hooks/item.ts index e810f2b5..5feff5a5 100644 --- a/src/hooks/item.ts +++ b/src/hooks/item.ts @@ -1,4 +1,5 @@ import { + ItemTypeUnion, MAX_TARGETS_FOR_READ_REQUEST, PackedItem, UUID, @@ -208,15 +209,25 @@ const config = ( }); }, - useDescendants: ({ id, enabled }: { id?: UUID; enabled?: boolean }) => { + useDescendants: ({ + id, + types, + showHidden, + enabled, + }: { + id?: UUID; + types?: ItemTypeUnion[]; + showHidden?: boolean; + enabled?: boolean; + }) => { const queryClient = useQueryClient(); return useQuery({ - queryKey: itemKeys.single(id).descendants, + queryKey: itemKeys.single(id).descendants({ types, showHidden }), queryFn: () => { if (!id) { throw new UndefinedArgument(); } - return Api.getDescendants({ id }, queryConfig); + return Api.getDescendants({ id, types, showHidden }, queryConfig); }, onSuccess: async (items) => { if (items?.length) { @@ -232,14 +243,6 @@ const config = ( }); }, - /** @deprecated use useAccessibleItems */ - useSharedItems: () => - useQuery({ - queryKey: itemKeys.shared(), - queryFn: () => Api.getSharedItems(queryConfig), - ...defaultQueryOptions, - }), - useItem: ( id?: UUID, options?: {