Commit c4461191 by Sanford Student

reset grades management command choose database

parent 067348b8
...@@ -65,6 +65,12 @@ class Command(BaseCommand): ...@@ -65,6 +65,12 @@ class Command(BaseCommand):
dest='modified_end', dest='modified_end',
help='Ending range for modified date (inclusive): e.g. "2016-12-23 16:43"', help='Ending range for modified date (inclusive): e.g. "2016-12-23 16:43"',
) )
parser.add_argument(
'--db_table',
dest='db_table',
help='Specify "subsection" to reset subsection grades or "course" to reset course grades. If absent, both '
'are reset.',
)
def handle(self, *args, **options): def handle(self, *args, **options):
course_keys = None course_keys = None
...@@ -73,6 +79,9 @@ class Command(BaseCommand): ...@@ -73,6 +79,9 @@ class Command(BaseCommand):
run_mode = get_mutually_exclusive_required_option(options, 'delete', 'dry_run') run_mode = get_mutually_exclusive_required_option(options, 'delete', 'dry_run')
courses_mode = get_mutually_exclusive_required_option(options, 'courses', 'all_courses') courses_mode = get_mutually_exclusive_required_option(options, 'courses', 'all_courses')
db_table = options.get('db_table')
if db_table not in {'subsection', 'course', None}:
raise CommandError('Invalid value for db_table. Valid options are "subsection" or "course" only.')
if options.get('modified_start'): if options.get('modified_start'):
modified_start = datetime.strptime(options['modified_start'], DATE_FORMAT) modified_start = datetime.strptime(options['modified_start'], DATE_FORMAT)
...@@ -89,7 +98,10 @@ class Command(BaseCommand): ...@@ -89,7 +98,10 @@ class Command(BaseCommand):
operation = self._query_grades if run_mode == 'dry_run' else self._delete_grades operation = self._query_grades if run_mode == 'dry_run' else self._delete_grades
if db_table == 'subsection' or db_table is None:
operation(PersistentSubsectionGrade, course_keys, modified_start, modified_end) operation(PersistentSubsectionGrade, course_keys, modified_start, modified_end)
if db_table == 'course' or db_table is None:
operation(PersistentCourseGrade, course_keys, modified_start, modified_end) operation(PersistentCourseGrade, course_keys, modified_start, modified_end)
log.info("reset_grade: Finished in %s mode!", run_mode) log.info("reset_grade: Finished in %s mode!", run_mode)
......
...@@ -94,23 +94,27 @@ class TestResetGrades(TestCase): ...@@ -94,23 +94,27 @@ class TestResetGrades(TestCase):
subsection_grade_params['usage_key'] = subsection_key subsection_grade_params['usage_key'] = subsection_key
PersistentSubsectionGrade.update_or_create_grade(**subsection_grade_params) PersistentSubsectionGrade.update_or_create_grade(**subsection_grade_params)
def _assert_grades_exist_for_courses(self, course_keys): def _assert_grades_exist_for_courses(self, course_keys, db_table=None):
""" """
Assert grades for given courses exist. Assert grades for given courses exist.
""" """
for course_key in course_keys: for course_key in course_keys:
if db_table == "course" or db_table is None:
self.assertIsNotNone(PersistentCourseGrade.read_course_grade(self.user_ids[0], course_key)) self.assertIsNotNone(PersistentCourseGrade.read_course_grade(self.user_ids[0], course_key))
if db_table == "subsection" or db_table is None:
for subsection_key in self.subsection_keys_by_course[course_key]: for subsection_key in self.subsection_keys_by_course[course_key]:
self.assertIsNotNone(PersistentSubsectionGrade.read_grade(self.user_ids[0], subsection_key)) self.assertIsNotNone(PersistentSubsectionGrade.read_grade(self.user_ids[0], subsection_key))
def _assert_grades_absent_for_courses(self, course_keys): def _assert_grades_absent_for_courses(self, course_keys, db_table=None):
""" """
Assert grades for given courses do not exist. Assert grades for given courses do not exist.
""" """
for course_key in course_keys: for course_key in course_keys:
if db_table == "course" or db_table is None:
with self.assertRaises(PersistentCourseGrade.DoesNotExist): with self.assertRaises(PersistentCourseGrade.DoesNotExist):
PersistentCourseGrade.read_course_grade(self.user_ids[0], course_key) PersistentCourseGrade.read_course_grade(self.user_ids[0], course_key)
if db_table == "subsection" or db_table is None:
for subsection_key in self.subsection_keys_by_course[course_key]: for subsection_key in self.subsection_keys_by_course[course_key]:
with self.assertRaises(PersistentSubsectionGrade.DoesNotExist): with self.assertRaises(PersistentSubsectionGrade.DoesNotExist):
PersistentSubsectionGrade.read_grade(self.user_ids[0], subsection_key) PersistentSubsectionGrade.read_grade(self.user_ids[0], subsection_key)
...@@ -222,6 +226,17 @@ class TestResetGrades(TestCase): ...@@ -222,6 +226,17 @@ class TestResetGrades(TestCase):
self._assert_grades_absent_for_courses(self.course_keys[:2]) self._assert_grades_absent_for_courses(self.course_keys[:2])
self._assert_grades_exist_for_courses(self.course_keys[2:]) self._assert_grades_exist_for_courses(self.course_keys[2:])
@ddt.data('subsection', 'course')
def test_specify_db_table(self, db_table):
self._update_or_create_grades()
self._assert_grades_exist_for_courses(self.course_keys)
self.command.handle(delete=True, all_courses=True, db_table=db_table)
self._assert_grades_absent_for_courses(self.course_keys, db_table=db_table)
if db_table == "subsection":
self._assert_grades_exist_for_courses(self.course_keys, db_table='course')
else:
self._assert_grades_exist_for_courses(self.course_keys, db_table='subsection')
@patch('lms.djangoapps.grades.management.commands.reset_grades.log') @patch('lms.djangoapps.grades.management.commands.reset_grades.log')
def test_dry_run_all_courses(self, mock_log): def test_dry_run_all_courses(self, mock_log):
self._update_or_create_grades() self._update_or_create_grades()
...@@ -279,6 +294,13 @@ class TestResetGrades(TestCase): ...@@ -279,6 +294,13 @@ class TestResetGrades(TestCase):
with self.assertRaisesRegexp(CommandError, 'Invalid key specified.*invalid/key'): with self.assertRaisesRegexp(CommandError, 'Invalid key specified.*invalid/key'):
self.command.handle(dry_run=True, courses=['invalid/key']) self.command.handle(dry_run=True, courses=['invalid/key'])
def test_invalid_db_table(self):
with self.assertRaisesMessage(
CommandError,
'Invalid value for db_table. Valid options are "subsection" or "course" only.'
):
self.command.handle(delete=True, all_courses=True, db_table="not course or subsection")
def test_no_run_mode(self): def test_no_run_mode(self):
with self.assertRaisesMessage(CommandError, 'Either --delete or --dry_run must be specified.'): with self.assertRaisesMessage(CommandError, 'Either --delete or --dry_run must be specified.'):
self.command.handle(all_courses=True) self.command.handle(all_courses=True)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment