Commit 7dd7e652 by Muzaffar yousaf

Merge pull request #8532 from edx/muzaffar/tnl2304-ora1-message-studio

Display error message on ORA 1 components in units Studio.
parents 8f769d23 4fecf038
import logging import logging
from lxml import etree
from lxml import etree
from pkg_resources import resource_string from pkg_resources import resource_string
from xmodule.raw_module import RawDescriptor from xmodule.raw_module import RawDescriptor
from .x_module import XModule, module_attr from .x_module import XModule, module_attr
from xblock.fields import Integer, Scope, String, List, Float, Boolean from xblock.fields import Integer, Scope, String, List, Float, Boolean
from xmodule.open_ended_grading_classes.combined_open_ended_modulev1 import CombinedOpenEndedV1Module, CombinedOpenEndedV1Descriptor from xmodule.open_ended_grading_classes.combined_open_ended_modulev1 import CombinedOpenEndedV1Module, CombinedOpenEndedV1Descriptor
from xmodule.validation import StudioValidation, StudioValidationMessage
from collections import namedtuple from collections import namedtuple
from .fields import Date, Timedelta from .fields import Date, Timedelta
import textwrap import textwrap
...@@ -472,6 +474,14 @@ class CombinedOpenEndedModule(CombinedOpenEndedFields, XModule): ...@@ -472,6 +474,14 @@ class CombinedOpenEndedModule(CombinedOpenEndedFields, XModule):
for attribute in self.student_attributes: for attribute in self.student_attributes:
setattr(self, attribute, getattr(self.child_module, attribute)) setattr(self, attribute, getattr(self.child_module, attribute))
def validate(self):
"""
Message for either error or warning validation message/s.
Returns message and type. Priority given to error type message.
"""
return self.descriptor.validate()
class CombinedOpenEndedDescriptor(CombinedOpenEndedFields, RawDescriptor): class CombinedOpenEndedDescriptor(CombinedOpenEndedFields, RawDescriptor):
""" """
...@@ -515,3 +525,22 @@ class CombinedOpenEndedDescriptor(CombinedOpenEndedFields, RawDescriptor): ...@@ -515,3 +525,22 @@ class CombinedOpenEndedDescriptor(CombinedOpenEndedFields, RawDescriptor):
# Proxy to CombinedOpenEndedModule so that external callers don't have to know if they're working # Proxy to CombinedOpenEndedModule so that external callers don't have to know if they're working
# with a module or a descriptor # with a module or a descriptor
child_module = module_attr('child_module') child_module = module_attr('child_module')
def validate(self):
"""
Validates the state of this instance. This is the override of the general XBlock method,
and it will also ask its superclass to validate.
"""
validation = super(CombinedOpenEndedDescriptor, self).validate()
validation = StudioValidation.copy(validation)
i18n_service = self.runtime.service(self, "i18n")
validation.summary = StudioValidationMessage(
StudioValidationMessage.ERROR,
i18n_service.ugettext(
"ORA1 is no longer supported. To use this assessment, "
"replace this ORA1 component with an ORA2 component."
)
)
return validation
...@@ -2,8 +2,11 @@ import json ...@@ -2,8 +2,11 @@ import json
import logging import logging
from datetime import datetime from datetime import datetime
from django.utils.timezone import UTC
from lxml import etree from lxml import etree
from pkg_resources import resource_string from pkg_resources import resource_string
from xblock.fields import Dict, String, Scope, Boolean, Float, Reference from xblock.fields import Dict, String, Scope, Boolean, Float, Reference
from xmodule.capa_module import ComplexEncoder from xmodule.capa_module import ComplexEncoder
...@@ -13,10 +16,10 @@ from xmodule.raw_module import RawDescriptor ...@@ -13,10 +16,10 @@ from xmodule.raw_module import RawDescriptor
from xmodule.timeinfo import TimeInfo from xmodule.timeinfo import TimeInfo
from xmodule.x_module import XModule, module_attr from xmodule.x_module import XModule, module_attr
from xmodule.open_ended_grading_classes.peer_grading_service import PeerGradingService, MockPeerGradingService from xmodule.open_ended_grading_classes.peer_grading_service import PeerGradingService, MockPeerGradingService
from xmodule.open_ended_grading_classes.grading_service_module import GradingServiceError
from xmodule.validation import StudioValidation, StudioValidationMessage
from open_ended_grading_classes import combined_open_ended_rubric from open_ended_grading_classes import combined_open_ended_rubric
from django.utils.timezone import UTC
from xmodule.open_ended_grading_classes.grading_service_module import GradingServiceError
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -643,6 +646,14 @@ class PeerGradingModule(PeerGradingFields, XModule): ...@@ -643,6 +646,14 @@ class PeerGradingModule(PeerGradingFields, XModule):
else: else:
return True, "" return True, ""
def validate(self):
"""
Message for either error or warning validation message/s.
Returns message and type. Priority given to error type message.
"""
return self.descriptor.validate()
class PeerGradingDescriptor(PeerGradingFields, RawDescriptor): class PeerGradingDescriptor(PeerGradingFields, RawDescriptor):
""" """
...@@ -709,3 +720,22 @@ class PeerGradingDescriptor(PeerGradingFields, RawDescriptor): ...@@ -709,3 +720,22 @@ class PeerGradingDescriptor(PeerGradingFields, RawDescriptor):
show_calibration_essay = module_attr('show_calibration_essay') show_calibration_essay = module_attr('show_calibration_essay')
use_for_single_location_local = module_attr('use_for_single_location_local') use_for_single_location_local = module_attr('use_for_single_location_local')
_find_corresponding_module_for_location = module_attr('_find_corresponding_module_for_location') _find_corresponding_module_for_location = module_attr('_find_corresponding_module_for_location')
def validate(self):
"""
Validates the state of this instance. This is the override of the general XBlock method,
and it will also ask its superclass to validate.
"""
validation = super(PeerGradingDescriptor, self).validate()
validation = StudioValidation.copy(validation)
i18n_service = self.runtime.service(self, "i18n")
validation.summary = StudioValidationMessage(
StudioValidationMessage.ERROR,
i18n_service.ugettext(
"ORA1 is no longer supported. To use this assessment, "
"replace this ORA1 component with an ORA2 component."
)
)
return validation
...@@ -25,7 +25,9 @@ from xmodule.combined_open_ended_module import CombinedOpenEndedModule ...@@ -25,7 +25,9 @@ from xmodule.combined_open_ended_module import CombinedOpenEndedModule
from opaque_keys.edx.locations import Location from opaque_keys.edx.locations import Location
from xmodule.tests import get_test_system, test_util_open_ended from xmodule.tests import get_test_system, test_util_open_ended
from xmodule.progress import Progress from xmodule.progress import Progress
from xmodule.validation import StudioValidationMessage
from xmodule.x_module import STUDENT_VIEW from xmodule.x_module import STUDENT_VIEW
from xmodule.tests.test_util_open_ended import ( from xmodule.tests.test_util_open_ended import (
DummyModulestore, TEST_STATE_SA_IN, DummyModulestore, TEST_STATE_SA_IN,
MOCK_INSTANCE_STATE, TEST_STATE_SA, TEST_STATE_AI, TEST_STATE_AI2, TEST_STATE_AI2_INVALID, MOCK_INSTANCE_STATE, TEST_STATE_SA, TEST_STATE_AI, TEST_STATE_AI2, TEST_STATE_AI2_INVALID,
...@@ -795,6 +797,23 @@ class CombinedOpenEndedModuleTest(unittest.TestCase): ...@@ -795,6 +797,23 @@ class CombinedOpenEndedModuleTest(unittest.TestCase):
def test_state_pe_single(self): def test_state_pe_single(self):
self.ai_state_success(TEST_STATE_PE_SINGLE, iscore=0, tasks=[self.task_xml2]) self.ai_state_success(TEST_STATE_PE_SINGLE, iscore=0, tasks=[self.task_xml2])
def test_deprecation_message(self):
"""
Test the validation message produced for deprecation.
"""
# pylint: disable=no-member
validation = self.combinedoe_container.validate()
deprecation_msg = "ORA1 is no longer supported. To use this assessment, " \
"replace this ORA1 component with an ORA2 component."
validation.summary.text = deprecation_msg
validation.summary.type = 'error'
self.assertEqual(
validation.summary.text,
deprecation_msg
)
self.assertEqual(validation.summary.type, StudioValidationMessage.ERROR)
class CombinedOpenEndedModuleConsistencyTest(unittest.TestCase): class CombinedOpenEndedModuleConsistencyTest(unittest.TestCase):
""" """
......
...@@ -13,6 +13,7 @@ from xmodule.tests.test_util_open_ended import DummyModulestore ...@@ -13,6 +13,7 @@ from xmodule.tests.test_util_open_ended import DummyModulestore
from xmodule.open_ended_grading_classes.peer_grading_service import MockPeerGradingService from xmodule.open_ended_grading_classes.peer_grading_service import MockPeerGradingService
from xmodule.peer_grading_module import PeerGradingModule, PeerGradingDescriptor, MAX_ALLOWED_FEEDBACK_LENGTH from xmodule.peer_grading_module import PeerGradingModule, PeerGradingDescriptor, MAX_ALLOWED_FEEDBACK_LENGTH
from xmodule.modulestore.exceptions import ItemNotFoundError, NoPathToItem from xmodule.modulestore.exceptions import ItemNotFoundError, NoPathToItem
from xmodule.validation import StudioValidationMessage
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -231,6 +232,21 @@ class PeerGradingModuleTest(unittest.TestCase, DummyModulestore): ...@@ -231,6 +232,21 @@ class PeerGradingModuleTest(unittest.TestCase, DummyModulestore):
# Returning score dict. # Returning score dict.
return self.peer_grading.get_score() return self.peer_grading.get_score()
def test_deprecation_message(self):
"""
Test the validation message produced for deprecation.
"""
peer_grading_module = self.peer_grading
validation = peer_grading_module.validate()
self.assertEqual(len(validation.messages), 0)
self.assertEqual(
validation.summary.text,
"ORA1 is no longer supported. To use this assessment, replace this ORA1 component with an ORA2 component."
)
self.assertEqual(validation.summary.type, StudioValidationMessage.ERROR)
class MockPeerGradingServiceProblemList(MockPeerGradingService): class MockPeerGradingServiceProblemList(MockPeerGradingService):
def get_problem_list(self, course_id, grader_id): def get_problem_list(self, course_id, grader_id):
......
...@@ -81,3 +81,22 @@ class ORAComponentTest(StudioCourseTest): ...@@ -81,3 +81,22 @@ class ORAComponentTest(StudioCourseTest):
location_input_element.get_attribute('value'), location_input_element.get_attribute('value'),
peer_problem_location peer_problem_location
) )
def test_verify_ora1_deprecation_message(self):
"""
Scenario: Verifies the ora1 deprecation message on ora components.
Given I have a course with ora 1 components
When I go to the unit page
Then I see a deprecation error message in ora 1 components.
"""
self.course_outline_page.visit()
unit = self._go_to_unit_page()
for xblock in unit.xblocks:
self.assertTrue(xblock.has_validation_error)
self.assertEqual(
xblock.validation_error_text,
"ORA1 is no longer supported. To use this assessment, "
"replace this ORA1 component with an ORA2 component."
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment