Skip to content

Commit abc0853

Browse files
authored
fix: add missing staff_ora_grading_url field to ORA list endpoint (#37937)
1 parent 12c1542 commit abc0853

4 files changed

Lines changed: 94 additions & 1 deletion

File tree

lms/djangoapps/instructor/docs/references/instructor-v2-ora-api-spec.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ definitions:
220220
- waiting
221221
- staff
222222
- final_grade_received
223+
- staff_ora_grading_url
223224
properties:
224225
block_id:
225226
type: string
@@ -268,7 +269,11 @@ definitions:
268269
minimum: 0
269270
description: Responses with final grade assigned
270271
example: 20
271-
272+
staff_ora_grading_url:
273+
type: string
274+
format: uri
275+
description: URL to the staff grading interface for this ORA assessment
276+
example: "http://apps.local.openedx.io:1993/ora-grading/block-v1:WGU+CS002+2025_T1+type@openassessment+block@ff4f5fddf42d4b9787e69c1a8cbeb058"
272277
Error:
273278
type: object
274279
description: Error response

lms/djangoapps/instructor/ora.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Utilities for retrieving Open Response Assessments (ORAs) data for instructor dashboards."""
22

33
from django.utils.translation import gettext as _
4+
from django.conf import settings
5+
46
from openassessment.data import OraAggregateData
57

68
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
@@ -37,6 +39,7 @@ def get_open_response_assessment_list(course):
3739

3840
parents_cache = {}
3941
ora_items = []
42+
ora_grading_base_url = getattr(settings, 'ORA_GRADING_MICROFRONTEND_URL', None)
4043

4144
for block in openassessment_blocks:
4245
block_id = str(block.location)
@@ -54,10 +57,28 @@ def get_open_response_assessment_list(course):
5457
else block.display_name
5558
)
5659

60+
staff_ora_grading_url = None
61+
62+
has_staff_assessment = 'staff-assessment' in block.assessment_steps
63+
is_team_enabled = block.teams_enabled
64+
if ora_grading_base_url and has_staff_assessment and not is_team_enabled:
65+
# Always generate a URL that points to the ORA Grading Microfrontend (MFE).
66+
#
67+
# During the migration to the ORA microfrontend,
68+
# only provide the grading URL for non-team assignments with staff assessment.
69+
# This logic was based on the original implementation in instructor_dashboard:
70+
# - lms/djangoapps/instructor/views/instructor_dashboard.py
71+
# (_section_open_response_assessment)
72+
# - edx-ora2:
73+
# https://github.com/openedx/edx-ora2/blob/801fbd14ebb059ab8c5ee8d5a39c260c7f87ab81/
74+
# openassessment/xblock/static/js/src/lms/oa_course_items_listing.js#L73
75+
staff_ora_grading_url = f"{ora_grading_base_url}/{block_id}"
76+
5777
ora_assessment_data = {
5878
'id': block_id,
5979
'name': assessment_name,
6080
'parent_name': parent_block.display_name,
81+
'staff_ora_grading_url': staff_ora_grading_url,
6182
**DEFAULT_ORA_METRICS,
6283
}
6384

lms/djangoapps/instructor/tests/test_api_v2.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,72 @@ def test_get_assessment_list(self):
960960
assert ora_data['waiting'] == 0
961961
assert ora_data['staff'] == 0
962962
assert ora_data['final_grade_received'] == 0
963+
assert ora_data['staff_ora_grading_url'] is None
964+
965+
@patch("lms.djangoapps.instructor.ora.modulestore")
966+
def test_get_assessment_list_includes_staff_ora_grading_url_for_non_team_assignment(
967+
self, mock_modulestore
968+
):
969+
"""
970+
Retrieve ORA assessments and ensure staff grading URL is included
971+
for non-team assignments with staff assessment enabled.
972+
"""
973+
mock_store = Mock()
974+
975+
mock_assessment_block = Mock(
976+
location=self.ora_block.location,
977+
parent=Mock(),
978+
teams_enabled=False,
979+
assessment_steps=["staff-assessment"],
980+
)
981+
982+
mock_store.get_items.return_value = [mock_assessment_block]
983+
mock_modulestore.return_value = mock_store
984+
985+
response = self.client.get(self._get_url())
986+
987+
assert response.status_code == 200
988+
989+
results = response.data["results"]
990+
assert len(results) == 1
991+
992+
ora_data = results[0]
993+
994+
assert "staff_ora_grading_url" in ora_data
995+
assert ora_data["staff_ora_grading_url"]
996+
997+
@patch("lms.djangoapps.instructor.ora.modulestore")
998+
def test_get_assessment_list_includes_staff_ora_grading_url_for_team_assignment(
999+
self, mock_modulestore
1000+
):
1001+
"""
1002+
Retrieve ORA assessments and ensure staff grading URL is included
1003+
for team assignments with staff assessment enabled.
1004+
"""
1005+
mock_store = Mock()
1006+
1007+
mock_assessment_block = Mock(
1008+
location=self.ora_block.location,
1009+
parent=Mock(),
1010+
teams_enabled=True,
1011+
display_name="Team Assignment",
1012+
assessment_steps=["staff-assessment"],
1013+
)
1014+
1015+
mock_store.get_items.return_value = [mock_assessment_block]
1016+
mock_modulestore.return_value = mock_store
1017+
1018+
response = self.client.get(self._get_url())
1019+
1020+
assert response.status_code == 200
1021+
1022+
results = response.data["results"]
1023+
assert len(results) == 1
1024+
1025+
ora_data = results[0]
1026+
1027+
assert "staff_ora_grading_url" in ora_data
1028+
assert ora_data["staff_ora_grading_url"] is None
9631029

9641030
def test_invalid_course_id(self):
9651031
"""Test error handling for invalid course ID."""

lms/djangoapps/instructor/views/serializers_v2.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ class ORASerializer(serializers.Serializer):
460460
waiting = serializers.IntegerField()
461461
staff = serializers.IntegerField()
462462
final_grade_received = serializers.IntegerField(source="done")
463+
staff_ora_grading_url = serializers.URLField(allow_null=True)
463464

464465

465466
class ORASummarySerializer(serializers.Serializer):

0 commit comments

Comments
 (0)