Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dauglyon committed Jan 22, 2025
1 parent d4ff1b3 commit 3112305
Show file tree
Hide file tree
Showing 7 changed files with 863 additions and 5 deletions.
7 changes: 4 additions & 3 deletions src/common/components/Loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const Loader = (props: {
...forwardProps
} = props;
return (
<Box sx={{ width, height, position: 'relative' }}>
<Box data-testid="loader" sx={{ width, height, position: 'relative' }}>
<Stack
direction="row"
justifyContent="center"
Expand All @@ -43,15 +43,16 @@ export const Loader = (props: {
if (props.render !== undefined) return <>{props.render}</>;
switch (props.type) {
case 'text':
return <>Loading...</>;
return <span data-testid="loader">Loading...</span>;
case 'spinner':
default:
return <FontAwesomeIcon icon={faSpinner} spin />;
return <FontAwesomeIcon data-testid="loader" icon={faSpinner} spin />;
}
}
if (props.error) {
return (
<Chip
data-testid="loader"
icon={<FontAwesomeIcon icon={faExclamationCircle} />}
variant="outlined"
color="error"
Expand Down
145 changes: 145 additions & 0 deletions src/features/account/Account.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { useEffect } from 'react';
import { MemoryRouter, Route, Routes, useLocation } from 'react-router-dom';
import { Account } from './Account';

// Mock component for the Outlet
let mockOutletLocation = '';
const MockOutlet = () => {
const location = useLocation();
useEffect(() => {
mockOutletLocation = location.pathname;
}, [location.pathname]);
return <div data-testid="mock-outlet">Outlet Content</div>;
};

// Mock scrollTo function since we're testing useEffect scroll behavior
const mockScrollTo = jest.fn();

describe('Account Component', () => {
afterEach(() => {
jest.clearAllMocks();
});

it('renders all tabs', () => {
render(
<MemoryRouter initialEntries={['/account/info']}>
<Routes>
<Route path="/account/*" element={<Account />}>
<Route path="*" element={<MockOutlet />} />
</Route>
</Routes>
</MemoryRouter>
);

expect(screen.getByText('Account')).toBeInTheDocument();
expect(screen.getByText('Linked Providers')).toBeInTheDocument();
expect(screen.getByText('Log In Sessions')).toBeInTheDocument();
expect(screen.getByText('Use Agreements')).toBeInTheDocument();
});

it('navigates to correct route when tab is clicked', () => {
render(
<MemoryRouter initialEntries={['/account/info']}>
<Routes>
<Route path="/account/*" element={<Account />}>
<Route path="*" element={<MockOutlet />} />
</Route>
</Routes>
</MemoryRouter>
);

fireEvent.click(screen.getByText('Linked Providers'));
expect(mockOutletLocation).toContain('/account/providers');

fireEvent.click(screen.getByText('Log In Sessions'));
expect(mockOutletLocation).toContain('/account/sessions');
});

it('scrolls to top when tab changes', () => {
render(
<MemoryRouter initialEntries={['/account/info']}>
<Routes>
<Route path="/account/*" element={<Account />}>
<Route path="*" element={<MockOutlet />} />
</Route>
</Routes>
</MemoryRouter>
);

const my_element = document.querySelector('main');
if (!my_element) return;
jest.spyOn(my_element, 'scrollTo').mockImplementation(mockScrollTo);

fireEvent.click(screen.getByText('Linked Providers'));
expect(mockScrollTo).toHaveBeenCalledWith(0, 0);
});

it('sets correct active tab based on current route', () => {
render(
<MemoryRouter initialEntries={['/account/providers']}>
<Routes>
<Route path="/account/*" element={<Account />}>
<Route path="*" element={<MockOutlet />} />
</Route>
</Routes>
</MemoryRouter>
);

const providersTab = screen.getByRole('tab', { name: 'Linked Providers' });
expect(providersTab).toHaveAttribute('aria-selected', 'true');
});

it('navigates to correct routes when tabs are clicked', () => {
render(
<MemoryRouter initialEntries={['/account']}>
<Routes>
<Route path="/account/*" element={<Account />}>
<Route path="*" element={<MockOutlet />} />
</Route>
</Routes>
</MemoryRouter>
);

// Test Account tab navigation
fireEvent.click(screen.getByRole('tab', { name: 'Account' }));
expect(mockOutletLocation).toBe('/account/info');

// Test Linked Providers tab navigation
fireEvent.click(screen.getByRole('tab', { name: 'Linked Providers' }));
expect(mockOutletLocation).toBe('/account/providers');

// Test Log In Sessions tab navigation
fireEvent.click(screen.getByRole('tab', { name: 'Log In Sessions' }));
expect(mockOutletLocation).toBe('/account/sessions');

// Test Use Agreements tab navigation
fireEvent.click(screen.getByRole('tab', { name: 'Use Agreements' }));
expect(mockOutletLocation).toBe('/account/use-agreements');
});

it('handles tab clicks with correct aria controls', () => {
render(
<MemoryRouter initialEntries={['/account']}>
<Routes>
<Route path="/account/*" element={<Account />}>
<Route path="*" element={<MockOutlet />} />
</Route>
</Routes>
</MemoryRouter>
);

const accountTab = screen.getByRole('tab', { name: 'Account' });
const providersTab = screen.getByRole('tab', { name: 'Linked Providers' });
const sessionsTab = screen.getByRole('tab', { name: 'Log In Sessions' });
const agreementsTab = screen.getByRole('tab', { name: 'Use Agreements' });

expect(accountTab).toHaveAttribute('aria-controls', 'account-tabpanel');
expect(providersTab).toHaveAttribute('aria-controls', 'providers-tabpanel');
expect(sessionsTab).toHaveAttribute('aria-controls', 'sessions-tabpanel');
expect(agreementsTab).toHaveAttribute(
'aria-controls',
'use-agreements-tabpanel'
);
});
});
Loading

0 comments on commit 3112305

Please sign in to comment.