def test_clean_bad_json(self): """ Tests if bad JSON string was given. """ self.config = CertificateHtmlViewConfiguration( configuration='{"bad":"test"') pytest.raises(ValidationError, self.config.clean)
def _certificate_html_view_configuration(self, configuration_string, enabled=True): """ This will create a certificate html configuration """ config = CertificateHtmlViewConfiguration(enabled=enabled, configuration=configuration_string) config.save() return config
def _setup_configuration(self, enabled=True): """ This will create a certificate html configuration """ config = CertificateHtmlViewConfiguration(enabled=enabled, configuration=self.test_configuration_string) config.save() return config
def setUp(self): super(CertificateHtmlViewConfigurationTest, self).setUp() self.configuration_string = """{ "default": { "url": "http://www.edx.org", "logo_src": "http://www.edx.org/static/images/logo.png" }, "honor": { "logo_src": "http://www.edx.org/static/images/honor-logo.png" } }""" self.config = CertificateHtmlViewConfiguration(configuration=self.configuration_string)
def setUp(self): super(CertificateHtmlViewConfigurationTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.configuration_string = """{ "default": { "url": "http://www.edx.org", "logo_src": "http://www.edx.org/static/images/logo.png" }, "honor": { "logo_src": "http://www.edx.org/static/images/honor-logo.png" } }""" self.config = CertificateHtmlViewConfiguration( configuration=self.configuration_string)
def unsupported_url(request, user_id, course_id): """ This view returns the un-supported url page aimed to let the user aware that url is no longer supported """ platform_name = configuration_helpers.get_value("platform_name", settings.PLATFORM_NAME) configuration = CertificateHtmlViewConfiguration.get_config() return _render_invalid_certificate( request, course_id, platform_name, configuration, cert_path='certificates/url_unsupported.html' )
class CertificateHtmlViewConfigurationTest(TestCase): """ Test the CertificateHtmlViewConfiguration model. """ def setUp(self): super().setUp() self.configuration_string = """{ "default": { "url": "http://www.edx.org", "logo_src": "http://www.edx.org/static/images/logo.png" }, "honor": { "logo_src": "http://www.edx.org/static/images/honor-logo.png" } }""" self.config = CertificateHtmlViewConfiguration( configuration=self.configuration_string) def test_create(self): """ Tests creation of configuration. """ self.config.save() assert self.config.configuration == self.configuration_string def test_clean_bad_json(self): """ Tests if bad JSON string was given. """ self.config = CertificateHtmlViewConfiguration( configuration='{"bad":"test"') pytest.raises(ValidationError, self.config.clean) def test_get(self): """ Tests get configuration from saved string. """ self.config.enabled = True self.config.save() expected_config = { "default": { "url": "http://www.edx.org", "logo_src": "http://www.edx.org/static/images/logo.png" }, "honor": { "logo_src": "http://www.edx.org/static/images/honor-logo.png" } } assert self.config.get_config() == expected_config def test_get_not_enabled_returns_blank(self): """ Tests get configuration that is not enabled. """ self.config.enabled = False self.config.save() assert len(self.config.get_config()) == 0 @override_settings(FEATURES=FEATURES_INVALID_FILE_PATH) def test_get_no_database_no_file(self): """ Tests get configuration that is not enabled. """ self.config.configuration = '' self.config.save() assert self.config.get_config() == {}
def render_html_view(request, user_id, course_id): """ This public view generates an HTML representation of the specified user and course If a certificate is not available, we display a "Sorry!" screen instead """ try: user_id = int(user_id) except ValueError: raise Http404 preview_mode = request.GET.get('preview', None) platform_name = configuration_helpers.get_value("platform_name", settings.PLATFORM_NAME) configuration = CertificateHtmlViewConfiguration.get_config() # Kick the user back to the "Invalid" screen if the feature is disabled globally if not settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False): return _render_invalid_certificate(course_id, platform_name, configuration) # Load the course and user objects try: course_key = CourseKey.from_string(course_id) user = User.objects.get(id=user_id) course = get_course_by_id(course_key) # For any course or user exceptions, kick the user back to the "Invalid" screen except (InvalidKeyError, User.DoesNotExist, Http404) as exception: error_str = (u"Invalid cert: error finding course %s or user with id " u"%d. Specific error: %s") log.info(error_str, course_id, user_id, str(exception)) return _render_invalid_certificate(course_id, platform_name, configuration) # Kick the user back to the "Invalid" screen if the feature is disabled for the course if not course.cert_html_view_enabled: log.info( u"Invalid cert: HTML certificates disabled for %s. User id: %d", course_id, user_id, ) return _render_invalid_certificate(course_id, platform_name, configuration) # Load user's certificate user_certificate = _get_user_certificate(request, user, course_key, course, preview_mode) if not user_certificate: log.info( u"Invalid cert: User %d does not have eligible cert for %s.", user_id, course_id, ) return _render_invalid_certificate(course_id, platform_name, configuration) # Get the active certificate configuration for this course # If we do not have an active certificate, we'll need to send the user to the "Invalid" screen # Passing in the 'preview' parameter, if specified, will return a configuration, if defined active_configuration = get_active_web_certificate(course, preview_mode) if active_configuration is None: log.info( u"Invalid cert: course %s does not have an active configuration. User id: %d", course_id, user_id, ) return _render_invalid_certificate(course_id, platform_name, configuration) # Get data from Discovery service that will be necessary for rendering this Certificate. catalog_data = _get_catalog_data_for_course(course_key) # Determine whether to use the standard or custom template to render the certificate. custom_template = None custom_template_language = None if settings.FEATURES.get('CUSTOM_CERTIFICATE_TEMPLATES_ENABLED', False): log.info("Custom certificate for course {course_id}".format( course_id=course_id)) custom_template, custom_template_language = _get_custom_template_and_language( course.id, user_certificate.mode, catalog_data.pop('content_language', None)) # Determine the language that should be used to render the certificate. # For the standard certificate template, use the user language. For custom templates, use # the language associated with the template. user_language = translation.get_language() certificate_language = custom_template_language if custom_template else user_language log.info("certificate language is: {language} for the course:{course_key}". format(language=certificate_language, course_key=course_key)) # Generate the certificate context in the correct language, then render the template. with translation.override(certificate_language): context = {'user_language': user_language} _update_context_with_basic_info(context, course_id, platform_name, configuration) context['certificate_data'] = active_configuration # Append/Override the existing view context values with any mode-specific ConfigurationModel values context.update(configuration.get(user_certificate.mode, {})) # Append organization info _update_organization_context(context, course) # Append course info _update_course_context(request, context, course, course_key, platform_name) # Append course run info from discovery context.update(catalog_data) # Append user info _update_context_with_user_info(context, user, user_certificate) # Append social sharing info _update_social_context(request, context, course, user, user_certificate, platform_name) # Append/Override the existing view context values with certificate specific values _update_certificate_context(context, course, user_certificate, platform_name) # Append badge info _update_badge_context(context, course, user) # Append site configuration overrides _update_configuration_context(context, configuration) # Add certificate header/footer data to current context context.update( get_certificate_header_context(is_secure=request.is_secure())) context.update(get_certificate_footer_context()) # Append/Override the existing view context values with any course-specific static values from Advanced Settings context.update(course.cert_html_view_overrides) # Track certificate view events _track_certificate_events(request, context, course, user, user_certificate) # Render the certificate return _render_valid_certificate(request, context, custom_template)
def test_clean_bad_json(self): """ Tests if bad JSON string was given. """ self.config = CertificateHtmlViewConfiguration(configuration='{"bad":"test"') self.assertRaises(ValidationError, self.config.clean)
class CertificateHtmlViewConfigurationTest(TestCase): """ Test the CertificateHtmlViewConfiguration model. """ def setUp(self): super(CertificateHtmlViewConfigurationTest, self).setUp() self.configuration_string = """{ "default": { "url": "http://www.edx.org", "logo_src": "http://www.edx.org/static/images/logo.png" }, "honor": { "logo_src": "http://www.edx.org/static/images/honor-logo.png" } }""" self.config = CertificateHtmlViewConfiguration(configuration=self.configuration_string) def test_create(self): """ Tests creation of configuration. """ self.config.save() self.assertEquals(self.config.configuration, self.configuration_string) def test_clean_bad_json(self): """ Tests if bad JSON string was given. """ self.config = CertificateHtmlViewConfiguration(configuration='{"bad":"test"') self.assertRaises(ValidationError, self.config.clean) def test_get(self): """ Tests get configuration from saved string. """ self.config.enabled = True self.config.save() expected_config = { "default": { "url": "http://www.edx.org", "logo_src": "http://www.edx.org/static/images/logo.png" }, "honor": { "logo_src": "http://www.edx.org/static/images/honor-logo.png" } } self.assertEquals(self.config.get_config(), expected_config) def test_get_not_enabled_returns_blank(self): """ Tests get configuration that is not enabled. """ self.config.enabled = False self.config.save() self.assertEquals(len(self.config.get_config()), 0) @override_settings(FEATURES=FEATURES_INVALID_FILE_PATH) def test_get_no_database_no_file(self): """ Tests get configuration that is not enabled. """ self.config.configuration = '' self.config.save() self.assertEquals(self.config.get_config(), {})
class CertificateHtmlViewConfigurationTest(TestCase, OpenEdxEventsTestMixin): """ Test the CertificateHtmlViewConfiguration model. """ ENABLED_OPENEDX_EVENTS = [] @classmethod def setUpClass(cls): """ Set up class method for the Test class. This method starts manually events isolation. Explanation here: openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44 """ super().setUpClass() cls.start_events_isolation() def setUp(self): super().setUp() self.configuration_string = """{ "default": { "url": "https://www.edx.org", "logo_src": "https://www.edx.org/static/images/logo.png" }, "honor": { "logo_src": "https://www.edx.org/static/images/honor-logo.png" } }""" self.config = CertificateHtmlViewConfiguration( configuration=self.configuration_string) def test_create(self): """ Tests creation of configuration. """ self.config.save() assert self.config.configuration == self.configuration_string def test_clean_bad_json(self): """ Tests if bad JSON string was given. """ self.config = CertificateHtmlViewConfiguration( configuration='{"bad":"test"') pytest.raises(ValidationError, self.config.clean) def test_get(self): """ Tests get configuration from saved string. """ self.config.enabled = True self.config.save() expected_config = { "default": { "url": "https://www.edx.org", "logo_src": "https://www.edx.org/static/images/logo.png" }, "honor": { "logo_src": "https://www.edx.org/static/images/honor-logo.png" } } assert self.config.get_config() == expected_config def test_get_not_enabled_returns_blank(self): """ Tests get configuration that is not enabled. """ self.config.enabled = False self.config.save() assert len(self.config.get_config()) == 0 @override_settings(FEATURES=FEATURES_INVALID_FILE_PATH) def test_get_no_database_no_file(self): """ Tests get configuration that is not enabled. """ self.config.configuration = '' self.config.save() assert self.config.get_config() == {}
def render_html_view(request, user_id, course_id): """ This public view generates an HTML representation of the specified user and course If a certificate is not available, we display a "Sorry!" screen instead """ try: user_id = int(user_id) except ValueError: raise Http404 preview_mode = request.GET.get('preview', None) platform_name = configuration_helpers.get_value("platform_name", settings.PLATFORM_NAME) configuration = CertificateHtmlViewConfiguration.get_config() # Kick the user back to the "Invalid" screen if the feature is disabled globally if not settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False): return _render_invalid_certificate(course_id, platform_name, configuration) # Load the course and user objects try: course_key = CourseKey.from_string(course_id) user = User.objects.get(id=user_id) course = get_course_by_id(course_key) # For any course or user exceptions, kick the user back to the "Invalid" screen except (InvalidKeyError, User.DoesNotExist, Http404) as exception: error_str = ( u"Invalid cert: error finding course %s or user with id " u"%d. Specific error: %s" ) log.info(error_str, course_id, user_id, str(exception)) return _render_invalid_certificate(course_id, platform_name, configuration) # Kick the user back to the "Invalid" screen if the feature is disabled for the course if not course.cert_html_view_enabled: log.info( u"Invalid cert: HTML certificates disabled for %s. User id: %d", course_id, user_id, ) return _render_invalid_certificate(course_id, platform_name, configuration) # Load user's certificate user_certificate = _get_user_certificate(request, user, course_key, course, preview_mode) if not user_certificate: log.info( u"Invalid cert: User %d does not have eligible cert for %s.", user_id, course_id, ) return _render_invalid_certificate(course_id, platform_name, configuration) # Get the active certificate configuration for this course # If we do not have an active certificate, we'll need to send the user to the "Invalid" screen # Passing in the 'preview' parameter, if specified, will return a configuration, if defined active_configuration = get_active_web_certificate(course, preview_mode) if active_configuration is None: log.info( u"Invalid cert: course %s does not have an active configuration. User id: %d", course_id, user_id, ) return _render_invalid_certificate(course_id, platform_name, configuration) # Get data from Discovery service that will be necessary for rendering this Certificate. catalog_data = _get_catalog_data_for_course(course_key) # Determine whether to use the standard or custom template to render the certificate. custom_template = None custom_template_language = None if settings.FEATURES.get('CUSTOM_CERTIFICATE_TEMPLATES_ENABLED', False): log.info(u"Custom certificate for course %s", course_id) custom_template, custom_template_language = _get_custom_template_and_language( course.id, user_certificate.mode, catalog_data.pop('content_language', None) ) # Determine the language that should be used to render the certificate. # For the standard certificate template, use the user language. For custom templates, use # the language associated with the template. user_language = translation.get_language() certificate_language = custom_template_language if custom_template else user_language log.info( u"certificate language is: %s for the course: %s", certificate_language, course_key ) # Generate the certificate context in the correct language, then render the template. with translation.override(certificate_language): context = {'user_language': user_language} _update_context_with_basic_info(context, course_id, platform_name, configuration) context['certificate_data'] = active_configuration # Append/Override the existing view context values with any mode-specific ConfigurationModel values context.update(configuration.get(user_certificate.mode, {})) # Append organization info _update_organization_context(context, course) # Append course info _update_course_context(request, context, course, course_key, platform_name) # Append course run info from discovery context.update(catalog_data) # Append user info _update_context_with_user_info(context, user, user_certificate) # Append social sharing info _update_social_context(request, context, course, user, user_certificate, platform_name) # Append/Override the existing view context values with certificate specific values _update_certificate_context(context, course, user_certificate, platform_name) # Append badge info _update_badge_context(context, course, user) # Append site configuration overrides _update_configuration_context(context, configuration) # Add certificate header/footer data to current context context.update(get_certificate_header_context(is_secure=request.is_secure())) context.update(get_certificate_footer_context()) # Append/Override the existing view context values with any course-specific static values from Advanced Settings context.update(course.cert_html_view_overrides) # Track certificate view events _track_certificate_events(request, context, course, user, user_certificate) # Render the certificate return _render_valid_certificate(request, context, custom_template)
def render_html_view(request, course_id, certificate=None): # pylint: disable=too-many-statements """ This public view generates an HTML representation of the specified user and course If a certificate is not available, we display a "Sorry!" screen instead It can be overridden by setting `OVERRIDE_RENDER_CERTIFICATE_VIEW` to an alternative implementation. """ user = certificate.user if certificate else request.user user_id = user.id preview_mode = request.GET.get('preview', None) platform_name = configuration_helpers.get_value("platform_name", settings.PLATFORM_NAME) configuration = CertificateHtmlViewConfiguration.get_config() # Kick the user back to the "Invalid" screen if the feature is disabled globally if not settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False): return _render_invalid_certificate(request, course_id, platform_name, configuration) # Load the course and user objects try: course_key = CourseKey.from_string(course_id) course = get_course_by_id(course_key) # For any course or user exceptions, kick the user back to the "Invalid" screen except (InvalidKeyError, Http404) as exception: error_str = ( "Invalid cert: error finding course %s " "Specific error: %s" ) log.info(error_str, course_id, str(exception)) return _render_invalid_certificate(request, course_id, platform_name, configuration) course_overview = get_course_overview_or_none(course_key) # Kick the user back to the "Invalid" screen if the feature is disabled for the course if not course.cert_html_view_enabled: log.info( "Invalid cert: HTML certificates disabled for %s. User id: %d", course_id, user_id, ) return _render_invalid_certificate(request, course_id, platform_name, configuration) # Load user's certificate user_certificate = _get_user_certificate(request, user, course_key, course_overview, preview_mode) if not user_certificate: log.info( "Invalid cert: User %d does not have eligible cert for %s.", user_id, course_id, ) return _render_invalid_certificate(request, course_id, platform_name, configuration) # Get the active certificate configuration for this course # If we do not have an active certificate, we'll need to send the user to the "Invalid" screen # Passing in the 'preview' parameter, if specified, will return a configuration, if defined active_configuration = get_active_web_certificate(course, preview_mode) if active_configuration is None: log.info( "Invalid cert: course %s does not have an active configuration. User id: %d", course_id, user_id, ) return _render_invalid_certificate(request, course_id, platform_name, configuration) # Get data from Discovery service that will be necessary for rendering this Certificate. catalog_data = _get_catalog_data_for_course(course_key) # Determine whether to use the standard or custom template to render the certificate. custom_template = None custom_template_language = None if settings.FEATURES.get('CUSTOM_CERTIFICATE_TEMPLATES_ENABLED', False): log.info("Custom certificate for course %s", course_id) custom_template, custom_template_language = _get_custom_template_and_language( course.id, user_certificate.mode, catalog_data.pop('content_language', None) ) # Determine the language that should be used to render the certificate. # For the standard certificate template, use the user language. For custom templates, use # the language associated with the template. user_language = translation.get_language() certificate_language = custom_template_language if custom_template else user_language log.info( "certificate language is: %s for the course: %s", certificate_language, course_key ) # Generate the certificate context in the correct language, then render the template. with translation.override(certificate_language): context = {'user_language': user_language} _update_context_with_basic_info(context, course_id, platform_name, configuration) context['certificate_data'] = active_configuration # Append/Override the existing view context values with any mode-specific ConfigurationModel values context.update(configuration.get(user_certificate.mode, {})) # Append organization info _update_organization_context(context, course) # Append course info _update_course_context(request, context, course, platform_name) # Append course run info from discovery context.update(catalog_data) # Append user info _update_context_with_user_info(context, user, user_certificate) # Append social sharing info _update_social_context(request, context, course, user_certificate, platform_name) # Append/Override the existing view context values with certificate specific values _update_certificate_context(context, course, course_overview, user_certificate, platform_name) # Append badge info _update_badge_context(context, course, user) # Add certificate header/footer data to current context context.update(get_certificate_header_context(is_secure=request.is_secure())) context.update(get_certificate_footer_context()) # Append/Override the existing view context values with any course-specific static values from Advanced Settings context.update(course.cert_html_view_overrides) # Track certificate view events _track_certificate_events(request, course, user, user_certificate) try: # .. filter_implemented_name: CertificateRenderStarted # .. filter_type: org.openedx.learning.certificate.render.started.v1 context, custom_template = CertificateRenderStarted.run_filter( context=context, custom_template=custom_template, ) except CertificateRenderStarted.RenderAlternativeInvalidCertificate as exc: response = _render_invalid_certificate( request, course_id, platform_name, configuration, cert_path=exc.template_name or INVALID_CERTIFICATE_TEMPLATE_PATH, ) except CertificateRenderStarted.RedirectToPage as exc: response = HttpResponseRedirect(exc.redirect_to) except CertificateRenderStarted.RenderCustomResponse as exc: response = exc.response else: response = _render_valid_certificate(request, context, custom_template) # Render the certificate return response