diff --git a/src/components/AppHeader/MobileMenu/__tests__/MobileMenu.spec.tsx b/src/components/AppHeader/MobileMenu/__tests__/MobileMenu.spec.tsx new file mode 100644 index 00000000..787a3795 --- /dev/null +++ b/src/components/AppHeader/MobileMenu/__tests__/MobileMenu.spec.tsx @@ -0,0 +1,74 @@ +import { BrowserRouter } from 'react-router-dom'; +import { QueryParamProvider } from 'use-query-params'; +import { ReactRouter5Adapter } from 'use-query-params/adapters/react-router-5'; +import { useModalManager } from '@/hooks'; +import { useDevice } from '@deriv-com/ui'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import MobileMenu from '../MobileMenu'; + +jest.mock('@/hooks', () => ({ + useModalManager: jest.fn().mockReturnValue({ + hideModal: jest.fn(), + isModalOpenFor: jest.fn().mockReturnValue(false), + showModal: jest.fn(), + }), + useNetworkStatus: jest.fn().mockReturnValue('online'), + useSyncedTime: jest.fn(), +})); + +jest.mock('@deriv-com/ui', () => ({ + ...jest.requireActual('@deriv-com/ui'), + useDevice: jest.fn(), +})); + +jest.mock('@deriv-com/api-hooks', () => ({ + useAuthData: jest.fn().mockReturnValue({ + isAuthorized: true, + }), +})); + +jest.mock('@deriv-com/translations', () => ({ + useTranslations: jest.fn().mockReturnValue({ + currentLang: 'EN', + localize: jest.fn(text => text), + }), +})); + +const MobileMenuComponent = () => ( + + + + + +); + +describe('MobileMenu component', () => { + it('should not render when isDesktop is true', () => { + (useDevice as jest.Mock).mockReturnValue({ isDesktop: true }); + render(); + expect(screen.queryByText('Menu')).not.toBeInTheDocument(); + }); + + it('should render toggle button and handle click', async () => { + (useDevice as jest.Mock).mockReturnValue({ isDesktop: false }); + render(); + expect(screen.queryByText('Menu')).not.toBeInTheDocument(); + await userEvent.click(screen.getByRole('button')); + expect(screen.getByText('Menu')).toBeInTheDocument(); + }); + + it('should open the language settings', async () => { + (useDevice as jest.Mock).mockReturnValue({ isDesktop: false }); + const { isModalOpenFor, showModal } = useModalManager(); + + render(); + await userEvent.click(screen.getByRole('button')); + expect(screen.getByText('EN')).toBeInTheDocument(); + + await userEvent.click(screen.getByText('EN')); + + expect(showModal).toHaveBeenCalledWith('MobileLanguagesDrawer'); + expect(isModalOpenFor).toHaveBeenCalledWith('MobileLanguagesDrawer'); + }); +}); diff --git a/src/hooks/__tests__/useFullScreen.spec.tsx b/src/hooks/__tests__/useFullScreen.spec.tsx new file mode 100644 index 00000000..5f1e2e55 --- /dev/null +++ b/src/hooks/__tests__/useFullScreen.spec.tsx @@ -0,0 +1,48 @@ +import { act, renderHook } from '@testing-library/react'; +import { useFullScreen } from '../custom-hooks'; + +describe('useFullScreen', () => { + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('should add and remove fullscreen event listeners', () => { + const addEventListenerSpy = jest.spyOn(document, 'addEventListener'); + const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener'); + + const { unmount } = renderHook(() => useFullScreen()); + + expect(addEventListenerSpy).toHaveBeenCalledWith('fullscreenchange', expect.any(Function), false); + expect(addEventListenerSpy).toHaveBeenCalledWith('webkitfullscreenchange', expect.any(Function), false); + expect(addEventListenerSpy).toHaveBeenCalledWith('mozfullscreenchange', expect.any(Function), false); + expect(addEventListenerSpy).toHaveBeenCalledWith('MSFullscreenChange', expect.any(Function), false); + + unmount(); + + expect(removeEventListenerSpy).toHaveBeenCalledWith('fullscreenchange', expect.any(Function), false); + expect(removeEventListenerSpy).toHaveBeenCalledWith('webkitfullscreenchange', expect.any(Function), false); + expect(removeEventListenerSpy).toHaveBeenCalledWith('mozfullscreenchange', expect.any(Function), false); + expect(removeEventListenerSpy).toHaveBeenCalledWith('MSFullscreenChange', expect.any(Function), false); + }); + + it('should call requestFullscreen when trying to enter fullscreen', () => { + const requestFullscreenMock = jest.fn(); + document.documentElement.requestFullscreen = requestFullscreenMock; + const { result } = renderHook(() => useFullScreen()); + + act(() => { + result.current.toggleFullScreenMode(); + }); + + expect(requestFullscreenMock).toHaveBeenCalled(); + }); + + it('should clean up event listeners on unmount', () => { + const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener'); + const { unmount } = renderHook(() => useFullScreen()); + + unmount(); + + expect(removeEventListenerSpy).toHaveBeenCalledTimes(4); + }); +}); diff --git a/src/hooks/custom-hooks/useFullScreen.ts b/src/hooks/custom-hooks/useFullScreen.ts index bf50da23..639e57e5 100644 --- a/src/hooks/custom-hooks/useFullScreen.ts +++ b/src/hooks/custom-hooks/useFullScreen.ts @@ -20,13 +20,19 @@ const useFullScreen = () => { screenChange.forEach(event => { document.addEventListener(event, onFullScreen, false); }); + + return () => { + screenChange.forEach(event => { + document.removeEventListener(event, onFullScreen, false); + }); + }; }, [onFullScreen, screenChange]); - const toggleFullScreenMode = (event: MouseEvent) => { - event.stopPropagation(); + const toggleFullScreenMode = (event?: MouseEvent) => { + event?.stopPropagation(); - const exitFullScreen = exit.find(element => document[element as keyof Document]); - const requestFullScreen = request.find(element => document.documentElement[element as keyof HTMLElement]); + const exitFullScreen = exit.find(method => document[method as keyof Document]); + const requestFullScreen = request.find(method => document.documentElement[method as keyof HTMLElement]); if (isInFullScreenMode && exitFullScreen) { (document[exitFullScreen as keyof Document] as Document['exitFullscreen'])();