From fc52b1d8b1820ee7c613361a73916d621c2e1e28 Mon Sep 17 00:00:00 2001 From: Martino Cesari Tomba <60693085+forrest57@users.noreply.github.com> Date: Fri, 14 Feb 2025 16:24:14 +0100 Subject: [PATCH] test: [IOCOM-1830] fimsHistoryNonEmptyContent tests (#6715) ## Short description tests for said component ## List of changes proposed in this pull request for fimsHistoryNonEmptyContent: - required tests - required mocks - snapshots - updated the jestSetup to include [its required setup for testing](https://shopify.github.io/flash-list/docs/testing/) - removal of deprecated component usage in favor of its updated version - addition of testIds where necessary - refactor of typing in order to better test - refactor of selector usage to include new, more direct selector that has already been implemented ## How to test automated tests should all pass correctly, also the "export" button should still work as intended. --------- Co-authored-by: Andrea --- jestSetup.js | 1 + .../components/FimsHistoryNonEmptyContent.tsx | 25 +- .../__mocks__/FimsHistoryListItemPicker.tsx | 5 + .../__mocks__/FimsHistoryLoaders.tsx | 3 + .../FimsHistoryNonEmptyContent.test.tsx | 169 + .../FimsHistoryNonEmptyContent.test.tsx.snap | 7016 +++++++++++++++++ .../__mocks__/useFimsHistoryResultToasts.tsx | 1 + .../fims/history/store/reducer/index.ts | 3 +- 8 files changed, 7210 insertions(+), 13 deletions(-) create mode 100644 ts/features/fims/history/components/__mocks__/FimsHistoryListItemPicker.tsx create mode 100644 ts/features/fims/history/components/__tests__/FimsHistoryNonEmptyContent.test.tsx create mode 100644 ts/features/fims/history/components/__tests__/__snapshots__/FimsHistoryNonEmptyContent.test.tsx.snap create mode 100644 ts/features/fims/history/hooks/__mocks__/useFimsHistoryResultToasts.tsx diff --git a/jestSetup.js b/jestSetup.js index 844325f538e..997eec3231d 100644 --- a/jestSetup.js +++ b/jestSetup.js @@ -12,6 +12,7 @@ import mockRNDeviceInfo from "react-native-device-info/jest/react-native-device- import mockZendesk from "./ts/__mocks__/io-react-native-zendesk.ts"; import "react-native-get-random-values"; +require("@shopify/flash-list/jestSetup"); jest.mock("@pagopa/io-react-native-zendesk", () => mockZendesk); jest.mock("@react-native-async-storage/async-storage", () => mockAsyncStorage); diff --git a/ts/features/fims/history/components/FimsHistoryNonEmptyContent.tsx b/ts/features/fims/history/components/FimsHistoryNonEmptyContent.tsx index a64e03d8f3d..7513f4ae52d 100644 --- a/ts/features/fims/history/components/FimsHistoryNonEmptyContent.tsx +++ b/ts/features/fims/history/components/FimsHistoryNonEmptyContent.tsx @@ -1,29 +1,28 @@ -import { Divider, IOStyles } from "@pagopa/io-app-design-system"; +import { Divider, FooterActions, IOStyles } from "@pagopa/io-app-design-system"; import { FlashList } from "@shopify/flash-list"; import { AccessHistoryPage } from "../../../../../definitions/fims_history/AccessHistoryPage"; -import * as RemoteValue from "../../../../common/model/RemoteValue"; -import { FooterActions } from "../../../../components/ui/FooterActions"; import { useFooterActionsMeasurements } from "../../../../hooks/useFooterActionsMeasurements"; import I18n from "../../../../i18n"; import { useIOSelector } from "../../../../store/hooks"; -import { LoadingFimsHistoryItemsFooter } from "../components/FimsHistoryLoaders"; import { useFimsHistoryExport } from "../hooks/useFimsHistoryResultToasts"; import { - fimsHistoryExportStateSelector, + isFimsHistoryExportingSelector, isFimsHistoryLoadingSelector } from "../store/selectors"; import { FimsHistoryHeaderComponent } from "./FimsHistoryHeaderComponent"; import { FimsHistoryListItemPicker } from "./FimsHistoryListItemPicker"; +import { LoadingFimsHistoryItemsFooter } from "./FimsHistoryLoaders"; + +export type FimsHistoryNonEmptyContentProps = { + accesses?: AccessHistoryPage; + fetchMore: () => void; +}; export const FimsHistoryNonEmptyContent = ({ accesses, fetchMore -}: { - accesses?: AccessHistoryPage; - fetchMore: () => void; -}) => { - const historyExportState = useIOSelector(fimsHistoryExportStateSelector); - const isHistoryExporting = RemoteValue.isLoading(historyExportState); +}: FimsHistoryNonEmptyContentProps) => { + const isHistoryExporting = useIOSelector(isFimsHistoryExportingSelector); const isHistoryLoading = useIOSelector(isFimsHistoryLoadingSelector); const { handleExportOnPress } = useFimsHistoryExport(); @@ -60,12 +59,14 @@ export const FimsHistoryNonEmptyContent = ({ {!shouldHideFooter && ( diff --git a/ts/features/fims/history/components/__mocks__/FimsHistoryListItemPicker.tsx b/ts/features/fims/history/components/__mocks__/FimsHistoryListItemPicker.tsx new file mode 100644 index 00000000000..f04d2920989 --- /dev/null +++ b/ts/features/fims/history/components/__mocks__/FimsHistoryListItemPicker.tsx @@ -0,0 +1,5 @@ +import { Text } from "react-native"; + +export const FimsHistoryListItemPicker = () => ( + TESTING LIST ITEM FROM PICKER +); diff --git a/ts/features/fims/history/components/__mocks__/FimsHistoryLoaders.tsx b/ts/features/fims/history/components/__mocks__/FimsHistoryLoaders.tsx index 76c5851457f..dfb947fe0be 100644 --- a/ts/features/fims/history/components/__mocks__/FimsHistoryLoaders.tsx +++ b/ts/features/fims/history/components/__mocks__/FimsHistoryLoaders.tsx @@ -1,3 +1,6 @@ import { Text } from "react-native"; export const LoadingFimsHistoryListItem = () => LOADING_LIST_ITEM; +export const LoadingFimsHistoryItemsFooter = () => ( + LOADING_FOOTER +); diff --git a/ts/features/fims/history/components/__tests__/FimsHistoryNonEmptyContent.test.tsx b/ts/features/fims/history/components/__tests__/FimsHistoryNonEmptyContent.test.tsx new file mode 100644 index 00000000000..05ea2b217a2 --- /dev/null +++ b/ts/features/fims/history/components/__tests__/FimsHistoryNonEmptyContent.test.tsx @@ -0,0 +1,169 @@ +jest.mock("../../hooks/useFimsHistoryResultToasts.tsx"); +jest.mock("../FimsHistoryLoaders.tsx"); +jest.mock("../FimsHistoryListItemPicker.tsx"); + +import * as pot from "@pagopa/ts-commons/lib/pot"; +import { fireEvent } from "@testing-library/react-native"; +import { createStore } from "redux"; +import { AccessHistoryPage } from "../../../../../../definitions/fims_history/AccessHistoryPage"; +import { + remoteLoading, + remoteReady +} from "../../../../../common/model/RemoteValue"; +import { applicationChangeState } from "../../../../../store/actions/application"; +import { appReducer } from "../../../../../store/reducers"; +import { GlobalState } from "../../../../../store/reducers/types"; +import { renderScreenWithNavigationStoreContext } from "../../../../../utils/testWrapper"; +import { FIMS_ROUTES } from "../../../common/navigation"; +import { + FimsHistoryNonEmptyContent, + FimsHistoryNonEmptyContentProps +} from "../FimsHistoryNonEmptyContent"; +import * as HOOK from "../../hooks/useFimsHistoryResultToasts"; + +const mockAccess = { + id: "TESTING", + redirect: { display_name: "TESTING", uri: "TESTING" }, + service_id: "TESTING_SID", + timestamp: new Date(0) +}; + +const mockAccesses: AccessHistoryPage = { + data: [mockAccess] +}; +const mockEmptyAccesses: AccessHistoryPage = { + data: [] +}; + +// ------------------- UTILS + +const generateMockStoreForSelectors = ( + isHistoryLoading: boolean, + isHistoryExporting: boolean +) => + ({ + features: { + fims: { + history: { + historyExportState: isHistoryExporting + ? remoteLoading + : remoteReady("SUCCESS"), + consentsList: isHistoryLoading ? pot.someLoading({}) : pot.none + } + } + } + } as GlobalState); +const renderComponent = ( + props: FimsHistoryNonEmptyContentProps, + mockState: GlobalState +) => { + const globalState = appReducer(mockState, applicationChangeState("active")); + + return renderScreenWithNavigationStoreContext( + () => , + FIMS_ROUTES.HISTORY, + {}, + createStore(appReducer, globalState as any) + ); +}; + +// --------------- END UTILS + +// eslint-disable-next-line sonarjs/cognitive-complexity +describe("fimsHistoryNonEmptyContent", () => { + beforeEach(() => { + jest.clearAllMocks(); + jest.restoreAllMocks(); + }); + + for (const historyLoading of [true, false]) { + for (const historyExporting of [true, false]) { + for (const hasAccesses of [true, false]) { + const fetchMore = jest.fn(); + const shouldShowLoadingListFooter = historyLoading; + const shouldRenderPageFooter = !historyLoading || hasAccesses; // component logic is !( hLoading && !accesses ) + const store = generateMockStoreForSelectors( + historyLoading, + historyExporting + ); + + const testString = `${+hasAccesses} accesses, historyLoading = ${historyLoading} and historyExporting = ${historyExporting}`; + + it(`should fetch automatically to try and fill the list, and match snapshot for ${testString} `, () => { + const component = renderComponent( + { + accesses: hasAccesses ? mockAccesses : mockEmptyAccesses, + fetchMore + }, + store + ); + expect(component).toBeTruthy(); + expect(component).toMatchSnapshot(); + expect(fetchMore).toHaveBeenCalledTimes(1); + }); + + it(`should ${ + shouldShowLoadingListFooter ? "" : "not" + } render list loading footer in case of ${testString} `, () => { + const component = renderComponent( + { + accesses: hasAccesses ? mockAccesses : mockEmptyAccesses, + fetchMore + }, + store + ); + if (shouldShowLoadingListFooter) { + expect(component.queryByTestId("testing-footer")).toBeTruthy(); + } else { + expect(component.queryByTestId("testing-footer")).toBeNull(); + } + }); + it(`should + ${shouldRenderPageFooter ? "" : "not"} + render export footer in case of ${testString} `, () => { + const component = renderComponent( + { + accesses: hasAccesses ? mockAccesses : mockEmptyAccesses, + fetchMore + }, + store + ); + if (shouldRenderPageFooter) { + expect(component.queryByTestId("export-footer")).toBeTruthy(); + } else { + expect(component.queryByTestId("export-footer")).toBeNull(); + } + }); + + if (shouldRenderPageFooter) { + const isPageFooterLoading = historyExporting; + it(`should ${ + isPageFooterLoading ? "not" : "" + } dispatch the onPress if the user taps the primary action in case of ${testString}`, () => { + const mockFetchMore = jest.fn(); + jest.spyOn(HOOK, "useFimsHistoryExport").mockReturnValue({ + handleExportOnPress: mockFetchMore + }); + + const component = renderComponent( + { + accesses: hasAccesses ? mockAccesses : mockEmptyAccesses, + fetchMore + }, + store + ); + + const renderedComponent = component.getByTestId("export-button"); + expect(renderedComponent).toBeTruthy(); + + fireEvent.press(renderedComponent); + + expect(mockFetchMore).toHaveBeenCalledTimes( + isPageFooterLoading ? 0 : 1 + ); + }); + } + } + } + } +}); diff --git a/ts/features/fims/history/components/__tests__/__snapshots__/FimsHistoryNonEmptyContent.test.tsx.snap b/ts/features/fims/history/components/__tests__/__snapshots__/FimsHistoryNonEmptyContent.test.tsx.snap new file mode 100644 index 00000000000..caae31e820b --- /dev/null +++ b/ts/features/fims/history/components/__tests__/__snapshots__/FimsHistoryNonEmptyContent.test.tsx.snap @@ -0,0 +1,7016 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`fimsHistoryNonEmptyContent should fetch automatically to try and fill the list, and match snapshot for 0 accesses, historyLoading = false and historyExporting = false 1`] = ` + + + + + + + + + + + + + + + FIMS_HISTORY + + + + + + + + + + + + + + + + + + + + + + + + + I tuoi accessi a servizi di terze parti + + + + Qui puoi consultare le cronologia dei tuoi accessi a servizi esterni tramite IO e richiederne una copia via email. + + + + + + + + + + + + + + + + + + + Richiedi una copia via email + + + + + + + + + + + + + + + + + +`; + +exports[`fimsHistoryNonEmptyContent should fetch automatically to try and fill the list, and match snapshot for 0 accesses, historyLoading = false and historyExporting = true 1`] = ` + + + + + + + + + + + + + + + FIMS_HISTORY + + + + + + + + + + + + + + + + + + + + + + + + + I tuoi accessi a servizi di terze parti + + + + Qui puoi consultare le cronologia dei tuoi accessi a servizi esterni tramite IO e richiederne una copia via email. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`fimsHistoryNonEmptyContent should fetch automatically to try and fill the list, and match snapshot for 0 accesses, historyLoading = true and historyExporting = false 1`] = ` + + + + + + + + + + + + + + + FIMS_HISTORY + + + + + + + + + + + + + + + + + + + + + + + + + I tuoi accessi a servizi di terze parti + + + + Qui puoi consultare le cronologia dei tuoi accessi a servizi esterni tramite IO e richiederne una copia via email. + + + + + + + + LOADING_FOOTER + + + + + + + + + + + + + + + + + + +`; + +exports[`fimsHistoryNonEmptyContent should fetch automatically to try and fill the list, and match snapshot for 0 accesses, historyLoading = true and historyExporting = true 1`] = ` + + + + + + + + + + + + + + + FIMS_HISTORY + + + + + + + + + + + + + + + + + + + + + + + + + I tuoi accessi a servizi di terze parti + + + + Qui puoi consultare le cronologia dei tuoi accessi a servizi esterni tramite IO e richiederne una copia via email. + + + + + + + + LOADING_FOOTER + + + + + + + + + + + + + + + + + + +`; + +exports[`fimsHistoryNonEmptyContent should fetch automatically to try and fill the list, and match snapshot for 1 accesses, historyLoading = false and historyExporting = false 1`] = ` + + + + + + + + + + + + + + + FIMS_HISTORY + + + + + + + + + + + + + + + + + + + + + + + + + I tuoi accessi a servizi di terze parti + + + + Qui puoi consultare le cronologia dei tuoi accessi a servizi esterni tramite IO e richiederne una copia via email. + + + + + + + + + TESTING LIST ITEM FROM PICKER + + + + + + + + + + + + + + + + + + Richiedi una copia via email + + + + + + + + + + + + + + + + + +`; + +exports[`fimsHistoryNonEmptyContent should fetch automatically to try and fill the list, and match snapshot for 1 accesses, historyLoading = false and historyExporting = true 1`] = ` + + + + + + + + + + + + + + + FIMS_HISTORY + + + + + + + + + + + + + + + + + + + + + + + + + I tuoi accessi a servizi di terze parti + + + + Qui puoi consultare le cronologia dei tuoi accessi a servizi esterni tramite IO e richiederne una copia via email. + + + + + + + + + TESTING LIST ITEM FROM PICKER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`fimsHistoryNonEmptyContent should fetch automatically to try and fill the list, and match snapshot for 1 accesses, historyLoading = true and historyExporting = false 1`] = ` + + + + + + + + + + + + + + + FIMS_HISTORY + + + + + + + + + + + + + + + + + + + + + + + + + I tuoi accessi a servizi di terze parti + + + + Qui puoi consultare le cronologia dei tuoi accessi a servizi esterni tramite IO e richiederne una copia via email. + + + + + + + + + TESTING LIST ITEM FROM PICKER + + + + + + + LOADING_FOOTER + + + + + + + + + + + + + + + Richiedi una copia via email + + + + + + + + + + + + + + + + + +`; + +exports[`fimsHistoryNonEmptyContent should fetch automatically to try and fill the list, and match snapshot for 1 accesses, historyLoading = true and historyExporting = true 1`] = ` + + + + + + + + + + + + + + + FIMS_HISTORY + + + + + + + + + + + + + + + + + + + + + + + + + I tuoi accessi a servizi di terze parti + + + + Qui puoi consultare le cronologia dei tuoi accessi a servizi esterni tramite IO e richiederne una copia via email. + + + + + + + + + TESTING LIST ITEM FROM PICKER + + + + + + + LOADING_FOOTER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; diff --git a/ts/features/fims/history/hooks/__mocks__/useFimsHistoryResultToasts.tsx b/ts/features/fims/history/hooks/__mocks__/useFimsHistoryResultToasts.tsx new file mode 100644 index 00000000000..9ef72dac52a --- /dev/null +++ b/ts/features/fims/history/hooks/__mocks__/useFimsHistoryResultToasts.tsx @@ -0,0 +1 @@ +export const useFimsHistoryExport = () => ({ handleExportOnPress: () => null }); diff --git a/ts/features/fims/history/store/reducer/index.ts b/ts/features/fims/history/store/reducer/index.ts index b7c7e940de9..1cfabfe8ef9 100644 --- a/ts/features/fims/history/store/reducer/index.ts +++ b/ts/features/fims/history/store/reducer/index.ts @@ -17,9 +17,10 @@ import { } from "../actions"; export type FimsExportSuccessStates = "SUCCESS" | "ALREADY_EXPORTING"; +export type FimsHistoryExportState = RemoteValue; export type FimsHistoryState = { - historyExportState: RemoteValue; + historyExportState: FimsHistoryExportState; consentsList: pot.Pot; };