Skip to content

Commit 99b5e8e

Browse files
feat: update test
1 parent e6eab50 commit 99b5e8e

File tree

6 files changed

+73
-10
lines changed

6 files changed

+73
-10
lines changed

src/courseware/course/sequence/sequence-navigation/SequenceNavigation.test.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ describe('Sequence Navigation', () => {
7676
const onNavigate = jest.fn();
7777
render(<SequenceNavigation {...mockData} {...{ onNavigate }} />, { wrapWithRouter: true });
7878

79-
const unitButtons = screen.getAllByRole('link', { name: /\d+/ });
79+
const unitButtons = screen.getAllByRole('tabpanel', { name: /\d+/ });
8080
expect(unitButtons).toHaveLength(unitButtons.length);
8181
unitButtons.forEach(button => fireEvent.click(button));
8282
expect(onNavigate).toHaveBeenCalledTimes(unitButtons.length);

src/courseware/course/sequence/sequence-navigation/SequenceNavigationDropdown.test.jsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ describe('Sequence Navigation Dropdown', () => {
5050
});
5151
const dropdownMenu = container.querySelector('.dropdown-menu');
5252
// Only the current unit should be marked as active.
53-
getAllByRole(dropdownMenu, 'link', { hidden: true }).forEach(button => {
53+
getAllByRole(dropdownMenu, 'tabpanel', { hidden: true }).forEach(button => {
5454
if (button.textContent === unit.display_name) {
5555
expect(button).toHaveClass('active');
5656
} else {
@@ -72,7 +72,7 @@ describe('Sequence Navigation Dropdown', () => {
7272
fireEvent.click(dropdownToggle);
7373
});
7474
const dropdownMenu = container.querySelector('.dropdown-menu');
75-
getAllByRole(dropdownMenu, 'link', { hidden: true }).forEach(button => fireEvent.click(button));
75+
getAllByRole(dropdownMenu, 'tabpanel', { hidden: true }).forEach(button => fireEvent.click(button));
7676
expect(onNavigate).toHaveBeenCalledTimes(unitBlocks.length);
7777
unitBlocks.forEach((unit, index) => {
7878
expect(onNavigate).toHaveBeenNthCalledWith(index + 1, unit.id);

src/courseware/course/sequence/sequence-navigation/SequenceNavigationTabs.test.jsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ describe('Sequence Navigation Tabs', () => {
4343
useIndexOfLastVisibleChild.mockReturnValue([0, null, null]);
4444
render(<SequenceNavigationTabs {...mockData} />, { wrapWithRouter: true });
4545

46-
expect(screen.getAllByRole('link')).toHaveLength(unitBlocks.length);
46+
expect(screen.getAllByRole('tabpanel')).toHaveLength(unitBlocks.length);
4747
});
4848

4949
it('renders unit buttons and dropdown button', async () => {
@@ -60,7 +60,7 @@ describe('Sequence Navigation Tabs', () => {
6060
await fireEvent.click(dropdownToggle);
6161
});
6262
const dropdownMenu = container.querySelector('.dropdown');
63-
const dropdownButtons = getAllByRole(dropdownMenu, 'link');
63+
const dropdownButtons = getAllByRole(dropdownMenu, 'tabpanel');
6464
expect(dropdownButtons).toHaveLength(unitBlocks.length);
6565
expect(screen.getByRole('button', { name: `${activeBlockNumber} of ${unitBlocks.length}` }))
6666
.toHaveClass('dropdown-toggle');

src/courseware/course/sequence/sequence-navigation/UnitButton.jsx

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ const UnitButton = ({
7575
{bookmarked ? (
7676
<BookmarkFilledIcon
7777
className="unit-filled-bookmark text-primary small position-absolute"
78+
data-testid="bookmark-icon"
7879
style={{
7980
top: '-3px', right: '2px', height: '20px', width: '20px',
8081
}}

src/courseware/course/sequence/sequence-navigation/UnitButton.test.jsx

+31-5
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,24 @@ describe('Unit Button', () => {
3434

3535
it('hides title by default', () => {
3636
render(<UnitButton {...mockData} />, { wrapWithRouter: true });
37-
expect(screen.getByRole('link')).not.toHaveTextContent(unit.display_name);
37+
expect(screen.getByRole('tabpanel')).not.toHaveTextContent(unit.display_name);
3838
});
3939

4040
it('shows title', () => {
41-
render(<UnitButton {...mockData} showTitle />);
41+
render(<UnitButton {...mockData} showTitle />, { wrapWithRouter: true });
4242
expect(screen.getByRole('tabpanel')).toHaveTextContent(unit.display_name);
4343
});
4444

4545
it('check button attributes', () => {
46-
render(<UnitButton {...mockData} showTitle />);
46+
render(<UnitButton {...mockData} showTitle />, { wrapWithRouter: true });
4747
expect(screen.getByRole('tabpanel')).toHaveAttribute('id', `${unit.display_name}-${courseMetadata.id}`);
4848
expect(screen.getByRole('tabpanel')).toHaveAttribute('aria-controls', unit.display_name);
4949
expect(screen.getByRole('tabpanel')).toHaveAttribute('aria-labelledby', unit.display_name);
5050
expect(screen.getByRole('tabpanel')).toHaveAttribute('tabindex', '-1');
5151
});
5252

5353
it('button with isActive prop has tabindex 0', () => {
54-
render(<UnitButton {...mockData} isActive />);
54+
render(<UnitButton {...mockData} isActive />, { wrapWithRouter: true });
5555
expect(screen.getByRole('tabpanel')).toHaveAttribute('tabindex', '0');
5656
});
5757

@@ -93,7 +93,33 @@ describe('Unit Button', () => {
9393
it('handles the click', () => {
9494
const onClick = jest.fn();
9595
render(<UnitButton {...mockData} onClick={onClick} />, { wrapWithRouter: true });
96-
fireEvent.click(screen.getByRole('link'));
96+
fireEvent.click(screen.getByRole('tabpanel'));
9797
expect(onClick).toHaveBeenCalledTimes(1);
9898
});
99+
100+
it('handles keydown events for Enter and Space and focuses bookmark button', async () => {
101+
const onClick = jest.fn();
102+
render(<UnitButton {...mockData} onClick={onClick} />, { wrapWithRouter: true });
103+
104+
const button = screen.getByRole('tabpanel');
105+
106+
fireEvent.keyDown(button, { key: 'Enter' });
107+
expect(onClick).toHaveBeenCalledTimes(1);
108+
109+
fireEvent.keyDown(button, { key: ' ' });
110+
expect(onClick).toHaveBeenCalledTimes(2);
111+
112+
const bookmarkButton = document.createElement('button');
113+
bookmarkButton.id = 'bookmark-button';
114+
document.body.appendChild(bookmarkButton);
115+
116+
fireEvent.keyDown(button, { key: 'Enter' });
117+
118+
// eslint-disable-next-line no-promise-executor-return
119+
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
120+
121+
expect(document.activeElement).toBe(bookmarkButton);
122+
123+
document.body.removeChild(bookmarkButton);
124+
});
99125
});

src/generic/hooks.test.jsx

+36
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import userEvent from '@testing-library/user-event';
33
import { useScrollToContent, useEventListener, useIFrameHeight } from './hooks';
44

55
global.scrollTo = jest.fn();
6+
global.console.warn = jest.fn();
67

78
describe('Hooks', () => {
89
test('useEventListener', async () => {
@@ -93,5 +94,40 @@ describe('Hooks', () => {
9394
});
9495
expect(targetContent.focus).toHaveBeenCalled();
9596
});
97+
98+
test('should warn if element is not focusable', async () => {
99+
render(<TestComponent />);
100+
101+
const skipLink = screen.getByRole('link', { name: /skip to content/i });
102+
const targetContent = screen.getByTestId('target-content');
103+
104+
delete targetContent.focus;
105+
106+
userEvent.click(skipLink);
107+
108+
await waitFor(() => {
109+
expect(global.scrollTo).toHaveBeenCalledWith({
110+
top: expect.any(Number), behavior: 'smooth',
111+
});
112+
});
113+
114+
// eslint-disable-next-line no-console
115+
expect(console.warn).toHaveBeenCalledWith('Element with ID "main-content" exists but is not focusable.');
116+
});
117+
118+
test('should warn if target element is not found', async () => {
119+
render(<TestComponent />);
120+
121+
const skipLink = screen.getByRole('link', { name: /skip to content/i });
122+
123+
document.getElementById('main-content').remove();
124+
125+
userEvent.click(skipLink);
126+
127+
await waitFor(() => {
128+
// eslint-disable-next-line no-console
129+
expect(console.warn).toHaveBeenCalledWith('Element with ID "main-content" not found.');
130+
});
131+
});
96132
});
97133
});

0 commit comments

Comments
 (0)