Skip to content

Commit 385171d

Browse files
committed
Restore 100% coverage
1 parent 0ffc5b1 commit 385171d

File tree

7 files changed

+77
-31
lines changed

7 files changed

+77
-31
lines changed

src/app/models/give-today.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import cmsFetch from '~/helpers/cms-fetch';
22
import {useDataFromPromise} from '~/helpers/page-data-utils';
33

4-
const promise = cmsFetch('give-today');
5-
64
type PromiseData = {
75
give_link_text: string;
86
give_link: string;
@@ -31,7 +29,7 @@ export default function useGiveToday(): Partial<GiveToday> {
3129
menu_expires: string;
3230
start: string;
3331
expires: string;
34-
}>(promise);
32+
}>(cmsFetch('give-today'));
3533

3634
return giveData ? {
3735
...giveData,

test/helpers/fetch-mocker.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ global.fetch = jest.fn().mockImplementation((...args) => {
8080
const isImage = args[0].includes('/api/images/');
8181
const isNewSubjects = args[0].includes('new-subjects');
8282
const isOsNews = (/openstax-news/).test(args[0]);
83+
const isOxMenus = args[0].includes('/oxmenus/');
8384
const isPartner = (/pages\/partners/).test(args[0]);
8485
const isPolishPhysics = (/fizyka/).test(args[0]);
8586
const isPress = (/api\/press\/\?/).test(args[0]);
@@ -169,6 +170,8 @@ global.fetch = jest.fn().mockImplementation((...args) => {
169170
payload = bookTitleData;
170171
} else if (isOsNews) {
171172
payload = osNewsData;
173+
} else if (isOxMenus) {
174+
payload = [];
172175
} else if (isBlogArticle) {
173176
payload = blogArticleData;
174177
} else if (isTeam) {

test/src/components/shell/header-menus.test.tsx

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,44 @@ import React from 'react';
22
import {describe, it, expect} from '@jest/globals';
33
import {render, screen} from '@testing-library/preact';
44
import Menus from '~/layouts/default/header/menus/menus';
5-
import {MemoryRouter} from 'react-router-dom';
5+
import MemoryRouter from '~/../../test/helpers/future-memory-router';
66
import userEvent from '@testing-library/user-event';
7-
import useGiveToday from '~/models/give-today';
7+
import * as PDU from '~/helpers/page-data-utils';
8+
import * as CF from '~/helpers/cms-fetch';
89

9-
global.fetch = jest.fn().mockImplementation(() => {
10-
return Promise.resolve({
11-
json() {
12-
return [];
13-
}
14-
});
15-
});
10+
/* eslint-disable camelcase */
11+
12+
const mockUseDataFromPromise = jest.spyOn(PDU, 'useDataFromPromise');
13+
const giveTodayData = {
14+
give_link_text: 'Give',
15+
give_link: 'https://riceconnect.rice.edu/donation/support-openstax-header',
16+
start: '2023-04-04T05:00:00Z',
17+
expires: '2023-04-05T05:00:00Z',
18+
menu_start: '2023-12-14T06:00:00Z',
19+
menu_expires: '2024-04-01T23:00:00Z'
20+
};
21+
const futureDate = new Date(Date.now() + 500000).toLocaleString();
1622

17-
jest.mock('~/models/give-today', () => jest.fn());
23+
jest.spyOn(CF, 'default').mockReturnValue(Promise.resolve({}));
1824

1925
describe('shell/header/menus', () => {
2026
const user = userEvent.setup();
2127

28+
// eslint-disable-next-line complexity
2229
it('renders', async () => {
23-
(useGiveToday as jest.Mock).mockReturnValue({
24-
showButton: true
30+
mockUseDataFromPromise.mockReturnValueOnce({
31+
...giveTodayData,
32+
menu_expires: futureDate
2533
});
2634
render(
2735
<MemoryRouter initialEntries={['/']}>
2836
<Menus />
2937
</MemoryRouter>
3038
);
31-
expect(screen.getAllByRole('listitem')).toHaveLength(16);
39+
const listitems = screen.queryAllByRole('listitem');
40+
41+
// The desktop Give menu item is off; Give button shows instead
42+
expect(listitems.filter((i) => i.textContent === 'Give').length).toBe(1);
3243
const button = screen.getByRole('button');
3344

3445
expect(screen.getAllByRole('menuitem')).toHaveLength(2);
@@ -55,14 +66,17 @@ describe('shell/header/menus', () => {
5566
expect(button.parentElement?.classList.contains('active')).toBe(true);
5667
});
5768
it('handles upper menus without Give', () => {
58-
(useGiveToday as jest.Mock).mockReturnValue({
59-
showButton: false
69+
mockUseDataFromPromise.mockReturnValueOnce({
70+
...giveTodayData
6071
});
6172
render(
6273
<MemoryRouter initialEntries={['/']}>
6374
<Menus />
6475
</MemoryRouter>
6576
);
66-
expect(screen.getAllByRole('listitem')).toHaveLength(18);
77+
const listitems = screen.queryAllByRole('listitem');
78+
79+
// No Give button, so Give menu item in both desktop and mobile
80+
expect(listitems.filter((i) => i.textContent === 'Give').length).toBe(2);
6781
});
6882
});

test/src/data/webinars.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ const pastWebinar: Webinar = {
3333

3434
const pageData = {
3535
title: 'Webinar title',
36-
heading: 'Webinar heading'
36+
heading: 'Webinar heading',
37+
webinars: []
3738
};
3839

3940
export {upcomingWebinar, pastWebinar, pageData};

test/src/helpers/link.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,10 @@ describe('stripOpenStaxDomain', () => {
3333
expect(linkHelper.validUrlClick({target: el} as unknown as React.MouseEvent)).toBe(false);
3434
});
3535
});
36+
describe('logoutLink', () => {
37+
it('generates a logoutLink', () => {
38+
const link = linkHelper.logoutLink();
39+
40+
expect(link).toMatch('accounts/logout');
41+
});
42+
});

test/src/pages/webinars/main-page.test.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import React from 'react';
22
import {describe, expect, it} from '@jest/globals';
33
import {render, screen} from '@testing-library/preact';
4-
import {MemoryRouter} from 'react-router-dom';
4+
import MemoryRouter from '~/../../test/helpers/future-memory-router';
55
import {RouterContextProvider} from '~/components/shell/router-context';
66
import MainPage from '~/pages/webinars/main-page/main-page';
7-
import useWebinarContext from '~/pages/webinars/webinar-context';
7+
import * as UWC from '~/pages/webinars/webinar-context';
8+
import * as UDH from '~/helpers/use-document-head';
89
import {pageData} from '../../data/webinars';
910

1011
function Component() {
@@ -17,12 +18,22 @@ function Component() {
1718
);
1819
}
1920

20-
jest.mock('~/pages/webinars/webinar-context', () => jest.fn());
21+
const mockUseWebinarContext = jest.spyOn(UWC, 'default');
22+
23+
jest.spyOn(UDH, 'default').mockImplementation(
24+
() => null
25+
);
2126

2227
describe('webinars main page', () => {
2328
it('renders the main page', () => {
24-
(useWebinarContext as jest.Mock).mockReturnValue({
25-
pageData
29+
mockUseWebinarContext.mockReturnValue({
30+
pageData,
31+
past: [],
32+
upcoming: [],
33+
subjects: [],
34+
collections: [],
35+
searchFor: jest.fn(),
36+
latestWebinars: []
2637
});
2738
render(<Component />);
2839
expect(screen.getByText(pageData.heading)).toBeTruthy();

test/src/pages/webinars/search-page.test.tsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import React from 'react';
22
import {describe, expect, it} from '@jest/globals';
33
import {render, screen} from '@testing-library/preact';
4-
import {MemoryRouter} from 'react-router-dom';
4+
import MemoryRouter from '~/../../test/helpers/future-memory-router';
55
import {RouterContextProvider} from '~/components/shell/router-context';
66
import SearchPage from '~/pages/webinars/search-page/search-page';
7-
import useFetchedData from '~/helpers/use-data';
7+
import * as UFD from '~/helpers/use-data';
88
import {upcomingWebinar} from '../../data/webinars';
9+
import * as UWC from '~/pages/webinars/webinar-context';
910

1011
function Component({term = ''}: {term?: string}) {
1112
return (
@@ -17,25 +18,36 @@ function Component({term = ''}: {term?: string}) {
1718
);
1819
}
1920

21+
jest.spyOn(UWC, 'default').mockReturnValue({
22+
pageData: {},
23+
past: [],
24+
upcoming: [],
25+
subjects: [],
26+
collections: [],
27+
searchFor: jest.fn(),
28+
latestWebinars: []
29+
});
30+
2031
jest.mock('~/helpers/use-data', () => jest.fn());
32+
const mockUseFetchedData = jest.spyOn(UFD, 'default');
2133

2234
describe('webinar search page', () => {
2335
it('short circuits while waiting for webinars to return', () => {
24-
(useFetchedData as jest.Mock).mockReturnValue(undefined);
36+
mockUseFetchedData.mockReturnValue(undefined);
2537
render(<Component term='waiting' />);
2638

2739
expect(screen.queryByText('matching')).toBeNull();
2840
});
2941
it('displays a message when search returns no results', () => {
30-
(useFetchedData as jest.Mock).mockReturnValue([]);
42+
mockUseFetchedData.mockReturnValue([]);
3143
render(<Component term='xnotfoundx' />);
3244

3345
expect(screen.getByText('No matching webinars found')).toBeTruthy();
3446
});
3547
it('displays results when they are returned', () => {
3648
// For code coverage
37-
(useFetchedData as jest.Mock).mockImplementation(({postProcess}) => {
38-
postProcess(upcomingWebinar);
49+
mockUseFetchedData.mockImplementation(({postProcess}) => {
50+
postProcess?.(upcomingWebinar);
3951
return [upcomingWebinar];
4052
});
4153
render(<Component term='something' />);

0 commit comments

Comments
 (0)