Skip to content

Commit

Permalink
refactor: separate the test for lang seector
Browse files Browse the repository at this point in the history
  • Loading branch information
dcoa committed Jan 13, 2025
1 parent 4880068 commit 1787607
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 47 deletions.
47 changes: 2 additions & 45 deletions src/components/Footer.test.jsx
Original file line number Diff line number Diff line change
@@ -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(() => ({
Expand Down Expand Up @@ -61,11 +52,6 @@ const FooterWithLanguageSelector = ({ authenticatedUser = null }) => {
};

describe('<Footer />', () => {
beforeEach(() => {
jest.clearAllMocks();
initializeMockApp();
});

describe('renders correctly', () => {
it('renders without a language selector', () => {
const tree = renderer
Expand All @@ -80,40 +66,11 @@ describe('<Footer />', () => {
expect(tree).toMatchSnapshot();
});
it('renders with a language selector', () => {
initializeMockApp();
const tree = renderer
.create(<FooterWithLanguageSelector />)
.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(<FooterWithLanguageSelector />);

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(<FooterWithLanguageSelector authenticatedUser={userData} />);

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');
});
});
});
});
2 changes: 0 additions & 2 deletions src/components/LanguageSelector/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
114 changes: 114 additions & 0 deletions src/components/LanguageSelector/index.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/* eslint-disable react/prop-types */
import React, { useMemo } from 'react';
import { 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 '@testing-library/jest-dom';

import { patchPreferences, postSetLang } from './data';
import LanguageSelector from '.';

jest.mock('@openedx/paragon/icons', () => ({
Language: () => <div>LanguageIcon</div>,
}));
jest.mock('./data', () => ({
patchPreferences: jest.fn(),
postSetLang: jest.fn(),
}));

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 (
<IntlProvider locale="en">
<AppContext.Provider
value={contextValue}
>
<LanguageSelector
options={['es', 'en']}
username={authenticatedUser?.username}
langCookieName={LANGUAGE_PREFERENCE_COOKIE_NAME}
/>
</AppContext.Provider>
</IntlProvider>
);
};

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(<LanguageSelectorContext />);

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(<LanguageSelectorContext authenticatedUser={userData} />);

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');
});
});

it('call logError if it can not update the user preference', async () => {
const userData = { username: 'test-user' };
const component = render(<LanguageSelectorContext authenticatedUser={userData} />);
patchPreferences.mockRejectedValueOnce(new Error('error'));

expect(component.queryByRole('button')).toBeInTheDocument();

const langDropdown = component.queryByRole('button');
const { loggingService } = initService;
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(<LanguageSelectorContext />);
expect(component.queryByRole('button').textContent).toBe('LanguageIconEnglish');

global.innerWidth = 700;
global.dispatchEvent(new Event('resize'));
expect(component.queryByRole('button').textContent).toBe('LanguageIconEN');

global.innerWidth = 500;
global.dispatchEvent(new Event('resize'));
expect(component.queryByRole('button').textContent).toBe('LanguageIcon');
});
});

0 comments on commit 1787607

Please sign in to comment.