Repository: kartoza/prj.app

Issue:
Error 500 when trying to print a certificate
This error produces when I try to print a new certificate or regenerate it.

If you need assistance, you may reference this error as e5bcad001ba1496c9f4bcf447afea2f9.


Discussion:
Can you fix this ASAP @ann26 ? Its probably this:

http://sentry.kartoza.com/sentry/projecta/issues/93/

@AurelioMorales My apologies for the delay in noticing your ticket!

Regards

Tim
@ann26 I deployed to live but it seems the error is still there e.g.

http://changelog.qgis.org/en/qgis/certificate/QGIS-118/
@timlinux sorry I missed that one, I fixed it in #876 but the pdf certificate printing should be working.
@AurelioMorales I have deployed @ann26 's fixes could you test again please?
Reopened pending confirmation from @AurelioMorales 
Everything is ok! Thanks!

El mar., 3 abr. 2018 22:40, Tim Sutton <notifications@github.com> escribió:

> Reopened pending confirmation from @AurelioMorales
> <https://github.com/AurelioMorales>
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/kartoza/projecta/issues/868#issuecomment-378391928>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AK_Gc6N1xVUcvcso71wmtLUy_QT2M9ZFks5tk95MgaJpZM4S4kdn>
> .
>

Thanks @AurelioMorales !
The problem is here again.

same problem with http://changelog.qgis.org/en/qgis/certificate/QGIS-117/ http://changelog.qgis.org/en/qgis/certificate/QGIS-118/ and http://changelog.qgis.org/en/qgis/certificate/QGIS-136/
Sorry about this @AurelioMorales we will fix ASAP

@ann26 looks like this:

http://sentry.kartoza.com/sentry/projecta/issues/137/

Can you systematically check that everything in the certification app is unicode friendly?
ok @timlinux , I will do

Resolving patch:
diff --git a/django_project/certification/views/certificate.py b/django_project/certification/views/certificate.py
--- a/django_project/certification/views/certificate.py
+++ b/django_project/certification/views/certificate.py
@@ -145,8 +145,10 @@ def get_context_data(self, **kwargs):
             certificate = context['certificate']
             convener_name = \
                 '{} {}'.format(
-                    certificate.course.course_convener.user.first_name,
-                    certificate.course.course_convener.user.last_name)
+                    certificate.course.course_convener.user.first_name.encode(
+                        'utf-8'),
+                    certificate.course.course_convener.user.last_name.encode(
+                        'utf-8'))
 
             if certificate.course.course_convener.title:
                 convener_name = \
@@ -211,8 +213,8 @@ def generate_pdf(
     center = height * 0.5
     convener_name = \
         '{} {}'.format(
-            course.course_convener.user.first_name,
-            course.course_convener.user.last_name)
+            course.course_convener.user.first_name.encode('utf-8'),
+            course.course_convener.user.last_name.encode('utf-8'))
 
     if course.course_convener.title:
         convener_name = \
@@ -295,12 +297,15 @@ def generate_pdf(
     page.setFont('Times-Bold', 26)
     page.drawCentredString(center, 480, 'Certificate of Completion')
     page.drawCentredString(
-        center, 400, '%s %s' % (attendee.firstname, attendee.surname))
+        center, 400, '%s %s' % (
+            attendee.firstname.encode('utf-8'),
+            attendee.surname.encode('utf-8')))
     page.setFont('Times-Roman', 16)
     page.drawCentredString(
         center, 360, 'Has attended and completed the course:')
     page.setFont('Times-Bold', 20)
-    page.drawCentredString(center, 300, course.course_type.name)
+    page.drawCentredString(
+        center, 300, course.course_type.name.encode('utf-8'))
     page.setFont('Times-Roman', 16)
     page.drawCentredString(
         center, 270, '{}'.format(course_duration))
@@ -330,7 +335,9 @@ def generate_pdf(
     page.setFont('Times-Italic', 12)
     page.drawCentredString(
         (margin_left + 150), (margin_bottom + 60),
-        '{} {}'.format(project.owner.first_name, project.owner.last_name))
+        '{} {}'.format(
+            project.owner.first_name.encode('utf-8'),
+            project.owner.last_name.encode('utf-8')))
     page.drawCentredString(
         (margin_right - 150), (margin_bottom + 60),
         '{}'.format(convener_name))


Test patch:
diff --git a/django_project/certification/tests/test_certificate_views.py b/django_project/certification/tests/test_certificate_views.py
new file mode 100644
--- /dev/null
+++ b/django_project/certification/tests/test_certificate_views.py
@@ -0,0 +1,108 @@
+# coding=utf-8
+import logging
+from mock import patch, MagicMock
+from django.core.urlresolvers import reverse
+from django.test import TestCase, override_settings
+from django.test.client import Client
+from base.tests.model_factories import ProjectF
+from core.model_factories import UserF
+from certification.tests.model_factories import (
+    CourseF,
+    CertifyingOrganisationF,
+    CourseConvenerF,
+    CertificateF,
+    TrainingCenterF,
+    CourseTypeF,
+    AttendeeF
+)
+
+
+class TestCertificateView(TestCase):
+    """Test that certificate detail view and generating certificate works."""
+
+    @override_settings(VALID_DOMAIN=['testserver', ])
+    def setUp(self):
+        """
+        Setup before each test
+        We force the locale to en otherwise it will use
+        the locale of the host running the tests and we
+        will get unpredictable results / 404s
+        """
+        self.client = Client()
+        self.client.post(
+            '/set_language/', data={'language': 'en'})
+        logging.disable(logging.CRITICAL)
+        self.project = ProjectF.create()
+        self.user = UserF.create(**{
+            'username': 'anita',
+            'password': 'password',
+            'is_staff': True
+        })
+        self.user.set_password('password')
+        self.user.save()
+
+        self.certifying_organisation = \
+            CertifyingOrganisationF.create()
+        self.course_convener = CourseConvenerF.create()
+        self.training_center = TrainingCenterF.create()
+        self.course_type = CourseTypeF.create()
+        self.course = CourseF.create(
+            course_convener=self.course_convener,
+            certifying_organisation=self.certifying_organisation,
+            course_type=self.course_type,
+            training_center=self.training_center
+        )
+        self.attendee = AttendeeF.create()
+        self.certificate = CertificateF.create(
+            course=self.course,
+            attendee=self.attendee,
+            author=self.user
+        )
+
+    @override_settings(VALID_DOMAIN=['testserver', ])
+    def tearDown(self):
+        """
+        Teardown after each test.
+
+        :return:
+        """
+        self.certificate.delete()
+        self.attendee.delete()
+        self.course.delete()
+        self.training_center.delete()
+        self.course_type.delete()
+        self.course_convener.delete()
+        self.certifying_organisation.delete()
+        self.project.delete()
+        self.user.delete()
+
+    @override_settings(VALID_DOMAIN=['testserver', ])
+    @patch('os.path.exists')
+    @patch('os.makedirs')
+    @patch('__builtin__.open', create=True)
+    def test_generate_certificate(
+            self, mock_open, mock_make_dirs, mock_exists):
+        mock_open.return_value = MagicMock()
+        mock_exists.return_value = False
+        client = Client(HTTP_HOST='testserver')
+        client.login(username='anita', password='password')
+        response = client.get(reverse('print-certificate', kwargs={
+            'project_slug': self.project.slug,
+            'organisation_slug': self.certifying_organisation.slug,
+            'course_slug': self.course.slug,
+            'pk': self.attendee.pk
+        }))
+        self.assertEqual(response.status_code, 200)
+
+    @override_settings(VALID_DOMAIN=['testserver', ])
+    def test_detail_certificate(self):
+        client = Client()
+        response = client.get(reverse('certificate-details', kwargs={
+            'project_slug': self.project.slug,
+            'id': self.certificate.certificateID
+        }))
+        self.assertEqual(response.status_code, 200)
+        expected_templates = [
+            'certificate/detail.html'
+        ]
+        self.assertEqual(response.template_name, expected_templates)