diff --git a/app/views/LanguageView/index.test.tsx b/app/views/LanguageView/index.test.tsx
new file mode 100644
index 00000000000..ccb5d9c1c91
--- /dev/null
+++ b/app/views/LanguageView/index.test.tsx
@@ -0,0 +1,91 @@
+import React from 'react';
+import { render, fireEvent, waitFor } from '@testing-library/react-native';
+
+import LanguageView from './index';
+import * as i18n from '../../i18n';
+
+jest.mock('@react-navigation/native', () => ({
+ useNavigation: () => ({ setOptions: jest.fn(), navigate: jest.fn() })
+}));
+
+jest.mock('../../lib/hooks/useAppSelector', () => ({
+ useAppSelector: () => ({ languageDefault: 'en', id: 'user-id' })
+}));
+
+jest.mock('react-redux', () => ({
+ useDispatch: () => jest.fn()
+}));
+
+jest.mock('../../actions/app', () => ({
+ appStart: jest.fn()
+}));
+
+jest.mock('../../actions/login', () => ({
+ setUser: jest.fn()
+}));
+
+jest.mock('react-native-restart', () => ({
+ Restart: { Restart: jest.fn() }
+}));
+
+jest.mock('react-native', () => {
+ const rn = jest.requireActual('react-native');
+ rn.FlatList = ({ data, renderItem }: any) => (
+ <>
+ {data.map((item: any, index: number) => (
+ {renderItem({ item, index })}
+ ))}
+ >
+ );
+ return rn;
+});
+
+jest.mock('../../lib/services/restApi', () => ({
+ saveUserPreferences: jest.fn(() => Promise.resolve())
+}));
+
+jest.mock('../../lib/database', () => ({
+ default: {
+ servers: {
+ write: jest.fn((fn: any) => fn()),
+ get: jest.fn(() => ({
+ find: jest.fn(() => Promise.resolve({ update: jest.fn() }))
+ }))
+ }
+ }
+}));
+
+jest.mock('../../i18n', () => {
+ const setLanguage = jest.fn();
+ const i18nMock = {
+ t: (key: string) => key,
+ locale: 'en',
+ translations: { en: {} }
+ };
+ return {
+ __esModule: true,
+ default: i18nMock,
+ setLanguage,
+ isRTL: jest.fn(() => false),
+ LANGUAGES: [
+ { label: 'English', value: 'en', file: () => ({}) },
+ { label: 'EspaƱol', value: 'es', file: () => ({}) }
+ ]
+ };
+});
+
+describe('LanguageView language change', () => {
+ it('applies the selected language at runtime via setLanguage', async () => {
+ const { findByTestId } = render();
+
+ const spanishOption = await findByTestId('language-view-es', {}, { timeout: 5000 });
+ fireEvent(spanishOption, 'onPress');
+
+ await waitFor(
+ () => {
+ expect((i18n as any).setLanguage).toHaveBeenCalledWith('es');
+ },
+ { timeout: 5000 }
+ );
+ });
+});
diff --git a/app/views/LanguageView/index.tsx b/app/views/LanguageView/index.tsx
index 8aec1f66cb4..850e53f6ff0 100644
--- a/app/views/LanguageView/index.tsx
+++ b/app/views/LanguageView/index.tsx
@@ -12,7 +12,7 @@ import { setUser } from '../../actions/login';
import * as List from '../../containers/List';
import SafeAreaView from '../../containers/SafeAreaView';
import { RootEnum } from '../../definitions';
-import I18n, { isRTL, LANGUAGES } from '../../i18n';
+import I18n, { isRTL, LANGUAGES, setLanguage } from '../../i18n';
import database from '../../lib/database';
import { getUserSelector } from '../../selectors/login';
import { type SettingsStackParamList } from '../../stacks/types';
@@ -46,7 +46,11 @@ const LanguageView = () => {
dispatch(appStart({ root: RootEnum.ROOT_LOADING, text: I18n.t('Change_language_loading') }));
// shows loading for at least 300ms
- await Promise.all([changeLanguage(language), new Promise(resolve => setTimeout(resolve, 300))]);
+ const [changed] = await Promise.all([changeLanguage(language), new Promise(resolve => setTimeout(resolve, 300))]);
+
+ if (changed) {
+ setLanguage(language);
+ }
if (shouldRestart) {
await RNRestart.Restart();
@@ -55,7 +59,7 @@ const LanguageView = () => {
}
};
- const changeLanguage = async (language: string) => {
+ const changeLanguage = async (language: string): Promise => {
logEvent(events.LANG_SET_LANGUAGE);
const params: { language?: string } = {};
@@ -72,19 +76,18 @@ const LanguageView = () => {
const serversDB = database.servers;
const usersCollection = serversDB.get('users');
await serversDB.write(async () => {
- try {
- const userRecord = await usersCollection.find(id);
- await userRecord.update(record => {
- record.language = params.language;
- });
- } catch (e) {
- logEvent(events.LANG_SET_LANGUAGE_F);
- }
+ const userRecord = await usersCollection.find(id);
+ await userRecord.update(record => {
+ record.language = params.language;
+ });
});
+
+ return true;
} catch (e) {
logEvent(events.LANG_SET_LANGUAGE_F);
showErrorAlert(I18n.t('There_was_an_error_while_action', { action: I18n.t('saving_preferences') }));
log(e);
+ return false;
}
};