Skip to content

Commit 45162f0

Browse files
authored
Core 597 include Spanish titles in renewal form (#2797)
* Include Spanish books like adoption form does * Simplify RawBook to Book * Tests * Test coverage
1 parent 4d88eac commit 45162f0

File tree

10 files changed

+3784
-665
lines changed

10 files changed

+3784
-665
lines changed

src/app/components/multiselect/book-tags/sf-book-context.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import React from 'react';
22
import buildContext from '~/components/jsx-helpers/build-context';
33
import useMultiselectContext from '../multiselect-context';
4-
import fetchBooks from '~/models/books';
4+
import {fetchAllBooks} from '~/models/books';
55
import {
66
salesforceTitles,
77
subjects as getSubjects,
88
SalesforceBook
99
} from '~/helpers/books';
10+
import { useDataFromPromise } from '~/helpers/page-data-utils';
1011

1112
function useSFBooks() {
1213
const [books, setBooks] = React.useState<SalesforceBook[]>([]);
14+
const fetched = useDataFromPromise(fetchAllBooks);
1315

1416
React.useEffect(() => {
15-
fetchBooks.then(salesforceTitles).then(setBooks);
16-
}, []);
17+
if (fetched) {
18+
setBooks(salesforceTitles(fetched));
19+
}
20+
}, [fetched]);
1721
return books;
1822
}
1923

src/app/components/shell/router-helpers/use-link-handler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ export type TrackedMouseEvent = React.MouseEvent<HTMLAnchorElement> & {
2020
function handleExternalLink(href: Location['href'], el: HTMLElement) {
2121
if (el.dataset.local === 'true') {
2222
// REX books open in the current window; track them
23-
window.location.href = href;
23+
window.location.assign(href);
2424
} else {
2525
const newWindow = window.open(href, '_blank');
2626

2727
if (newWindow === null) {
28-
window.location.href = href;
28+
window.location.assign(href);
2929
}
3030
}
3131
}
@@ -45,7 +45,7 @@ export default function useLinkHandler() {
4545
const stripped = linkHelper.stripOpenStaxDomain(path);
4646

4747
if (stripped.startsWith('http')) {
48-
window.location.href = stripped;
48+
window.location.assign(stripped);
4949
} else {
5050
navigate(stripped, state);
5151
}

src/app/models/books.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,14 @@ const bookFields = [
2424

2525
type RawBook = Omit<Book, 'subjects'> & {book_subjects: {subject_name: string}[];};
2626

27-
function rawToBook(b: RawBook): Book {
28-
const result = b as Book & RawBook;
29-
30-
result.subjects = b.book_subjects.map((sObj) => sObj.subject_name);
31-
32-
return result;
27+
function rawToBook(b: RawBook) {
28+
return {
29+
...b,
30+
subjects: b.book_subjects.map((sObj) => sObj.subject_name)
31+
};
3332
}
3433

3534
export const fetchAllBooks = cmsFetch(`pages/?type=books.Book&fields=${bookFields}&limit=250`)
3635
.then((r: {items: RawBook[]}) => {
37-
for (const b of r.items) {
38-
rawToBook(b);
39-
}
40-
41-
return r.items;
36+
return r.items.map(rawToBook);
4237
});

src/app/pages/renewal-form/renewal-form.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,23 @@ function HiddenFields({
6161
const source = fromValue || 'email';
6262
const {selectedItems} = useBookTagsContext();
6363
const json = React.useMemo(
64-
() =>
65-
JSON.stringify({
66-
Books: selectedItems.map(({value: name}) => ({
67-
name,
64+
() => {
65+
const rewrittenBookData = selectedItems.map(({value: name}) => {
66+
const match = name.match(/(.*?) *\[(.*)\]/);
67+
const [title, language] = match ? match.slice(1) : [name, 'English'];
68+
69+
return ({
70+
name: title,
6871
students: +counts[name],
72+
language,
6973
baseYear: year
70-
}))
71-
}),
72-
[selectedItems, counts, year]
74+
});
75+
});
76+
77+
return JSON.stringify({
78+
Books: rewrittenBookData
79+
});
80+
}, [selectedItems, counts, year]
7381
);
7482
const subjects = React.useMemo(
7583
() => selectedItems.map((i) => i.value).join(';'),

test/helpers/fetch-mocker.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import adoptionFormData from '../src/data/adoption-form';
2-
import allBooksData from '../src/data/all-books';
2+
import allBooksData from '../src/data/all-books.json';
33
import amazonBlurb from '../src/data/amazon-blurb';
44
import algebraData from '../src/data/details-college-algebra';
55
import assignableData from '../src/data/assignable.json';
@@ -67,7 +67,7 @@ global.fetch = jest.fn().mockImplementation((...args) => {
6767
const isBlogCollection = args[0].includes('blogcollection');
6868
const isBooks = (/api\/books/).test(args[0]);
6969
const isBooksForAnalytics = (/book_student_resources/).test(args[0]);
70-
const isBookTitles = (/fields=title,id/).test(args[0]);
70+
const isBookTitles = args[0].endsWith('pages/?type=books.Book&fields=title,id,book_state,promote_snippet&limit=250');
7171
const isBuyprint = args[0].includes('buyprint');
7272
const isChemistry = args[0].endsWith('pages/93/?format=json');
7373
const isDonationPopup = args[0].includes('donation-popup');

test/src/components/book-selector.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ describe('book-selector', () => {
4747
render(<Component route='/selector?Calculus' />);
4848
const checkboxes = await screen.findAllByRole('checkbox');
4949

50-
expect(checkboxes).toHaveLength(9);
50+
expect(checkboxes).toHaveLength(58);
5151
const checked = await screen.findByRole('checkbox', {checked: true});
5252
const unchecked = screen.getAllByRole('checkbox', {checked: false});
5353

test/src/components/shell/use-link-handler.test.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ describe('use-link-handler', () => {
6060
<InnerComponent {...props} />
6161
</MemoryRouter>
6262
);
63+
const saveError = console.error;
6364

6465
afterEach(jest.resetAllMocks);
6566

@@ -98,10 +99,29 @@ describe('use-link-handler', () => {
9899
(useNavigate as jest.Mock).mockReturnValue(navigate);
99100

100101
render(<Component />);
102+
console.error = jest.fn();
101103
await user.click(screen.getByRole('link'));
104+
expect(console.error).toHaveBeenCalled();
105+
console.error = saveError;
102106
expect(notPrevented).not.toBeCalled();
103107
expect(navigate).toBeCalledWith('whatever', {x: 0, y: 0});
104108
});
109+
it('Changes window location when stripping does nothing', async () => {
110+
setPortalPrefix('/portal');
111+
const el = document.createElement('a');
112+
113+
jest.spyOn(linkHelper, 'validUrlClick').mockReturnValue(el);
114+
jest.spyOn(linkHelper, 'stripOpenStaxDomain').mockReturnValue(
115+
'http://whatever'
116+
);
117+
118+
render(<Component />);
119+
console.error = jest.fn();
120+
await user.click(screen.getByRole('link'));
121+
expect(console.error).toHaveBeenCalled();
122+
console.error = saveError;
123+
expect(notPrevented).not.toBeCalled();
124+
});
105125
it('calls piTracker if available', async () => {
106126
setPortalPrefix('/portal');
107127
const navigate = jest.fn();
@@ -141,7 +161,10 @@ describe('use-link-handler', () => {
141161
(useNavigate as jest.Mock).mockReturnValue(navigate);
142162

143163
render(<Component />);
164+
console.error = jest.fn();
144165
await user.click(screen.getByRole('link'));
166+
expect(console.error).toHaveBeenCalled();
167+
console.error = saveError;
145168
expect(notPrevented).not.toBeCalled();
146169
expect(navigate).not.toBeCalled();
147170
});
@@ -163,7 +186,10 @@ describe('use-link-handler', () => {
163186
(useNavigate as jest.Mock).mockReturnValue(navigate);
164187

165188
render(<Component />);
189+
console.error = jest.fn();
166190
await user.click(screen.getByRole('link'));
191+
expect(console.error).toHaveBeenCalled();
192+
console.error = saveError;
167193
expect(notPrevented).not.toBeCalled();
168194
expect(navigate).not.toBeCalled();
169195
});
@@ -212,5 +238,6 @@ describe('use-link-handler', () => {
212238
);
213239
await user.click(screen.getByRole('link'));
214240
expect(console.error).toBeCalled();
241+
console.error = saveError;
215242
});
216243
});

0 commit comments

Comments
 (0)