From f832e4f2943bef67b912ca75a37ff1ad48ab446e Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Fri, 12 Sep 2014 17:50:30 -0700 Subject: [PATCH 1/2] Convert unicode emails to byte strings for CSV grade reports --- .../instructor_task/tasks_helper.py | 2 +- .../tests/test_tasks_helper.py | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 lms/djangoapps/instructor_task/tests/test_tasks_helper.py diff --git a/lms/djangoapps/instructor_task/tasks_helper.py b/lms/djangoapps/instructor_task/tasks_helper.py index 54131f22d0..ffe5c687c0 100644 --- a/lms/djangoapps/instructor_task/tasks_helper.py +++ b/lms/djangoapps/instructor_task/tasks_helper.py @@ -547,7 +547,7 @@ def push_grades_to_s3(_xmodule_instance_args, _entry_id, course_id, _task_input, # possible for a student to have a 0.0 show up in their row but # still have 100% for the course. row_percents = [percents.get(label, 0.0) for label in header] - rows.append([student.id, student.email, student.username, gradeset['percent']] + row_percents) + rows.append([student.id, unicode(student.email).encode('utf-8'), student.username, gradeset['percent']] + row_percents) else: # An empty gradeset means we failed to grade a student. num_failed += 1 diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py new file mode 100644 index 0000000000..af3ae214e1 --- /dev/null +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -0,0 +1,62 @@ +""" +Unit tests for LMS instructor-initiated background tasks helper functions. + +Tests that CSV grade report generation works with unicode emails. + +""" +import os +import shutil + +import ddt +from mock import Mock, patch + +from django.conf import settings +from django.test.testcases import TestCase + +from xmodule.modulestore.tests.factories import CourseFactory + +from student.tests.factories import CourseEnrollmentFactory, UserFactory + +from instructor_task.tasks_helper import push_grades_to_s3 + + +TEST_COURSE_ORG = 'edx' +TEST_COURSE_NAME = 'test_course' +TEST_COURSE_NUMBER = '1.23x' + + +@ddt.ddt +class TestInstructorGradeReport(TestCase): + """ + Tests that CSV grade report generation works. + """ + def setUp(self): + self.course = CourseFactory.create(org=TEST_COURSE_ORG, + number=TEST_COURSE_NUMBER, + display_name=TEST_COURSE_NAME) + + def tearDown(self): + if os.path.exists(settings.GRADES_DOWNLOAD['ROOT_PATH']): + shutil.rmtree(settings.GRADES_DOWNLOAD['ROOT_PATH']) + + def create_student(self, username, email): + student = UserFactory.create(username=username, email=email) + CourseEnrollmentFactory.create(user=student, course_id=self.course.id) + + @ddt.data([u'student@example.com', u'ni\xf1o@example.com']) + def test_unicode_emails(self, emails): + """ + Test that students with unicode characters in emails is handled. + """ + i = 0 + for email in emails: + self.create_student('student{0}'.format(i), email) + i += 1 + + self.current_task = Mock() + self.current_task.update_state = Mock() + with patch('instructor_task.tasks_helper._get_current_task') as mock_current_task: + mock_current_task.return_value = self.current_task + result = push_grades_to_s3(None, None, self.course.id, None, 'graded') + #This assertion simply confirms that the generation completed with no errors + self.assertEquals(result['succeeded'], result['attempted']) From 7627d34339cf5cd439ee5b0e896a933d23e40dd9 Mon Sep 17 00:00:00 2001 From: Kevin Luo Date: Mon, 15 Sep 2014 10:58:09 -0700 Subject: [PATCH 2/2] Remove unicode conversion of email since it should always be unicode --- lms/djangoapps/instructor_task/tasks_helper.py | 2 +- lms/djangoapps/instructor_task/tests/test_tasks_helper.py | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lms/djangoapps/instructor_task/tasks_helper.py b/lms/djangoapps/instructor_task/tasks_helper.py index ffe5c687c0..c13d22271f 100644 --- a/lms/djangoapps/instructor_task/tasks_helper.py +++ b/lms/djangoapps/instructor_task/tasks_helper.py @@ -547,7 +547,7 @@ def push_grades_to_s3(_xmodule_instance_args, _entry_id, course_id, _task_input, # possible for a student to have a 0.0 show up in their row but # still have 100% for the course. row_percents = [percents.get(label, 0.0) for label in header] - rows.append([student.id, unicode(student.email).encode('utf-8'), student.username, gradeset['percent']] + row_percents) + rows.append([student.id, student.email.encode('utf-8'), student.username, gradeset['percent']] + row_percents) else: # An empty gradeset means we failed to grade a student. num_failed += 1 diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index af3ae214e1..99bc997a18 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -48,10 +48,8 @@ class TestInstructorGradeReport(TestCase): """ Test that students with unicode characters in emails is handled. """ - i = 0 - for email in emails: + for i, email in enumerate(emails): self.create_student('student{0}'.format(i), email) - i += 1 self.current_task = Mock() self.current_task.update_state = Mock()