* feat: add language selection chore: update tests so we have less error message test: update test * test: update tests * chore: remove duplicate translation * chore: lint for console * chore: remove comments * chore: make sure the affect url frame refresh after the language selection change * chore: add whole_course_translation and language to courseware meta (#1305) * feat: Add feedback widget UI mock Add unit tests Fix snapshot Clean Sequence component logEvent calls Clean unit test Put feedback widget behind whole course translation flag Fix useFeedbackWidget test * chore: add src and dest translation * feat: first iteration of plugin translation chore: update plugin instruction * feat: Connect FeedbackWidget with backend services (#1325) Connect FeedbackWidget with backend services Move feedback widget to unit translation plugin * feat: Add authentication to WCT feedback endpoints (#1329) * chore: add fetch config and move feedback widget for the plugin chore: rewrite and test the api request chore: rebase chore: update translation feedback chore: test chore: add more tests * chore: rebase * chore: update requested change * chore: update package * chore: upgrade frontend-lib-special-exams and frontend-lib-learning-assistant * chore: update tests * chore: remove unneeded package * chore: update example config * chore: add source-map-loader * fix: feedback widget render error after submit feedback (#1335) * fix: feedback widget render error after submit feedback * fix: widget logic --------- Co-authored-by: Rodrigo Martin <rodrigom_94@hotmail.com>
126 lines
4.1 KiB
JavaScript
126 lines
4.1 KiB
JavaScript
import { camelCaseObject } from '@edx/frontend-platform';
|
|
import { logError } from '@edx/frontend-platform/logging';
|
|
import { stringify } from 'query-string';
|
|
|
|
import {
|
|
fetchTranslationConfig,
|
|
getTranslationFeedback,
|
|
createTranslationFeedback,
|
|
} from './api';
|
|
|
|
const mockGetMethod = jest.fn();
|
|
const mockPostMethod = jest.fn();
|
|
jest.mock('@edx/frontend-platform/auth', () => ({
|
|
getAuthenticatedHttpClient: () => ({
|
|
get: mockGetMethod,
|
|
post: mockPostMethod,
|
|
}),
|
|
}));
|
|
jest.mock('@edx/frontend-platform/logging', () => ({
|
|
logError: jest.fn(),
|
|
}));
|
|
|
|
describe('UnitTranslation api', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
describe('fetchTranslationConfig', () => {
|
|
const courseId = 'course-v1:edX+DemoX+Demo_Course';
|
|
const expectedResponse = {
|
|
feature_enabled: true,
|
|
available_translation_languages: [
|
|
{
|
|
code: 'en',
|
|
label: 'English',
|
|
},
|
|
{
|
|
code: 'es',
|
|
label: 'Spanish',
|
|
},
|
|
],
|
|
};
|
|
it('should fetch translation config', async () => {
|
|
const expectedUrl = `http://localhost:18000/api/translatable_xblocks/config/?course_id=${encodeURIComponent(
|
|
courseId,
|
|
)}`;
|
|
mockGetMethod.mockResolvedValueOnce({ data: expectedResponse });
|
|
const result = await fetchTranslationConfig(courseId);
|
|
expect(result).toEqual({
|
|
enabled: true,
|
|
availableLanguages: expectedResponse.available_translation_languages,
|
|
});
|
|
expect(mockGetMethod).toHaveBeenCalledWith(expectedUrl);
|
|
});
|
|
|
|
it('should return disabled and unavailable languages on error', async () => {
|
|
mockGetMethod.mockRejectedValueOnce(new Error('error'));
|
|
const result = await fetchTranslationConfig(courseId);
|
|
expect(result).toEqual({
|
|
enabled: false,
|
|
availableLanguages: [],
|
|
});
|
|
expect(logError).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('getTranslationFeedback', () => {
|
|
const props = {
|
|
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
|
translationLanguage: 'es',
|
|
unitId: 'unit-v1:edX+DemoX+Demo_Course+type@video+block@video',
|
|
userId: 'test_user',
|
|
};
|
|
const expectedResponse = {
|
|
feedback: 'good',
|
|
};
|
|
it('should fetch translation feedback', async () => {
|
|
const params = stringify({
|
|
translation_language: props.translationLanguage,
|
|
course_id: encodeURIComponent(props.courseId),
|
|
unit_id: encodeURIComponent(props.unitId),
|
|
user_id: props.userId,
|
|
});
|
|
const expectedUrl = `http://localhost:18760/api/v1/whole-course-translation-feedback?${params}`;
|
|
mockGetMethod.mockResolvedValueOnce({ data: expectedResponse });
|
|
const result = await getTranslationFeedback(props);
|
|
expect(result).toEqual(camelCaseObject(expectedResponse));
|
|
expect(mockGetMethod).toHaveBeenCalledWith(expectedUrl);
|
|
});
|
|
|
|
it('should return empty object on error', async () => {
|
|
mockGetMethod.mockRejectedValueOnce(new Error('error'));
|
|
const result = await getTranslationFeedback(props);
|
|
expect(result).toEqual({});
|
|
expect(logError).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe('createTranslationFeedback', () => {
|
|
const props = {
|
|
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
|
feedbackValue: 'good',
|
|
translationLanguage: 'es',
|
|
unitId: 'unit-v1:edX+DemoX+Demo_Course+type@video+block@video',
|
|
userId: 'test_user',
|
|
};
|
|
it('should create translation feedback', async () => {
|
|
const expectedUrl = 'http://localhost:18760/api/v1/whole-course-translation-feedback/';
|
|
mockPostMethod.mockResolvedValueOnce({});
|
|
await createTranslationFeedback(props);
|
|
expect(mockPostMethod).toHaveBeenCalledWith(expectedUrl, {
|
|
course_id: props.courseId,
|
|
feedback_value: props.feedbackValue,
|
|
translation_language: props.translationLanguage,
|
|
unit_id: props.unitId,
|
|
user_id: props.userId,
|
|
});
|
|
});
|
|
|
|
it('should log error on failure', async () => {
|
|
mockPostMethod.mockRejectedValueOnce(new Error('error'));
|
|
await createTranslationFeedback(props);
|
|
expect(logError).toHaveBeenCalled();
|
|
});
|
|
});
|
|
});
|