diff --git a/src/courseware/course/sequence/Unit/index.jsx b/src/courseware/course/sequence/Unit/index.jsx
index dcaff7a559..656f6cdda0 100644
--- a/src/courseware/course/sequence/Unit/index.jsx
+++ b/src/courseware/course/sequence/Unit/index.jsx
@@ -24,24 +24,28 @@ const Unit = ({
const examAccess = useExamAccess({ id });
const shouldDisplayHonorCode = useShouldDisplayHonorCode({ courseId, id });
const unit = useModel(modelKeys.units, id);
- const { wholeCourseTranslationEnabled } = useModel('coursewareMeta', courseId);
+ const { language, wholeCourseTranslationEnabled } = useModel('courseHomeMeta', courseId);
const isProcessing = unit.bookmarkedUpdateState === 'loading';
const view = authenticatedUser ? views.student : views.public;
- const { selectedLanguage, setSelectedLanguage } = useSelectLanguage(courseId);
+ const { selectedLanguage, setSelectedLanguage } = useSelectLanguage({
+ courseId,
+ language,
+ });
const iframeUrl = useMemo(() => getIFrameUrl({
id,
view,
format,
examAccess,
- translateLanguage: selectedLanguage,
- }), [id, view, format, examAccess, selectedLanguage]);
+ srcLanguage: language,
+ destLanguage: selectedLanguage,
+ }), [id, view, format, examAccess, selectedLanguage, language]);
return (
{unit.title}
- {wholeCourseTranslationEnabled && (
+ {wholeCourseTranslationEnabled && language && (
({ wholeCourseTranslationEnabled: fal
const mockUnitsFn = jest.fn(() => unit);
when(useModel)
- .calledWith('coursewareMeta', props.courseId)
+ .calledWith('courseHomeMeta', props.courseId)
.mockImplementation(mockCoursewareMetaFn)
.calledWith(modelKeys.units, props.id)
.mockImplementation(mockUnitsFn);
@@ -201,8 +201,8 @@ describe('Unit component', () => {
});
});
describe('TranslationSelection', () => {
- test('renders if wholeCourseTranslationEnabled', () => {
- mockCoursewareMetaFn.mockReturnValueOnce({ wholeCourseTranslationEnabled: true });
+ test('renders if wholeCourseTranslationEnabled and language is defined', () => {
+ mockCoursewareMetaFn.mockReturnValueOnce({ wholeCourseTranslationEnabled: true, language: 'en' });
el = shallow();
expect(el.snapshot).toMatchSnapshot();
expect(el.instance.findByType('TranslationSelection')).toHaveLength(1);
@@ -212,6 +212,11 @@ describe('Unit component', () => {
el = shallow();
expect(el.instance.findByType('TranslationSelection')).toHaveLength(0);
});
+ test('does not render if language is undefined', () => {
+ mockCoursewareMetaFn.mockReturnValueOnce({ wholeCourseTranslationEnabled: true });
+ el = shallow();
+ expect(el.instance.findByType('TranslationSelection')).toHaveLength(0);
+ });
});
});
});
diff --git a/src/courseware/course/sequence/Unit/translation-selection/useSelectLanguage.js b/src/courseware/course/sequence/Unit/translation-selection/useSelectLanguage.js
index 5977ee0244..c6aed3994a 100644
--- a/src/courseware/course/sequence/Unit/translation-selection/useSelectLanguage.js
+++ b/src/courseware/course/sequence/Unit/translation-selection/useSelectLanguage.js
@@ -6,6 +6,7 @@ import {
} from '../../../../../data/localStorage';
export const selectedLanguageKey = 'selectedLanguages';
+// This will be use to check supported languages
export const languages = Object.entries({
en: 'English',
es: 'Spanish',
@@ -18,11 +19,11 @@ export const stateKeys = StrictDict({
selectedLanguage: 'selectedLanguage',
});
-const useSelectLanguage = (courseId) => {
+const useSelectLanguage = ({ courseId, language }) => {
const selectedLanguageItem = getLocalStorage(selectedLanguageKey) || {};
const [selectedLanguage, updateSelectedLanguage] = useKeyedState(
stateKeys.selectedLanguage,
- selectedLanguageItem[courseId] || 'en',
+ selectedLanguageItem[courseId] || language,
);
const setSelectedLanguage = useCallback((newSelectedLanguage) => {
diff --git a/src/courseware/course/sequence/Unit/translation-selection/useSelectLanguage.test.js b/src/courseware/course/sequence/Unit/translation-selection/useSelectLanguage.test.js
index a461ae709f..62e8e3ea8f 100644
--- a/src/courseware/course/sequence/Unit/translation-selection/useSelectLanguage.test.js
+++ b/src/courseware/course/sequence/Unit/translation-selection/useSelectLanguage.test.js
@@ -29,7 +29,10 @@ jest.mock('../../../../../data/localStorage', () => ({
}));
describe('useSelectLanguage', () => {
- const courseId = 'some-course-id';
+ const props = {
+ courseId: 'test-course-id',
+ language: 'en',
+ };
beforeEach(() => {
jest.clearAllMocks();
@@ -41,8 +44,8 @@ describe('useSelectLanguage', () => {
languages.forEach(([key, value]) => {
it(`initializes selectedLanguage to the selected language (${value})`, () => {
- getLocalStorage.mockReturnValueOnce({ [courseId]: key });
- const { selectedLanguage } = useSelectLanguage(courseId);
+ getLocalStorage.mockReturnValueOnce({ [props.courseId]: key });
+ const { selectedLanguage } = useSelectLanguage(props);
state.expectInitializedWith(stateKeys.selectedLanguage, key);
expect(selectedLanguage).toBe(key);
@@ -50,12 +53,12 @@ describe('useSelectLanguage', () => {
});
test('setSelectedLanguage behavior', () => {
- const { setSelectedLanguage } = useSelectLanguage(courseId);
+ const { setSelectedLanguage } = useSelectLanguage(props);
setSelectedLanguage('es');
state.expectSetStateCalledWith(stateKeys.selectedLanguage, 'es');
expect(setLocalStorage).toHaveBeenCalledWith(selectedLanguageKey, {
- [courseId]: 'es',
+ [props.courseId]: 'es',
});
});
});
diff --git a/src/courseware/course/sequence/Unit/urls.js b/src/courseware/course/sequence/Unit/urls.js
index abed160641..0d76edcde4 100644
--- a/src/courseware/course/sequence/Unit/urls.js
+++ b/src/courseware/course/sequence/Unit/urls.js
@@ -12,7 +12,8 @@ export const getIFrameUrl = ({
view,
format,
examAccess,
- translateLanguage,
+ srcLanguage,
+ destLanguage,
}) => {
const xblockUrl = `${getConfig().LMS_BASE_URL}/xblock/${id}`;
const params = stringify({
@@ -20,7 +21,10 @@ export const getIFrameUrl = ({
view,
...(format && { format }),
...(!examAccess.blockAccess && { exam_access: examAccess.accessToken }),
- ...(translateLanguage && { translate_lang: translateLanguage }),
+ ...(srcLanguage && destLanguage && srcLanguage !== destLanguage && {
+ src_lang: srcLanguage,
+ dest_lang: destLanguage,
+ }),
});
return `${xblockUrl}?${params}`;
};
diff --git a/src/courseware/course/sequence/Unit/urls.test.js b/src/courseware/course/sequence/Unit/urls.test.js
index 409b5d65a1..2b0e46d8f7 100644
--- a/src/courseware/course/sequence/Unit/urls.test.js
+++ b/src/courseware/course/sequence/Unit/urls.test.js
@@ -17,28 +17,45 @@ const props = {
view: 'test-view',
format: 'test-format',
examAccess: { blockAccess: false, accessToken: 'test-access-token' },
- translateLanguage: 'test-translate-language',
};
-describe('urls module', () => {
- describe('getIFrameUrl', () => {
- test('format provided, exam access and token available', () => {
- const params = stringify({
- ...iframeParams,
- view: props.view,
- format: props.format,
- exam_access: props.examAccess.accessToken,
- translate_lang: props.translateLanguage,
- });
- expect(getIFrameUrl(props)).toEqual(`${config.LMS_BASE_URL}/xblock/${props.id}?${params}`);
+describe('urls module getIFrameUrl', () => {
+ test('format provided, exam access and token available', () => {
+ const params = stringify({
+ ...iframeParams,
+ view: props.view,
+ format: props.format,
+ exam_access: props.examAccess.accessToken,
});
- test('no format provided, exam access blocked', () => {
- const params = stringify({ ...iframeParams, view: props.view });
- expect(getIFrameUrl({
- id: props.id,
- view: props.view,
- examAccess: { blockAccess: true },
- })).toEqual(`${config.LMS_BASE_URL}/xblock/${props.id}?${params}`);
+ expect(getIFrameUrl(props)).toEqual(`${config.LMS_BASE_URL}/xblock/${props.id}?${params}`);
+ });
+ test('no format provided, exam access blocked', () => {
+ const params = stringify({ ...iframeParams, view: props.view });
+ expect(getIFrameUrl({
+ id: props.id,
+ view: props.view,
+ examAccess: { blockAccess: true },
+ })).toEqual(`${config.LMS_BASE_URL}/xblock/${props.id}?${params}`);
+ });
+ test('src and dest languages provided', () => {
+ const params = stringify({
+ ...iframeParams,
+ view: props.view,
+ src_lang: 'test-src-lang',
+ dest_lang: 'test-dest-lang',
});
+ expect(getIFrameUrl({
+ ...props,
+ srcLanguage: 'test-src-lang',
+ destLanguage: 'test-dest-lang',
+ })).toEqual(`${config.LMS_BASE_URL}/xblock/${props.id}?${params}`);
+ });
+ test('src and dest languages provided are the same', () => {
+ const params = stringify({ ...iframeParams, view: props.view });
+ expect(getIFrameUrl({
+ ...props,
+ srcLanguage: 'test-lang',
+ destLanguage: 'test-lang',
+ })).toEqual(`${config.LMS_BASE_URL}/xblock/${props.id}?${params}`);
});
});
diff --git a/src/courseware/data/api.js b/src/courseware/data/api.js
index 7643796695..f3a82a5e2b 100644
--- a/src/courseware/data/api.js
+++ b/src/courseware/data/api.js
@@ -110,8 +110,6 @@ function normalizeMetadata(metadata) {
showCalculator: data.show_calculator,
notes: camelCaseObject(data.notes),
marketingUrl: data.marketing_url,
- language: data.language,
- wholeCourseTranslationEnabled: data.whole_course_translation_enabled,
celebrations: camelCaseObject(data.celebrations),
userHasPassingGrade: data.user_has_passing_grade,
courseExitPageIsActive: data.course_exit_page_is_active,