Skip to content

Commit 066c845

Browse files
committed
feat: add tests for submit_student_enrollment_batch api function
1 parent 23ba9e4 commit 066c845

1 file changed

Lines changed: 105 additions & 4 deletions

File tree

lms/djangoapps/instructor_task/tests/test_api.py

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@
33
"""
44

55
import datetime
6+
import hashlib
67
import json
8+
from unittest import mock
79
from unittest.mock import MagicMock, Mock, patch
810
from uuid import uuid4
911

12+
import ddt
1013
import pytest
1114
import pytz
12-
import ddt
13-
from testfixtures import LogCapture
1415
from celery.states import FAILURE, SUCCESS
15-
from xmodule.modulestore.exceptions import ItemNotFoundError
16+
from django.http import HttpRequest
17+
from opaque_keys.edx.keys import CourseKey
18+
from testfixtures import LogCapture
1619

1720
from common.djangoapps.student.tests.factories import UserFactory
1821
from common.test.utils import normalize_repr
@@ -44,6 +47,7 @@
4447
submit_rescore_problem_for_student,
4548
submit_reset_problem_attempts_for_all_students,
4649
submit_reset_problem_attempts_in_entrance_exam,
50+
submit_student_enrollment_batch,
4751
)
4852
from lms.djangoapps.instructor_task.api_helper import AlreadyRunningError, QueueConnectionError
4953
from lms.djangoapps.instructor_task.data import InstructorTaskTypes
@@ -52,15 +56,17 @@
5256
export_ora2_data,
5357
export_ora2_submission_files,
5458
generate_anonymous_ids_for_course,
59+
student_enrollment_batch,
5560
)
5661
from lms.djangoapps.instructor_task.tests.factories import InstructorTaskFactory, InstructorTaskScheduleFactory
5762
from lms.djangoapps.instructor_task.tests.test_base import (
5863
TEST_COURSE_KEY,
5964
InstructorTaskCourseTestCase,
6065
InstructorTaskModuleTestCase,
6166
InstructorTaskTestCase,
62-
TestReportMixin
67+
TestReportMixin,
6368
)
69+
from xmodule.modulestore.exceptions import ItemNotFoundError
6470

6571
LOG_PATH = 'lms.djangoapps.instructor_task.api'
6672

@@ -528,3 +534,98 @@ def test_process_scheduled_tasks_expect_error(self, mock_scheduled_task):
528534
process_scheduled_instructor_tasks()
529535

530536
log.check_present((LOG_PATH, "ERROR", expected_messages[0]),)
537+
538+
539+
class SubmitStudentEnrollmentBatchTests(InstructorTaskCourseTestCase):
540+
"""
541+
Tests for the submit_student_enrollment_batch API function.
542+
"""
543+
544+
def setUp(self):
545+
self.request = HttpRequest()
546+
self.course_key = CourseKey.from_string("course-v1:edX+DemoX+2025")
547+
548+
@mock.patch("lms.djangoapps.instructor_task.api.submit_task")
549+
def test_basic_submission(self, mock_submit_task):
550+
"""
551+
Basic test with <= 5 identifiers.
552+
Verifies: task_input, task_type, task_class, task_key.
553+
"""
554+
identifiers = ["u1", "u2", "username3@example.com"]
555+
action = "enroll"
556+
mock_submit_task.return_value = "task-result"
557+
expected_input = {
558+
"action": action,
559+
"identifiers": identifiers,
560+
"auto_enroll": True,
561+
"email_students": False,
562+
"reason": "test",
563+
"secure": True,
564+
}
565+
566+
result = submit_student_enrollment_batch(
567+
request=self.request,
568+
course_key=self.course_key,
569+
action=action,
570+
identifiers=identifiers,
571+
auto_enroll=True,
572+
email_students=False,
573+
reason="test",
574+
secure=True,
575+
)
576+
577+
self.assertEqual(result, "task-result")
578+
key_stub = f"{self.course_key}_{action}_{'_'.join(identifiers)}"
579+
expected_key = hashlib.md5(key_stub.encode("utf-8")).hexdigest()
580+
mock_submit_task.assert_called_once_with(
581+
self.request,
582+
InstructorTaskTypes.STUDENT_ENROLLMENT_BATCH,
583+
student_enrollment_batch,
584+
self.course_key,
585+
expected_input,
586+
expected_key,
587+
)
588+
589+
@mock.patch("lms.djangoapps.instructor_task.api.submit_task")
590+
def test_identifiers_are_truncated_to_5_for_key(self, mock_submit_task):
591+
"""
592+
When identifiers > 5, only first 5 go into the task_key.
593+
"""
594+
identifiers = ["u1", "u2", "u3", "u4", "u5", "u6", "u7"]
595+
596+
submit_student_enrollment_batch(
597+
request=self.request,
598+
course_key=self.course_key,
599+
action="unenroll",
600+
identifiers=identifiers,
601+
auto_enroll=False,
602+
email_students=True,
603+
reason=None,
604+
secure=False,
605+
)
606+
607+
truncated = identifiers[:5]
608+
key_stub = f"{self.course_key}_unenroll_{'_'.join(truncated)}"
609+
expected_key = hashlib.md5(key_stub.encode("utf-8")).hexdigest()
610+
call_args = mock_submit_task.call_args[0]
611+
received_key = call_args[5]
612+
self.assertEqual(received_key, expected_key)
613+
614+
@mock.patch("lms.djangoapps.instructor_task.api.submit_task")
615+
def test_already_running_error_is_propagated(self, mock_submit_task):
616+
"""
617+
submit_task may raise AlreadyRunningError; our function should not swallow it.
618+
"""
619+
mock_submit_task.side_effect = AlreadyRunningError("Task already running")
620+
621+
with self.assertRaises(AlreadyRunningError):
622+
submit_student_enrollment_batch(
623+
request=self.request,
624+
course_key=self.course_key,
625+
action="enroll",
626+
identifiers=["john"],
627+
auto_enroll=False,
628+
email_students=False,
629+
reason=None,
630+
secure=False,
631+
)

0 commit comments

Comments
 (0)