Skip to content

Commit

Permalink
Merge branch 'main' into huniafatima/deprecate-edx-sphinx-theme
Browse files Browse the repository at this point in the history
  • Loading branch information
huniafatima-arbi authored Sep 2, 2024
2 parents 4ce5aac + 01b8d56 commit dfec69c
Show file tree
Hide file tree
Showing 17 changed files with 367 additions and 406 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-20.04]
python-version: ['3.8']
python-version: ['3.11']
toxenv: [django42, quality, pii_check]

steps:
Expand All @@ -38,7 +38,7 @@ jobs:
run: tox

- name: Run coverage
if: matrix.python-version == '3.8' && matrix.toxenv == 'django42'
if: matrix.python-version == '3.11' && matrix.toxenv == 'django42'
uses: py-cov-action/python-coverage-comment-action@v3
with:
GITHUB_TOKEN: ${{ github.token }}
Expand Down
53 changes: 25 additions & 28 deletions edx_exams/apps/core/management/commands/bulk_add_course_staff.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import time

from django.core.management.base import BaseCommand
from django.db import transaction
from django.db import IntegrityError, transaction

from edx_exams.apps.core.models import CourseStaffRole, User

Expand Down Expand Up @@ -63,34 +63,31 @@ def add_course_staff_from_csv(self, csv_file, batch_size, batch_delay):
Add the given set of course staff provided in csv
"""
reader = list(csv.DictReader(csv_file))
users = {}

# bulk create users
for i in range(0, len(reader), batch_size):
User.objects.bulk_create(
(User(
username=row.get('username'),
email=row.get('email'),
) for row in reader[i:i + batch_size]),
ignore_conflicts=True,
)
CourseStaffRole.objects.bulk_create(
(CourseStaffRole(
user=User.objects.get(username=row.get('username')),
course_id=row.get('course_id'),
role=row.get('role'),
) for row in reader[i:i + batch_size]),
ignore_conflicts=True,
)
users_list = []
for row in reader[i:i + batch_size]:
username = row.get('username')
email = row.get('email')
try:
users_list.append(User.objects.get_or_create(username=row.get('username'), email=row.get('email')))
except IntegrityError:
logger.warning(
f'User with username={username} and email={email} was not created due to an existing duplicate '
f'user with username.'
)
continue
users_dict = {(u.username, u) for (u, c) in users_list}
users.update(users_dict)
time.sleep(batch_delay)

# bulk create course staff
# for i in range(0, len(reader), batch_size):
# CourseStaffRole.objects.bulk_create(
# (CourseStaffRole(
# user=User.objects.get(username=row.get('username')),
# course_id=row.get('course_id'),
# role=row.get('role'),
# ) for row in reader[i:i + batch_size]),
# ignore_conflicts=True,
# )
# time.sleep(batch_delay)
CourseStaffRole.objects.bulk_create(
(CourseStaffRole(
user=users.get(row.get('username')),
course_id=row.get('course_id'),
role=row.get('role'),
) for row in reader),
ignore_conflicts=True,
batch_size=batch_size,
)
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def test_add_course_staff_with_not_default_batch_size(self):
'sam,[email protected],staff,course-v1:edx+test+f20\n']
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines)
with self.assertNumQueries(8):
with self.assertNumQueries(12):
call_command(self.command, f'--csv_path={csv.name}', '--batch_size=1')

def test_add_course_staff_with_batch_size_larger_than_list(self):
Expand All @@ -99,7 +99,7 @@ def test_add_course_staff_with_batch_size_larger_than_list(self):
'sam,[email protected],staff,course-v1:edx+test+f20\n']
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines)
with self.assertNumQueries(6):
with self.assertNumQueries(11):
call_command(self.command, f'--csv_path={csv.name}', '--batch_size=3')

def test_add_course_staff_with_batch_size_smaller_than_list(self):
Expand All @@ -109,7 +109,7 @@ def test_add_course_staff_with_batch_size_smaller_than_list(self):
'tam,[email protected],staff,course-v1:edx+test+f20\n']
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines)
with self.assertNumQueries(9):
with self.assertNumQueries(16):
call_command(self.command, f'--csv_path={csv.name}', '--batch_size=2')

def test_add_course_staff_with_not_default_batch_delay(self):
Expand All @@ -125,16 +125,16 @@ def test_add_course_staff_with_not_default_batch_delay(self):

def test_num_queries_correct(self):
"""
Assert the number of queries to be 4 + 1 * number of lines:
Assert the number of queries to be 2 + 1 * number of lines:
2 for savepoint/release savepoint
1 to bulk create users, 1 to bulk create course role
1 for each user (to get user)
1 to bulk create course role
4 for each user (to get user, and savepoints)
"""
num_lines = 20
lines = [f'pam{i},pam{i}@pond.com,staff,course-v1:edx+test+f20\n' for i in range(num_lines)]
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines)
with self.assertNumQueries(4 + num_lines):
with self.assertNumQueries(3 + 4 * num_lines):
call_command(self.command, f'--csv_path={csv.name}')

def test_dupe_user_csv(self):
Expand Down
63 changes: 63 additions & 0 deletions edx_exams/apps/core/migrations/0028_admin_optional_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Generated by Django 4.2.13 on 2024-08-21 13:32

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('core', '0027_coursestaffrole_unique_course_staff_role'),
]

operations = [
migrations.AlterField(
model_name='exam',
name='due_date',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AlterField(
model_name='examattempt',
name='end_time',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AlterField(
model_name='examattempt',
name='start_time',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AlterField(
model_name='historicalexam',
name='due_date',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AlterField(
model_name='historicalexamattempt',
name='end_time',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AlterField(
model_name='historicalexamattempt',
name='start_time',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AlterField(
model_name='proctoringprovider',
name='org_key',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AlterField(
model_name='proctoringprovider',
name='tech_support_email',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AlterField(
model_name='proctoringprovider',
name='tech_support_phone',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AlterField(
model_name='proctoringprovider',
name='tech_support_url',
field=models.URLField(blank=True, max_length=255, null=True),
),
]
14 changes: 7 additions & 7 deletions edx_exams/apps/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,13 @@ class ProctoringProvider(TimeStampedModel):

lti_configuration_id = models.CharField(max_length=255, db_index=True)

org_key = models.CharField(max_length=255, null=True)
org_key = models.CharField(max_length=255, null=True, blank=True)

tech_support_phone = models.CharField(max_length=255, null=True)
tech_support_phone = models.CharField(max_length=255, null=True, blank=True)

tech_support_email = models.CharField(max_length=255, null=True)
tech_support_email = models.CharField(max_length=255, null=True, blank=True)

tech_support_url = models.URLField(max_length=255, null=True)
tech_support_url = models.URLField(max_length=255, null=True, blank=True)

class Meta:
""" Meta class for this Django model """
Expand Down Expand Up @@ -140,7 +140,7 @@ class Exam(TimeStampedModel):
time_limit_mins = models.PositiveIntegerField()

# Due date is a deadline to finish the exam
due_date = models.DateTimeField(null=True)
due_date = models.DateTimeField(null=True, blank=True)

# Whether to hide this exam after the due date
hide_after_due = models.BooleanField(default=False)
Expand Down Expand Up @@ -208,9 +208,9 @@ class ExamAttempt(TimeStampedModel):

status = models.CharField(max_length=64, choices=[(status, status) for status in STATUS_CHOICES])

start_time = models.DateTimeField(null=True)
start_time = models.DateTimeField(null=True, blank=True)

end_time = models.DateTimeField(null=True)
end_time = models.DateTimeField(null=True, blank=True)

allowed_time_limit_mins = models.IntegerField(null=True)

Expand Down
Loading

0 comments on commit dfec69c

Please sign in to comment.