diff --git a/src/components/Footer.test.jsx b/src/components/Footer.test.jsx
index ac20190ac..139a0aae1 100644
--- a/src/components/Footer.test.jsx
+++ b/src/components/Footer.test.jsx
@@ -1,20 +1,11 @@
/* eslint-disable react/prop-types */
import React, { useMemo } from 'react';
import renderer from 'react-test-renderer';
-import { fireEvent, render, waitFor } from '@testing-library/react';
-import { initializeMockApp } from '@edx/frontend-platform/testing';
import { IntlProvider } from '@edx/frontend-platform/i18n';
-import { getCookies } from '@edx/frontend-platform/i18n/lib';
import { AppContext } from '@edx/frontend-platform/react';
-import '@testing-library/jest-dom';
+import { initializeMockApp } from '@edx/frontend-platform/testing';
import Footer from './Footer';
-import { patchPreferences, postSetLang } from './LanguageSelector/data';
-
-jest.mock('./LanguageSelector/data', () => ({
- patchPreferences: jest.fn(),
- postSetLang: jest.fn(),
-}));
const FooterWithContext = ({ locale = 'es' }) => {
const contextValue = useMemo(() => ({
@@ -61,11 +52,6 @@ const FooterWithLanguageSelector = ({ authenticatedUser = null }) => {
};
describe('', () => {
- beforeEach(() => {
- jest.clearAllMocks();
- initializeMockApp();
- });
-
describe('renders correctly', () => {
it('renders without a language selector', () => {
const tree = renderer
@@ -80,40 +66,11 @@ describe('', () => {
expect(tree).toMatchSnapshot();
});
it('renders with a language selector', () => {
+ initializeMockApp();
const tree = renderer
.create()
.toJSON();
expect(tree).toMatchSnapshot();
});
});
-
- describe('handles language switching', () => {
- it('calls publish with LOCALE_CHANGED when the language changed', () => {
- const setSpy = jest.spyOn(getCookies(), 'set');
- const component = render();
-
- expect(component.queryByRole('button')).toBeInTheDocument();
-
- const langDropdown = component.queryByRole('button');
- fireEvent.click(langDropdown);
- fireEvent.click(component.queryByText('Español'));
-
- expect(setSpy).toHaveBeenCalledWith(LANGUAGE_PREFERENCE_COOKIE_NAME, 'es');
- });
- it('update the lang preference for an autheticathed user', async () => {
- const userData = { username: 'test-user' };
- const component = render();
-
- expect(component.queryByRole('button')).toBeInTheDocument();
-
- const langDropdown = component.queryByRole('button');
- fireEvent.click(langDropdown);
- fireEvent.click(component.queryByText('Español'));
-
- await waitFor(() => {
- expect(patchPreferences).toHaveBeenCalledWith(userData.username, { prefLang: 'es' });
- expect(postSetLang).toHaveBeenCalledWith('es');
- });
- });
- });
});
diff --git a/src/components/LanguageSelector/data.js b/src/components/LanguageSelector/data.js
index 0ec420007..08cb6a225 100644
--- a/src/components/LanguageSelector/data.js
+++ b/src/components/LanguageSelector/data.js
@@ -12,8 +12,6 @@ export async function patchPreferences(username, params) {
.patch(`${getConfig().LMS_BASE_URL}/api/user/v1/preferences/${username}`, processedParams, {
headers: { 'Content-Type': 'application/merge-patch+json' },
});
-
- return params;
}
export async function postSetLang(code) {
diff --git a/src/components/LanguageSelector/index.jsx b/src/components/LanguageSelector/index.jsx
index 0a0f79dc5..d3861e2af 100644
--- a/src/components/LanguageSelector/index.jsx
+++ b/src/components/LanguageSelector/index.jsx
@@ -44,7 +44,7 @@ const LanguageSelector = ({
const currentLocaleLabel = useMemo(() => {
if (width < 576) {
- return null;
+ return '';
}
if (width < 768) {
return getPrimaryLanguageSubtag(currentLocale).toUpperCase();
diff --git a/src/components/LanguageSelector/index.test.jsx b/src/components/LanguageSelector/index.test.jsx
new file mode 100644
index 000000000..b3f1ab50d
--- /dev/null
+++ b/src/components/LanguageSelector/index.test.jsx
@@ -0,0 +1,141 @@
+/* eslint-disable react/prop-types */
+import React, { useMemo } from 'react';
+import {
+ act, fireEvent, render, waitFor,
+} from '@testing-library/react';
+import { IntlProvider } from '@edx/frontend-platform/i18n';
+import { getCookies } from '@edx/frontend-platform/i18n/lib';
+import { AppContext } from '@edx/frontend-platform/react';
+import { initializeMockApp } from '@edx/frontend-platform/testing';
+import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
+
+import '@testing-library/jest-dom';
+
+import LanguageSelector from '.';
+
+jest.mock('@edx/frontend-platform/auth', () => ({
+ ...jest.requireActual('@edx/frontend-platform/auth'),
+ getAuthenticatedHttpClient: jest.fn(),
+}));
+
+jest.mock('@openedx/paragon/icons', () => ({
+ Language: () =>
LanguageIcon
,
+}));
+
+const { LANGUAGE_PREFERENCE_COOKIE_NAME } = process.env;
+
+const LanguageSelectorContext = ({ authenticatedUser = null }) => {
+ const contextValue = useMemo(() => ({
+ authenticatedUser,
+ config: {
+ LANGUAGE_PREFERENCE_COOKIE_NAME,
+ LOGO_TRADEMARK_URL: process.env.LOGO_TRADEMARK_URL,
+ LMS_BASE_URL: process.env.LMS_BASE_URL,
+ SITE_SUPPORTED_LANGUAGES: ['es', 'en'],
+ },
+ }), [authenticatedUser]);
+
+ return (
+
+
+
+
+
+ );
+};
+
+describe('LanguageSelector', () => {
+ let initService;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ initService = initializeMockApp();
+ });
+
+ it('change the language for a non authenticated user', () => {
+ const setSpy = jest.spyOn(getCookies(), 'set');
+ const component = render();
+
+ expect(component.queryByRole('button')).toBeInTheDocument();
+
+ const langDropdown = component.queryByRole('button');
+ fireEvent.click(langDropdown);
+ fireEvent.click(component.queryByText('Español'));
+
+ expect(setSpy).toHaveBeenCalledWith(LANGUAGE_PREFERENCE_COOKIE_NAME, 'es');
+ });
+
+ it('update the lang preference for an autheticathed user', async () => {
+ const userData = { username: 'test-user' };
+ const processedParams = {
+ 'pref-lang': 'es',
+ };
+ getAuthenticatedHttpClient.mockReturnValue({
+ patch: jest.fn(),
+ post: jest.fn(),
+ });
+ const formData = new FormData();
+ formData.append('language', 'es');
+
+ const component = render();
+
+ expect(component.queryByRole('button')).toBeInTheDocument();
+
+ const langDropdown = component.queryByRole('button');
+ fireEvent.click(langDropdown);
+ fireEvent.click(component.queryByText('Español'));
+
+ await waitFor(() => {
+ expect(getAuthenticatedHttpClient().patch)
+ .toHaveBeenCalledWith(`${process.env.LMS_BASE_URL}/api/user/v1/preferences/${userData.username}`, processedParams, {
+ headers: { 'Content-Type': 'application/merge-patch+json' },
+ });
+ expect(getAuthenticatedHttpClient().post)
+ .toHaveBeenCalledWith(
+ `${process.env.LMS_BASE_URL}/i18n/setlang/`,
+ formData,
+ { headers: { Accept: 'application/json', 'X-Requested-With': 'XMLHttpRequest' } },
+ );
+ });
+ });
+
+ it('call logError if it can not update the user preference', async () => {
+ const { loggingService } = initService;
+ const userData = { username: 'test-user' };
+ const component = render();
+ getAuthenticatedHttpClient.mockReturnValue({
+ patch: jest.fn().mockRejectedValue(new Error('Error')),
+ });
+ expect(component.queryByRole('button')).toBeInTheDocument();
+
+ const langDropdown = component.queryByRole('button');
+ fireEvent.click(langDropdown);
+ fireEvent.click(component.queryByText('Español'));
+
+ await waitFor(() => {
+ expect(loggingService.logError).toHaveBeenCalled();
+ });
+ });
+
+ it('should disp,ay the language icon and modify the label according to the screen size', () => {
+ const component = render();
+ expect(component.queryByRole('button').textContent).toBe('LanguageIconEnglish');
+
+ act(() => {
+ global.innerWidth = 700;
+ global.dispatchEvent(new Event('resize'));
+ });
+ expect(component.queryByRole('button').textContent).toBe('LanguageIconEN');
+ act(() => {
+ global.innerWidth = 500;
+ global.dispatchEvent(new Event('resize'));
+ });
+ expect(component.queryByRole('button').textContent).toBe('LanguageIcon');
+ });
+});