fix: Restructuring to send course_id and score to edx submission fix: Refactoring of sending information to sent_to_submission fix: Elimination of unnecessary functions fix: Added usage comment to ProblemBlock in XqueueInterface constructor fix: update doc ADR fix: setting for Quality Others test (ubuntu-24.04, 3.11, 20) fix: Deprecation for django-trans-escape-filter-parse-error test: Add @pytest.mark.django_db decorator to test functions test: Fix for pylint being disabled fix: updated changes for pylint disable fix: update error from docs ADR-0005 update: xmodule/docs/decisions/0005-send-data-to-edx-submission.rst Co-authored-by: Sarina Canelake <sarina@axim.org> update: xmodule/docs/decisions/0005-send-data-to-edx-submission.rst Co-authored-by: Sarina Canelake <sarina@axim.org> fix: Adjusted correction fix: update date for docs ADR Revert "fix: update date for docs ADR" This reverts commit 0b4229c51c4937f95cb407872645dd448df45418. fix: replace call created_submission to create_external_grader_detail fix: update test xqueue_submission fix: add docstring in test_xqueue_submission fix: update date doc ADR fix: update version edx-submission 3.8.6 fix: add @pytest.mark.xfail fix: add 20 chances in test_capa_block: fix: increase retry attempts for seed generation in ProblemBlockTest fix: change version to edx-submission lib fix: new version edx-submission in testings fix: replace parameter file to files fix: update variable grader_file_name and points_possible fix: Adjustment in the is_flag_active function to always take the last record edited in the waffle fix: wrap large line of code fix: update function is_flag_active fix: code style adjustment fix: changes for 60 retry feat: use CourseWaffleFlag to determine xqueue callback path fix: Code style adjustment fix: remove deprecated xqueue callback route and simplify callback type logic fix: Deleting a comment in the ADR document fix: add log in self.block is None fix: Code style adjustment in log
118 lines
3.9 KiB
Python
118 lines
3.9 KiB
Python
"""
|
|
Unit tests for the XQueueInterfaceSubmission class.
|
|
"""
|
|
import json
|
|
import pytest
|
|
from unittest.mock import Mock, patch
|
|
from xmodule.capa.xqueue_submission import XQueueInterfaceSubmission
|
|
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
|
|
from xblock.fields import ScopeIds
|
|
|
|
|
|
@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):
|
|
"""
|
|
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):
|
|
"""
|
|
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)
|
|
|
|
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',
|
|
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):
|
|
"""
|
|
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)
|
|
|
|
assert "error" in result
|
|
assert "Validation error" in result["error"]
|
|
mock_create_external_grader_detail.assert_not_called()
|