import React from "react"; import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext"; import { renderHook } from "@testing-library/react-hooks"; import { isNavBarVisible, useRoute } from "../"; import { Provider } from "react-redux"; import configureMockStore from "redux-mock-store"; import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NavigationContext"; import { ROUTE_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/routeTypes"; import { ScreenDataContext } from "@applicaster/zapp-react-native-ui-components/Contexts/ScreenDataContext"; const plugins = []; const rivers = { "river-player": { id: "river-player", plugin_type: "player", }, "river-general": { id: "river-general", plugin_type: "general", }, }; const contentTypes = { video: { screen_id: "river-player" }, link: { screen_id: "river-general" }, }; const screen = { id: "123", }; const entry = { id: "abc" }; const homeStack = { route: "/home", state: { screen, entry, }, }; const videoItem = { id: "video-1", type: { value: "video" }, }; const mockGetStackForPathname = jest.fn().mockReturnValue(homeStack); const mainStackNavigator = { getStackForPathname: mockGetStackForPathname, getModalState: () => {}, videoModalState: {}, canGoBack: jest.fn(), }; const _createWrapper = (Wrapper, props) => { return function CreatedWrapper({ children }: any) { return {children}; }; }; const videoModalNavigator = { ...mainStackNavigator, videoModalState: { item: videoItem }, }; const hookModalNavigator = { ...mainStackNavigator, }; const hookModalContextState = { isRunningInBackground: false, setIsRunningInBackground: jest.fn(), setIsPresentingFullScreen: jest.fn(), isPresentationFullScreen: true, isHooksExecutionInProgress: true, setIsHooksExecutionInProgress: jest.fn(), state: { path: "/home", screenData: { payload: { id: "hookExecutedInModal" } }, }, setState: jest.fn(), resetState: jest.fn(), hookPresentationMode: null, }; const hooksModalPathname = `${ROUTE_TYPES.HOOKS_MODAL}/${hookModalContextState.state.screenData.payload.id}`; jest.mock( "@applicaster/zapp-react-native-ui-components/Contexts/ZappHookModalContext", () => { // Define state inside mock factory to avoid hoisting issues const mockState = { isRunningInBackground: false, setIsRunningInBackground: jest.fn(), setIsPresentingFullScreen: jest.fn(), isPresentationFullScreen: true, isHooksExecutionInProgress: true, setIsHooksExecutionInProgress: jest.fn(), state: { path: "/home", screenData: { payload: { id: "hookExecutedInModal" } }, }, setState: jest.fn(), resetState: jest.fn(), hookPresentationMode: null, }; const mockHook = jest.fn((selector) => { return selector ? selector(mockState) : mockState; }) as jest.MockedFunction & { getState: () => typeof mockState }; // Add getState method to the mock hook (Zustand stores have this) mockHook.getState = jest.fn(() => mockState); return { useZappHookModalStore: mockHook, zappHookModalStore: mockHook, }; } ); const videoModalPathname = `${ROUTE_TYPES.VIDEO_MODAL}/${videoModalNavigator.videoModalState.item.id}`; const mockStore = configureMockStore(); const store = mockStore({ plugins, rivers, contentTypes, }); const mainStackWrapper = ({ children, navigator = {}, pathname = homeStack.route, }) => ( {children} ); const videoModalWrapper = ({ children }) => ( {children} ); const hookModalWrapper = ({ children }) => ( {children} ); describe("navigation", () => { describe("useRoute", () => { describe("Main stack components", () => { it("should return a correct pathname", () => { const { result } = renderHook(() => useRoute(), { wrapper: mainStackWrapper, }); expect(result.current.pathname).toEqual(homeStack.route); }); it("should return correct screenData information", () => { const { result } = renderHook(() => useRoute(), { wrapper: mainStackWrapper, }); expect(result.current.screenData.id).toEqual(entry.id); expect(result.current.screenData.targetScreen.id).toEqual(screen.id); }); }); describe("Hook modal components", () => { it("should return a correct pathname", () => { const { result } = renderHook(() => useRoute(), { wrapper: hookModalWrapper, }); expect(result.current.pathname).toEqual(hooksModalPathname); }); it("should return correct screenData information", () => { const { result } = renderHook(() => useRoute(), { wrapper: hookModalWrapper, }); expect(result.current.screenData.id).toEqual( hookModalContextState.state.screenData.payload.id ); }); }); describe("Video modal components", () => { it("should return a correct pathname", () => { const { result } = renderHook(() => useRoute(), { wrapper: videoModalWrapper, }); expect(result.current.pathname).toEqual(videoModalPathname); }); it("should return correct screenData information", () => { const { result } = renderHook(() => useRoute(), { wrapper: videoModalWrapper, }); expect(result.current.screenData.id).toEqual( videoModalNavigator.videoModalState.item.id ); expect(result.current.screenData.targetScreen.id).toEqual( rivers["river-player"].id ); }); }); }); describe("isNavBarVisible", () => { it("returns false when the route is a player route", () => { const navBarVisible = isNavBarVisible( "/playable/some_vod_item", {} as ZappRiver, false, false ); expect(navBarVisible).toBe(false); }); it("returns false when the next screen is the QB search screen", () => { const navBarVisible = isNavBarVisible( "/river/A1234", { type: "qb_search_screen", } as any, false, false ); expect(navBarVisible).toBe(false); }); describe("when screen is a hook", () => { it("returns true if the `showNavBar` flag is set to true", () => { const navBarVisible = isNavBarVisible( "", { hookPlugin: { module: { showNavBar: true, }, }, } as any, false, false ); expect(navBarVisible).toBe(true); }); it("returns true if presentFullScreen flag is set to false", () => { const navBarVisible = isNavBarVisible( "", { hookPlugin: { module: { presentFullScreen: false, }, }, } as any, false, false ); expect(navBarVisible).toBe(true); }); it("returns false if presentFullScreen flag is set to true", () => { const navBarVisible = isNavBarVisible( "", { hookPlugin: { module: { presentFullScreen: true, }, }, } as any, false, false ); expect(navBarVisible).toBe(false); }); }); it("returns false if the screen's general settings allow screen presentation", () => { const navBarVisible = isNavBarVisible( "", { general: { allow_screen_plugin_presentation: true, }, } as any, false, false ); expect(navBarVisible).toBe(false); }); it("returns false if the screen's general settings hide app nav bar", () => { const navBarVisible = isNavBarVisible( "", { general: { hide_app_nav_bar: true, }, } as any, false, false ); expect(navBarVisible).toBe(false); }); it("returns false if it's secondary nav bar and show_secondary_level_menu is false", () => { const navBarVisible = isNavBarVisible( "", { navigations: [ { styles: { show_secondary_level_menu: false, }, }, ], } as any, false, true ); expect(navBarVisible).toBe(false); }); it("returns true if it's secondary nav bar and show_secondary_level_menu is true", () => { const navBarVisible = isNavBarVisible( "", { navigations: [ { styles: { show_secondary_level_menu: true, }, }, ], } as any, true, false ); expect(navBarVisible).toBe(true); }); it("returns true if it's first level menu and show_secondary_level_menu is false", () => { const navBarVisible = isNavBarVisible( "", { navigations: [ { styles: { show_secondary_level_menu: false, }, }, ], } as any, true, false ); expect(navBarVisible).toBe(true); }); }); });