diff --git a/common/djangoapps/util/organizations_helpers.py b/common/djangoapps/util/organizations_helpers.py
index 5164ae3dd9..124ab8f1c9 100644
--- a/common/djangoapps/util/organizations_helpers.py
+++ b/common/djangoapps/util/organizations_helpers.py
@@ -88,6 +88,16 @@ def get_course_organizations(course_id):
return organizations_api.get_course_organizations(course_id)
+def get_course_organization_id(course_id):
+ """
+ Returns organization id for course or None if the course is not linked to an org
+ """
+ course_organization = get_course_organizations(course_id)
+ if course_organization:
+ return course_organization[0]['id']
+ return None
+
+
def organizations_enabled():
"""
Returns boolean indication if organizations app is enabled on not.
diff --git a/lms/djangoapps/certificates/admin.py b/lms/djangoapps/certificates/admin.py
index 378bf4c106..fc10ca0159 100644
--- a/lms/djangoapps/certificates/admin.py
+++ b/lms/djangoapps/certificates/admin.py
@@ -47,7 +47,7 @@ class CertificateTemplateAdmin(admin.ModelAdmin):
"""
Django admin customizations for CertificateTemplate model
"""
- list_display = ('name', 'description', 'organization_id', 'course_key', 'mode', 'is_active')
+ list_display = ('name', 'description', 'organization_id', 'course_key', 'mode', 'language', 'is_active')
form = CertificateTemplateForm
diff --git a/lms/djangoapps/certificates/api.py b/lms/djangoapps/certificates/api.py
index 7ce8155a48..a2f710bbd6 100644
--- a/lms/djangoapps/certificates/api.py
+++ b/lms/djangoapps/certificates/api.py
@@ -8,6 +8,7 @@ import logging
from django.conf import settings
from django.core.urlresolvers import reverse
+from django.db.models import Q
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
@@ -27,7 +28,7 @@ from certificates.queue import XQueueCertInterface
from eventtracking import tracker
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.xmodule_django.models import CourseKeyField
-from util.organizations_helpers import get_course_organizations
+from util.organizations_helpers import get_course_organization_id
from xmodule.modulestore.django import modulestore
log = logging.getLogger("edx.certificate")
@@ -463,49 +464,76 @@ def get_active_web_certificate(course, is_preview_mode=None):
return None
-def get_certificate_template(course_key, mode, language): # pylint: disable=unused-argument
+def get_certificate_template(course_key, mode, language):
"""
Retrieves the custom certificate template based on course_key, mode, and language.
"""
- org_id, template = None, None
+ template = None
# fetch organization of the course
- course_organization = get_course_organizations(course_key)
- if course_organization:
- org_id = course_organization[0]['id']
+ org_id = get_course_organization_id(course_key)
- if org_id and mode:
- template = CertificateTemplate.objects.filter(
+ # only consider active templates
+ active_templates = CertificateTemplate.objects.filter(is_active=True)
+
+ if org_id and mode: # get template by org, mode, and key
+ org_mode_and_key_templates = active_templates.filter(
organization_id=org_id,
- course_key=course_key,
mode=mode,
- is_active=True
+ course_key=course_key
)
- # if don't template find by org and mode
- if not template and org_id and mode:
- template = CertificateTemplate.objects.filter(
+ template = get_language_specific_template_or_default(language, org_mode_and_key_templates)
+
+ # since no template matched that course_key, only consider templates with empty course_key
+ empty_course_key_templates = active_templates.filter(course_key=CourseKeyField.Empty)
+ if not template and org_id and mode: # get template by org and mode
+ org_and_mode_templates = empty_course_key_templates.filter(
organization_id=org_id,
- course_key=CourseKeyField.Empty,
- mode=mode,
- is_active=True
+ mode=mode
)
- # if don't template find by only org
- if not template and org_id:
- template = CertificateTemplate.objects.filter(
+ template = get_language_specific_template_or_default(language, org_and_mode_templates)
+ if not template and org_id: # get template by only org
+ org_templates = empty_course_key_templates.filter(
organization_id=org_id,
- course_key=CourseKeyField.Empty,
- mode=None,
- is_active=True
+ mode=None
)
- # if we still don't template find by only course mode
- if not template and mode:
- template = CertificateTemplate.objects.filter(
+ template = get_language_specific_template_or_default(language, org_templates)
+ if not template and mode: # get template by only mode
+ mode_templates = empty_course_key_templates.filter(
organization_id=None,
- course_key=CourseKeyField.Empty,
- mode=mode,
- is_active=True
+ mode=mode
)
+ template = get_language_specific_template_or_default(language, mode_templates)
+ #return template[0].template if template else None
+ return template.template if template else None
- return template[0].template if template else None
+
+def get_language_specific_template_or_default(language, templates):
+ """
+ Returns templates that match passed in language.
+ Returns default templates If no language matches, or language passed is None
+ """
+ two_letter_language = _get_two_letter_language_code(language)
+ language_or_default_templates = list(templates.filter(Q(language=two_letter_language) | Q(language=None)))
+ language_specific_template = get_language_specific_template(language, language_or_default_templates)
+ if language_specific_template:
+ return language_specific_template
+ else:
+ return language_or_default_templates[0] if language_or_default_templates else None
+
+
+def get_language_specific_template(language, templates):
+ for template in templates:
+ if template.language == language:
+ return template
+ return None
+
+
+def _get_two_letter_language_code(language_code):
+ """
+ Shortens language to only first two characters (e.g. es-419 becomes es)
+ This is needed because Catalog returns locale language which is not always a 2 letter code.
+ """
+ return language_code[:2] if language_code else None
def emit_certificate_event(event_name, user, course_id, course=None, event_data=None):
diff --git a/lms/djangoapps/certificates/migrations/0011_certificatetemplate_alter_unique.py b/lms/djangoapps/certificates/migrations/0011_certificatetemplate_alter_unique.py
new file mode 100644
index 0000000000..8ea49e8815
--- /dev/null
+++ b/lms/djangoapps/certificates/migrations/0011_certificatetemplate_alter_unique.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+import logging
+from django.db import migrations, models
+from opaque_keys.edx.keys import CourseKey
+from openedx.core.djangoapps.xmodule_django.models import CourseKeyField
+
+log = logging.getLogger(__name__)
+
+def revert_alter_unique(apps, schema_editor):
+ CertificateTemplateModel = apps.get_model("certificates", "CertificateTemplate")
+
+ all_unique_templates_ignoring_language = CertificateTemplateModel.objects.values_list(
+ "organization_id",
+ "course_key",
+ "mode").distinct()
+
+ for org_id, course_key, mode in all_unique_templates_ignoring_language:
+ key = CourseKey.from_string(course_key) if course_key else CourseKeyField.Empty
+ templates = CertificateTemplateModel.objects.filter(organization_id=org_id, course_key=key, mode=mode)
+ if templates.count() > 1:
+ # remove all templates past the first (null or default languages are ordered first)
+ language_specific_templates = templates.order_by('language')[1:]
+ language_specific_template_ids = language_specific_templates.values_list('id', flat=True)
+ for template in language_specific_templates:
+ log.info('Deleting template ' + str(template.id) + ' with details {' +
+ " name: "+ str(template.name) +
+ " description: "+ str(template.description) +
+ " template: "+ str(template.template) +
+ " organization_id: "+ str(template.organization_id) +
+ " course_key: "+ str(template.course_key) +
+ " mode: "+ str(template.mode) +
+ " is_active: "+ str(template.is_active) +
+ " language: "+ str(template.language) + " }"
+ )
+ CertificateTemplateModel.objects.filter(id__in=list(language_specific_template_ids)).delete()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('certificates', '0010_certificatetemplate_language'),
+ ]
+
+ operations = [
+ migrations.AlterUniqueTogether(
+ name='certificatetemplate',
+ unique_together=set([('organization_id', 'course_key', 'mode', 'language')]),
+ ),
+ migrations.RunPython(migrations.RunPython.noop, reverse_code=revert_alter_unique)
+ ]
diff --git a/lms/djangoapps/certificates/models.py b/lms/djangoapps/certificates/models.py
index 613fa69451..27c4313132 100644
--- a/lms/djangoapps/certificates/models.py
+++ b/lms/djangoapps/certificates/models.py
@@ -1063,7 +1063,7 @@ class CertificateTemplate(TimeStampedModel):
class Meta(object):
get_latest_by = 'created'
- unique_together = (('organization_id', 'course_key', 'mode'),)
+ unique_together = (('organization_id', 'course_key', 'mode', 'language'),)
app_label = "certificates"
diff --git a/lms/djangoapps/certificates/signals.py b/lms/djangoapps/certificates/signals.py
index faa2444b38..edce379a4c 100644
--- a/lms/djangoapps/certificates/signals.py
+++ b/lms/djangoapps/certificates/signals.py
@@ -7,7 +7,6 @@ from django.db.models.signals import post_save
from django.dispatch import receiver
from certificates.models import (
- CertificateGenerationCourseSetting,
CertificateWhitelist,
CertificateStatuses,
GeneratedCertificate
diff --git a/lms/djangoapps/certificates/tests/test_webview_views.py b/lms/djangoapps/certificates/tests/test_webview_views.py
index 7e348d70d8..fadda9ce0a 100644
--- a/lms/djangoapps/certificates/tests/test_webview_views.py
+++ b/lms/djangoapps/certificates/tests/test_webview_views.py
@@ -18,6 +18,7 @@ from nose.plugins.attrib import attr
from certificates.api import get_certificate_url
from certificates.models import (
+ CertificateGenerationCourseSetting,
CertificateHtmlViewConfiguration,
CertificateSocialNetworks,
CertificateStatuses,
@@ -147,7 +148,7 @@ class CommonCertificatesTestCase(ModuleStoreTestCase):
self.course.save()
self.store.update_item(self.course, self.user.id)
- def _create_custom_template(self, org_id=None, mode=None, course_key=None):
+ def _create_custom_template(self, org_id=None, mode=None, course_key=None, language=None):
"""
Creates a custom certificate template entry in DB.
"""
@@ -170,7 +171,36 @@ class CommonCertificatesTestCase(ModuleStoreTestCase):
organization_id=org_id,
course_key=course_key,
mode=mode,
- is_active=True
+ is_active=True,
+ language=language
+ )
+ template.save()
+
+ def _create_custom_named_template(self, template_name, org_id=None, mode=None, course_key=None, language=None):
+ """
+ Creates a custom certificate template entry in DB.
+ """
+ template_html = """
+ <%namespace name='static' file='static_content.html'/>
+
+
+ lang: ${LANGUAGE_CODE}
+ course name: """ + template_name + """
+ mode: ${course_mode}
+ ${accomplishment_copy_course_description}
+ ${twitter_url}
+
+
+
+ """
+ template = CertificateTemplate(
+ name=template_name,
+ template=template_html,
+ organization_id=org_id,
+ course_key=course_key,
+ mode=mode,
+ is_active=True,
+ language=language
)
template.save()
@@ -882,94 +912,97 @@ class CertificatesViewsTests(CommonCertificatesTestCase):
response_json = json.loads(response.content)
self.assertEqual(CertificateStatuses.generating, response_json['add_status'])
+ #TEMPLATES WITHOUT LANGUAGE TESTS
@override_settings(FEATURES=FEATURES_WITH_CUSTOM_CERTS_ENABLED)
@override_settings(LANGUAGE_CODE='fr')
@patch('certificates.views.webview.get_course_run_details')
- def test_certificate_custom_template_with_org_mode_course(self, mock_get_course_run_details):
+ def test_certificate_custom_template_with_org_mode_and_course_key(self, mock_get_course_run_details):
"""
Tests custom template search and rendering.
This test should check template matching when org={org}, course={course}, mode={mode}.
"""
mock_get_course_run_details.return_value = {'content_language': 'en'}
self._add_course_certificates(count=1, signatory_count=2)
- self._create_custom_template(org_id=1, mode='honor', course_key=unicode(self.course.id))
- self._create_custom_template(org_id=2, mode='honor')
+ self._create_custom_named_template('test_template_1_course', org_id=1, mode='honor', course_key=unicode(self.course.id))
+ self._create_custom_named_template('test_template_2_course', org_id=1, mode='verified', course_key=unicode(self.course.id))
+ self._create_custom_named_template('test_template_3_course', org_id=2, mode='honor')
test_url = get_certificate_url(
user_id=self.user.id,
course_id=unicode(self.course.id)
)
- with patch('certificates.api.get_course_organizations') as mock_get_orgs:
- mock_get_orgs.side_effect = [
- [{"id": 1, "name": "organization name"}],
- [{"id": 2, "name": "organization name 2"}],
- ]
+ with patch('certificates.api.get_course_organization_id') as mock_get_org_id:
+ mock_get_org_id.side_effect = [1, 2]
response = self.client.get(test_url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'lang: fr')
- self.assertContains(response, 'course name: course_title_0')
+ self.assertContains(response, 'course name: test_template_1_course')
# test with second organization template
response = self.client.get(test_url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'lang: fr')
- self.assertContains(response, 'course name: course_title_0')
+ self.assertContains(response, 'course name: test_template_3_course')
@override_settings(FEATURES=FEATURES_WITH_CUSTOM_CERTS_ENABLED)
@patch('certificates.views.webview.get_course_run_details')
- def test_certificate_custom_template_with_org(self, mock_get_course_run_details):
+ def test_certificate_custom_template_with_org_and_mode(self, mock_get_course_run_details):
"""
- Tests custom template search if we have a single template for organization and mode
- with course set to Null.
+ Tests custom template search if no template matches course_key, but a template does
+ match org and mode.
This test should check template matching when org={org}, course=Null, mode={mode}.
"""
mock_get_course_run_details.return_value = {'content_language': 'en'}
- course = CourseFactory.create(
+ othercourse = CourseFactory.create(
org='cstX', number='cst_22', display_name='custom template course'
)
self._add_course_certificates(count=1, signatory_count=2)
- self._create_custom_template(org_id=1, mode='honor')
- self._create_custom_template(org_id=1, mode='honor', course_key=course.id)
+ self._create_custom_named_template('test_template_1_course', org_id=1, mode='honor') # Correct template
+ self._create_custom_named_template( # wrong course key
+ 'test_template_2_course',
+ org_id=1,
+ mode='honor',
+ course_key=unicode(othercourse.id)
+ )
+ self._create_custom_named_template('test_template_3_course', org_id=1, mode='verified') # wrong mode
+ self._create_custom_named_template('test_template_4_course', org_id=2, mode='honor') # wrong org
test_url = get_certificate_url(
user_id=self.user.id,
course_id=unicode(self.course.id)
)
- with patch('certificates.api.get_course_organizations') as mock_get_orgs:
- mock_get_orgs.side_effect = [
- [{"id": 1, "name": "organization name"}],
- ]
+ with patch('certificates.api.get_course_organization_id') as mock_get_org_id:
+ mock_get_org_id.side_effect = [1]
response = self.client.get(test_url)
self.assertEqual(response.status_code, 200)
- self.assertContains(response, 'course name: course_title_0')
+ self.assertContains(response, 'course name: test_template_1_course')
@override_settings(FEATURES=FEATURES_WITH_CUSTOM_CERTS_ENABLED)
@patch('certificates.views.webview.get_course_run_details')
- def test_certificate_custom_template_with_organization(self, mock_get_course_run_details):
+ def test_certificate_custom_template_with_org(self, mock_get_course_run_details):
"""
Tests custom template search when we have a single template for a organization.
This test should check template matching when org={org}, course=Null, mode=null.
"""
mock_get_course_run_details.return_value = {'content_language': 'en'}
self._add_course_certificates(count=1, signatory_count=2)
- self._create_custom_template(org_id=1, mode='honor')
- self._create_custom_template(org_id=1, mode='honor', course_key=self.course.id)
- self._create_custom_template(org_id=2)
+ self._create_custom_named_template('test_template_1_course', org_id=1, mode=None) # Correct template
+ self._create_custom_named_template('test_template_2_course', org_id=1, mode='verified') # wrong mode
+ self._create_custom_named_template('test_template_3_course', org_id=2, mode=None) # wrong org
test_url = get_certificate_url(
user_id=self.user.id,
course_id=unicode(self.course.id)
)
- with patch('certificates.api.get_course_organizations') as mock_get_orgs:
- mock_get_orgs.side_effect = [
- [{"id": 2, "name": "organization name 2"}],
- ]
+ with patch('certificates.api.get_course_organization_id') as mock_get_org_id:
+ mock_get_org_id.side_effect = [1]
response = self.client.get(test_url)
self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_template_1_course')
@override_settings(FEATURES=FEATURES_WITH_CUSTOM_CERTS_ENABLED)
@patch('certificates.views.webview.get_course_run_details')
- def test_certificate_custom_template_with_course_mode(self, mock_get_course_run_details):
+ def test_certificate_custom_template_with_mode(self, mock_get_course_run_details):
"""
Tests custom template search if we have a single template for a course mode.
This test should check template matching when org=null, course=Null, mode={mode}.
@@ -977,17 +1010,231 @@ class CertificatesViewsTests(CommonCertificatesTestCase):
mock_get_course_run_details.return_value = {'content_language': 'en'}
mode = 'honor'
self._add_course_certificates(count=1, signatory_count=2)
- self._create_custom_template(mode=mode)
+ self._create_custom_named_template('test_template_1_course', org_id=None, mode=mode) # Correct template
+ self._create_custom_named_template('test_template_2_course', org_id=None, mode='verified') # wrong mode
+ self._create_custom_named_template('test_template_3_course', org_id=2, mode=mode) # wrong org
test_url = get_certificate_url(
user_id=self.user.id,
course_id=unicode(self.course.id)
)
- with patch('certificates.api.get_course_organizations') as mock_get_orgs:
- mock_get_orgs.return_value = []
+ with patch('certificates.api.get_course_organization_id') as mock_get_org_id:
+ mock_get_org_id.return_value = None
response = self.client.get(test_url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'mode: {}'.format(mode))
+ self.assertContains(response, 'course name: test_template_1_course')
+
+ ## Templates With Language tests
+ #1
+ @override_settings(FEATURES=FEATURES_WITH_CUSTOM_CERTS_ENABLED)
+ @override_settings(LANGUAGE_CODE='fr')
+ @patch('certificates.views.webview.get_course_run_details')
+ @patch('certificates.api.get_course_organization_id')
+ def test_certificate_custom_language_template_with_org_mode_and_course_key(self, mock_get_org_id, mock_get_course_run_details):
+ """
+ Tests custom template search and rendering.
+ This test should check template matching when org={org}, course={course}, mode={mode}.
+ """
+ right_language = 'es'
+ wrong_language = 'fr'
+ mock_get_org_id.return_value = 1
+ mock_get_course_run_details.return_value = {'content_language': 'es'}
+ CertificateGenerationCourseSetting.set_language_specific_templates_enabled_for_course(self.course.id, True)
+
+ self._add_course_certificates(count=1, signatory_count=2)
+
+ test_url = get_certificate_url(
+ user_id=self.user.id,
+ course_id=unicode(self.course.id)
+ )
+ #create a org_mode_and_coursekey template language=null
+ self._create_custom_named_template('test_null_lang_template', org_id=1, mode='honor', course_key=unicode(self.course.id), language=None)
+ #verify return template lang = null
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_null_lang_template')
+
+ #create a org_mode_and_coursekey template language=wrong_language
+ self._create_custom_named_template('test_wrong_lang_template', org_id=1, mode='honor', course_key=unicode(self.course.id), language=wrong_language)
+ #verify returns null lang template
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_null_lang_template')
+
+ #create a org_mode_and_coursekey template language=lang
+ self._create_custom_named_template('test_right_lang_template', org_id=1, mode='honor', course_key=unicode(self.course.id), language=right_language)
+ # verify return right_language template
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_right_lang_template')
+
+ #2
+ @override_settings(FEATURES=FEATURES_WITH_CUSTOM_CERTS_ENABLED)
+ @patch('certificates.views.webview.get_course_run_details')
+ @patch('certificates.api.get_course_organization_id')
+ def test_certificate_custom_language_template_with_org_and_mode(self, mock_get_org_id, mock_get_course_run_details):
+ """
+ Tests custom template search if no template matches course_key, but a template does
+ match org and mode.
+ This test should check template matching when org={org}, course=Null, mode={mode}.
+ """
+ right_language = 'es'
+ wrong_language = 'fr'
+ mock_get_org_id.return_value = 1
+ mock_get_course_run_details.return_value = {'content_language': 'es'}
+ CertificateGenerationCourseSetting.set_language_specific_templates_enabled_for_course(self.course.id, True)
+
+ self._add_course_certificates(count=1, signatory_count=2)
+
+ test_url = get_certificate_url(
+ user_id=self.user.id,
+ course_id=unicode(self.course.id)
+ )
+ #create a org and mode template language=null
+ self._create_custom_named_template('test_null_lang_template', org_id=1, mode='honor', language=None)
+ #verify return template lang = null
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_null_lang_template')
+
+ #create a org and mode template language=wrong_language
+ self._create_custom_named_template('test_wrong_lang_template', org_id=1, mode='honor', language=wrong_language)
+ #verify returns null lang template
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_null_lang_template')
+
+ #create a org and mode template language=lang
+ self._create_custom_named_template('test_right_lang_template', org_id=1, mode='honor', language=right_language)
+ # verify return right_language template
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_right_lang_template')
+
+ #3
+ @override_settings(FEATURES=FEATURES_WITH_CUSTOM_CERTS_ENABLED)
+ @patch('certificates.views.webview.get_course_run_details')
+ @patch('certificates.api.get_course_organization_id')
+ def test_certificate_custom_language_template_with_org(self, mock_get_org_id, mock_get_course_run_details):
+ """
+ Tests custom template search when we have a single template for a organization.
+ This test should check template matching when org={org}, course=Null, mode=null.
+ """
+ right_language = 'es'
+ wrong_language = 'fr'
+ mock_get_org_id.return_value = 1
+ mock_get_course_run_details.return_value = {'content_language': 'es'}
+ CertificateGenerationCourseSetting.set_language_specific_templates_enabled_for_course(self.course.id, True)
+
+ self._add_course_certificates(count=1, signatory_count=2)
+ test_url = get_certificate_url(
+ user_id=self.user.id,
+ course_id=unicode(self.course.id)
+ )
+ #create a org template language=null
+ self._create_custom_named_template('test_null_lang_template', org_id=1, language=None)
+ #verify return template lang = null
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_null_lang_template')
+
+ #create a org template language=wrong_language
+ self._create_custom_named_template('test_wrong_lang_template', org_id=1, language=wrong_language)
+ #verify returns null lang template
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_null_lang_template')
+
+ #create a org template language=lang
+ self._create_custom_named_template('test_right_lang_template', org_id=1, language=right_language)
+ # verify return right_language template
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_right_lang_template')
+
+ #4
+ @override_settings(FEATURES=FEATURES_WITH_CUSTOM_CERTS_ENABLED)
+ @patch('certificates.views.webview.get_course_run_details')
+ @patch('certificates.api.get_course_organization_id')
+ def test_certificate_custom_language_template_with_mode(self, mock_get_org_id, mock_get_course_run_details):
+ """
+ Tests custom template search if we have a single template for a course mode.
+ This test should check template matching when org=null, course=Null, mode={mode}.
+ """
+ right_language = 'es'
+ wrong_language = 'fr'
+ mock_get_org_id.return_value = 1
+ mock_get_course_run_details.return_value = {'content_language': 'es'}
+ CertificateGenerationCourseSetting.set_language_specific_templates_enabled_for_course(self.course.id, True)
+
+ self._add_course_certificates(count=1, signatory_count=2)
+
+ test_url = get_certificate_url(
+ user_id=self.user.id,
+ course_id=unicode(self.course.id)
+ )
+ #create a mode template language=null
+ self._create_custom_named_template('test_null_lang_template', mode='honor', language=None)
+ #verify return template with lang = null
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_null_lang_template')
+
+ #create a mode template language=wrong_language
+ self._create_custom_named_template('test_wrong_lang_template', mode='honor', language=wrong_language)
+ #verify returns null lang template
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_null_lang_template')
+
+ #create a mode template language=lang
+ self._create_custom_named_template('test_right_lang_template', mode='honor', language=right_language)
+ # verify return right_language template
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_right_lang_template')
+
+ @override_settings(FEATURES=FEATURES_WITH_CUSTOM_CERTS_ENABLED)
+ @patch('certificates.views.webview.get_course_run_details')
+ @patch('certificates.api.get_course_organization_id')
+ def test_certificate_custom_language_template_with_locale_language_from_catalogue(self, mock_get_org_id, mock_get_course_run_details):
+ """
+ Tests custom template search if we have a single template for a course mode.
+ This test should check template matching when org=null, course=Null, mode={mode}.
+ """
+ right_language = 'es'
+ wrong_language = 'fr'
+ mock_get_org_id.return_value = 1
+ mock_get_course_run_details.return_value = {'content_language': 'es-419'}
+ CertificateGenerationCourseSetting.set_language_specific_templates_enabled_for_course(self.course.id, True)
+
+ self._add_course_certificates(count=1, signatory_count=2)
+
+ test_url = get_certificate_url(
+ user_id=self.user.id,
+ course_id=unicode(self.course.id)
+ )
+ #create a mode template language=null
+ self._create_custom_named_template('test_null_lang_template', org_id=1, mode='honor', language=None)
+ #verify return template with lang = null
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_null_lang_template')
+
+ #create a mode template language=wrong_language
+ self._create_custom_named_template('test_wrong_lang_template', org_id=1, mode='honor', language=wrong_language)
+ #verify returns null lang template
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_null_lang_template')
+
+ #create a mode template language=lang
+ self._create_custom_named_template('test_right_lang_template', org_id=1, mode='honor', language=right_language)
+ # verify return right_language template
+ response = self.client.get(test_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'course name: test_right_lang_template')
@ddt.data(True, False)
@patch('certificates.views.webview.get_course_run_details')
@@ -1013,8 +1260,8 @@ class CertificatesViewsTests(CommonCertificatesTestCase):
}):
with patch('django.http.HttpRequest.build_absolute_uri') as mock_abs_uri:
mock_abs_uri.return_value = '='.join(['http://localhost/?param', u'é'])
- with patch('certificates.api.get_course_organizations') as mock_get_orgs:
- mock_get_orgs.return_value = []
+ with patch('certificates.api.get_course_organization_id') as mock_get_org_id:
+ mock_get_org_id.return_value = None
response = self.client.get(test_url)
self.assertEqual(response.status_code, 200)
if custom_certs_enabled:
@@ -1038,8 +1285,8 @@ class CertificatesViewsTests(CommonCertificatesTestCase):
)
# render certificate without template asset
- with patch('certificates.api.get_course_organizations') as mock_get_orgs:
- mock_get_orgs.return_value = []
+ with patch('certificates.api.get_course_organization_id') as mock_get_org_id:
+ mock_get_org_id.return_value = None
response = self.client.get(test_url)
self.assertContains(response, '
')
@@ -1051,8 +1298,8 @@ class CertificatesViewsTests(CommonCertificatesTestCase):
template_asset.save()
# render certificate with template asset
- with patch('certificates.api.get_course_organizations') as mock_get_orgs:
- mock_get_orgs.return_value = []
+ with patch('certificates.api.get_course_organization_id') as mock_get_org_id:
+ mock_get_org_id.return_value = None
response = self.client.get(test_url)
self.assertContains(
response, '
'.format(