Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Niloofar/ Added test cases for BackButton and MenuContent components #138

Merged
merged 4 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/components/AppHeader/MobileMenu/MenuContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const MenuContent = () => {
className={clsx('pl-[4.8rem] pr-[1.6rem]', {
'border-b border-[#f2f3f4]': !removeBorderBottom,
})}
data-testid='dt_menu_item'
key={index}
>
{item.map(({ LeftComponent, RightComponent, as, href, label, onClick, target }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { MenuContent } from './MenuContent';
import { MenuHeader } from './MenuHeader';
import { ToggleButton } from './ToggleButton';

export const MobileMenu = () => {
const MobileMenu = () => {
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const { currentLang = 'EN', localize, switchLanguage } = useTranslations();
const { hideModal, isModalOpenFor, showModal } = useModalManager();
Expand Down Expand Up @@ -62,3 +62,5 @@ export const MobileMenu = () => {
</>
);
};

export default MobileMenu;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useDevice } from '@deriv-com/ui';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { BackButton } from '../BackButton';

const mockOnClick = jest.fn();

jest.mock('@deriv-com/ui', () => ({
...jest.requireActual('@deriv-com/ui'),
useDevice: jest.fn(() => ({ isMobile: true })),
}));

describe('BackButton Component', () => {
it('renders the button with the correct text', () => {
render(<BackButton buttonText='Go Back' onClick={mockOnClick} />);
expect(screen.getByRole('button')).toBeInTheDocument();
});

it('calls the onClick handler when clicked', async () => {
render(<BackButton buttonText='Go Back' onClick={mockOnClick} />);
await userEvent.click(screen.getByRole('button'));
expect(mockOnClick).toHaveBeenCalledTimes(1);
});

it('adjusts the text size for mobile devices', () => {
render(<BackButton buttonText='Go Back' onClick={mockOnClick} />);
const textComponent = screen.getByText('Go Back');
expect(textComponent).toHaveClass('derivs-text__size--lg');
});

it('uses a smaller text size for non-mobile devices', () => {
(useDevice as jest.Mock).mockReturnValue({ isMobile: false });
render(<BackButton buttonText='Go Back' onClick={mockOnClick} />);
const textComponent = screen.getByText('Go Back');
expect(textComponent).toHaveClass('derivs-text__size--md');
});
});
105 changes: 105 additions & 0 deletions src/components/AppHeader/MobileMenu/__tests__/MenuContent.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { useDevice } from '@deriv-com/ui';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MenuContent } from '../MenuContent';

const mockSettingsButtonClick = jest.fn();

jest.mock('@deriv-com/ui', () => ({
...jest.requireActual('@deriv-com/ui'),
useDevice: jest.fn(() => ({ isMobile: true })),
}));

jest.mock('@deriv-com/api-hooks', () => ({
useAuthData: jest.fn().mockReturnValue({
isAuthorized: true,
}),
}));

jest.mock('../../PlatformSwitcher', () => ({
PlatformSwitcher: () => <div>PlatformSwitcher</div>,
}));

jest.mock('../MobileMenuConfig', () => ({
MobileMenuConfig: jest.fn(() => [
[
{
as: 'a',
href: '/home',
label: 'Home',
LeftComponent: () => <span>Home Icon</span>,
removeBorderBottom: false,
},
],
[
{
as: 'button',
label: 'Settings',
LeftComponent: () => <span>Settings Icon</span>,
onClick: mockSettingsButtonClick,
removeBorderBottom: true,
},
],
]),
}));

describe('MenuContent Component', () => {
beforeEach(() => {
Object.defineProperty(window, 'matchMedia', {
value: jest.fn(),
writable: true,
});
});

it('renders PlatformSwitcher and MenuItem components correctly', () => {
render(<MenuContent />);
expect(screen.getByText('PlatformSwitcher')).toBeInTheDocument();
expect(screen.getByText('Home')).toBeInTheDocument();
expect(screen.getByText('Settings')).toBeInTheDocument();
});

it('renders MenuItem as an anchor when `as` prop is "a"', () => {
render(<MenuContent />);
expect(screen.getByRole('link', { name: 'Home Icon Home' })).toBeInTheDocument();
});

it('renders anchor props correctly', () => {
render(<MenuContent />);
const link = screen.getByRole('link', { name: 'Home Icon Home' });
expect(link).toBeInTheDocument();
expect(link).toHaveAttribute('href', '/home');
expect(screen.getByText('Home Icon')).toBeInTheDocument();
});

it('renders MenuItem as a button when `as` prop is "button"', () => {
render(<MenuContent />);
expect(screen.getByRole('button', { name: 'Settings Icon Settings' })).toBeInTheDocument();
});

it('renders button props correctly', async () => {
render(<MenuContent />);
const settingsButton = screen.getByRole('button', { name: 'Settings Icon Settings' });
expect(settingsButton).toBeInTheDocument();
await userEvent.click(settingsButton);
expect(mockSettingsButtonClick).toHaveBeenCalled();
});

it('adjusts text size for mobile devices', () => {
render(<MenuContent />);
const text = screen.getByText('Home');
expect(text).toHaveClass('derivs-text__size--md');
});

it('adjusts text size for desktop devices', () => {
(useDevice as jest.Mock).mockReturnValue({ isMobile: false });
render(<MenuContent />);
const text = screen.getByText('Home');
expect(text).toHaveClass('derivs-text__size--sm');
});

it('applies conditional border styles based on configuration', () => {
render(<MenuContent />);
expect(screen.getAllByTestId('dt_menu_item')[0]).toHaveClass('border-b');
expect(screen.getAllByTestId('dt_menu_item')[1]).not.toHaveClass('border-b');
});
});
1 change: 1 addition & 0 deletions src/components/AppHeader/MobileMenu/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as MobileMenu } from './MobileMenu';
44 changes: 44 additions & 0 deletions src/hooks/__tests__/useNavigatorOnline.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { act, renderHook } from '@testing-library/react';
import { useNavigatorOnline } from '../custom-hooks';

describe('useNavigatorOnline', () => {
it('initializes as true when browser is online', () => {
const { result } = renderHook(() => useNavigatorOnline());
expect(result.current).toBe(true);
});

it('sets status to false when offline event is triggered', () => {
const { result } = renderHook(() => useNavigatorOnline());

act(() => {
window.dispatchEvent(new Event('offline'));
});

expect(result.current).toBe(false);
});

it('sets status to true when online event is triggered', () => {
Object.defineProperty(navigator, 'onLine', {
value: false,
writable: true,
});

const { result } = renderHook(() => useNavigatorOnline());

act(() => {
window.dispatchEvent(new Event('online'));
});

expect(result.current).toBe(true);
});

it('removes event listeners on unmount', () => {
const addSpy = jest.spyOn(window, 'addEventListener');
const removeSpy = jest.spyOn(window, 'removeEventListener');
const { unmount } = renderHook(() => useNavigatorOnline());

expect(addSpy).toHaveBeenCalledTimes(2);
unmount();
expect(removeSpy).toHaveBeenCalledTimes(2);
});
});
34 changes: 34 additions & 0 deletions src/hooks/__tests__/useNetworkStatus.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { renderHook } from '@testing-library/react';
import { useNavigatorOnline, useNetworkStatus } from '../custom-hooks';

jest.mock('../custom-hooks/useNavigatorOnline');

describe('useNetworkStatus', () => {
it('initializes as online', () => {
(useNavigatorOnline as jest.Mock).mockReturnValue(true);
const { result } = renderHook(() => useNetworkStatus());
expect(result.current).toBe('online');
});

it('changes status to offline when network is down', () => {
(useNavigatorOnline as jest.Mock).mockReturnValue(false);
const { result } = renderHook(() => useNetworkStatus());
expect(result.current).toBe('offline');
});

it('reacts to changes in network status', () => {
(useNavigatorOnline as jest.Mock).mockReturnValue(true);
const { rerender, result } = renderHook(() => useNetworkStatus());
expect(result.current).toBe('online');

// Simulating network going offline
(useNavigatorOnline as jest.Mock).mockReturnValue(false);
rerender();
expect(result.current).toBe('offline');

// Simulating network coming back online
(useNavigatorOnline as jest.Mock).mockReturnValue(true);
rerender();
expect(result.current).toBe('online');
});
});
46 changes: 46 additions & 0 deletions src/hooks/__tests__/useSyncedTime.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { act, renderHook } from '@testing-library/react';
import { useSyncedTime } from '../custom-hooks';

const initialTime = Math.floor(Date.now() / 1000);

jest.mock('@deriv-com/api-hooks', () => ({
useTime: jest.fn(() => ({ data: initialTime })),
}));

describe('useSyncedTime', () => {
beforeAll(() => {
jest.useFakeTimers();
});

it('initializes with the current date', async () => {
const { result } = renderHook(() => useSyncedTime());
expect(result.current).toBe(initialTime);
});

it('updates server time every second', () => {
const { result } = renderHook(() => useSyncedTime());

act(() => {
jest.advanceTimersByTime(1000);
});

expect(result.current).toBe(initialTime + 1);
});

it('stops updating after unmount', () => {
const { result, unmount } = renderHook(() => useSyncedTime());

act(() => {
jest.advanceTimersByTime(3000);
});

expect(result.current).toBe(initialTime + 3);
unmount();

act(() => {
jest.advanceTimersByTime(1000);
});

expect(result.current).toBe(initialTime + 3);
});
});
Loading