mirror of
https://github.com/suitenumerique/docs.git
synced 2026-10-21 15:31:45 +02:00
🐛(frontend) switch language when the current one is untranslated
With zh-tw active, selecting English did nothing: its bundle is empty, so i18next reports `resolvedLanguage` as en while `language` is zh-tw, and the hook skipped the change. Compare with `language` instead, and add unit tests on the language pickers.
This commit is contained in:
@@ -13,6 +13,7 @@ and this project adheres to
|
||||
### Fixed
|
||||
|
||||
- 🐛(backend) bypass throttling on access/me action from yhub
|
||||
- 🐛(frontend) switch language when the current one is untranslated #2790
|
||||
|
||||
## [v6.0.0] - 2026-10-05
|
||||
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import i18next from 'i18next';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { AppWrapper } from '@/tests/utils';
|
||||
|
||||
import { LanguagePicker, LanguagePickerLegacy } from '../LanguagePicker';
|
||||
|
||||
const LANGUAGES = [
|
||||
['en-us', 'English'],
|
||||
['fr-fr', 'Français'],
|
||||
['zh-cn', '中文'],
|
||||
['zh-tw', '繁體中文'],
|
||||
];
|
||||
|
||||
const updateUser = vi.fn();
|
||||
|
||||
vi.mock('@/core', async () => {
|
||||
const actual = await vi.importActual('@/core');
|
||||
|
||||
return {
|
||||
...actual,
|
||||
useConfig: () => ({ data: { LANGUAGES } }),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('@/core/config/api/useConfig', () => ({
|
||||
useConfig: () => ({ data: { LANGUAGES } }),
|
||||
}));
|
||||
|
||||
vi.mock('@/core/api/useUserUpdate', () => ({
|
||||
useUserUpdate: () => ({ mutateAsync: updateUser }),
|
||||
}));
|
||||
|
||||
vi.mock('@/features/auth', async () => {
|
||||
const actual = await vi.importActual('@/features/auth');
|
||||
|
||||
return {
|
||||
...actual,
|
||||
useAuthQuery: () => ({
|
||||
data: { id: 'user-1', language: 'zh-tw' },
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
const kitSelection = () =>
|
||||
Array.from(document.querySelectorAll('.c__dropdown-menu-item__check')).map(
|
||||
(check) => check.closest('[role="menuitem"]')?.textContent,
|
||||
);
|
||||
|
||||
const legacySelection = () =>
|
||||
screen
|
||||
.getAllByRole('menuitemradio')
|
||||
.filter((item) => item.getAttribute('aria-checked') === 'true')
|
||||
.map((item) => item.textContent?.replace('check', ''));
|
||||
|
||||
describe.each([
|
||||
['LanguagePicker', LanguagePicker, 'menuitem', kitSelection],
|
||||
[
|
||||
'LanguagePickerLegacy',
|
||||
LanguagePickerLegacy,
|
||||
'menuitemradio',
|
||||
legacySelection,
|
||||
],
|
||||
] as const)('<%s />', (_name, Picker, itemRole, getSelection) => {
|
||||
beforeEach(async () => {
|
||||
updateUser.mockReset();
|
||||
updateUser.mockResolvedValue({});
|
||||
await i18next.changeLanguage('zh-tw');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await i18next.changeLanguage('en');
|
||||
});
|
||||
|
||||
const openPicker = async () => {
|
||||
render(<Picker />, { wrapper: AppWrapper });
|
||||
await userEvent.click(screen.getByRole('button'));
|
||||
};
|
||||
|
||||
it('marks a single language as selected', async () => {
|
||||
await openPicker();
|
||||
|
||||
expect(getSelection()).toEqual(['繁體中文']);
|
||||
});
|
||||
|
||||
it('switches from zh-tw to English and keeps it', async () => {
|
||||
await openPicker();
|
||||
|
||||
await userEvent.click(screen.getByRole(itemRole, { name: 'English' }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(i18next.language).toBe('en');
|
||||
});
|
||||
expect(updateUser).toHaveBeenCalledWith({
|
||||
id: 'user-1',
|
||||
language: 'en-us',
|
||||
});
|
||||
|
||||
// The picker follows the language and still shows a single selection
|
||||
await userEvent.click(screen.getByRole('button'));
|
||||
expect(getSelection()).toEqual(['English']);
|
||||
});
|
||||
});
|
||||
@@ -41,10 +41,7 @@ export const useSynchronizedLanguage = () => {
|
||||
availableFrontendLanguages,
|
||||
[language],
|
||||
)[0];
|
||||
if (
|
||||
i18n.isInitialized &&
|
||||
i18n.resolvedLanguage !== closestFrontendLanguage
|
||||
) {
|
||||
if (i18n.isInitialized && i18n.language !== closestFrontendLanguage) {
|
||||
await i18n.changeLanguage(closestFrontendLanguage);
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user