From d6acfa679f95f84bffbce42e89a9967553711458 Mon Sep 17 00:00:00 2001 From: Qubad786 Date: Tue, 10 Oct 2017 16:47:04 +0500 Subject: [PATCH] Add video source language support for Cielo24 - EDUCATOR-1491 --- .../contentstore/views/tests/test_videos.py | 16 +- cms/djangoapps/contentstore/views/videos.py | 7 +- .../spec/views/course_video_settings_spec.js | 160 +++++++++++++++++- cms/static/js/views/course_video_settings.js | 36 +++- cms/static/sass/views/_video-upload.scss | 6 +- 5 files changed, 204 insertions(+), 21 deletions(-) diff --git a/cms/djangoapps/contentstore/views/tests/test_videos.py b/cms/djangoapps/contentstore/views/tests/test_videos.py index b2c3f0b7ea..e162d4d029 100644 --- a/cms/djangoapps/contentstore/views/tests/test_videos.py +++ b/cms/djangoapps/contentstore/views/tests/test_videos.py @@ -953,17 +953,30 @@ class TranscriptPreferencesTestCase(VideoUploadTestBase, CourseTestCase): { 'provider': TranscriptProvider.CIELO24, 'cielo24_fidelity': 'PROFESSIONAL', - 'cielo24_turnaround': 'STANDARD' + 'cielo24_turnaround': 'STANDARD', + 'video_source_language': 'en' }, True, u"Invalid languages [].", 400 ), + ( + { + 'provider': TranscriptProvider.CIELO24, + 'cielo24_fidelity': 'PREMIUM', + 'cielo24_turnaround': 'STANDARD', + 'video_source_language': 'es' + }, + True, + u"Unsupported source language es.", + 400 + ), ( { 'provider': TranscriptProvider.CIELO24, 'cielo24_fidelity': 'PROFESSIONAL', 'cielo24_turnaround': 'STANDARD', + 'video_source_language': 'en', 'preferred_languages': ['es', 'ur'] }, True, @@ -1016,6 +1029,7 @@ class TranscriptPreferencesTestCase(VideoUploadTestBase, CourseTestCase): 'provider': TranscriptProvider.CIELO24, 'cielo24_fidelity': 'PROFESSIONAL', 'cielo24_turnaround': 'STANDARD', + 'video_source_language': 'es', 'preferred_languages': ['en'] }, True, diff --git a/cms/djangoapps/contentstore/views/videos.py b/cms/djangoapps/contentstore/views/videos.py index 8630611ff0..c7ef4be093 100644 --- a/cms/djangoapps/contentstore/views/videos.py +++ b/cms/djangoapps/contentstore/views/videos.py @@ -266,7 +266,7 @@ def validate_transcript_preferences(provider, cielo24_fidelity, cielo24_turnarou cielo24_fidelity: Cielo24 transcription fidelity. cielo24_turnaround: Cielo24 transcription turnaround. three_play_turnaround: 3PlayMedia transcription turnaround. - video_source_language: Source/Speech language of the videos that are going to be submitted to 3PlayMedia. + video_source_language: Source/Speech language of the videos that are going to be submitted to the Providers. preferred_languages: list of language codes. Returns: @@ -291,12 +291,17 @@ def validate_transcript_preferences(provider, cielo24_fidelity, cielo24_turnarou # Validate transcription languages supported_languages = transcription_plans[provider]['fidelity'][cielo24_fidelity]['languages'] + if video_source_language not in supported_languages: + error = 'Unsupported source language {}.'.format(video_source_language) + return error, preferences + if not len(preferred_languages) or not (set(preferred_languages) <= set(supported_languages.keys())): error = 'Invalid languages {}.'.format(preferred_languages) return error, preferences # Validated Cielo24 preferences preferences = { + 'video_source_language': video_source_language, 'cielo24_fidelity': cielo24_fidelity, 'cielo24_turnaround': cielo24_turnaround, 'preferred_languages': preferred_languages, diff --git a/cms/static/js/spec/views/course_video_settings_spec.js b/cms/static/js/spec/views/course_video_settings_spec.js index ac99fc2885..6035e0b966 100644 --- a/cms/static/js/spec/views/course_video_settings_spec.js +++ b/cms/static/js/spec/views/course_video_settings_spec.js @@ -9,12 +9,15 @@ define( renderCourseVideoSettingsView, destroyCourseVideoSettingsView, verifyPreferanceErrorState, + selectPreference, + chooseProvider, transcriptPreferencesUrl = '/transcript_preferences/course-v1:edX+DemoX+Demo_Course', activeTranscriptPreferences = { provider: 'Cielo24', cielo24_fidelity: 'PROFESSIONAL', cielo24_turnaround: 'PRIORITY', three_play_turnaround: '', + video_source_language: 'en', preferred_languages: ['fr', 'en'], modified: '2017-08-27T12:28:17.421260Z' }, @@ -22,7 +25,8 @@ define( '3PlayMedia': { languages: { fr: 'French', - en: 'English' + en: 'English', + ur: 'Urdu' }, turnaround: { default: '4-Day/Default', @@ -31,6 +35,10 @@ define( extended_service: '10-Day/Extended', expedited_service: '2-Day/Expedited' }, + translations: { + es: ['en'], + en: ['en', 'ur'] + }, display_name: '3PlayMedia' }, Cielo24: { @@ -92,6 +100,18 @@ define( expect($preferanceContainerEl.find('.error-info').html()).toEqual(requiredText); }; + selectPreference = function(preferenceSelector, preferanceValue) { + var $preference = $courseVideoSettingsEl.find(preferenceSelector); + // Select a vlaue for preference. + $preference.val(preferanceValue); + // Trigger on change event. + $preference.change(); + }; + + chooseProvider = function(selectedProvider) { + $courseVideoSettingsEl.find('#transcript-provider-' + selectedProvider).click(); + }; + beforeEach(function() { setFixtures( '
' + @@ -135,9 +155,10 @@ define( renderCourseVideoSettingsView(null, null); expect($courseVideoSettingsEl.find('.transcript-provider-group').html()).toEqual(''); - expect($courseVideoSettingsEl.find('#transcript-turnaround').html()).toEqual(''); - expect($courseVideoSettingsEl.find('#transcript-fidelity').html()).toEqual(''); - expect($courseVideoSettingsEl.find('#transcript-language').html()).toEqual(''); + expect($courseVideoSettingsEl.find('.transcript-turnaround').html()).toEqual(''); + expect($courseVideoSettingsEl.find('.transcript-fidelity').html()).toEqual(''); + expect($courseVideoSettingsEl.find('.video-source-language').html()).toEqual(''); + expect($courseVideoSettingsEl.find('.transcript-language-menu').html()).toEqual(''); }); it('populates transcription plans correctly', function() { @@ -151,12 +172,15 @@ define( expect($courseVideoSettingsEl.find('.transcript-provider-group input:checked').val()).toEqual( activeTranscriptPreferences.provider ); - expect($courseVideoSettingsEl.find('#transcript-turnaround').val()).toEqual( + expect($courseVideoSettingsEl.find('.transcript-turnaround').val()).toEqual( activeTranscriptPreferences.cielo24_turnaround ); - expect($courseVideoSettingsEl.find('#transcript-fidelity').val()).toEqual( + expect($courseVideoSettingsEl.find('.transcript-fidelity').val()).toEqual( activeTranscriptPreferences.cielo24_fidelity ); + expect($courseVideoSettingsEl.find('.video-source-language').val()).toEqual( + activeTranscriptPreferences.video_source_language + ); expect($courseVideoSettingsEl.find('.transcript-language-container').length).toEqual( activeTranscriptPreferences.preferred_languages.length ); @@ -165,9 +189,124 @@ define( expect(courseVideoSettingsView.selectedProvider, activeTranscriptPreferences.provider); expect(courseVideoSettingsView.selectedTurnaroundPlan, activeTranscriptPreferences.cielo24_turnaround); expect(courseVideoSettingsView.selectedFidelityPlan, activeTranscriptPreferences.cielo24_fidelity); + expect( + courseVideoSettingsView.selectedSourceLanguage, + activeTranscriptPreferences.video_source_language + ); expect(courseVideoSettingsView.selectedLanguages, activeTranscriptPreferences.preferred_languages); }); + it('shows video source language directly in case of 3Play provider', function() { + var sourceLanguages, + selectedProvider = '3PlayMedia'; + + // Select CIELIO24 provider + chooseProvider(selectedProvider); + expect(courseVideoSettingsView.selectedProvider).toEqual(selectedProvider); + + // Verify source langauges menu is shown. + sourceLanguages = courseVideoSettingsView.getSourceLanguages(); + expect($courseVideoSettingsEl.find('.video-source-language option')).toExist(); + expect($courseVideoSettingsEl.find('.video-source-language option').length).toEqual( + _.keys(sourceLanguages).length + 1 + ); + + expect(_.keys(transcriptionPlans[selectedProvider].translations)).toEqual(_.keys(sourceLanguages)); + }); + + it('shows source language when fidelity is selected', function() { + var sourceLanguages, + selectedProvider = 'Cielo24', + selectedFidelity = 'PROFESSIONAL'; + + renderCourseVideoSettingsView(null, transcriptionPlans); + + // Select CIELIO24 provider + chooseProvider(selectedProvider); + expect(courseVideoSettingsView.selectedProvider).toEqual(selectedProvider); + + // Verify source language is not shown. + sourceLanguages = courseVideoSettingsView.getSourceLanguages(); + expect($courseVideoSettingsEl.find('.video-source-language option')).not.toExist(); + expect(sourceLanguages).toBeUndefined(); + + // Select fidelity + selectPreference('.transcript-fidelity', selectedFidelity); + expect(courseVideoSettingsView.selectedFidelityPlan).toEqual(selectedFidelity); + + // Verify source langauges menu is shown. + sourceLanguages = courseVideoSettingsView.getSourceLanguages(); + expect($courseVideoSettingsEl.find('.video-source-language option')).toExist(); + expect($courseVideoSettingsEl.find('.video-source-language option').length).toEqual( + _.keys(sourceLanguages).length + 1 + ); + + // Verify getSourceLangaues return a list of langauges. + expect(sourceLanguages).toBeDefined(); + expect(transcriptionPlans[selectedProvider].fidelity[selectedFidelity].languages).toEqual( + sourceLanguages + ); + }); + + it('shows target language when source language is selected', function() { + var targetLanguages, + selectedSourceLanguage = 'en', + selectedProvider = 'Cielo24', + selectedFidelity = 'PROFESSIONAL'; + + // Select CIELIO24 provider + chooseProvider(selectedProvider); + expect(courseVideoSettingsView.selectedProvider).toEqual(selectedProvider); + + // Select fidelity + selectPreference('.transcript-fidelity', selectedFidelity); + expect(courseVideoSettingsView.selectedFidelityPlan).toEqual(selectedFidelity); + + // Verify target langauges not shown. + expect($courseVideoSettingsEl.find('.transcript-language-menu:visible option')).not.toExist(); + + // Select source language + selectPreference('.video-source-language', selectedSourceLanguage); + expect(courseVideoSettingsView.selectedVideoSourceLanguage).toEqual(selectedSourceLanguage); + + // Verify target languages are shown. + targetLanguages = courseVideoSettingsView.getTargetLanguages(); + expect($courseVideoSettingsEl.find('.transcript-language-menu:visible option')).toExist(); + expect($courseVideoSettingsEl.find('.transcript-language-menu:visible option').length).toEqual( + _.keys(targetLanguages).length + 1 + ); + }); + + it('shows target language same as selected source language in case of mechanical fidelity', function() { + var targetLanguages, + selectedSourceLanguage = 'en', + selectedProvider = 'Cielo24', + selectedFidelity = 'MECHANICAL'; + + // Select CIELIO24 provider + chooseProvider(selectedProvider); + expect(courseVideoSettingsView.selectedProvider).toEqual(selectedProvider); + + // Select fidelity + selectPreference('.transcript-fidelity', selectedFidelity); + expect(courseVideoSettingsView.selectedFidelityPlan).toEqual(selectedFidelity); + + // Select source language + selectPreference('.video-source-language', selectedSourceLanguage); + expect(courseVideoSettingsView.selectedVideoSourceLanguage).toEqual(selectedSourceLanguage); + + // Verify target languages are shown. + targetLanguages = courseVideoSettingsView.getTargetLanguages(); + expect($courseVideoSettingsEl.find('.transcript-language-menu:visible option')).toExist(); + expect($courseVideoSettingsEl.find('.transcript-language-menu:visible option').length).toEqual( + _.keys(targetLanguages).length + 1 + ); + + // Also verify that target language are same as selected source language. + expect(_.keys(targetLanguages).length).toEqual(1); + expect(_.keys(targetLanguages)).toEqual([selectedSourceLanguage]); + }); + it('saves transcript settings on update settings button click if preferances are selected', function() { var requests = AjaxHelpers.requests(this); $courseVideoSettingsEl.find('.action-update-course-video-settings').click(); @@ -182,6 +321,7 @@ define( cielo24_turnaround: activeTranscriptPreferences.cielo24_turnaround, three_play_turnaround: activeTranscriptPreferences.three_play_turnaround, preferred_languages: activeTranscriptPreferences.preferred_languages, + video_source_language: activeTranscriptPreferences.video_source_language, global: false }) ); @@ -239,6 +379,7 @@ define( cielo24_turnaround: activeTranscriptPreferences.cielo24_turnaround, three_play_turnaround: activeTranscriptPreferences.three_play_turnaround, preferred_languages: activeTranscriptPreferences.preferred_languages, + video_source_language: activeTranscriptPreferences.video_source_language, global: false }) ); @@ -272,9 +413,10 @@ define( it('removes error state on preferances if selected', function() { // Provide values for preferances. - $courseVideoSettingsEl.find('#transcript-turnaround').val('test-value'); - $courseVideoSettingsEl.find('#transcript-fidelity').val('test-value'); - $courseVideoSettingsEl.find('#transcript-language-menu').val('test-value'); + selectPreference('.transcript-turnaround', activeTranscriptPreferences.cielo24_turnaround); + selectPreference('.transcript-fidelity', activeTranscriptPreferences.cielo24_fidelity); + selectPreference('.video-source-language', activeTranscriptPreferences.video_source_language); + selectPreference('.transcript-language-menu', activeTranscriptPreferences.preferred_languages[0]); verifyPreferanceErrorState($courseVideoSettingsEl.find('.transcript-turnaround-wrapper'), false); verifyPreferanceErrorState($courseVideoSettingsEl.find('.transcript-fidelity-wrapper'), false); diff --git a/cms/static/js/views/course_video_settings.js b/cms/static/js/views/course_video_settings.js index 71a75f65fa..bbaa675af5 100644 --- a/cms/static/js/views/course_video_settings.js +++ b/cms/static/js/views/course_video_settings.js @@ -101,6 +101,13 @@ function($, Backbone, _, gettext, moment, HtmlUtils, StringUtils, TranscriptSett if (selectedPlan) { if (this.selectedProvider === CIELO24 && this.selectedFidelityPlan) { availableLanguages = selectedPlan.fidelity[this.selectedFidelityPlan].languages; + // If fidelity is mechanical then target language would be same as source language. + if (this.selectedFidelityPlan === 'MECHANICAL' && this.selectedVideoSourceLanguage) { + availableLanguages = _.pick( + availableLanguages, + this.selectedVideoSourceLanguage + ); + } } else if (this.selectedProvider === THREE_PLAY_MEDIA) { availableLanguages = selectedPlan.languages; } @@ -108,6 +115,16 @@ function($, Backbone, _, gettext, moment, HtmlUtils, StringUtils, TranscriptSett return availableLanguages; }, + getSourceLanguages: function() { + var sourceLanguages = []; + if (this.selectedProvider === THREE_PLAY_MEDIA) { + sourceLanguages = this.availableTranscriptionPlans[this.selectedProvider].translations; + } else { + sourceLanguages = this.getTargetLanguages(); + } + return sourceLanguages; + }, + fidelitySelected: function(event) { var $fidelityContainer = this.$el.find('.transcript-fidelity-wrapper'); this.selectedFidelityPlan = event.target.value; @@ -116,6 +133,9 @@ function($, Backbone, _, gettext, moment, HtmlUtils, StringUtils, TranscriptSett // Clear active and selected languages. this.selectedLanguages = this.activeLanguages = []; + // Also clear selected language. + this.selectedVideoSourceLanguage = ''; + this.renderSourceLanguages(); this.renderTargetLanguages(); }, @@ -272,8 +292,8 @@ function($, Backbone, _, gettext, moment, HtmlUtils, StringUtils, TranscriptSett $languagesContainer.empty(); - // Show language container if fidelity or source language is selected . - if (self.selectedVideoSourceLanguage || self.selectedFidelityPlan) { + // Show language container if source language is selected . + if (self.selectedVideoSourceLanguage) { _.each(self.activeLanguages, function(language) { // Only add if not in the list already. if (_.indexOf(self.selectedLanguages, language) === -1) { @@ -289,16 +309,18 @@ function($, Backbone, _, gettext, moment, HtmlUtils, StringUtils, TranscriptSett } }, - renderVideoSourceLanguageMenu: function() { + renderSourceLanguages: function() { var self = this, - availableTranslations, availableLanguages = self.getTargetLanguages(), + availableTranslations = self.getSourceLanguages(), $videoSourceLanguageContainer = self.$el.find('.video-source-language-wrapper'), $languageMenuEl = self.$el.find('.video-source-language'), selectOptionEl = new Option(gettext('Select language'), ''); - if (this.selectedProvider === THREE_PLAY_MEDIA) { - availableTranslations = self.availableTranscriptionPlans[this.selectedProvider].translations; + // Clear error state if present any. + self.clearPreferenceErrorState($videoSourceLanguageContainer); + + if (!_.isEmpty(availableTranslations)) { $videoSourceLanguageContainer.show(); // We need to set id due to a11y aria-labelledby @@ -368,7 +390,7 @@ function($, Backbone, _, gettext, moment, HtmlUtils, StringUtils, TranscriptSett this.renderProviders(); this.renderTurnaround(); this.renderFidelity(); - this.renderVideoSourceLanguageMenu(); + this.renderSourceLanguages(); this.renderTargetLanguages(); }, diff --git a/cms/static/sass/views/_video-upload.scss b/cms/static/sass/views/_video-upload.scss index 0b09435141..a7c9c0b2a3 100644 --- a/cms/static/sass/views/_video-upload.scss +++ b/cms/static/sass/views/_video-upload.scss @@ -143,9 +143,6 @@ } .transcript-language-menu-container { margin-top: ($baseline*0.8); - .transcript-language-menu { - width: 60%; - } .add-language-action { display: inline-block; .action-add-language { @@ -153,6 +150,9 @@ } } } + .transcript-language-menu, .video-source-language { + width: 60%; + } } .course-video-settings-footer {