Skip to content

Commit c2d269c

Browse files
committed
test(i18n): add unit tests for languageApi and languageManager functions
1 parent a3c25d1 commit c2d269c

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

src/i18n/languageApi.test.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { updateUserPreferences, setSessionLanguage } from './languageApi';
2+
import { getConfig } from '../config';
3+
import { getAuthenticatedHttpClient } from '../auth';
4+
5+
jest.mock('../config');
6+
jest.mock('../auth');
7+
8+
const LMS_BASE_URL = 'http://test.lms';
9+
10+
describe('languageApi', () => {
11+
beforeEach(() => {
12+
jest.clearAllMocks();
13+
getConfig.mockReturnValue({ LMS_BASE_URL });
14+
});
15+
16+
describe('updateUserPreferences', () => {
17+
it('should send a PATCH request with correct data', async () => {
18+
const patchMock = jest.fn().mockResolvedValue({});
19+
getAuthenticatedHttpClient.mockReturnValue({ patch: patchMock });
20+
21+
await updateUserPreferences('user1', { prefLang: 'es' });
22+
23+
expect(patchMock).toHaveBeenCalledWith(
24+
`${LMS_BASE_URL}/api/user/v1/preferences/user1`,
25+
expect.any(Object),
26+
expect.objectContaining({ headers: expect.any(Object) }),
27+
);
28+
});
29+
});
30+
31+
describe('setSessionLanguage', () => {
32+
it('should send a POST request to setlang endpoint', async () => {
33+
const postMock = jest.fn().mockResolvedValue({});
34+
getAuthenticatedHttpClient.mockReturnValue({ post: postMock });
35+
36+
await setSessionLanguage('ar');
37+
38+
expect(postMock).toHaveBeenCalledWith(
39+
`${LMS_BASE_URL}/i18n/setlang/`,
40+
expect.any(FormData),
41+
expect.objectContaining({ headers: expect.any(Object) }),
42+
);
43+
});
44+
});
45+
});

src/i18n/languageManager.test.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { changeUserSessionLanguage } from './languageManager';
2+
import { getConfig } from '../config';
3+
import { getAuthenticatedUser } from '../auth';
4+
import { getCookies, handleRtl, LOCALE_CHANGED } from './lib';
5+
import { logError } from '../logging';
6+
import { publish } from '../pubSub';
7+
import { updateUserPreferences, setSessionLanguage } from './languageApi';
8+
9+
jest.mock('../config');
10+
jest.mock('../auth');
11+
jest.mock('./lib');
12+
jest.mock('../logging');
13+
jest.mock('../pubSub');
14+
jest.mock('./languageApi');
15+
16+
const LMS_BASE_URL = 'http://test.lms';
17+
const LANGUAGE_PREFERENCE_COOKIE_NAME = 'lang';
18+
19+
describe('languageManager', () => {
20+
let mockCookies;
21+
let mockUser;
22+
let mockReload;
23+
24+
beforeEach(() => {
25+
jest.clearAllMocks();
26+
getConfig.mockReturnValue({
27+
LMS_BASE_URL,
28+
LANGUAGE_PREFERENCE_COOKIE_NAME,
29+
});
30+
31+
mockCookies = { set: jest.fn() };
32+
getCookies.mockReturnValue(mockCookies);
33+
34+
mockUser = { username: 'testuser', userId: '123' };
35+
getAuthenticatedUser.mockReturnValue(mockUser);
36+
37+
mockReload = jest.fn();
38+
Object.defineProperty(window, 'location', {
39+
configurable: true,
40+
writable: true,
41+
value: { reload: mockReload },
42+
});
43+
44+
updateUserPreferences.mockResolvedValue({});
45+
setSessionLanguage.mockResolvedValue({});
46+
});
47+
48+
describe('changeUserSessionLanguage', () => {
49+
it('should perform complete language change process', async () => {
50+
await changeUserSessionLanguage('fr');
51+
52+
expect(getCookies().set).toHaveBeenCalledWith(
53+
LANGUAGE_PREFERENCE_COOKIE_NAME,
54+
'fr',
55+
);
56+
expect(updateUserPreferences).toHaveBeenCalledWith('testuser', {
57+
prefLang: 'fr',
58+
});
59+
expect(setSessionLanguage).toHaveBeenCalledWith('fr');
60+
expect(handleRtl).toHaveBeenCalledWith('fr');
61+
expect(publish).toHaveBeenCalledWith(LOCALE_CHANGED, 'fr');
62+
expect(mockReload).not.toHaveBeenCalled();
63+
});
64+
65+
it('should handle errors gracefully', async () => {
66+
updateUserPreferences.mockRejectedValue(new Error('fail'));
67+
await changeUserSessionLanguage('es', true);
68+
expect(logError).toHaveBeenCalled();
69+
});
70+
71+
it('should skip updateUserPreferences if user is not authenticated', async () => {
72+
getAuthenticatedUser.mockReturnValue(null);
73+
await changeUserSessionLanguage('en', true);
74+
expect(updateUserPreferences).not.toHaveBeenCalled();
75+
});
76+
77+
it('should reload if forceReload is true', async () => {
78+
await changeUserSessionLanguage('de', true);
79+
expect(mockReload).toHaveBeenCalled();
80+
});
81+
});
82+
});

0 commit comments

Comments
 (0)