From ca983aa14bbc1e33d3cdcc722513548280c14739 Mon Sep 17 00:00:00 2001 From: Simon Chen Date: Wed, 17 Nov 2021 10:21:01 -0500 Subject: [PATCH] fix: add SimpleHistory child model to proctoring_proctoredexam model (#1003) MST-1101 Add the SimpleHistory table to the proctoring_proctoredexam table to capture exam changes with history records Co-authored-by: Simon Chen --- .annotation_safe_list.yml | 2 + CHANGELOG.rst | 4 ++ edx_proctoring/__init__.py | 2 +- .../0023_historicalproctoredexam.py | 50 +++++++++++++++++++ edx_proctoring/models.py | 3 ++ edx_proctoring/tests/test_models.py | 17 +++++++ package.json | 2 +- 7 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 edx_proctoring/migrations/0023_historicalproctoredexam.py diff --git a/.annotation_safe_list.yml b/.annotation_safe_list.yml index 18b4091b870..67dcf926852 100644 --- a/.annotation_safe_list.yml +++ b/.annotation_safe_list.yml @@ -28,3 +28,5 @@ sessions.Session: # Automatically generated models that cannot be annotated edx_proctoring.HistoricalProctoredExamStudentAttempt: ".. no_pii": "This model has no PII" +edx_proctoring.HistoricalProctoredExam: + ".. no_pii": "This model has no PII" diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2bc32bca12f..6bf39b2d6c3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,10 @@ Change Log Unreleased ~~~~~~~~~~ +[4.7.2] - 2021-11-17 +~~~~~~~~~~~~~~~~~~~~ +* Add SimpleHistory to proctoring_proctoredexam table + [4.7.1] - 2021-11-16 ~~~~~~~~~~~~~~~~~~~~ * Assign interstitial to timed exam status diff --git a/edx_proctoring/__init__.py b/edx_proctoring/__init__.py index 9b63b889c6f..b806e5de885 100644 --- a/edx_proctoring/__init__.py +++ b/edx_proctoring/__init__.py @@ -3,6 +3,6 @@ """ # Be sure to update the version number in edx_proctoring/package.json -__version__ = '4.7.1' +__version__ = '4.7.2' default_app_config = 'edx_proctoring.apps.EdxProctoringConfig' # pylint: disable=invalid-name diff --git a/edx_proctoring/migrations/0023_historicalproctoredexam.py b/edx_proctoring/migrations/0023_historicalproctoredexam.py new file mode 100644 index 00000000000..24028508808 --- /dev/null +++ b/edx_proctoring/migrations/0023_historicalproctoredexam.py @@ -0,0 +1,50 @@ +# Generated by Django 2.2.24 on 2021-11-16 21:03 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import model_utils.fields +import simple_history.models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('edx_proctoring', '0022_proctoredexamstudentattempt_add_readytoresume_resumed'), + ] + + operations = [ + migrations.CreateModel( + name='HistoricalProctoredExam', + fields=[ + ('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')), + ('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')), + ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')), + ('course_id', models.CharField(db_index=True, max_length=255)), + ('content_id', models.CharField(db_index=True, max_length=255)), + ('external_id', models.CharField(db_index=True, max_length=255, null=True)), + ('exam_name', models.TextField()), + ('time_limit_mins', models.IntegerField()), + ('due_date', models.DateTimeField(null=True)), + ('is_proctored', models.BooleanField(default=False)), + ('is_practice_exam', models.BooleanField(default=False)), + ('is_active', models.BooleanField(default=False)), + ('hide_after_due', models.BooleanField(default=False)), + ('backend', models.CharField(default=None, max_length=255, null=True)), + ('history_id', models.AutoField(primary_key=True, serialize=False)), + ('history_date', models.DateTimeField()), + ('history_change_reason', models.CharField(max_length=100, null=True)), + ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)), + ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'historical proctored exam', + 'db_table': 'proctoring_proctoredexamhistory', + 'ordering': ('-history_date', '-history_id'), + 'get_latest_by': 'history_date', + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + ] diff --git a/edx_proctoring/models.py b/edx_proctoring/models.py index 8d72a8f97f4..75dee0437a1 100644 --- a/edx_proctoring/models.py +++ b/edx_proctoring/models.py @@ -70,6 +70,9 @@ class ProctoredExam(TimeStampedModel): # override the platform default backend choice backend = models.CharField(max_length=255, null=True, default=None) + # This is the reference to the SimpleHistory table + history = HistoricalRecords(table_name='proctoring_proctoredexamhistory') + class Meta: """ Meta class for this Django model """ unique_together = (('course_id', 'content_id'),) diff --git a/edx_proctoring/tests/test_models.py b/edx_proctoring/tests/test_models.py index 2f2d7495a19..17909103393 100644 --- a/edx_proctoring/tests/test_models.py +++ b/edx_proctoring/tests/test_models.py @@ -57,6 +57,23 @@ def test_unicode(self): output = str(policy) self.assertEqual(output, "ProctoredExamReviewPolicy: tester (test_course: अआईउऊऋऌ अआईउऊऋऌ (inactive))") + def test_history(self): + proctored_exam = ProctoredExam.objects.create( + course_id='test_course', + content_id='test_content', + exam_name='test_exam_name', + external_id='test_id', + time_limit_mins=60 + ) + + self.assertEqual(len(proctored_exam.history.filter(course_id='test_course', content_id='test_content')), 1) + + proctored_exam.external_id = 'test_id_2' + proctored_exam.backend = 'proctortrack' + proctored_exam.save() + + self.assertEqual(len(proctored_exam.history.filter(course_id='test_course', content_id='test_content')), 2) + def test_save_proctored_exam_student_allowance_history(self): # pylint: disable=invalid-name """ Test to Save and update the proctored Exam Student Allowance object. diff --git a/package.json b/package.json index d705d3c471e..f7d4d7f8a5c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@edx/edx-proctoring", "//": "Note that the version format is slightly different than that of the Python version when using prereleases.", - "version": "4.7.1", + "version": "4.7.2", "main": "edx_proctoring/static/index.js", "scripts": { "test": "gulp test"