Commit 14d6bbbd by Waheed Ahmed

edX staff change role assignment email.

ECOM-6468
parent 1390f980
...@@ -13,8 +13,8 @@ from rest_framework import serializers ...@@ -13,8 +13,8 @@ from rest_framework import serializers
from course_discovery.apps.core.models import User from course_discovery.apps.core.models import User
from course_discovery.apps.publisher.choices import PublisherUserRole from course_discovery.apps.publisher.choices import PublisherUserRole
from course_discovery.apps.publisher.emails import ( from course_discovery.apps.publisher.emails import (
send_email_for_studio_instance_created, send_email_preview_accepted, send_email_preview_page_is_available send_change_role_assignment_email, send_email_for_studio_instance_created, send_email_preview_accepted,
) send_email_preview_page_is_available)
from course_discovery.apps.publisher.models import CourseRun, CourseRunState, CourseState, CourseUserRole from course_discovery.apps.publisher.models import CourseRun, CourseRunState, CourseState, CourseUserRole
...@@ -35,6 +35,15 @@ class CourseUserRoleSerializer(serializers.ModelSerializer): ...@@ -35,6 +35,15 @@ class CourseUserRoleSerializer(serializers.ModelSerializer):
return validated_values return validated_values
@transaction.atomic
def update(self, instance, validated_data):
former_user = instance.user
instance = super(CourseUserRoleSerializer, self).update(instance, validated_data)
if not instance.role == PublisherUserRole.CourseTeam:
send_change_role_assignment_email(instance, former_user)
return instance
class GroupUserSerializer(serializers.ModelSerializer): class GroupUserSerializer(serializers.ModelSerializer):
"""Serializer for the `User` model used in OrganizationGroupUserView. """ """Serializer for the `User` model used in OrganizationGroupUserView. """
......
"""Tests API Serializers.""" """Tests API Serializers."""
import mock
from django.core import mail from django.core import mail
from django.test import RequestFactory, TestCase from django.test import RequestFactory, TestCase
from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.keys import CourseKey
...@@ -25,7 +26,7 @@ class CourseUserRoleSerializerTests(TestCase): ...@@ -25,7 +26,7 @@ class CourseUserRoleSerializerTests(TestCase):
def setUp(self): def setUp(self):
super(CourseUserRoleSerializerTests, self).setUp() super(CourseUserRoleSerializerTests, self).setUp()
self.request = RequestFactory() self.request = RequestFactory()
self.course_user_role = CourseUserRoleFactory() self.course_user_role = CourseUserRoleFactory(role=PublisherUserRole.MarketingReviewer)
self.request.user = self.course_user_role.user self.request.user = self.course_user_role.user
def get_expected_data(self): def get_expected_data(self):
...@@ -41,6 +42,27 @@ class CourseUserRoleSerializerTests(TestCase): ...@@ -41,6 +42,27 @@ class CourseUserRoleSerializerTests(TestCase):
validated_data = serializer.validate(serializer.data) validated_data = serializer.validate(serializer.data)
self.assertEqual(validated_data, self.get_expected_data()) self.assertEqual(validated_data, self.get_expected_data())
def test_update(self):
"""
Test that user role assignment changed on update.
"""
new_user = UserFactory()
serializer = self.serializer_class(self.course_user_role, context={'request': self.request})
course_role = serializer.update(self.course_user_role, {'user': new_user})
self.assertEqual(course_role.user, new_user)
self.assertEqual(len(mail.outbox), 1)
def test_update_with_error(self):
"""
Test that whole transaction roll backed if error in email sending.
"""
new_user = UserFactory()
serializer = self.serializer_class(self.course_user_role, context={'request': self.request})
with mock.patch('django.core.mail.message.EmailMessage.send', side_effect=TypeError):
with self.assertRaises(Exception):
course_role = serializer.update(self.course_user_role, {'user': new_user})
self.assertNotEqual(course_role.user, new_user)
class GroupUserSerializerTests(TestCase): class GroupUserSerializerTests(TestCase):
......
...@@ -130,6 +130,7 @@ class CourseRoleAssignmentViewTests(TestCase): ...@@ -130,6 +130,7 @@ class CourseRoleAssignmentViewTests(TestCase):
} }
self.assertDictEqual(response.data, expected) self.assertDictEqual(response.data, expected)
self.assertEqual(self.internal_user, self.course.course_user_roles.get(role=user_course_role.role).user) self.assertEqual(self.internal_user, self.course.course_user_roles.get(role=user_course_role.role).user)
self.assertEqual(len(mail.outbox), 1)
class OrganizationGroupUserViewTests(TestCase): class OrganizationGroupUserViewTests(TestCase):
......
...@@ -449,3 +449,56 @@ def send_course_run_published_email(course_run): ...@@ -449,3 +449,56 @@ def send_course_run_published_email(course_run):
) )
logger.exception(error_message) logger.exception(error_message)
raise Exception(error_message) raise Exception(error_message)
def send_change_role_assignment_email(course_role, former_user):
""" Send email for role assignment changed.
Arguments:
course_role (Object): CourseUserRole object
former_user (Object): User object
"""
txt_template = 'publisher/email/role_assignment_changed.txt'
html_template = 'publisher/email/role_assignment_changed.html'
try:
subject = _('Role assignment changed for role: {role_name} against {course_title}').format( # pylint: disable=no-member
role_name=course_role.get_role_display(),
course_title=course_role.course.title
)
to_addresses = course_role.course.get_course_users_emails()
to_addresses.append(former_user.email)
if course_role.course.course_team_admin:
to_addresses.remove(course_role.course.course_team_admin.email)
from_address = settings.PUBLISHER_FROM_EMAIL
project_coordinator = course_role.course.project_coordinator
page_path = reverse('publisher:publisher_course_detail', kwargs={'pk': course_role.course.id})
context = {
'course_title': course_role.course.title,
'role_name': course_role.get_role_display(),
'former_user_name': former_user.get_full_name() or former_user.username,
'current_user_name': course_role.user.get_full_name() or course_role.user.username,
'contact_us_email': project_coordinator.email if project_coordinator else '',
'course_url': 'https://{host}{path}'.format(
host=Site.objects.get_current().domain.strip('/'), path=page_path
),
'platform_name': settings.PLATFORM_NAME,
}
template = get_template(txt_template)
plain_content = template.render(context)
template = get_template(html_template)
html_content = template.render(context)
email_msg = EmailMultiAlternatives(
subject, plain_content, from_address, to=to_addresses
)
email_msg.attach_alternative(html_content, 'text/html')
email_msg.send()
except Exception: # pylint: disable=broad-except
error_message = 'Failed to send email notifications for change role assignment of role: [{role_id}]'.format(
role_id=course_role.id
)
logger.exception(error_message)
raise Exception(error_message)
...@@ -544,3 +544,56 @@ class CourseRunPublishedEmailTests(TestCase): ...@@ -544,3 +544,56 @@ class CourseRunPublishedEmailTests(TestCase):
with self.assertRaises(Exception) as ex: with self.assertRaises(Exception) as ex:
emails.send_course_run_published_email(self.course_run) emails.send_course_run_published_email(self.course_run)
self.assertEqual(str(ex.exception), message) self.assertEqual(str(ex.exception), message)
class CourseChangeRoleAssignmentEmailTests(TestCase):
"""
Tests email functionality for course role assignment changed.
"""
def setUp(self):
super(CourseChangeRoleAssignmentEmailTests, self).setUp()
self.user = UserFactory()
self.marketing_role = factories.CourseUserRoleFactory(role=PublisherUserRole.MarketingReviewer, user=self.user)
self.course = self.marketing_role.course
factories.CourseUserRoleFactory(course=self.course, role=PublisherUserRole.Publisher)
factories.CourseUserRoleFactory(course=self.course, role=PublisherUserRole.ProjectCoordinator)
factories.CourseUserRoleFactory(course=self.course, role=PublisherUserRole.CourseTeam)
toggle_switch('enable_publisher_email_notifications', True)
def test_change_role_assignment_email(self):
"""
Verify that course role assignment chnage email functionality works fine.
"""
emails.send_change_role_assignment_email(self.marketing_role, self.user)
expected_subject = 'Role assignment changed for role: {role_name} against {course_title}'.format(
role_name=self.marketing_role.get_role_display(),
course_title=self.course.title
)
expected_emails = set(self.course.get_course_users_emails())
expected_emails.remove(self.course.course_team_admin.email)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(expected_emails, set(mail.outbox[0].to))
self.assertEqual(str(mail.outbox[0].subject), expected_subject)
body = mail.outbox[0].body.strip()
page_path = reverse('publisher:publisher_course_detail', kwargs={'pk': self.course.id})
page_url = 'https://{host}{path}'.format(host=Site.objects.get_current().domain.strip('/'), path=page_path)
self.assertIn(page_url, body)
self.assertIn('has been changed.', body)
def test_change_role_assignment_email_with_error(self):
"""
Verify that email failure raises exception.
"""
message = 'Failed to send email notifications for change role assignment of role: [{role_id}]'.format(
role_id=self.marketing_role.id
)
with mock.patch('django.core.mail.message.EmailMessage.send', side_effect=TypeError):
with self.assertRaises(Exception) as ex:
emails.send_change_role_assignment_email(self.marketing_role, self.user)
self.assertEqual(str(ex.exception), message)
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-09 14:55+0500\n" "POT-Creation-Date: 2017-03-09 15:51+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
#: apps/api/filters.py #: apps/api/filters.py
#, python-brace-format #, python-brace-format
...@@ -521,6 +521,11 @@ msgstr "" ...@@ -521,6 +521,11 @@ msgstr ""
msgid "Publication complete: {course_name} {run_number}" msgid "Publication complete: {course_name} {run_number}"
msgstr "" msgstr ""
#: apps/publisher/emails.py
#, python-brace-format
msgid "Role assignment changed for role: {role_name} against {course_title}"
msgstr ""
#: apps/publisher/forms.py #: apps/publisher/forms.py
msgid "Remove Image" msgid "Remove Image"
msgstr "" msgstr ""
...@@ -991,7 +996,7 @@ msgid "day in ownership" ...@@ -991,7 +996,7 @@ msgid "day in ownership"
msgstr "" msgstr ""
#: templates/publisher/_approval_widget.html #: templates/publisher/_approval_widget.html
msgid "change owner" msgid "change"
msgstr "" msgstr ""
#: templates/publisher/_approval_widget.html #: templates/publisher/_approval_widget.html
...@@ -2688,6 +2693,32 @@ msgid "" ...@@ -2688,6 +2693,32 @@ msgid ""
"been declined." "been declined."
msgstr "" msgstr ""
#: templates/publisher/email/role_assignment_changed.html
#, python-format
msgid ""
"The %(role_name)s for the "
"%(link_start)s%(course_url)s%(link_middle)s%(course_title)s%(link_end)s has "
"been changed."
msgstr ""
#: templates/publisher/email/role_assignment_changed.html
#: templates/publisher/email/role_assignment_changed.txt
#, python-format
msgid "Former %(role_name)s: %(former_user_name)s"
msgstr ""
#: templates/publisher/email/role_assignment_changed.html
#: templates/publisher/email/role_assignment_changed.txt
#, python-format
msgid "Current %(role_name)s: %(current_user_name)s"
msgstr ""
#: templates/publisher/email/role_assignment_changed.txt
#, python-format
msgid ""
"The %(role_name)s for the %(course_title)s: %(course_url)s has been changed."
msgstr ""
#. Translators: course_team_name is course team member name. #. Translators: course_team_name is course team member name.
#: templates/publisher/email/studio_instance_created.html #: templates/publisher/email/studio_instance_created.html
#: templates/publisher/email/studio_instance_created.txt #: templates/publisher/email/studio_instance_created.txt
...@@ -2763,33 +2794,6 @@ msgstr "" ...@@ -2763,33 +2794,6 @@ msgstr ""
msgid "Please create a Studio instance for the following course." msgid "Please create a Studio instance for the following course."
msgstr "" msgstr ""
#: templates/publisher/email/user_role_changed.html
#, python-format
msgid ""
"The %(role_name)s for the "
"%(link_start)s%(course_url)s%(link_middle)s%(course_title)s%(link_end)s "
"course has changed."
msgstr ""
#: templates/publisher/email/user_role_changed.html
#: templates/publisher/email/user_role_changed.txt
#, python-format
msgid "Former %(role_name)s: %(former_user_name)s"
msgstr ""
#: templates/publisher/email/user_role_changed.html
#: templates/publisher/email/user_role_changed.txt
#, python-format
msgid "Current %(role_name)s: %(current_user_name)s"
msgstr ""
#: templates/publisher/email/user_role_changed.txt
#, python-format
msgid ""
"The %(role_name)s for the %(course_title)s: %(course_url)s course has "
"changed."
msgstr ""
#: templates/publisher/seat_form.html #: templates/publisher/seat_form.html
msgid "Seat Form" msgid "Seat Form"
msgstr "" msgstr ""
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-09 14:55+0500\n" "POT-Creation-Date: 2017-03-09 15:51+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
#: static/js/catalogs-change-form.js #: static/js/catalogs-change-form.js
msgid "Preview" msgid "Preview"
......
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-09 14:55+0500\n" "POT-Creation-Date: 2017-03-09 15:51+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: apps/api/filters.py #: apps/api/filters.py
...@@ -647,6 +647,13 @@ msgstr "" ...@@ -647,6 +647,13 @@ msgstr ""
"Püßlïçätïön çömplété: {course_name} {run_number} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт " "Püßlïçätïön çömplété: {course_name} {run_number} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт "
"αмєт, ¢σηѕє¢#" "αмєт, ¢σηѕє¢#"
#: apps/publisher/emails.py
#, python-brace-format
msgid "Role assignment changed for role: {role_name} against {course_title}"
msgstr ""
"Rölé ässïgnmént çhängéd för rölé: {role_name} ägäïnst {course_title} Ⱡ'σяєм "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
#: apps/publisher/forms.py #: apps/publisher/forms.py
msgid "Remove Image" msgid "Remove Image"
msgstr "Rémövé Ìmägé Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#" msgstr "Rémövé Ìmägé Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
...@@ -1159,8 +1166,8 @@ msgid "day in ownership" ...@@ -1159,8 +1166,8 @@ msgid "day in ownership"
msgstr "däý ïn öwnérshïp Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#" msgstr "däý ïn öwnérshïp Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
#: templates/publisher/_approval_widget.html #: templates/publisher/_approval_widget.html
msgid "change owner" msgid "change"
msgstr "çhängé öwnér Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#" msgstr "çhängé Ⱡ'σяєм ιρѕυ#"
#: templates/publisher/_approval_widget.html #: templates/publisher/_approval_widget.html
msgid "CHANGE" msgid "CHANGE"
...@@ -3200,6 +3207,38 @@ msgstr "" ...@@ -3200,6 +3207,38 @@ msgstr ""
"Prévïéw lïnk %(preview_url)s för thé %(course_title)s: %(course_url)s häs " "Prévïéw lïnk %(preview_url)s för thé %(course_title)s: %(course_url)s häs "
"ßéén déçlïnéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#" "ßéén déçlïnéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
#: templates/publisher/email/role_assignment_changed.html
#, python-format
msgid ""
"The %(role_name)s for the "
"%(link_start)s%(course_url)s%(link_middle)s%(course_title)s%(link_end)s has "
"been changed."
msgstr ""
"Thé %(role_name)s för thé "
"%(link_start)s%(course_url)s%(link_middle)s%(course_title)s%(link_end)s häs "
"ßéén çhängéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
#: templates/publisher/email/role_assignment_changed.html
#: templates/publisher/email/role_assignment_changed.txt
#, python-format
msgid "Former %(role_name)s: %(former_user_name)s"
msgstr "Förmér %(role_name)s: %(former_user_name)s Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
#: templates/publisher/email/role_assignment_changed.html
#: templates/publisher/email/role_assignment_changed.txt
#, python-format
msgid "Current %(role_name)s: %(current_user_name)s"
msgstr ""
"Çürrént %(role_name)s: %(current_user_name)s Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
#: templates/publisher/email/role_assignment_changed.txt
#, python-format
msgid ""
"The %(role_name)s for the %(course_title)s: %(course_url)s has been changed."
msgstr ""
"Thé %(role_name)s för thé %(course_title)s: %(course_url)s häs ßéén çhängéd."
" Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #"
#. Translators: course_team_name is course team member name. #. Translators: course_team_name is course team member name.
#: templates/publisher/email/studio_instance_created.html #: templates/publisher/email/studio_instance_created.html
#: templates/publisher/email/studio_instance_created.txt #: templates/publisher/email/studio_instance_created.txt
...@@ -3308,39 +3347,6 @@ msgstr "" ...@@ -3308,39 +3347,6 @@ msgstr ""
"Pléäsé çréäté ä Stüdïö ïnstänçé för thé föllöwïng çöürsé. Ⱡ'σяєм ιρѕυм ∂σłσя" "Pléäsé çréäté ä Stüdïö ïnstänçé för thé föllöwïng çöürsé. Ⱡ'σяєм ιρѕυм ∂σłσя"
" ѕιт αмєт, ¢σηѕє¢тєтυя α#" " ѕιт αмєт, ¢σηѕє¢тєтυя α#"
#: templates/publisher/email/user_role_changed.html
#, python-format
msgid ""
"The %(role_name)s for the "
"%(link_start)s%(course_url)s%(link_middle)s%(course_title)s%(link_end)s "
"course has changed."
msgstr ""
"Thé %(role_name)s för thé "
"%(link_start)s%(course_url)s%(link_middle)s%(course_title)s%(link_end)s "
"çöürsé häs çhängéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
#: templates/publisher/email/user_role_changed.html
#: templates/publisher/email/user_role_changed.txt
#, python-format
msgid "Former %(role_name)s: %(former_user_name)s"
msgstr "Förmér %(role_name)s: %(former_user_name)s Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
#: templates/publisher/email/user_role_changed.html
#: templates/publisher/email/user_role_changed.txt
#, python-format
msgid "Current %(role_name)s: %(current_user_name)s"
msgstr ""
"Çürrént %(role_name)s: %(current_user_name)s Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
#: templates/publisher/email/user_role_changed.txt
#, python-format
msgid ""
"The %(role_name)s for the %(course_title)s: %(course_url)s course has "
"changed."
msgstr ""
"Thé %(role_name)s för thé %(course_title)s: %(course_url)s çöürsé häs "
"çhängéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #"
#: templates/publisher/seat_form.html #: templates/publisher/seat_form.html
msgid "Seat Form" msgid "Seat Form"
msgstr "Séät Förm Ⱡ'σяєм ιρѕυм ∂σł#" msgstr "Séät Förm Ⱡ'σяєм ιρѕυм ∂σł#"
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-09 14:55+0500\n" "POT-Creation-Date: 2017-03-09 15:51+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/js/catalogs-change-form.js #: static/js/catalogs-change-form.js
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
</span> </span>
{% if role_widget.can_change_role_assignment %} {% if role_widget.can_change_role_assignment %}
<a class="change-role-assignment" data-role="{{ role_widget.course_role.role }}" href="#"> <a class="change-role-assignment" data-role="{{ role_widget.course_role.role }}" href="#">
{% trans "change owner" %} {% trans "change" %}
</a> </a>
{% endif %} {% endif %}
</div> </div>
......
{% extends "publisher/email/email_base.html" %}{% load i18n %} {% extends "publisher/email/email_base.html" %}
{% load i18n %}
{% block body %} {% block body %}
<p> <p>
{% blocktrans trimmed with link_start='<a href="' link_middle='">' link_end='</a>' %} {% blocktrans trimmed with link_start='<a href="' link_middle='">' link_end='</a>' %}
The {{ role_name }} for the {{ link_start }}{{ course_url }}{{ link_middle }}{{ course_title }}{{ link_end }} The {{ role_name }} for the {{ link_start }}{{ course_url }}{{ link_middle }}{{ course_title }}{{ link_end }} has been changed.
course has changed.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
......
{% load i18n %} {% load i18n %}
{% blocktrans trimmed %} {% blocktrans trimmed %}
The {{ role_name }} for the {{ course_title }}: {{ course_url }} course has changed. The {{ role_name }} for the {{ course_title }}: {{ course_url }} has been changed.
{% endblocktrans %} {% endblocktrans %}
{% blocktrans trimmed %} {% blocktrans trimmed %}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment