Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a runtime service for answer_available function #33424

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions cms/djangoapps/contentstore/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.exceptions import ItemNotFoundError # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.partitions.partitions_service import get_all_partitions_for_course # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.services import SettingsService, ConfigurationService, TeamsConfigurationService
from xmodule.services import (
SettingsService,
ConfigurationService,
TeamsConfigurationService,
ProblemFeedbackService
)


log = logging.getLogger(__name__)
Expand Down Expand Up @@ -1186,7 +1191,8 @@ def load_services_for_studio(runtime, user):
"settings": SettingsService(),
"lti-configuration": ConfigurationService(CourseAllowPIISharingInLTIFlag),
"teams_configuration": TeamsConfigurationService(),
"library_tools": LibraryToolsService(modulestore(), user.id)
"library_tools": LibraryToolsService(modulestore(), user.id),
"problem_feedback": ProblemFeedbackService,
}

runtime._services.update(services) # lint-amnesty, pylint: disable=protected-access
Expand Down
5 changes: 3 additions & 2 deletions cms/djangoapps/contentstore/views/preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from xmodule.exceptions import NotFoundError, ProcessingError
from xmodule.modulestore.django import XBlockI18nService, modulestore
from xmodule.partitions.partitions_service import PartitionService
from xmodule.services import SettingsService, TeamsConfigurationService
from xmodule.services import SettingsService, TeamsConfigurationService, ProblemFeedbackService
from xmodule.studio_editable import has_author_view
from xmodule.util.sandboxing import SandboxService
from xmodule.util.builtin_assets import add_webpack_js_to_fragment
Expand Down Expand Up @@ -212,7 +212,8 @@ def _prepare_runtime_for_preview(request, block):
"teams_configuration": TeamsConfigurationService(),
"sandbox": SandboxService(contentstore=contentstore, course_id=course_id),
"cache": CacheService(cache),
'replace_urls': ReplaceURLService
'replace_urls': ReplaceURLService,
"problem_feedback": partial(ProblemFeedbackService, user_is_staff=True),
}

block.runtime.get_block_for_descriptor = partial(_load_preview_block, request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,19 @@
from openedx.core.lib.gating import api as gating_api
from openedx.core.lib.cache_utils import request_cached
from openedx.core.toggles import ENTRANCE_EXAMS
from xmodule.services import (
ConfigurationService,
SettingsService,
TeamsConfigurationService,
ProblemFeedbackService
) # lint-amnesty, pylint: disable=wrong-import-order
steff456 marked this conversation as resolved.
Show resolved Hide resolved
from xmodule.course_block import DEFAULT_START_DATE
from xmodule.library_tools import LibraryToolsService
from xmodule.modulestore import EdxJSONEncoder, ModuleStoreEnum
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.draft_and_published import DIRECT_ONLY_CATEGORIES
from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError
from xmodule.modulestore.inheritance import own_metadata
from xmodule.services import ConfigurationService, SettingsService, TeamsConfigurationService
from xmodule.tabs import CourseTabList

from ..utils import (
Expand Down Expand Up @@ -331,6 +336,7 @@ def load_services_for_studio(runtime, user):
"lti-configuration": ConfigurationService(CourseAllowPIISharingInLTIFlag),
"teams_configuration": TeamsConfigurationService(),
"library_tools": LibraryToolsService(modulestore(), user.id),
"problem_feedback": ProblemFeedbackService,
}

runtime._services.update(services) # lint-amnesty, pylint: disable=protected-access
Expand Down
9 changes: 8 additions & 1 deletion lms/djangoapps/courseware/block_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,13 @@
from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.partitions.partitions_service import PartitionService
from xmodule.util.sandboxing import SandboxService
from xmodule.services import EventPublishingService, RebindUserService, SettingsService, TeamsConfigurationService
from xmodule.services import (
EventPublishingService,
RebindUserService,
SettingsService,
TeamsConfigurationService,
ProblemFeedbackService
)
from common.djangoapps.static_replace.services import ReplaceURLService
from common.djangoapps.static_replace.wrapper import replace_urls_wrapper
from lms.djangoapps.courseware.access import get_user_role, has_access
Expand Down Expand Up @@ -632,6 +638,7 @@ def inner_get_block(block: XBlock) -> XBlock | None:
'teams_configuration': TeamsConfigurationService(),
'call_to_action': CallToActionService(),
'publish': EventPublishingService(user, course_id, track_function),
'problem_feedback': partial(ProblemFeedbackService, user_is_staff=user_is_staff)
}

runtime.get_block_for_descriptor = inner_get_block
Expand Down
2 changes: 2 additions & 0 deletions lms/djangoapps/courseware/tests/test_block_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
@XBlock.needs('teams')
@XBlock.needs('teams_configuration')
@XBlock.needs('call_to_action')
@XBlock.needs('problem_feedback')
class PureXBlock(XBlock):
"""
Pure XBlock to use in tests.
Expand Down Expand Up @@ -2340,6 +2341,7 @@ class LMSXBlockServiceBindingTest(LMSXBlockServiceMixin):
'teams',
'teams_configuration',
'call_to_action',
'problem_feedback',
)
def test_expected_services_exist(self, expected_service):
"""
Expand Down
6 changes: 4 additions & 2 deletions lms/djangoapps/grades/subsection_grade.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
from lms.djangoapps.grades.models import BlockRecord, PersistentSubsectionGrade
from lms.djangoapps.grades.scores import compute_percent, get_score, possibly_scored
from xmodule import block_metadata_utils, graders # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.graders import AggregatedScore, ShowCorrectness # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.graders import AggregatedScore # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.services import ProblemFeedbackService

log = getLogger(__name__)

Expand All @@ -23,6 +24,7 @@ class SubsectionGradeBase(metaclass=ABCMeta):
"""

def __init__(self, subsection):
self._block = subsection
self.location = subsection.location
self.display_name = block_metadata_utils.display_name_with_default(subsection)
self.url_name = block_metadata_utils.url_name_for_block(subsection)
Expand Down Expand Up @@ -59,7 +61,7 @@ def show_grades(self, has_staff_access):
"""
Returns whether subsection scores are currently available to users with or without staff access.
"""
return ShowCorrectness.correctness_available(self.show_correctness, self.due, has_staff_access)
return ProblemFeedbackService(block=self._block, user_is_staff=has_staff_access).correctness_available()

@property
def attempted_graded(self):
Expand Down
4 changes: 3 additions & 1 deletion openedx/core/djangoapps/xblock/runtime/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from xmodule.errortracker import make_error_tracker
from xmodule.contentstore.django import contentstore
from xmodule.modulestore.django import XBlockI18nService
from xmodule.services import EventPublishingService, RebindUserService
from xmodule.services import EventPublishingService, RebindUserService, ProblemFeedbackService
from xmodule.util.sandboxing import SandboxService
from common.djangoapps.edxmako.services import MakoService
from common.djangoapps.static_replace.services import ReplaceURLService
Expand Down Expand Up @@ -299,6 +299,8 @@ def service(self, block: XBlock, service_name: str):
)
elif service_name == 'publish':
return EventPublishingService(self.user, context_key, make_track_function())
elif service_name == 'problem_feedback':
return ProblemFeedbackService(block=block, user_is_staff=self.user.is_staff) # type: ignore

# Check if the XBlockRuntimeSystem wants to handle this:
service = self.system.get_service(block, service_name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from lms.djangoapps.courseware.field_overrides import FieldOverrideProvider
from openedx.features.course_experience import RELATIVE_DATES_FLAG
from xmodule.capa_block import SHOWANSWER # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.graders import ShowAnswer


class ShowAnswerFieldOverride(FieldOverrideProvider):
Expand All @@ -27,11 +27,11 @@ def get(self, block, name, default):
return default

mapping = {
SHOWANSWER.ATTEMPTED: SHOWANSWER.ATTEMPTED_NO_PAST_DUE,
SHOWANSWER.CLOSED: SHOWANSWER.AFTER_ALL_ATTEMPTS,
SHOWANSWER.CORRECT_OR_PAST_DUE: SHOWANSWER.ANSWERED,
SHOWANSWER.FINISHED: SHOWANSWER.AFTER_ALL_ATTEMPTS_OR_CORRECT,
SHOWANSWER.PAST_DUE: SHOWANSWER.NEVER,
ShowAnswer.ATTEMPTED: ShowAnswer.ATTEMPTED_NO_PAST_DUE,
ShowAnswer.CLOSED: ShowAnswer.AFTER_ALL_ATTEMPTS,
ShowAnswer.CORRECT_OR_PAST_DUE: ShowAnswer.ANSWERED,
ShowAnswer.FINISHED: ShowAnswer.AFTER_ALL_ATTEMPTS_OR_CORRECT,
ShowAnswer.PAST_DUE: ShowAnswer.NEVER,
}
current_show_answer_value = self.fallback_field_data.get(block, 'showanswer')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from lms.djangoapps.courseware.model_data import FieldDataCache
from lms.djangoapps.courseware.block_render import get_block
from openedx.features.course_experience import RELATIVE_DATES_FLAG
from xmodule.capa_block import SHOWANSWER # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.graders import ShowAnswer
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order

Expand Down Expand Up @@ -41,27 +41,27 @@ def test_override_enabled_for(self, active):
# Instructor paced course will just have the default value
ip_course = self.setup_course()
course_block = self.get_course_block(ip_course)
assert course_block.showanswer == SHOWANSWER.FINISHED
assert course_block.showanswer == ShowAnswer.FINISHED

# This should be updated to not explicitly add in the showanswer so it can test the
# default case of never touching showanswer. Reference ticket AA-307 (if that's closed,
# this can be updated!)
sp_course = self.setup_course(self_paced=True, showanswer=SHOWANSWER.FINISHED)
sp_course = self.setup_course(self_paced=True, showanswer=ShowAnswer.FINISHED)
course_block = self.get_course_block(sp_course)
if active:
assert course_block.showanswer == SHOWANSWER.AFTER_ALL_ATTEMPTS_OR_CORRECT
assert course_block.showanswer == ShowAnswer.AFTER_ALL_ATTEMPTS_OR_CORRECT
else:
assert course_block.showanswer == SHOWANSWER.FINISHED
assert course_block.showanswer == ShowAnswer.FINISHED

@ddt.data(
(SHOWANSWER.ATTEMPTED, SHOWANSWER.ATTEMPTED_NO_PAST_DUE),
(SHOWANSWER.CLOSED, SHOWANSWER.AFTER_ALL_ATTEMPTS),
(SHOWANSWER.CORRECT_OR_PAST_DUE, SHOWANSWER.ANSWERED),
(SHOWANSWER.FINISHED, SHOWANSWER.AFTER_ALL_ATTEMPTS_OR_CORRECT),
(SHOWANSWER.PAST_DUE, SHOWANSWER.NEVER),
(SHOWANSWER.NEVER, SHOWANSWER.NEVER),
(SHOWANSWER.AFTER_SOME_NUMBER_OF_ATTEMPTS, SHOWANSWER.AFTER_SOME_NUMBER_OF_ATTEMPTS),
(SHOWANSWER.ALWAYS, SHOWANSWER.ALWAYS),
(ShowAnswer.ATTEMPTED, ShowAnswer.ATTEMPTED_NO_PAST_DUE),
(ShowAnswer.CLOSED, ShowAnswer.AFTER_ALL_ATTEMPTS),
(ShowAnswer.CORRECT_OR_PAST_DUE, ShowAnswer.ANSWERED),
(ShowAnswer.FINISHED, ShowAnswer.AFTER_ALL_ATTEMPTS_OR_CORRECT),
(ShowAnswer.PAST_DUE, ShowAnswer.NEVER),
(ShowAnswer.NEVER, ShowAnswer.NEVER),
(ShowAnswer.AFTER_SOME_NUMBER_OF_ATTEMPTS, ShowAnswer.AFTER_SOME_NUMBER_OF_ATTEMPTS),
(ShowAnswer.ALWAYS, ShowAnswer.ALWAYS),
)
@ddt.unpack
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
Expand Down
Loading
Loading