import { CommonActions } from '@react-navigation/native' import { fireEvent, render } from '@testing-library/react-native' import React from 'react' import { Text } from 'react-native' import { Provider } from 'react-redux' import { getAppConfig } from 'src/appConfig' import { Screens } from 'src/navigator/Screens' import TabNavigator from 'src/navigator/TabNavigator' import { PublicAppConfig } from 'src/public/types' import MockedNavigator from 'test/MockedNavigator' import { createMockStore } from 'test/utils' jest.mock('src/appConfig') const mockGetAppConfig = jest.mocked(getAppConfig) const defaultConfig: PublicAppConfig = { registryName: 'test', displayName: 'test', deepLinkUrlScheme: 'test', } describe('TabNavigator', () => { beforeEach(() => { jest.clearAllMocks() mockGetAppConfig.mockReturnValue(defaultConfig) }) it('shows the expected tabs', () => { const store = createMockStore({}) const { queryByText, getByTestId } = render( ) // By Text expect(queryByText('bottomTabsNavigator.wallet.tabName')).toBeTruthy() expect(queryByText('bottomTabsNavigator.home.tabName')).toBeTruthy() expect(queryByText('bottomTabsNavigator.discover.tabName')).toBeTruthy() // By testId - useful for e2e tests expect(getByTestId('Tab/Wallet')).toBeTruthy() expect(getByTestId('Tab/Home')).toBeTruthy() expect(getByTestId('Tab/Discover')).toBeTruthy() }) it.each([ { testId: 'Tab/Wallet', tabName: 'bottomTabsNavigator.wallet.tabName', expectedScreen: Screens.TabWallet, }, { testId: 'Tab/Discover', tabName: 'bottomTabsNavigator.discover.tabName', expectedScreen: Screens.TabDiscover, }, ])( `navigates to non initial screens $expectedScreen`, async ({ testId, tabName, expectedScreen }) => { const store = createMockStore({}) const { getByText, getByTestId } = render( ) // Check that the tab contains the correct text expect(getByTestId(testId)).toContainElement(getByText(tabName)) // Check tab navigation await fireEvent.press(getByTestId(testId)) expect(CommonActions.navigate).toHaveBeenCalledWith({ name: expectedScreen, key: expect.stringMatching(new RegExp(`${expectedScreen}-\\S+`)), }) } ) it('does not attempt navigate to current screen', async () => { const store = createMockStore({}) const { getByText, getByTestId } = render( ) expect(getByTestId('Tab/Home')).toContainElement(getByText('bottomTabsNavigator.home.tabName')) await fireEvent.press(getByTestId('Tab/Home')) expect(CommonActions.navigate).not.toHaveBeenCalled() }) describe('with custom screen configuration', () => { it('shows configured tabs in specified order', () => { mockGetAppConfig.mockReturnValue({ ...defaultConfig, screens: { tabs: ({ defaultTabs }) => ({ screens: [defaultTabs.activity, defaultTabs.wallet], // Only showing 2 tabs in custom order }), }, }) const store = createMockStore({}) const { queryByText } = render( ) // Should show configured tabs expect(queryByText('bottomTabsNavigator.home.tabName')).toBeTruthy() expect(queryByText('bottomTabsNavigator.wallet.tabName')).toBeTruthy() // Should not show unconfigured tab expect(queryByText('bottomTabsNavigator.discover.tabName')).toBeFalsy() }) it('uses custom initial screen when configured', () => { mockGetAppConfig.mockReturnValue({ ...defaultConfig, screens: { tabs: ({ defaultTabs }) => ({ screens: [defaultTabs.wallet, defaultTabs.activity, defaultTabs.discover], initialScreen: 'discover', }), }, }) const store = createMockStore({}) const { getByTestId } = render( ) // Press discover tab - should not trigger navigation since it's the initial screen fireEvent.press(getByTestId('Tab/Discover')) expect(CommonActions.navigate).not.toHaveBeenCalled() // Press home tab - should trigger navigation since it's not the initial screen fireEvent.press(getByTestId('Tab/Home')) expect(CommonActions.navigate).toHaveBeenCalled() }) it('supports custom screen configuration objects', () => { mockGetAppConfig.mockReturnValue({ ...defaultConfig, screens: { tabs: ({ defaultTabs }) => ({ screens: [ defaultTabs.wallet, { name: 'custom-tab', component: () => Custom screen content, icon: jest.fn(), label: (t: any) => 'Custom tab', testID: 'Tab/CustomTab', }, ], initialScreen: 'custom-tab', }), }, }) const store = createMockStore({}) const { getByTestId, getByText } = render( ) // Check that the initial screen is the custom discover screen and displayed expect(getByText('Custom screen content')).toBeTruthy() expect(getByText('Custom tab')).toBeTruthy() expect(getByTestId('Tab/CustomTab')).toBeTruthy() }) }) })