richie-education 2.14.0 → 2.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,17 @@
1
1
  import { render, screen } from '@testing-library/react';
2
2
  import userEvent from '@testing-library/user-event';
3
3
  import { IntlProvider } from 'react-intl';
4
-
4
+ import { HistoryProvider } from 'data/useHistory';
5
5
  import LanguageSelector from '.';
6
6
 
7
+ jest.mock('utils/indirection/window', () => ({
8
+ location: {
9
+ assign: jest.fn(),
10
+ replace: jest.fn(),
11
+ search: '?args=0',
12
+ },
13
+ }));
14
+
7
15
  describe('<LanguageSelector />', () => {
8
16
  it('shows a dropdown menu that allows the user to change languages', async () => {
9
17
  const languages = {
@@ -41,4 +49,35 @@ describe('<LanguageSelector />', () => {
41
49
  name: 'Switch to Français (currently selected)',
42
50
  });
43
51
  });
52
+
53
+ it('should preserve location search parameters if there are any', async () => {
54
+ const languages = {
55
+ en: {
56
+ code: 'en',
57
+ name: 'Anglais',
58
+ url: '/switch/to/en/',
59
+ },
60
+ fr: {
61
+ code: 'fr',
62
+ name: 'Français',
63
+ url: '/switch/to/fr/',
64
+ },
65
+ };
66
+
67
+ render(
68
+ <HistoryProvider>
69
+ <IntlProvider locale="en">
70
+ <LanguageSelector currentLanguage="fr" languages={languages} />
71
+ </IntlProvider>
72
+ </HistoryProvider>,
73
+ );
74
+
75
+ const button = screen.getByLabelText('Select a language: Français', {
76
+ selector: 'button',
77
+ });
78
+
79
+ await userEvent.click(button);
80
+ const link = screen.getByRole('link', { name: 'Switch to Anglais' });
81
+ expect(link).toHaveAttribute('href', '/switch/to/en/?args=0');
82
+ });
44
83
  });
@@ -1,6 +1,6 @@
1
1
  import { useSelect } from 'downshift';
2
2
  import { FC } from 'react';
3
- import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
3
+ import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
4
4
 
5
5
  import { location } from 'utils/indirection/window';
6
6
 
@@ -51,7 +51,8 @@ const LanguageSelector: FC<LanguageSelectorProps> = ({ currentLanguage, language
51
51
  onSelectedItemChange: ({ selectedItem: newSelectedItem }) => {
52
52
  // Manually handle location changes in case the user interacted with a keyboard, and therefore with a
53
53
  // list item, and not by clicking on the actual links.
54
- location.replace(newSelectedItem!.url);
54
+
55
+ location.replace(`${newSelectedItem!.url}${location.search}`);
55
56
  },
56
57
  });
57
58
 
@@ -77,7 +78,7 @@ const LanguageSelector: FC<LanguageSelectorProps> = ({ currentLanguage, language
77
78
  className={`selector__list__link ${
78
79
  highlightedIndex === index ? 'selector__list__link--highlighted' : ''
79
80
  }`}
80
- href={language.url}
81
+ href={`${language!.url}${location.search}`}
81
82
  title={`${intl.formatMessage(messages.switchToLanguage, {
82
83
  language: language.name,
83
84
  })}${
@@ -87,7 +88,6 @@ const LanguageSelector: FC<LanguageSelectorProps> = ({ currentLanguage, language
87
88
  }`}
88
89
  >
89
90
  {language.name}
90
- {}
91
91
  </a>
92
92
  </li>
93
93
  ))}
@@ -75,7 +75,7 @@ describe('<SearchFilterGroupModal />', () => {
75
75
  const coursesDeferred = new Deferred();
76
76
  fetchMock.get(
77
77
  '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=' +
78
- range(0, 21).join(','),
78
+ range(0, 21).join('&universities_aggs='),
79
79
  coursesDeferred.promise,
80
80
  );
81
81
 
@@ -145,7 +145,7 @@ describe('<SearchFilterGroupModal />', () => {
145
145
  const coursesDeferred = new Deferred();
146
146
  fetchMock.get(
147
147
  '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=' +
148
- range(21, 42).join(','),
148
+ range(21, 42).join('&universities_aggs='),
149
149
  coursesDeferred.promise,
150
150
  );
151
151
 
@@ -190,7 +190,7 @@ describe('<SearchFilterGroupModal />', () => {
190
190
  const coursesDeferred = new Deferred();
191
191
  fetchMock.get(
192
192
  '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=' +
193
- range(42, 46).join(','),
193
+ range(42, 46).join('&universities_aggs='),
194
194
  coursesDeferred.promise,
195
195
  );
196
196
 
@@ -235,7 +235,7 @@ describe('<SearchFilterGroupModal />', () => {
235
235
  fetchMock.get('/api/v1.0/universities/?limit=21&offset=0', universitiesDeferred.promise);
236
236
  const coursesDeferred = new Deferred();
237
237
  fetchMock.get(
238
- '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-42,L-84,L-99',
238
+ '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-42&universities_aggs=L-84&universities_aggs=L-99',
239
239
  coursesDeferred.promise,
240
240
  );
241
241
 
@@ -312,7 +312,7 @@ describe('<SearchFilterGroupModal />', () => {
312
312
  );
313
313
  const coursesDeferred = new Deferred();
314
314
  fetchMock.get(
315
- '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-12,L-17',
315
+ '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-12&universities_aggs=L-17',
316
316
  coursesDeferred.promise,
317
317
  );
318
318
  fireEvent.change(field, { target: { value: 'user' } });
@@ -361,7 +361,7 @@ describe('<SearchFilterGroupModal />', () => {
361
361
  );
362
362
  const coursesDeferred = new Deferred();
363
363
  fetchMock.get(
364
- '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-03,L-66',
364
+ '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-03&universities_aggs=L-66',
365
365
  coursesDeferred.promise,
366
366
  );
367
367
  fireEvent.change(field, { target: { value: 'user input' } });
@@ -409,7 +409,7 @@ describe('<SearchFilterGroupModal />', () => {
409
409
  fetchMock.get('/api/v1.0/universities/?limit=21&offset=0', universitiesDeferred.promise);
410
410
  const coursesDeferred = new Deferred();
411
411
  fetchMock.get(
412
- '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-42,L-84,L-99',
412
+ '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-42&universities_aggs=L-84&universities_aggs=L-99',
413
413
  coursesDeferred.promise,
414
414
  );
415
415
 
@@ -468,7 +468,7 @@ describe('<SearchFilterGroupModal />', () => {
468
468
  fetchMock.get('/api/v1.0/universities/?limit=21&offset=0', universitiesDeferred.promise);
469
469
  const coursesDeferred = new Deferred();
470
470
  fetchMock.get(
471
- '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-42,L-84,L-99',
471
+ '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-42&universities_aggs=L-84&universities_aggs=L-99',
472
472
  coursesDeferred.promise,
473
473
  );
474
474
 
@@ -583,7 +583,7 @@ describe('<SearchFilterGroupModal />', () => {
583
583
  objects: [{ id: 'L-42' }, { id: 'L-84' }, { id: 'L-99' }],
584
584
  });
585
585
  fetchMock.get(
586
- '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-42,L-84,L-99',
586
+ '/api/v1.0/courses/?facet_sorting=name&limit=21&offset=0&scope=filters&universities_aggs=L-42&universities_aggs=L-84&universities_aggs=L-99',
587
587
  { throws: new Error('Failed to search for universities') },
588
588
  );
589
589
 
@@ -17,14 +17,11 @@ export async function fetchList(
17
17
  params: APIListRequestParams = API_LIST_DEFAULT_PARAMS,
18
18
  ): Promise<FetchListResponse> {
19
19
  try {
20
- const response = await fetch(
21
- `/api/v1.0/${kind}/?${stringify(params, { arrayFormat: 'comma' })}`,
22
- {
23
- headers: {
24
- 'Content-Type': 'application/json',
25
- },
20
+ const response = await fetch(`/api/v1.0/${kind}/?${stringify(params)}`, {
21
+ headers: {
22
+ 'Content-Type': 'application/json',
26
23
  },
27
- );
24
+ });
28
25
 
29
26
  if (!response.ok) {
30
27
  // Push remote errors to the error channel for consistency
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "richie-education",
3
- "version": "2.14.0",
3
+ "version": "2.14.1",
4
4
  "description": "A CMS to build learning portals for Open Education",
5
5
  "main": "sandbox/manage.py",
6
6
  "scripts": {
@@ -157,7 +157,8 @@ $course-glimpse-content-padding-sides: 0.7rem !default;
157
157
  position: relative;
158
158
  }
159
159
 
160
- &__title {
160
+ &__title,
161
+ &__title-text {
161
162
  @include font-size($h6-font-size);
162
163
  color: r-theme-val(course-glimpse, title-color);
163
164
  font-family: $r-font-family-montserrat;