Files
edx-platform/xmodule/capa/tests/test_xqueue_submission.py
2026-01-07 16:39:11 +05:00

126 lines
4.2 KiB
Python

"""
Unit tests for the XQueueInterfaceSubmission class.
"""
import json
from unittest.mock import Mock, patch
import pytest
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xblock.fields import ScopeIds
from xmodule.capa.xqueue_submission import XQueueInterfaceSubmission
@pytest.fixture
def xqueue_service():
"""
Fixture that returns an instance of XQueueInterfaceSubmission.
"""
location = BlockUsageLocator(CourseLocator("test_org", "test_course", "test_run"), "problem", "ExampleProblem")
block = Mock(scope_ids=ScopeIds("user1", "problem", location, location))
block.max_score = Mock(return_value=10)
return XQueueInterfaceSubmission(block)
def test_get_submission_params(xqueue_service): # pylint: disable=redefined-outer-name
"""
Test extracting item data from an xqueue submission.
"""
header = json.dumps({"lms_callback_url": "http://example.com/callback", "queue_name": "default"})
payload = json.dumps(
{
"student_info": json.dumps({"anonymous_student_id": "student_id"}),
"student_response": "student_answer",
"grader_payload": json.dumps({"grader": "test.py"}),
}
)
student_item, student_answer, queue_name, grader_file_name, points_possible = xqueue_service.get_submission_params(
header, payload
)
assert student_item == {
"item_id": "block-v1:test_org+test_course+test_run+type@problem+block@ExampleProblem",
"item_type": "problem",
"course_id": "course-v1:test_org+test_course+test_run",
"student_id": "student_id",
}
assert student_answer == "student_answer"
assert queue_name == "default"
assert grader_file_name == "test.py"
assert points_possible == 10
@pytest.mark.django_db
@patch("submissions.api.create_external_grader_detail")
def test_send_to_submission(mock_create_external_grader_detail, xqueue_service): # pylint: disable=redefined-outer-name
"""
Test sending a submission to the grading system.
"""
header = json.dumps(
{
"lms_callback_url": (
"http://example.com/courses/course-v1:test_org+test_course+test_run/xqueue/5/"
"block-v1:test_org+test_course+test_run+type@problem+block@ExampleProblem/"
),
}
)
body = json.dumps(
{
"student_info": json.dumps({"anonymous_student_id": "student_id"}),
"student_response": "student_answer",
"grader_payload": json.dumps({"grader": "test.py"}),
}
)
mock_response = {"submission": "mock_submission"}
mock_create_external_grader_detail.return_value = mock_response
result = xqueue_service.send_to_submission(header, body, queue_key="default")
assert result == mock_response
mock_create_external_grader_detail.assert_called_once_with(
{
"item_id": "block-v1:test_org+test_course+test_run+type@problem+block@ExampleProblem",
"item_type": "problem",
"course_id": "course-v1:test_org+test_course+test_run",
"student_id": "student_id",
},
"student_answer",
queue_name="default",
queue_key="default",
grader_file_name="test.py",
points_possible=10,
files=None,
)
@pytest.mark.django_db
@patch("submissions.api.create_external_grader_detail")
def test_send_to_submission_with_missing_fields(
mock_create_external_grader_detail, xqueue_service
): # pylint: disable=redefined-outer-name
"""
Test send_to_submission with missing required fields.
"""
header = json.dumps(
{
"lms_callback_url": (
"http://example.com/courses/course-v1:test_org+test_course+test_run/xqueue/5/" "block@item_id/"
)
}
)
body = json.dumps(
{
"student_info": json.dumps({"anonymous_student_id": "student_id"}),
"grader_payload": json.dumps({"grader": "test.py"}),
}
)
result = xqueue_service.send_to_submission(header, body, queue_key="default")
assert "error" in result
assert "Validation error" in result["error"]
mock_create_external_grader_detail.assert_not_called()