From 5f295e0d008fb5db92b82f7ac1aa09dbbac06bbe Mon Sep 17 00:00:00 2001 From: Fran McDade Date: Tue, 19 Nov 2024 17:46:51 +1000 Subject: [PATCH] fix: add support for inclusion of orphans in verbatim PFB (#264) (#269) * fix!: add support for inclusion of orphans in verbatim PFB (#264) * feat: added tests for file facets status (#264) * feat: added tests for file manifest request filters (#264) * fix: import (#264) --------- Co-authored-by: Fran McDade --- .../downloadCurlCommand.tsx | 2 + .../ExportToTerra/exportToTerra.tsx | 8 +- .../manifestDownloadEntity.tsx | 8 +- .../ManifestDownload/manifestDownload.tsx | 2 + .../common/buildFileManifestRequestURL.ts | 7 +- src/hooks/useFileManifest/common/entities.ts | 11 +- .../useFileManifest/useRequestFileManifest.ts | 5 + src/providers/fileManifestState.tsx | 88 ++++------ src/providers/fileManifestState/actions.ts | 34 ++++ src/providers/fileManifestState/constants.ts | 31 ++++ src/providers/fileManifestState/utils.ts | 108 ++++++++++++ src/views/ExportView/exportView.tsx | 2 +- tests/fileManifestRequestFilters.test.ts | 160 ++++++++++++++++++ tests/updateFilesFacetsStatus.test.ts | 84 +++++++++ 14 files changed, 479 insertions(+), 71 deletions(-) create mode 100644 src/providers/fileManifestState/actions.ts create mode 100644 src/providers/fileManifestState/constants.ts create mode 100644 src/providers/fileManifestState/utils.ts create mode 100644 tests/fileManifestRequestFilters.test.ts create mode 100644 tests/updateFilesFacetsStatus.test.ts diff --git a/src/components/Export/components/DownloadCurlCommand/downloadCurlCommand.tsx b/src/components/Export/components/DownloadCurlCommand/downloadCurlCommand.tsx index de8e4f71..a3ac3b70 100644 --- a/src/components/Export/components/DownloadCurlCommand/downloadCurlCommand.tsx +++ b/src/components/Export/components/DownloadCurlCommand/downloadCurlCommand.tsx @@ -32,11 +32,13 @@ export const DownloadCurlCommand = ({ DownloadCurlStart, DownloadCurlSuccess, fileManifestState, + fileManifestType, fileSummaryFacetName, filters, formFacet, }: DownloadCurlCommandProps): JSX.Element => { useRequestFileManifest( + fileManifestType, MANIFEST_DOWNLOAD_FORMAT.CURL, filters, fileSummaryFacetName diff --git a/src/components/Export/components/ExportToTerra/exportToTerra.tsx b/src/components/Export/components/ExportToTerra/exportToTerra.tsx index a892b736..eaa5e3d9 100644 --- a/src/components/Export/components/ExportToTerra/exportToTerra.tsx +++ b/src/components/Export/components/ExportToTerra/exportToTerra.tsx @@ -29,6 +29,7 @@ export const ExportToTerra = ({ ExportToTerraStart, ExportToTerraSuccess, fileManifestState, + fileManifestType, fileSummaryFacetName, filters, formFacet, @@ -38,7 +39,12 @@ export const ExportToTerra = ({ const { exploreState: { tabValue: entityList }, } = useExploreState(); - useRequestFileManifest(manifestDownloadFormat, filters, fileSummaryFacetName); + useRequestFileManifest( + fileManifestType, + manifestDownloadFormat, + filters, + fileSummaryFacetName + ); const { requestParams } = fileManifestState; const { data, isLoading, run } = useFileManifest(); const exportURL = useExportToTerraResponseURL(requestParams, data); diff --git a/src/components/Export/components/ManifestDownload/components/ManifestDownloadEntity/manifestDownloadEntity.tsx b/src/components/Export/components/ManifestDownload/components/ManifestDownloadEntity/manifestDownloadEntity.tsx index 3be2974e..94b073bc 100644 --- a/src/components/Export/components/ManifestDownload/components/ManifestDownloadEntity/manifestDownloadEntity.tsx +++ b/src/components/Export/components/ManifestDownload/components/ManifestDownloadEntity/manifestDownloadEntity.tsx @@ -13,10 +13,16 @@ export interface ManifestDownloadEntityProps { } export const ManifestDownloadEntity = ({ + fileManifestType, filters, metadataFilters, }: ManifestDownloadEntityProps): JSX.Element => { - useRequestFileManifest(MANIFEST_DOWNLOAD_FORMAT.COMPACT, filters, undefined); + useRequestFileManifest( + fileManifestType, + MANIFEST_DOWNLOAD_FORMAT.COMPACT, + filters, + undefined + ); return ( <> diff --git a/src/components/Export/components/ManifestDownload/manifestDownload.tsx b/src/components/Export/components/ManifestDownload/manifestDownload.tsx index 1ebcb20e..5ca93d9f 100644 --- a/src/components/Export/components/ManifestDownload/manifestDownload.tsx +++ b/src/components/Export/components/ManifestDownload/manifestDownload.tsx @@ -25,6 +25,7 @@ export interface ManifestDownloadProps { export const ManifestDownload = ({ fileManifestState, + fileManifestType, fileSummaryFacetName, filters, formFacet, @@ -33,6 +34,7 @@ export const ManifestDownload = ({ ManifestDownloadSuccess, }: ManifestDownloadProps): JSX.Element => { useRequestFileManifest( + fileManifestType, MANIFEST_DOWNLOAD_FORMAT.COMPACT, filters, fileSummaryFacetName diff --git a/src/hooks/useFileManifest/common/buildFileManifestRequestURL.ts b/src/hooks/useFileManifest/common/buildFileManifestRequestURL.ts index cac9da51..f84ea8d6 100644 --- a/src/hooks/useFileManifest/common/buildFileManifestRequestURL.ts +++ b/src/hooks/useFileManifest/common/buildFileManifestRequestURL.ts @@ -20,13 +20,12 @@ export interface FileManifestRequestURL { */ export const buildFileManifestRequestURL = ( url: string, - filters: Filters, + filters: Filters | undefined, catalog: string, manifestFormat: ManifestDownloadFormat | undefined ): FileManifestRequestURL | undefined => { - if (!manifestFormat) { - return; - } + if (!manifestFormat) return; + if (!filters) return; // Build request params. const requestParams = new URLSearchParams({ diff --git a/src/hooks/useFileManifest/common/entities.ts b/src/hooks/useFileManifest/common/entities.ts index 2e9180c6..0401b0ab 100644 --- a/src/hooks/useFileManifest/common/entities.ts +++ b/src/hooks/useFileManifest/common/entities.ts @@ -37,21 +37,20 @@ export interface FileFacet { export enum FILE_MANIFEST_TYPE { BULK_DOWNLOAD = "BULK_DOWNLOAD", DOWNLOAD_MANIFEST = "DOWNLOAD_MANIFEST", - ENITY_EXPORT_TO_TERRA = "ENITY_EXPORT_TO_TERRA", ENTITY_BULK_DOWNLOAD = "ENTITY_BULK_DOWNLOAD", ENTITY_DOWNLOAD_MANIFEST = "ENTITY_DOWNLOAD_MANIFEST", + ENTITY_EXPORT_TO_TERRA = "ENTITY_EXPORT_TO_TERRA", EXPORT_TO_TERRA = "EXPORT_TO_TERRA", } export type FileManifestType = FILE_MANIFEST_TYPE; -export enum FILE_MANIFEST_STATE_STATUS { - ACTIVE = "ACTIVE", - INACTIVE = "INACTIVE", +export enum FILES_FACETS_STATUS { + COMPLETED = "COMPLETED", + IN_PROGRESS = "IN_PROGRESS", + NOT_STARTED = "NOT_STARTED", } -export type FileManifestStateStatus = FILE_MANIFEST_STATE_STATUS; - export type SelectedSearchTermsBySearchKey = Map< CategoryKey, Set diff --git a/src/hooks/useFileManifest/useRequestFileManifest.ts b/src/hooks/useFileManifest/useRequestFileManifest.ts index 97b1cd5d..a2b4066c 100644 --- a/src/hooks/useFileManifest/useRequestFileManifest.ts +++ b/src/hooks/useFileManifest/useRequestFileManifest.ts @@ -3,14 +3,17 @@ import { ManifestDownloadFormat } from "../../apis/azul/common/entities"; import { Filters } from "../../common/entities"; import { FileManifestActionKind } from "../../providers/fileManifestState"; import { useFileManifestState } from "../useFileManifestState"; +import { FileManifestType } from "./common/entities"; /** * Initializes and fetches file manifest comprising file facets and summary for the given file manifest format. + * @param fileManifestType - File manifest type. * @param fileManifestFormat - File manifest format. * @param initialFilters - Filters to initialize file manifest request. * @param fileSummaryFacetName - File summary facet name. */ export const useRequestFileManifest = ( + fileManifestType: FileManifestType | undefined, fileManifestFormat: ManifestDownloadFormat | undefined, initialFilters: Filters | undefined = [], fileSummaryFacetName?: string @@ -26,6 +29,7 @@ export const useRequestFileManifest = ( fileManifestDispatch({ payload: { fileManifestFormat, + fileManifestType, fileSummaryFacetName, filters: initFilters, }, @@ -40,6 +44,7 @@ export const useRequestFileManifest = ( }, [ fileManifestDispatch, fileManifestFormat, + fileManifestType, fileSummaryFacetName, initFilters, ]); diff --git a/src/providers/fileManifestState.tsx b/src/providers/fileManifestState.tsx index 737f6790..36200a5b 100644 --- a/src/providers/fileManifestState.tsx +++ b/src/providers/fileManifestState.tsx @@ -19,36 +19,26 @@ import { import { useCatalog } from "../hooks/useCatalog"; import { buildNextFilterState } from "../hooks/useCategoryFilter"; import { buildFileManifestRequestURL } from "../hooks/useFileManifest/common/buildFileManifestRequestURL"; -import { FileFacet } from "../hooks/useFileManifest/common/entities"; +import { + FileFacet, + FileManifestType, + FILES_FACETS_STATUS, +} from "../hooks/useFileManifest/common/entities"; import { useFetchFilesFacets } from "../hooks/useFileManifest/useFetchFilesFacets"; import { useFetchSummary } from "../hooks/useFileManifest/useFetchSummary"; import { useFileManifestURL } from "../hooks/useFileManifest/useFileManifestURL"; - -// Default file manifest state. -export const DEFAULT_FILE_MANIFEST_STATE = { - fileManifestFormat: undefined, - fileSummary: undefined, - fileSummaryFacetName: undefined, - fileSummaryFilters: [], - filesFacets: [], - filters: [], - isEnabled: false, - isFacetsLoading: false, - isFacetsSuccess: false, - isFileSummaryLoading: false, - isLoading: false, - isSummaryLoading: false, - requestParams: undefined, - requestURL: undefined, - summary: undefined, -}; +import { updateFileManifestAction } from "./fileManifestState/actions"; +import { FILE_MANIFEST_STATE } from "./fileManifestState/constants"; +import { getRequestFilters } from "./fileManifestState/utils"; /** * File manifest state. */ export type FileManifestState = { fileManifestFormat?: ManifestDownloadFormat; + fileManifestType?: FileManifestType; filesFacets: FileFacet[]; + filesFacetsStatus: FILES_FACETS_STATUS; fileSummary?: AzulSummaryResponse; fileSummaryFacetName?: string; fileSummaryFilters: Filters; @@ -76,7 +66,7 @@ export const FileManifestStateContext = createContext({ // eslint-disable-next-line @typescript-eslint/no-empty-function -- allow dummy function for default state. fileManifestDispatch: () => {}, - fileManifestState: DEFAULT_FILE_MANIFEST_STATE, + fileManifestState: FILE_MANIFEST_STATE, }); export interface FileManifestStateProps { @@ -96,7 +86,7 @@ export function FileManifestStateProvider({ const [fileManifestState, fileManifestDispatch] = useReducer( (s: FileManifestState, a: FileManifestAction) => fileManifestReducer(s, a, { URL, catalog }), - DEFAULT_FILE_MANIFEST_STATE + FILE_MANIFEST_STATE ); const { fileSummaryFacetName, fileSummaryFilters, filters, isEnabled } = @@ -233,6 +223,7 @@ type UpdateFiltersCategoryAction = { */ type FetchFileManifestPayload = { fileManifestFormat?: ManifestDownloadFormat; + fileManifestType?: FileManifestType; fileSummaryFacetName?: string; filters: Filters; }; @@ -240,7 +231,7 @@ type FetchFileManifestPayload = { /** * Update file manifest payload. */ -type UpdateFileManifestPayload = { +export type UpdateFileManifestPayload = { filesFacets: FileFacet[]; fileSummary?: AzulSummaryResponse; isFacetsLoading: boolean; @@ -288,6 +279,7 @@ function fileManifestReducer( return { ...state, fileManifestFormat: undefined, + filesFacetsStatus: FILES_FACETS_STATUS.NOT_STARTED, isEnabled: false, requestParams: undefined, requestURL: undefined, @@ -300,35 +292,29 @@ function fileManifestReducer( payload.filters, payload.fileSummaryFacetName ); - // Build request params and request URL. - const { requestParams, requestURL } = - buildFileManifestRequestURL( - URL, - payload.filters, - catalog, - payload.fileManifestFormat - ) || {}; return { ...state, ...payload, fileSummaryFilters, isEnabled: true, - requestParams, - requestURL, + requestParams: undefined, + requestURL: undefined, }; } // Updates file manifest. case FileManifestActionKind.UpdateFileManifest: { - return { - ...state, - ...payload, - }; + return updateFileManifestAction(state, payload, fileManifestContext); } // Updates file manifest format. case FileManifestActionKind.UpdateFileManifestFormat: { // Build request params and request URL. const { requestParams, requestURL } = - buildFileManifestRequestURL(URL, state.filters, catalog, payload) || {}; + buildFileManifestRequestURL( + URL, + getRequestFilters(state), + catalog, + payload + ) || {}; return { ...state, fileManifestFormat: payload, @@ -350,20 +336,13 @@ function fileManifestReducer( filters, state.fileSummaryFacetName ); - // Build request params and request URL. - const { requestParams, requestURL } = - buildFileManifestRequestURL( - URL, - filters, - catalog, - state.fileManifestFormat - ) || {}; return { ...state, fileSummaryFilters, + filesFacetsStatus: FILES_FACETS_STATUS.NOT_STARTED, filters, - requestParams, - requestURL, + requestParams: undefined, + requestURL: undefined, }; } // Updates selected file manifest filters by category. @@ -379,20 +358,13 @@ function fileManifestReducer( filters, state.fileSummaryFacetName ); - // Build request params and request URL. - const { requestParams, requestURL } = - buildFileManifestRequestURL( - URL, - filters, - catalog, - state.fileManifestFormat - ) || {}; return { ...state, fileSummaryFilters, + filesFacetsStatus: FILES_FACETS_STATUS.NOT_STARTED, filters, - requestParams, - requestURL, + requestParams: undefined, + requestURL: undefined, }; } default: diff --git a/src/providers/fileManifestState/actions.ts b/src/providers/fileManifestState/actions.ts new file mode 100644 index 00000000..7936bc0f --- /dev/null +++ b/src/providers/fileManifestState/actions.ts @@ -0,0 +1,34 @@ +import { buildFileManifestRequestURL } from "../../hooks/useFileManifest/common/buildFileManifestRequestURL"; +import { + FileManifestContext, + FileManifestState, + UpdateFileManifestPayload, +} from "../fileManifestState"; +import { getRequestFilters, updateFilesFacetsStatus } from "./utils"; + +/** + * Update file manifest action. + * @param state - State. + * @param payload - Payload. + * @param context - Context. + * @returns state. + */ +export function updateFileManifestAction( + state: FileManifestState, + payload: UpdateFileManifestPayload, + context: FileManifestContext +): FileManifestState { + const { catalog, URL } = context; + const filesFacetsStatus = updateFilesFacetsStatus(state, payload); + const nextState = { ...state, ...payload, filesFacetsStatus }; + const fileManifestRequest = buildFileManifestRequestURL( + URL, + getRequestFilters(nextState), + catalog, + nextState.fileManifestFormat + ); + return { + ...nextState, + ...fileManifestRequest, + }; +} diff --git a/src/providers/fileManifestState/constants.ts b/src/providers/fileManifestState/constants.ts new file mode 100644 index 00000000..e568b0b1 --- /dev/null +++ b/src/providers/fileManifestState/constants.ts @@ -0,0 +1,31 @@ +import { + FILE_MANIFEST_TYPE, + FILES_FACETS_STATUS, +} from "../../hooks/useFileManifest/common/entities"; +import { FileManifestState } from "../fileManifestState"; + +export const ENTITIES_FILE_MANIFEST_TYPES: FILE_MANIFEST_TYPE[] = [ + FILE_MANIFEST_TYPE.BULK_DOWNLOAD, + FILE_MANIFEST_TYPE.DOWNLOAD_MANIFEST, + FILE_MANIFEST_TYPE.EXPORT_TO_TERRA, +]; + +export const FILE_MANIFEST_STATE: FileManifestState = { + fileManifestFormat: undefined, + fileManifestType: undefined, + fileSummary: undefined, + fileSummaryFacetName: undefined, + fileSummaryFilters: [], + filesFacets: [], + filesFacetsStatus: FILES_FACETS_STATUS.NOT_STARTED, + filters: [], + isEnabled: false, + isFacetsLoading: false, + isFacetsSuccess: false, + isFileSummaryLoading: false, + isLoading: false, + isSummaryLoading: false, + requestParams: undefined, + requestURL: undefined, + summary: undefined, +}; diff --git a/src/providers/fileManifestState/utils.ts b/src/providers/fileManifestState/utils.ts new file mode 100644 index 00000000..11169fc2 --- /dev/null +++ b/src/providers/fileManifestState/utils.ts @@ -0,0 +1,108 @@ +import { Filters } from "../../common/entities"; +import { + FileFacet, + FILES_FACETS_STATUS, +} from "../../hooks/useFileManifest/common/entities"; +import { findFacet } from "../../hooks/useFileManifest/common/utils"; +import { + FileManifestState, + UpdateFileManifestPayload, +} from "../fileManifestState"; +import { ENTITIES_FILE_MANIFEST_TYPES } from "./constants"; + +/** + * Generates the filters for a request URL based on the file manifest state. + * If all terms in a facet are selected, the corresponding facet is excluded. + * @param state - File manifest state. + * @returns filters for the request URL. + */ +export function getRequestFilters( + state: FileManifestState +): Filters | undefined { + if (state.filesFacetsStatus !== FILES_FACETS_STATUS.COMPLETED) return; + // Determine if the filters are user-selected. + if (isFiltersUserSelected(state)) { + return state.filters; + } + for (const filter of state.filters) { + const facet = findFacet(state.filesFacets, filter.categoryKey); + if (!facet) return [filter]; // The entity identifier related filter will not have a corresponding term facet. + } +} + +/** + * Returns true if filter values for each selected facet are partially selected. + * @param filters - Selected filters. + * @param filesFacets - Files facets. + * @returns true if the filters are partially selected. + */ +function isFiltersPartiallySelected( + filters: Filters, + filesFacets: FileFacet[] +): boolean { + for (const { categoryKey, value } of filters) { + const facet = findFacet(filesFacets, categoryKey); + if (!facet) continue; // Continue; the entity identifier related filter will not have a corresponding term facet. + if (value.length < facet.termCount) return true; + } + return false; +} + +/** + * Returns true if the filters are user-selected, when: + * - The file manifest type is not set. + * - The file manifest type is an entity list related type. + * - Filter values for each selected facet are partially selected. + * @param state - File manifest state. + * @returns true if the filters are user-selected. + */ +export function isFiltersUserSelected(state: FileManifestState): boolean { + if (!state.fileManifestType) return true; + if (ENTITIES_FILE_MANIFEST_TYPES.includes(state.fileManifestType)) + return true; + return isFiltersPartiallySelected(state.filters, state.filesFacets); +} + +/** + * Transitions the files facets' status. + * @param shouldTransition - True if transitioning, false otherwise. + * @param nextStatus - Next files facets' status. + * @param currentStatus - Current files facets' status. + * @returns files facets' status. + */ +export function transitionFilesFacetsStatus( + shouldTransition: boolean, + nextStatus: FILES_FACETS_STATUS, + currentStatus: FILES_FACETS_STATUS +): FILES_FACETS_STATUS { + return shouldTransition ? nextStatus : currentStatus; +} + +/** + * Returns the updated files facets' status. + * @param state - File manifest state. + * @param payload - Update file manifest payload. + * @returns files facets' status. + */ +export function updateFilesFacetsStatus( + state: FileManifestState, + payload: UpdateFileManifestPayload +): FILES_FACETS_STATUS { + if (state.filesFacetsStatus === FILES_FACETS_STATUS.NOT_STARTED) { + // If the current status is NOT_STARTED, transition to IN_PROGRESS if facets are loading. + return transitionFilesFacetsStatus( + payload.isFacetsLoading, + FILES_FACETS_STATUS.IN_PROGRESS, + FILES_FACETS_STATUS.NOT_STARTED + ); + } + if (state.filesFacetsStatus === FILES_FACETS_STATUS.IN_PROGRESS) { + // If the current status is IN_PROGRESS, transition to COMPLETED if facets are successfully loaded. + return transitionFilesFacetsStatus( + payload.isFacetsSuccess, + FILES_FACETS_STATUS.COMPLETED, + FILES_FACETS_STATUS.IN_PROGRESS + ); + } + return FILES_FACETS_STATUS.COMPLETED; +} diff --git a/src/views/ExportView/exportView.tsx b/src/views/ExportView/exportView.tsx index 9d24b950..88dff7fd 100644 --- a/src/views/ExportView/exportView.tsx +++ b/src/views/ExportView/exportView.tsx @@ -14,7 +14,7 @@ export const ExportView = (props: ExportViewProps): JSX.Element => { exploreState: { filterState }, } = useExploreState(); useUpdateURLSearchParams(); - useRequestFileManifest(undefined, filterState, undefined); + useRequestFileManifest(undefined, undefined, filterState, undefined); const { tabs, top } = useExportConfig(); const currentTab = tabs[0]; const { mainColumn, sideColumn } = currentTab; diff --git a/tests/fileManifestRequestFilters.test.ts b/tests/fileManifestRequestFilters.test.ts new file mode 100644 index 00000000..943deb77 --- /dev/null +++ b/tests/fileManifestRequestFilters.test.ts @@ -0,0 +1,160 @@ +import { Filters, SelectedFilter } from "../src/common/entities"; +import { + FILE_MANIFEST_TYPE, + FileFacet, + FILES_FACETS_STATUS, +} from "../src/hooks/useFileManifest/common/entities"; +import { FileManifestState } from "../src/providers/fileManifestState"; +import { FILE_MANIFEST_STATE } from "../src/providers/fileManifestState/constants"; +import { getRequestFilters } from "../src/providers/fileManifestState/utils"; + +const FILE_MANIFEST_STATE_NOT_STARTED: FileManifestState = { + ...FILE_MANIFEST_STATE, + filesFacetsStatus: FILES_FACETS_STATUS.NOT_STARTED, +}; + +const FILE_MANIFEST_STATE_IN_PROGRESS: FileManifestState = { + ...FILE_MANIFEST_STATE, + filesFacetsStatus: FILES_FACETS_STATUS.IN_PROGRESS, +}; + +const FILE_MANIFEST_STATE_COMPLETED: FileManifestState = { + ...FILE_MANIFEST_STATE, + filesFacetsStatus: FILES_FACETS_STATUS.COMPLETED, +}; + +const FILES_FACETS: Partial[] = [ + { + name: "category01", + termCount: 2, + }, + { + name: "category02", + termCount: 3, + }, +]; + +const FILTER_IDENTIFIER: SelectedFilter = { + categoryKey: "identifier", + value: ["value05"], +}; + +const FILTERS_COMPLETE_SET: Filters = [ + { categoryKey: "category01", value: ["value01", "value02"] }, + { categoryKey: "category02", value: ["value02", "value03", "value04"] }, +]; + +const FILTERS_SUBSET: Filters = [ + { categoryKey: "category01", value: ["value01"] }, + { categoryKey: "category02", value: ["value02", "value03", "value04"] }, +]; + +const FILE_MANIFEST_STATE_USER_SELECT_FILTERS: FileManifestState = { + ...FILE_MANIFEST_STATE, + filesFacetsStatus: FILES_FACETS_STATUS.COMPLETED, + filters: FILTERS_SUBSET, +}; + +describe("fileManifestRequestFilters", () => { + describe("when filters and facets are undefined or empty", () => { + test("returns undefined for empty filters and facets", () => { + expect( + getRequestFilters({ + ...FILE_MANIFEST_STATE, + }) + ).toBeUndefined(); + }); + }); + + describe("when checking filesFacetsStatus", () => { + test("returns undefined when status is NOT_STARTED", () => { + expect( + getRequestFilters(FILE_MANIFEST_STATE_NOT_STARTED) + ).toBeUndefined(); + }); + + test("returns undefined when status is IN_PROGRESS", () => { + expect( + getRequestFilters(FILE_MANIFEST_STATE_IN_PROGRESS) + ).toBeUndefined(); + }); + + test("returns request filters when status is COMPLETED", () => { + expect(FILE_MANIFEST_STATE_COMPLETED.fileManifestType).toBeUndefined(); + expect(getRequestFilters(FILE_MANIFEST_STATE_COMPLETED)).toEqual([]); + }); + }); + + describe("when filters are user-selected", () => { + describe("and fileManifestType is undefined", () => { + test("returns user-selected filters", () => { + expect( + getRequestFilters(FILE_MANIFEST_STATE_USER_SELECT_FILTERS) + ).toEqual(FILTERS_SUBSET); + }); + }); + + describe("and fileManifestType is ENTITY LIST", () => { + test("returns user-selected filters for BULK_DOWNLOAD", () => { + expect( + getRequestFilters({ + ...FILE_MANIFEST_STATE_USER_SELECT_FILTERS, + fileManifestType: FILE_MANIFEST_TYPE.BULK_DOWNLOAD, + }) + ).toEqual(FILTERS_SUBSET); + }); + + test("returns user-selected filters for DOWNLOAD_MANIFEST", () => { + expect( + getRequestFilters({ + ...FILE_MANIFEST_STATE_USER_SELECT_FILTERS, + fileManifestType: FILE_MANIFEST_TYPE.DOWNLOAD_MANIFEST, + }) + ).toEqual(FILTERS_SUBSET); + }); + + test("returns user-selected filters for EXPORT_TO_TERRA", () => { + expect( + getRequestFilters({ + ...FILE_MANIFEST_STATE_USER_SELECT_FILTERS, + fileManifestType: FILE_MANIFEST_TYPE.EXPORT_TO_TERRA, + }) + ).toEqual(FILTERS_SUBSET); + }); + }); + + test("returns user-selected filters that are a subset of facet terms", () => { + expect( + getRequestFilters({ + ...FILE_MANIFEST_STATE_USER_SELECT_FILTERS, + fileManifestType: FILE_MANIFEST_TYPE.ENTITY_BULK_DOWNLOAD, // FILE_MANIFEST_TYPE is NOT ENTITY LIST. + filesFacets: FILES_FACETS as FileFacet[], + }) + ).toEqual(FILTERS_SUBSET); + }); + }); + + describe("when filters are NOT user-selected", () => { + test("returns undefined when all terms are included, and identifier filter is not defined", () => { + expect( + getRequestFilters({ + ...FILE_MANIFEST_STATE_USER_SELECT_FILTERS, + fileManifestType: FILE_MANIFEST_TYPE.ENTITY_BULK_DOWNLOAD, // FILE_MANIFEST_TYPE is NOT ENTITY LIST. + filesFacets: FILES_FACETS as FileFacet[], + filters: FILTERS_COMPLETE_SET, + }) + ).toBeUndefined(); + }); + + test("returns identifier filter when all terms are included, and identifier filter is defined", () => { + const filters = getRequestFilters({ + ...FILE_MANIFEST_STATE_USER_SELECT_FILTERS, + fileManifestType: FILE_MANIFEST_TYPE.ENTITY_BULK_DOWNLOAD, // FILE_MANIFEST_TYPE is NOT ENTITY LIST. + filesFacets: FILES_FACETS as FileFacet[], + filters: [...FILTERS_COMPLETE_SET, FILTER_IDENTIFIER], + }); + expect(filters?.length).toBe(1); + expect(filters?.[0].categoryKey).toBe(FILTER_IDENTIFIER.categoryKey); + }); + }); +}); diff --git a/tests/updateFilesFacetsStatus.test.ts b/tests/updateFilesFacetsStatus.test.ts new file mode 100644 index 00000000..24174bcb --- /dev/null +++ b/tests/updateFilesFacetsStatus.test.ts @@ -0,0 +1,84 @@ +import { FILES_FACETS_STATUS } from "../src/hooks/useFileManifest/common/entities"; +import { + FileManifestState, + UpdateFileManifestPayload, +} from "../src/providers/fileManifestState"; +import { FILE_MANIFEST_STATE } from "../src/providers/fileManifestState/constants"; +import { updateFilesFacetsStatus } from "../src/providers/fileManifestState/utils"; + +const FILE_MANIFEST_STATE_NOT_STARTED: FileManifestState = { + ...FILE_MANIFEST_STATE, + filesFacetsStatus: FILES_FACETS_STATUS.NOT_STARTED, +}; + +const FILE_MANIFEST_STATE_IN_PROGRESS: FileManifestState = { + ...FILE_MANIFEST_STATE, + filesFacetsStatus: FILES_FACETS_STATUS.IN_PROGRESS, +}; + +const FILE_MANIFEST_STATE_COMPLETED: FileManifestState = { + ...FILE_MANIFEST_STATE, + filesFacetsStatus: FILES_FACETS_STATUS.COMPLETED, +}; + +const UPDATE_FILE_MANIFEST_PAYLOAD_IDLE = { + isFacetsLoading: false, + isFacetsSuccess: false, +} as UpdateFileManifestPayload; + +const UPDATE_FILE_MANIFEST_PAYLOAD_LOADING = { + isFacetsLoading: true, + isFacetsSuccess: false, +} as UpdateFileManifestPayload; + +const UPDATE_FILE_MANIFEST_PAYLOAD_SUCCESS = { + isFacetsLoading: false, + isFacetsSuccess: true, +} as UpdateFileManifestPayload; + +describe("updateFilesFacetsStatus", () => { + test("files facets NOT_STARTED, request is IDLE", () => { + expect( + updateFilesFacetsStatus( + FILE_MANIFEST_STATE_NOT_STARTED, + UPDATE_FILE_MANIFEST_PAYLOAD_IDLE + ) + ).toBe(FILES_FACETS_STATUS.NOT_STARTED); + }); + + test("files facets NOT_STARTED, request is LOADING", () => { + expect( + updateFilesFacetsStatus( + FILE_MANIFEST_STATE_NOT_STARTED, + UPDATE_FILE_MANIFEST_PAYLOAD_LOADING + ) + ).toBe(FILES_FACETS_STATUS.IN_PROGRESS); + }); + + test("files facets IN_PROGRESS, request is LOADING", () => { + expect( + updateFilesFacetsStatus( + FILE_MANIFEST_STATE_IN_PROGRESS, + UPDATE_FILE_MANIFEST_PAYLOAD_LOADING + ) + ).toBe(FILES_FACETS_STATUS.IN_PROGRESS); + }); + + test("files facets IN_PROGRESS, request is SUCCESS", () => { + expect( + updateFilesFacetsStatus( + FILE_MANIFEST_STATE_IN_PROGRESS, + UPDATE_FILE_MANIFEST_PAYLOAD_SUCCESS + ) + ).toBe(FILES_FACETS_STATUS.COMPLETED); + }); + + test("files facets COMPLETED, request is SUCCESS", () => { + expect( + updateFilesFacetsStatus( + FILE_MANIFEST_STATE_COMPLETED, + UPDATE_FILE_MANIFEST_PAYLOAD_SUCCESS + ) + ).toBe(FILES_FACETS_STATUS.COMPLETED); + }); +});