diff --git a/lms/djangoapps/instructor_task/api.py b/lms/djangoapps/instructor_task/api.py index d5ca3b7b264b..4c8f1060f54d 100644 --- a/lms/djangoapps/instructor_task/api.py +++ b/lms/djangoapps/instructor_task/api.py @@ -344,31 +344,31 @@ def submit_calculate_problem_responses_csv( return submit_task(request, task_type, task_class, course_key, task_input, task_key) -def submit_calculate_grades_csv(request, course_key): +def submit_calculate_grades_csv(request, course_key, **task_kwargs): """ AlreadyRunningError is raised if the course's grades are already being updated. """ task_type = 'grade_course' task_class = calculate_grades_csv - task_input = {} + task_input = task_kwargs task_key = "" return submit_task(request, task_type, task_class, course_key, task_input, task_key) -def submit_problem_grade_report(request, course_key): +def submit_problem_grade_report(request, course_key, **task_kwargs): """ Submits a task to generate a CSV grade report containing problem values. """ task_type = 'grade_problems' task_class = calculate_problem_grade_report - task_input = {} + task_input = task_kwargs task_key = "" return submit_task(request, task_type, task_class, course_key, task_input, task_key) -def submit_calculate_students_features_csv(request, course_key, features): +def submit_calculate_students_features_csv(request, course_key, features, **task_kwargs): """ Submits a task to generate a CSV containing student profile info. @@ -376,7 +376,7 @@ def submit_calculate_students_features_csv(request, course_key, features): """ task_type = 'profile_info_csv' task_class = calculate_students_features_csv - task_input = features + task_input = dict(features=features, **task_kwargs) task_key = "" return submit_task(request, task_type, task_class, course_key, task_input, task_key) diff --git a/lms/djangoapps/instructor_task/models.py b/lms/djangoapps/instructor_task/models.py index 95a8d05d0ac5..71d4cf90b281 100644 --- a/lms/djangoapps/instructor_task/models.py +++ b/lms/djangoapps/instructor_task/models.py @@ -272,13 +272,13 @@ def from_config(cls, config_name): getattr(settings, config_name).get('STORAGE_KWARGS'), ) - def store(self, course_id, filename, buff): + def store(self, course_id, filename, buff, parent_dir=''): """ Store the contents of `buff` in a directory determined by hashing `course_id`, and name the file `filename`. `buff` can be any file-like object, ready to be read from the beginning. """ - path = self.path_to(course_id, filename) + path = self.path_to(course_id, filename, parent_dir) # See https://github.com/boto/boto/issues/2868 # Boto doesn't play nice with unicode in python3 if not six.PY2: @@ -291,7 +291,7 @@ def store(self, course_id, filename, buff): self.storage.save(path, buff) - def store_rows(self, course_id, filename, rows): + def store_rows(self, course_id, filename, rows, parent_dir=''): """ Given a course_id, filename, and rows (each row is an iterable of strings), write the rows to the storage backend in csv format. @@ -303,7 +303,7 @@ def store_rows(self, course_id, filename, rows): csvwriter = csv.writer(output_buffer) csvwriter.writerows(self._get_utf8_encoded_rows(rows)) output_buffer.seek(0) - self.store(course_id, filename, output_buffer) + self.store(course_id, filename, output_buffer, parent_dir) def links_for(self, course_id): """ @@ -333,9 +333,10 @@ def links_for(self, course_id): for filename, full_path in files ] - def path_to(self, course_id, filename=''): + def path_to(self, course_id, filename='', parent_dir=''): """ Return the full path to a given file for a given course. """ - hashed_course_id = hashlib.sha1(text_type(course_id).encode('utf-8')).hexdigest() - return os.path.join(hashed_course_id, filename) + hashed_course_id = hashlib.sha1(str(course_id).encode('utf-8')).hexdigest() + directory = parent_dir if bool(parent_dir) else hashed_course_id + return os.path.join(directory, filename) diff --git a/lms/djangoapps/instructor_task/tasks_helper/enrollments.py b/lms/djangoapps/instructor_task/tasks_helper/enrollments.py index 3b2b8c9588a6..cbe6cd8bbe94 100644 --- a/lms/djangoapps/instructor_task/tasks_helper/enrollments.py +++ b/lms/djangoapps/instructor_task/tasks_helper/enrollments.py @@ -74,7 +74,7 @@ def upload_students_csv(_xmodule_instance_args, _entry_id, course_id, task_input task_progress.update_task_state(extra_meta=current_step) # compute the student features table and format it - query_features = task_input + query_features = task_input.get('features') student_data = enrolled_students_features(course_id, query_features) header, rows = format_dictlist(student_data, query_features) @@ -87,6 +87,8 @@ def upload_students_csv(_xmodule_instance_args, _entry_id, course_id, task_input task_progress.update_task_state(extra_meta=current_step) # Perform the upload - upload_csv_to_report_store(rows, 'student_profile_info', course_id, start_date) + upload_parent_dir = task_input.get('upload_parent_dir', '') + upload_filename = task_input.get('filename', 'student_profile_info') + upload_csv_to_report_store(rows, upload_filename, course_id, start_date, parent_dir=upload_parent_dir) return task_progress.update_task_state(extra_meta=current_step) diff --git a/lms/djangoapps/instructor_task/tasks_helper/grades.py b/lms/djangoapps/instructor_task/tasks_helper/grades.py index 911b64a702c6..8a7eded0e6d3 100644 --- a/lms/djangoapps/instructor_task/tasks_helper/grades.py +++ b/lms/djangoapps/instructor_task/tasks_helper/grades.py @@ -187,9 +187,9 @@ def _upload(self, context, success_rows, error_rows): Creates and uploads a CSV for the given headers and rows. """ date = datetime.now(UTC) - upload_csv_to_report_store(success_rows, context.file_name, context.course_id, date) + upload_csv_to_report_store(success_rows, context.upload_filename, context.course_id, date) if len(error_rows) > 1: - upload_csv_to_report_store(error_rows, context.file_name + '_err', context.course_id, date) + upload_csv_to_report_store(error_rows, context.upload_filename + '_err', context.course_id, date) def log_additional_info_for_testing(self, context, message): """ @@ -224,6 +224,8 @@ def __init__(self, _xmodule_instance_args, _entry_id, course_id, _task_input, ac self.course_id = course_id self.task_progress = TaskProgress(self.action_name, total=None, start_time=time()) self.report_for_verified_only = course_grade_report_verified_only(self.course_id) + self.upload_parent_dir = _task_input.get('upload_parent_dir', '') + self.upload_filename = _task_input.get('filename', 'grade_report') @lazy def course(self): @@ -317,7 +319,8 @@ def __init__(self, _xmodule_instance_args, _entry_id, course_id, _task_input, ac self.course_id = course_id self.report_for_verified_only = problem_grade_report_verified_only(self.course_id) self.task_progress = TaskProgress(self.action_name, total=None, start_time=time()) - self.file_name = 'problem_grade_report' + self.upload_filename = _task_input.get('filename', 'problem_grade_report') + self.upload_dir = _task_input.get('upload_parent_dir', '') @lazy def course(self): @@ -485,10 +488,21 @@ def _upload(self, context, success_headers, success_rows, error_headers, error_r Creates and uploads a CSV for the given headers and rows. """ date = datetime.now(UTC) - upload_csv_to_report_store([success_headers] + success_rows, 'grade_report', context.course_id, date) + upload_csv_to_report_store( + [success_headers] + success_rows, + context.upload_filename, + context.course_id, + date, + parent_dir=context.upload_parent_dir + ) if len(error_rows) > 0: - error_rows = [error_headers] + error_rows - upload_csv_to_report_store(error_rows, 'grade_report_err', context.course_id, date) + upload_csv_to_report_store( + [error_headers] + error_rows, + '{}_err'.format(context.upload_filename), + context.course_id, + date, + parent_dir=context.upload_parent_dir + ) def _grades_header(self, context): """ diff --git a/lms/djangoapps/instructor_task/tasks_helper/utils.py b/lms/djangoapps/instructor_task/tasks_helper/utils.py index 07de2e8e9167..58fdd7d68b80 100644 --- a/lms/djangoapps/instructor_task/tasks_helper/utils.py +++ b/lms/djangoapps/instructor_task/tasks_helper/utils.py @@ -19,7 +19,7 @@ UPDATE_STATUS_SKIPPED = 'skipped' -def upload_csv_to_report_store(rows, csv_name, course_id, timestamp, config_name='GRADES_DOWNLOAD'): +def upload_csv_to_report_store(rows, csv_name, course_id, timestamp, config_name='GRADES_DOWNLOAD', parent_dir=''): """ Upload data as a CSV using ReportStore. @@ -32,6 +32,7 @@ def upload_csv_to_report_store(rows, csv_name, course_id, timestamp, config_name ] csv_name: Name of the resulting CSV course_id: ID of the course + parent_dor: Name of the directory where the CSV file will be stored Returns: report_name: string - Name of the generated report @@ -43,7 +44,7 @@ def upload_csv_to_report_store(rows, csv_name, course_id, timestamp, config_name timestamp_str=timestamp.strftime("%Y-%m-%d-%H%M") ) - report_store.store_rows(course_id, report_name, rows) + report_store.store_rows(course_id, report_name, rows, parent_dir) tracker_emit(csv_name) return report_name diff --git a/lms/djangoapps/instructor_task/tests/test_integration.py b/lms/djangoapps/instructor_task/tests/test_integration.py index 487246c9ee60..613c941d51f4 100644 --- a/lms/djangoapps/instructor_task/tests/test_integration.py +++ b/lms/djangoapps/instructor_task/tests/test_integration.py @@ -638,7 +638,7 @@ def test_both_groups_problems(self): self.submit_student_answer(self.student_b.username, problem_b_url, [OPTION_1, OPTION_2]) with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): - result = CourseGradeReport.generate(None, None, self.course.id, None, 'graded') + result = CourseGradeReport.generate(None, None, self.course.id, {}, 'graded') self.verify_csv_task_success(result) self.verify_grades_in_csv( [ @@ -671,7 +671,7 @@ def test_one_group_problem(self): self.submit_student_answer(self.student_a.username, problem_a_url, [OPTION_1, OPTION_1]) with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): - result = CourseGradeReport.generate(None, None, self.course.id, None, 'graded') + result = CourseGradeReport.generate(None, None, self.course.id, {}, 'graded') self.verify_csv_task_success(result) self.verify_grades_in_csv( [ diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index 77e8c4662adc..d799f35beb7c 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -100,7 +100,7 @@ def _verify_cell_data_for_user(self, username, course_id, column_header, expecte Verify cell data in the grades CSV for a particular user. """ with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): - result = CourseGradeReport.generate(None, None, course_id, None, 'graded') + result = CourseGradeReport.generate(None, None, course_id, {}, 'graded') self.assertDictContainsSubset({'attempted': num_rows, 'succeeded': num_rows, 'failed': 0}, result) report_store = ReportStore.from_config(config_name='GRADES_DOWNLOAD') report_csv_filename = report_store.links_for(course_id)[0][0] @@ -135,7 +135,7 @@ def test_unicode_emails(self, emails): self.current_task.update_state = Mock() with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task') as mock_current_task: mock_current_task.return_value = self.current_task - result = CourseGradeReport.generate(None, None, self.course.id, None, 'graded') + result = CourseGradeReport.generate(None, None, self.course.id, {}, 'graded') num_students = len(emails) self.assertDictContainsSubset({'attempted': num_students, 'succeeded': num_students, 'failed': 0}, result) @@ -149,7 +149,7 @@ def test_grading_failure(self, mock_grades_iter, _mock_current_task): mock_grades_iter.return_value = [ (self.create_student('username', 'student@example.com'), None, TypeError('Cannot grade student')) ] - result = CourseGradeReport.generate(None, None, self.course.id, None, 'graded') + result = CourseGradeReport.generate(None, None, self.course.id, {}, 'graded') self.assertDictContainsSubset({'attempted': 1, 'succeeded': 0, 'failed': 1}, result) report_store = ReportStore.from_config(config_name='GRADES_DOWNLOAD') @@ -333,7 +333,7 @@ def test_unicode_in_csv_header(self, mock_grades_iter, _mock_current_task): None, ) ] - result = CourseGradeReport.generate(None, None, self.course.id, None, 'graded') + result = CourseGradeReport.generate(None, None, self.course.id, {}, 'graded') self.assertDictContainsSubset({'attempted': 1, 'succeeded': 1, 'failed': 0}, result) def test_certificate_eligibility(self): @@ -415,7 +415,7 @@ def test_query_counts(self, store_type, mongo_count): with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): with check_mongo_calls(mongo_count): with self.assertNumQueries(expected_query_count): - CourseGradeReport.generate(None, None, course.id, None, 'graded') + CourseGradeReport.generate(None, None, course.id, {}, 'graded') def test_inactive_enrollments(self): """ @@ -429,7 +429,7 @@ def test_inactive_enrollments(self): with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task') as mock_current_task: mock_current_task.return_value = self.current_task - result = CourseGradeReport.generate(None, None, self.course.id, None, 'graded') + result = CourseGradeReport.generate(None, None, self.course.id, {}, 'graded') self._verify_cell_data_for_user('active-student', self.course.id, 'Enrollment Status', ENROLLED_IN_COURSE) self._verify_cell_data_for_user('inactive-student', self.course.id, 'Enrollment Status', NOT_ENROLLED_IN_COURSE) @@ -774,7 +774,7 @@ def test_no_problems(self, _get_current_task): Verify that we see no grade information for a course with no graded problems. """ - result = ProblemGradeReport.generate(None, None, self.course.id, None, 'graded') + result = ProblemGradeReport.generate(None, None, self.course.id, {}, 'graded') self.assertDictContainsSubset({'action_name': 'graded', 'attempted': 2, 'succeeded': 2, 'failed': 0}, result) self.verify_rows_in_csv([ dict(list(zip( @@ -797,8 +797,8 @@ def test_single_problem(self, _get_current_task): ) self.define_option_problem(u'Problem1', parent=vertical) - self.submit_student_answer(self.student_1.username, u'Problem1', ['Option 1']) - result = ProblemGradeReport.generate(None, None, self.course.id, None, 'graded') + self.submit_student_answer(self.student_1.username, 'Problem1', ['Option 1']) + result = ProblemGradeReport.generate(None, None, self.course.id, {}, 'graded') self.assertDictContainsSubset({'action_name': 'graded', 'attempted': 2, 'succeeded': 2, 'failed': 0}, result) problem_name = u'Homework 1: Subsection - Problem1' header_row = self.csv_header_row + [problem_name + ' (Earned)', problem_name + ' (Possible)'] @@ -840,9 +840,9 @@ def test_single_problem_verified_student_only(self, _get_current_task): ) self.define_option_problem(u'Problem1', parent=vertical) - self.submit_student_answer(self.student_1.username, u'Problem1', ['Option 1']) - self.submit_student_answer(student_verified.username, u'Problem1', ['Option 1']) - result = ProblemGradeReport.generate(None, None, self.course.id, None, 'graded') + self.submit_student_answer(self.student_1.username, 'Problem1', ['Option 1']) + self.submit_student_answer(student_verified.username, 'Problem1', ['Option 1']) + result = ProblemGradeReport.generate(None, None, self.course.id, {}, 'graded') self.assertDictContainsSubset( {'action_name': 'graded', 'attempted': 1, 'succeeded': 1, 'failed': 0}, result ) @@ -861,8 +861,8 @@ def test_inactive_enrollment_included(self, _get_current_task): ) self.define_option_problem(u'Problem1', parent=vertical) - self.submit_student_answer(self.student_1.username, u'Problem1', ['Option 1']) - result = ProblemGradeReport.generate(None, None, self.course.id, None, 'graded') + self.submit_student_answer(self.student_1.username, 'Problem1', ['Option 1']) + result = ProblemGradeReport.generate(None, None, self.course.id, {}, 'graded') self.assertDictContainsSubset({'action_name': 'graded', 'attempted': 3, 'succeeded': 3, 'failed': 0}, result) problem_name = u'Homework 1: Subsection - Problem1' header_row = self.csv_header_row + [problem_name + ' (Earned)', problem_name + ' (Possible)'] @@ -933,7 +933,7 @@ def test_problem_grade_report(self): self.submit_student_answer(self.student_b.username, self.problem_b_url, [self.OPTION_1, self.OPTION_2]) with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): - result = ProblemGradeReport.generate(None, None, self.course.id, None, 'graded') + result = ProblemGradeReport.generate(None, None, self.course.id, {}, 'graded') self.assertDictContainsSubset( {'action_name': 'graded', 'attempted': 2, 'succeeded': 2, 'failed': 0}, result ) @@ -1028,8 +1028,8 @@ def test_problem_grade_report_valid_columns_order(self): header_row += [problem + ' (Earned)', problem + ' (Possible)'] with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): - ProblemGradeReport.generate(None, None, self.course.id, None, 'graded') - self.assertEqual(self.get_csv_row_with_headers(), header_row) + ProblemGradeReport.generate(None, None, self.course.id, {}, 'graded') + assert self.get_csv_row_with_headers() == header_row class TestProblemReportCohortedContent(TestReportMixin, ContentGroupTestCase, InstructorTaskModuleTestCase): @@ -1085,7 +1085,7 @@ def test_cohort_content(self): self.submit_student_answer(self.beta_user.username, u'Problem1', ['Option 1', 'Option 2']) with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): - result = ProblemGradeReport.generate(None, None, self.course.id, None, 'graded') + result = ProblemGradeReport.generate(None, None, self.course.id, {}, 'graded') self.assertDictContainsSubset( {'action_name': 'graded', 'attempted': 5, 'succeeded': 5, 'failed': 0}, result ) @@ -1242,7 +1242,37 @@ def test_success(self): self.assertEqual(len(links), 1) self.assertDictContainsSubset({'attempted': 1, 'succeeded': 1, 'failed': 0}, result) - @ddt.data([u'student', u'student\xec']) + def test_custom_directory(self): + self.create_student('student', 'student@example.com') + directory_name = 'test_dir' + task_input = {'features': [], 'upload_parent_dir': directory_name} + patched_upload = patch('lms.djangoapps.instructor_task.tasks_helper.enrollments.upload_csv_to_report_store') + + with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): + with patched_upload as mock_upload_report: + upload_students_csv(None, None, self.course.id, task_input, 'calculated') + + mock_upload_report.assert_called_once_with( + [[], []], + 'student_profile_info', + self.course.id, + ANY, + parent_dir=directory_name + ) + + def test_custom_filename(self): + self.create_student('student', 'student@example.com') + filename = "test_filename" + task_input = {'features': [], 'filename': filename} + patched_upload = patch('lms.djangoapps.instructor_task.tasks_helper.enrollments.upload_csv_to_report_store') + + with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): + with patched_upload as mock_upload_report: + upload_students_csv(None, None, self.course.id, task_input, 'calculated') + + mock_upload_report.assert_called_once_with([[], []], filename, self.course.id, ANY, parent_dir='') + + @ddt.data(['student', 'student\xec']) def test_unicode_usernames(self, students): """ Test that students with unicode characters in their usernames @@ -1283,11 +1313,13 @@ def _generate_and_verify_teams_column(self, username, expected_team): """ Run the upload_students_csv task and verify that the correct team was added to the CSV. """ current_task = Mock() current_task.update_state = Mock() - task_input = [ - 'id', 'username', 'name', 'email', 'language', 'location', - 'year_of_birth', 'gender', 'level_of_education', 'mailing_address', - 'goals', 'team' - ] + task_input = { + 'features': [ + 'id', 'username', 'name', 'email', 'language', 'location', + 'year_of_birth', 'gender', 'level_of_education', 'mailing_address', + 'goals', 'team' + ] + } with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task') as mock_current_task: mock_current_task.return_value = current_task result = upload_students_csv(None, None, self.course.id, task_input, 'calculated') @@ -1716,7 +1748,7 @@ def test_grade_report(self, persistent_grades_enabled): with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'), \ patch.dict(settings.FEATURES, {'PERSISTENT_GRADES_ENABLED_FOR_ALL_TESTS': persistent_grades_enabled}): - result = CourseGradeReport.generate(None, None, self.course.id, None, 'graded') + result = CourseGradeReport.generate(None, None, self.course.id, {}, 'graded') self.assertDictContainsSubset( {'action_name': 'graded', 'attempted': 1, 'succeeded': 1, 'failed': 0}, result, @@ -1738,6 +1770,27 @@ def test_grade_report(self, persistent_grades_enabled): ignore_other_columns=True, ) + def test_grade_report_custom_directory(self): + self.submit_student_answer(self.student.username, 'Problem1', ['Option 1']) + + directory_name = "test_dir" + task_input = { + "upload_parent_dir": directory_name + } + + patched_upload = patch('lms.djangoapps.instructor_task.tasks_helper.grades.upload_csv_to_report_store') + with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): + with patched_upload as mock_upload_report: + CourseGradeReport.generate(None, None, self.course.id, task_input, 'graded') + + mock_upload_report.assert_called_once_with( + [ANY, ANY], + 'grade_report', + self.course.id, + ANY, + parent_dir=directory_name + ) + def test_grade_report_with_overrides(self): course_data = CourseData(self.student, course=self.course) subsection_grade = CreateSubsectionGrade(self.unattempted_section, course_data.structure, {}, {}) @@ -1754,7 +1807,7 @@ def test_grade_report_with_overrides(self): self.submit_student_answer(self.student.username, u'Problem1', ['Option 1']) with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): - result = CourseGradeReport.generate(None, None, self.course.id, None, 'graded') + result = CourseGradeReport.generate(None, None, self.course.id, {}, 'graded') self.assertDictContainsSubset( {'action_name': 'graded', 'attempted': 1, 'succeeded': 1, 'failed': 0}, result, @@ -1796,9 +1849,9 @@ def test_course_grade_with_verified_student_only(self, _get_current_task): ) self.define_option_problem(u'Problem1', parent=vertical) - self.submit_student_answer(student_1.username, u'Problem1', ['Option 1']) - self.submit_student_answer(student_verified.username, u'Problem1', ['Option 1']) - result = CourseGradeReport.generate(None, None, self.course.id, None, 'graded') + self.submit_student_answer(student_1.username, 'Problem1', ['Option 1']) + self.submit_student_answer(student_verified.username, 'Problem1', ['Option 1']) + result = CourseGradeReport.generate(None, None, self.course.id, {}, 'graded') self.assertDictContainsSubset( {'action_name': 'graded', 'attempted': 1, 'succeeded': 1, 'failed': 0}, result ) @@ -1810,7 +1863,7 @@ def test_fast_generation(self, create_non_zero_grade): with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'), \ patch('lms.djangoapps.grades.course_data.get_course_blocks') as mock_course_blocks, \ patch('lms.djangoapps.grades.subsection_grade.get_score') as mock_get_score: - CourseGradeReport.generate(None, None, self.course.id, None, 'graded') + CourseGradeReport.generate(None, None, self.course.id, {}, 'graded') assert not mock_course_blocks.called assert not mock_get_score.called @@ -1874,7 +1927,7 @@ def _verify_csv_data(self, username, expected_data): Verify grade report data. """ with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'): - CourseGradeReport.generate(None, None, self.course.id, None, 'graded') + CourseGradeReport.generate(None, None, self.course.id, {}, 'graded') report_store = ReportStore.from_config(config_name='GRADES_DOWNLOAD') report_csv_filename = report_store.links_for(self.course.id)[0][0] report_path = report_store.path_to(self.course.id, report_csv_filename) @@ -2582,8 +2635,8 @@ def test_report_stores_results(self): course_id_string = quote(text_type(self.course.id).replace('/', '_')) filename = u'{}_ORA_data_{}.csv'.format(course_id_string, timestamp_str) - self.assertEqual(return_val, UPDATE_STATUS_SUCCEEDED) - mock_store_rows.assert_called_once_with(self.course.id, filename, [test_header] + test_rows) + assert return_val == UPDATE_STATUS_SUCCEEDED + mock_store_rows.assert_called_once_with(self.course.id, filename, [test_header] + test_rows, '') class TestInstructorOra2AttachmentsExport(SharedModuleStoreTestCase):