diff --git a/course_discovery/apps/publisher/api/serializers.py b/course_discovery/apps/publisher/api/serializers.py index 5cfc0fca38..0da2f93a54 100644 --- a/course_discovery/apps/publisher/api/serializers.py +++ b/course_discovery/apps/publisher/api/serializers.py @@ -1,5 +1,7 @@ """Publisher API Serializers""" import waffle + +from django.utils.translation import ugettext_lazy as _ from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey from rest_framework import serializers @@ -51,7 +53,10 @@ def validate(self, data): try: CourseKey.from_string(lms_course_id) except InvalidKeyError: - raise serializers.ValidationError('Invalid course key [{}]'.format(lms_course_id)) + # pylint: disable=no-member + raise serializers.ValidationError( + {'lms_course_id': _('Invalid course key "{lms_course_id}"').format(lms_course_id=lms_course_id)} + ) request = self.context.get('request') if request: diff --git a/course_discovery/apps/publisher/api/tests/test_views.py b/course_discovery/apps/publisher/api/tests/test_views.py index ffc7e38940..458fe34308 100644 --- a/course_discovery/apps/publisher/api/tests/test_views.py +++ b/course_discovery/apps/publisher/api/tests/test_views.py @@ -243,7 +243,42 @@ def test_update_course_key_with_errors(self): self.assertEqual(response.status_code, 400) self.assertEqual( - response.data.get('non_field_errors'), ['Invalid course key [{}]'.format(invalid_course_id)] + response.data.get('lms_course_id'), + ['Invalid course key "{lms_course_id}"'.format(lms_course_id=invalid_course_id)] + ) + + def test_update_course_key_without_permission(self): + """ + Test that api returns error without permission. + """ + self.user.groups.remove(Group.objects.get(name=INTERNAL_USER_GROUP_NAME)) + response = self.client.patch( + self.update_course_key_url, + data=json.dumps({'lms_course_id': 'course-v1:edxTest+TC12+2050Q1'}), + content_type=JSON_CONTENT_TYPE + ) + + self.assertEqual(response.status_code, 403) + self.assertEqual( + response.data.get('detail'), 'You do not have permission to perform this action.' + ) + + def test_update_course_key_with_duplicate(self): + """ + Test that api returns error if course key already exist. + """ + lms_course_id = 'course-v1:edxTest+TC12+2050Q1' + factories.CourseRunFactory(lms_course_id=lms_course_id) + + response = self.client.patch( + self.update_course_key_url, + data=json.dumps({'lms_course_id': lms_course_id}), + content_type=JSON_CONTENT_TYPE + ) + + self.assertEqual(response.status_code, 400) + self.assertEqual( + response.data.get('lms_course_id'), ['CourseRun with this lms course id already exists.'] ) def test_update_course_key(self): diff --git a/course_discovery/conf/locale/en/LC_MESSAGES/django.mo b/course_discovery/conf/locale/en/LC_MESSAGES/django.mo index e8c4806de0..126ad24aa6 100644 Binary files a/course_discovery/conf/locale/en/LC_MESSAGES/django.mo and b/course_discovery/conf/locale/en/LC_MESSAGES/django.mo differ diff --git a/course_discovery/conf/locale/en/LC_MESSAGES/django.po b/course_discovery/conf/locale/en/LC_MESSAGES/django.po index 20df0b0d22..2554b514e0 100644 --- a/course_discovery/conf/locale/en/LC_MESSAGES/django.po +++ b/course_discovery/conf/locale/en/LC_MESSAGES/django.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-01-16 14:06+0500\n" +"POT-Creation-Date: 2017-01-18 12:59+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: \n" #: apps/api/filters.py #, python-brace-format @@ -411,6 +411,11 @@ msgstr "" msgid "JSON string containing an elasticsearch function score config." msgstr "" +#: apps/publisher/api/serializers.py +#, python-brace-format +msgid "Invalid course key \"{lms_course_id}\"" +msgstr "" + #: apps/publisher/choices.py templates/publisher/courses.html msgid "Partner Coordinator" msgstr "" diff --git a/course_discovery/conf/locale/en/LC_MESSAGES/djangojs.mo b/course_discovery/conf/locale/en/LC_MESSAGES/djangojs.mo index e8c4806de0..126ad24aa6 100644 Binary files a/course_discovery/conf/locale/en/LC_MESSAGES/djangojs.mo and b/course_discovery/conf/locale/en/LC_MESSAGES/djangojs.mo differ diff --git a/course_discovery/conf/locale/en/LC_MESSAGES/djangojs.po b/course_discovery/conf/locale/en/LC_MESSAGES/djangojs.po index b8480e2b5e..295d02063b 100644 --- a/course_discovery/conf/locale/en/LC_MESSAGES/djangojs.po +++ b/course_discovery/conf/locale/en/LC_MESSAGES/djangojs.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-01-16 14:06+0500\n" +"POT-Creation-Date: 2017-01-18 12:59+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: \n" #: static/js/catalogs-change-form.js msgid "Preview" @@ -26,6 +26,10 @@ msgid "" "{courseRunDetail} with a start date of {startDate}" msgstr "" +#: static/js/publisher/views/dashboard.js +msgid "There was an error in saving your data." +msgstr "" + #: static/js/publisher/views/navbar.js msgid "OFF" msgstr "" diff --git a/course_discovery/conf/locale/eo/LC_MESSAGES/django.mo b/course_discovery/conf/locale/eo/LC_MESSAGES/django.mo index a2e38a1cea..77d5d19ffa 100644 Binary files a/course_discovery/conf/locale/eo/LC_MESSAGES/django.mo and b/course_discovery/conf/locale/eo/LC_MESSAGES/django.mo differ diff --git a/course_discovery/conf/locale/eo/LC_MESSAGES/django.po b/course_discovery/conf/locale/eo/LC_MESSAGES/django.po index 25e2d819e4..0add83181f 100644 --- a/course_discovery/conf/locale/eo/LC_MESSAGES/django.po +++ b/course_discovery/conf/locale/eo/LC_MESSAGES/django.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-01-16 14:06+0500\n" +"POT-Creation-Date: 2017-01-18 12:59+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: apps/api/filters.py @@ -517,6 +517,11 @@ msgstr "" "JSÖN strïng çöntäïnïng än élästïçséärçh fünçtïön sçöré çönfïg. Ⱡ'σяєм ιρѕυм " "∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#" +#: apps/publisher/api/serializers.py +#, python-brace-format +msgid "Invalid course key \"{lms_course_id}\"" +msgstr "Ìnvälïd çöürsé kéý \"{lms_course_id}\" Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢ση#" + #: apps/publisher/choices.py templates/publisher/courses.html msgid "Partner Coordinator" msgstr "Pärtnér Çöördïnätör Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#" diff --git a/course_discovery/conf/locale/eo/LC_MESSAGES/djangojs.mo b/course_discovery/conf/locale/eo/LC_MESSAGES/djangojs.mo index bda5110774..9989eab4b2 100644 Binary files a/course_discovery/conf/locale/eo/LC_MESSAGES/djangojs.mo and b/course_discovery/conf/locale/eo/LC_MESSAGES/djangojs.mo differ diff --git a/course_discovery/conf/locale/eo/LC_MESSAGES/djangojs.po b/course_discovery/conf/locale/eo/LC_MESSAGES/djangojs.po index 7705ee31a8..7d0cab6d29 100644 --- a/course_discovery/conf/locale/eo/LC_MESSAGES/djangojs.po +++ b/course_discovery/conf/locale/eo/LC_MESSAGES/djangojs.po @@ -7,14 +7,14 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-01-16 14:06+0500\n" +"POT-Creation-Date: 2017-01-18 12:59+0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: static/js/catalogs-change-form.js @@ -30,6 +30,12 @@ msgstr "" "{courseRunDetail} wïth ä stärt däté öf {startDate} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт " "αмєт, ¢σηѕє¢#" +#: static/js/publisher/views/dashboard.js +msgid "There was an error in saving your data." +msgstr "" +"Théré wäs än érrör ïn sävïng ýöür dätä. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, " +"¢σηѕє¢тєтυя#" + #: static/js/publisher/views/navbar.js msgid "OFF" msgstr "ÖFF Ⱡ'σяєм#" diff --git a/course_discovery/static/js/publisher/views/dashboard.js b/course_discovery/static/js/publisher/views/dashboard.js index 04393e4a66..08535ca7df 100644 --- a/course_discovery/static/js/publisher/views/dashboard.js +++ b/course_discovery/static/js/publisher/views/dashboard.js @@ -18,6 +18,7 @@ $(document).ready(function() { courseTitleTag = $courseRunParentTag.find("#course-title").html().trim(), startDateTag = $courseRunParentTag.find("#course-start").html().trim(), $studioInstanceSuccess = $(".studio-instance-success"), + $studioInstanceError = $(".studio-instance-error"), successMessage = interpolateString( gettext("You have successfully created a studio instance ({studioLinkTag}) for {courseRunDetail} with a start date of {startDate}"), { @@ -38,6 +39,16 @@ $(document).ready(function() { $("#studio-count").html(data_table_studio.rows().count()); $studioInstanceSuccess.find(".copy-meta").html(successMessage); $studioInstanceSuccess.css("display", "block"); + }, + error: function (response) { + if(response.responseJSON.lms_course_id) { + $studioInstanceError.find(".copy").html(response.responseJSON.lms_course_id[0]); + } else if(response.responseJSON.detail) { + $studioInstanceError.find(".copy").html(response.responseJSON.detail); + } else { + $studioInstanceError.find(".copy").html(gettext("There was an error in saving your data.")); + } + $studioInstanceError.removeClass("hidden"); } }); }); diff --git a/course_discovery/static/sass/publisher/dashboard.scss b/course_discovery/static/sass/publisher/dashboard.scss index c70a86f9ec..0b5d4d6852 100644 --- a/course_discovery/static/sass/publisher/dashboard.scss +++ b/course_discovery/static/sass/publisher/dashboard.scss @@ -10,6 +10,10 @@ } } + .studio-instance-error { + margin-bottom: 20px; + } + .tabs { @include padding(0, 0, 0, 0); @include margin(0, 0, 0, 0); diff --git a/course_discovery/templates/publisher/dashboard/_studio_requests.html b/course_discovery/templates/publisher/dashboard/_studio_requests.html index 1db2053036..9653215408 100644 --- a/course_discovery/templates/publisher/dashboard/_studio_requests.html +++ b/course_discovery/templates/publisher/dashboard/_studio_requests.html @@ -5,6 +5,11 @@

+