Skip to content

Commit 4fb83f9

Browse files
committed
refactor: implement typescript
1 parent 37dea13 commit 4fb83f9

File tree

7 files changed

+84
-59
lines changed

7 files changed

+84
-59
lines changed
File renamed without changes.
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ const LMS_BASE_URL = 'http://test.lms';
1010
describe('languageApi', () => {
1111
beforeEach(() => {
1212
jest.clearAllMocks();
13-
getConfig.mockReturnValue({ LMS_BASE_URL });
14-
getAuthenticatedUser.mockReturnValue({ username: 'testuser', userId: '123' });
13+
(getConfig as jest.Mock).mockReturnValue({ LMS_BASE_URL });
14+
(getAuthenticatedUser as jest.Mock).mockReturnValue({ username: 'testuser', userId: '123' });
1515
});
1616

1717
describe('updateAuthenticatedUserPreferences', () => {
1818
it('should send a PATCH request with correct data', async () => {
1919
const patchMock = jest.fn().mockResolvedValue({});
20-
getAuthenticatedHttpClient.mockReturnValue({ patch: patchMock });
20+
(getAuthenticatedHttpClient as jest.Mock).mockReturnValue({ patch: patchMock });
2121

2222
await updateAuthenticatedUserPreferences({ prefLang: 'es' });
2323

@@ -30,8 +30,8 @@ describe('languageApi', () => {
3030

3131
it('should return early if no authenticated user', async () => {
3232
const patchMock = jest.fn().mockResolvedValue({});
33-
getAuthenticatedHttpClient.mockReturnValue({ patch: patchMock });
34-
getAuthenticatedUser.mockReturnValue(null);
33+
(getAuthenticatedHttpClient as jest.Mock).mockReturnValue({ patch: patchMock });
34+
(getAuthenticatedUser as jest.Mock).mockReturnValue(null);
3535

3636
await updateAuthenticatedUserPreferences({ prefLang: 'es' });
3737

@@ -42,7 +42,7 @@ describe('languageApi', () => {
4242
describe('setSessionLanguage', () => {
4343
it('should send a POST request to setlang endpoint', async () => {
4444
const postMock = jest.fn().mockResolvedValue({});
45-
getAuthenticatedHttpClient.mockReturnValue({ post: postMock });
45+
(getAuthenticatedHttpClient as jest.Mock).mockReturnValue({ post: postMock });
4646

4747
await setSessionLanguage('ar');
4848

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,23 @@ import { getConfig } from '../config';
22
import { getAuthenticatedHttpClient, getAuthenticatedUser } from '../auth';
33
import { convertKeyNames, snakeCaseObject } from '../utils';
44

5+
interface PreferenceData {
6+
prefLang: string;
7+
[key: string]: string;
8+
}
9+
510
/**
611
* Updates user language preferences via the preferences API.
712
*
813
* This function gets the authenticated user, converts preference data to snake_case
914
* and formats specific keys according to backend requirements before sending the PATCH request.
1015
* If no user is authenticated, the function returns early without making the API call.
1116
*
12-
* @param {Object} preferenceData - The preference parameters to update (e.g., { prefLang: 'en' }).
17+
* @param {PreferenceData} preferenceData - The preference parameters to update (e.g., { prefLang: 'en' }).
1318
* @returns {Promise} - A promise that resolves when the API call completes successfully,
1419
* or rejects if there's an error with the request. Returns early if no user is authenticated.
1520
*/
16-
export async function updateAuthenticatedUserPreferences(preferenceData) {
21+
export async function updateAuthenticatedUserPreferences(preferenceData: PreferenceData): Promise<void> {
1722
const user = getAuthenticatedUser();
1823
if (!user) {
1924
return Promise.resolve();
@@ -37,12 +42,13 @@ export async function updateAuthenticatedUserPreferences(preferenceData) {
3742
* This function sends a POST request to the LMS setlang endpoint to change
3843
* the language for the current user session.
3944
*
40-
* @param {string} languageCode - The language code to set (e.g., 'en', 'es', 'ar').
41-
* Should be a valid ISO language code supported by the platform.
45+
* @param {string} languageCode - The selected language locale code (e.g., 'en', 'es-419', 'ar', 'de-de').
46+
* Should be a valid ISO language code supported by the platform. For reference:
47+
* https://github.com/openedx/openedx-platform/blob/master/openedx/envs/common.py#L231
4248
* @returns {Promise} - A promise that resolves when the API call completes successfully,
4349
* or rejects if there's an error with the request.
4450
*/
45-
export async function setSessionLanguage(languageCode) {
51+
export async function setSessionLanguage(languageCode: string): Promise<void> {
4652
const formData = new FormData();
4753
formData.append('language', languageCode);
4854

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jest.mock('../pubSub');
1010
jest.mock('./languageApi');
1111

1212
describe('languageManager', () => {
13-
let mockReload;
13+
let mockReload: jest.Mock;
1414

1515
beforeEach(() => {
1616
jest.clearAllMocks();
@@ -22,8 +22,8 @@ describe('languageManager', () => {
2222
value: { reload: mockReload },
2323
});
2424

25-
updateAuthenticatedUserPreferences.mockResolvedValue({});
26-
setSessionLanguage.mockResolvedValue({});
25+
(updateAuthenticatedUserPreferences as jest.Mock).mockResolvedValue({});
26+
(setSessionLanguage as jest.Mock).mockResolvedValue({});
2727
});
2828

2929
describe('changeUserSessionLanguage', () => {
@@ -33,13 +33,13 @@ describe('languageManager', () => {
3333
prefLang: 'fr',
3434
});
3535
expect(setSessionLanguage).toHaveBeenCalledWith('fr');
36-
expect(handleRtl).toHaveBeenCalledWith('fr');
36+
expect(handleRtl).toHaveBeenCalled();
3737
expect(publish).toHaveBeenCalledWith(LOCALE_CHANGED, 'fr');
3838
expect(mockReload).not.toHaveBeenCalled();
3939
});
4040

4141
it('should handle errors gracefully', async () => {
42-
updateAuthenticatedUserPreferences.mockRejectedValue(new Error('fail'));
42+
(updateAuthenticatedUserPreferences as jest.Mock).mockRejectedValue(new Error('fail'));
4343
await changeUserSessionLanguage('es', true);
4444
expect(logError).toHaveBeenCalled();
4545
});
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,23 @@ import { updateAuthenticatedUserPreferences, setSessionLanguage } from './langua
1212
* 3. Updates the session language through the setlang endpoint
1313
* 4. Publishes a locale change event to notify other parts of the application
1414
*
15-
* @param {string} languageCode - The selected language locale code (e.g., 'en', 'es', 'ar').
16-
* Should be a valid ISO language code supported by the platform.
15+
* @param {string} languageCode - The selected language locale code (e.g., 'en', 'es-419', 'ar', 'de-de').
16+
* Should be a valid ISO language code supported by the platform. For reference:
17+
* https://github.com/openedx/openedx-platform/blob/master/openedx/envs/common.py#L231
1718
* @param {boolean} [forceReload=false] - Whether to force a page reload after changing the language.
1819
* @returns {Promise} - A promise that resolves when all operations complete.
1920
*
2021
*/
2122
export async function changeUserSessionLanguage(
22-
languageCode,
23-
forceReload = false,
24-
) {
23+
languageCode: string,
24+
forceReload: boolean = false,
25+
): Promise<void> {
2526
try {
2627
await updateAuthenticatedUserPreferences({ prefLang: languageCode });
2728
await setSessionLanguage(languageCode);
28-
handleRtl(languageCode);
29+
handleRtl();
2930
publish(LOCALE_CHANGED, languageCode);
30-
} catch (error) {
31+
} catch (error: any) {
3132
logError(error);
3233
}
3334

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ jest.mock('universal-cookie');
1515

1616
describe('lib', () => {
1717
describe('configure', () => {
18-
let originalWarn = null;
18+
let originalWarn: typeof console.warn | null = null;
1919

2020
beforeEach(() => {
2121
originalWarn = console.warn;
2222
console.warn = jest.fn();
2323
});
2424

2525
afterEach(() => {
26-
console.warn = originalWarn;
26+
console.warn = originalWarn!;
2727
});
2828

2929
it('should not call console.warn in production', () => {
@@ -177,11 +177,11 @@ describe('lib', () => {
177177
});
178178

179179
it('should return the messages for the provided locale', () => {
180-
expect(getMessages('en-us').message).toEqual('en-us-hah');
180+
expect(getMessages('en-us')!.message).toEqual('en-us-hah');
181181
});
182182

183183
it('should return the messages for the preferred locale if no argument is passed', () => {
184-
expect(getMessages().message).toEqual('es-hah');
184+
expect(getMessages()!.message).toEqual('es-hah');
185185
});
186186
});
187187

@@ -231,15 +231,15 @@ describe('lib', () => {
231231
});
232232

233233
describe('handleRtl', () => {
234-
let setAttribute;
234+
let setAttribute: jest.Mock;
235235
beforeEach(() => {
236236
setAttribute = jest.fn();
237237

238238
global.document.getElementsByTagName = jest.fn(() => [
239239
{
240240
setAttribute,
241241
},
242-
]);
242+
]) as any;
243243
});
244244

245245
it('should do the right thing for non-RTL languages', () => {
@@ -310,7 +310,7 @@ describe('mergeMessages', () => {
310310
ar: { message: 'ar-hah' },
311311
},
312312
});
313-
const result = mergeMessages([{ foo: 'bar' }, { buh: 'baz' }, { gah: 'wut' }]);
313+
const result = mergeMessages([{ foo: 'bar' }, { buh: 'baz' }, { gah: 'wut' }] as any);
314314
expect(result).toEqual({
315315
ar: { message: 'ar-hah' },
316316
foo: 'bar',
@@ -331,7 +331,7 @@ describe('mergeMessages', () => {
331331
es: { init: 'inicial' },
332332
},
333333
});
334-
const messages = [
334+
const msgs: import('./lib').I18nMessages[] = [
335335
{
336336
en: { hello: 'hello' },
337337
es: { hello: 'hola' },
@@ -342,7 +342,7 @@ describe('mergeMessages', () => {
342342
},
343343
];
344344

345-
const result = mergeMessages(messages);
345+
const result = mergeMessages(msgs);
346346
expect(result).toEqual({
347347
en: {
348348
init: 'initial',

0 commit comments

Comments
 (0)