fix: add missing staff_ora_grading_url field to ORA list endpoint (#37937)

This commit is contained in:
Daniel Wong
2026-01-29 11:36:38 -06:00
committed by GitHub
parent 12c1542e5e
commit abc0853e1b
4 changed files with 94 additions and 1 deletions

View File

@@ -220,6 +220,7 @@ definitions:
- waiting
- staff
- final_grade_received
- staff_ora_grading_url
properties:
block_id:
type: string
@@ -268,7 +269,11 @@ definitions:
minimum: 0
description: Responses with final grade assigned
example: 20
staff_ora_grading_url:
type: string
format: uri
description: URL to the staff grading interface for this ORA assessment
example: "http://apps.local.openedx.io:1993/ora-grading/block-v1:WGU+CS002+2025_T1+type@openassessment+block@ff4f5fddf42d4b9787e69c1a8cbeb058"
Error:
type: object
description: Error response

View File

@@ -1,6 +1,8 @@
"""Utilities for retrieving Open Response Assessments (ORAs) data for instructor dashboards."""
from django.utils.translation import gettext as _
from django.conf import settings
from openassessment.data import OraAggregateData
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
@@ -37,6 +39,7 @@ def get_open_response_assessment_list(course):
parents_cache = {}
ora_items = []
ora_grading_base_url = getattr(settings, 'ORA_GRADING_MICROFRONTEND_URL', None)
for block in openassessment_blocks:
block_id = str(block.location)
@@ -54,10 +57,28 @@ def get_open_response_assessment_list(course):
else block.display_name
)
staff_ora_grading_url = None
has_staff_assessment = 'staff-assessment' in block.assessment_steps
is_team_enabled = block.teams_enabled
if ora_grading_base_url and has_staff_assessment and not is_team_enabled:
# Always generate a URL that points to the ORA Grading Microfrontend (MFE).
#
# During the migration to the ORA microfrontend,
# only provide the grading URL for non-team assignments with staff assessment.
# This logic was based on the original implementation in instructor_dashboard:
# - lms/djangoapps/instructor/views/instructor_dashboard.py
# (_section_open_response_assessment)
# - edx-ora2:
# https://github.com/openedx/edx-ora2/blob/801fbd14ebb059ab8c5ee8d5a39c260c7f87ab81/
# openassessment/xblock/static/js/src/lms/oa_course_items_listing.js#L73
staff_ora_grading_url = f"{ora_grading_base_url}/{block_id}"
ora_assessment_data = {
'id': block_id,
'name': assessment_name,
'parent_name': parent_block.display_name,
'staff_ora_grading_url': staff_ora_grading_url,
**DEFAULT_ORA_METRICS,
}

View File

@@ -960,6 +960,72 @@ class ORAViewTest(ORABaseViewsTest):
assert ora_data['waiting'] == 0
assert ora_data['staff'] == 0
assert ora_data['final_grade_received'] == 0
assert ora_data['staff_ora_grading_url'] is None
@patch("lms.djangoapps.instructor.ora.modulestore")
def test_get_assessment_list_includes_staff_ora_grading_url_for_non_team_assignment(
self, mock_modulestore
):
"""
Retrieve ORA assessments and ensure staff grading URL is included
for non-team assignments with staff assessment enabled.
"""
mock_store = Mock()
mock_assessment_block = Mock(
location=self.ora_block.location,
parent=Mock(),
teams_enabled=False,
assessment_steps=["staff-assessment"],
)
mock_store.get_items.return_value = [mock_assessment_block]
mock_modulestore.return_value = mock_store
response = self.client.get(self._get_url())
assert response.status_code == 200
results = response.data["results"]
assert len(results) == 1
ora_data = results[0]
assert "staff_ora_grading_url" in ora_data
assert ora_data["staff_ora_grading_url"]
@patch("lms.djangoapps.instructor.ora.modulestore")
def test_get_assessment_list_includes_staff_ora_grading_url_for_team_assignment(
self, mock_modulestore
):
"""
Retrieve ORA assessments and ensure staff grading URL is included
for team assignments with staff assessment enabled.
"""
mock_store = Mock()
mock_assessment_block = Mock(
location=self.ora_block.location,
parent=Mock(),
teams_enabled=True,
display_name="Team Assignment",
assessment_steps=["staff-assessment"],
)
mock_store.get_items.return_value = [mock_assessment_block]
mock_modulestore.return_value = mock_store
response = self.client.get(self._get_url())
assert response.status_code == 200
results = response.data["results"]
assert len(results) == 1
ora_data = results[0]
assert "staff_ora_grading_url" in ora_data
assert ora_data["staff_ora_grading_url"] is None
def test_invalid_course_id(self):
"""Test error handling for invalid course ID."""

View File

@@ -460,6 +460,7 @@ class ORASerializer(serializers.Serializer):
waiting = serializers.IntegerField()
staff = serializers.IntegerField()
final_grade_received = serializers.IntegerField(source="done")
staff_ora_grading_url = serializers.URLField(allow_null=True)
class ORASummarySerializer(serializers.Serializer):