Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
7 changes: 6 additions & 1 deletion cms/djangoapps/contentstore/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from xmodule.contentstore.django import contentstore
from xmodule.exceptions import NotFoundError
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.xml_block import XmlMixin
from openedx.core.djangoapps.video_config.transcripts_utils import Transcript, build_components_import_path
from edxval.api import (
Expand Down Expand Up @@ -592,7 +593,11 @@ def _import_xml_node_to_parent(
raise NotImplementedError("We don't yet support pasting XBlocks with children")

if node_copied_from:
_fetch_and_set_upstream_link(node_copied_from, node_copied_version, temp_xblock, user)
try:
_fetch_and_set_upstream_link(node_copied_from, node_copied_version, temp_xblock, user)
except ItemNotFoundError:
# We don't have a version of the node being copied. Skip setting upstream link
log.warning("Could not find original node '%s' in modulestore to set upstream link.", node_copied_from)

# Save the XBlock into modulestore. We need to save the block and its parent for this to work:
new_xblock = store.update_item(temp_xblock, user.id, allow_not_found=True)
Expand Down
3 changes: 2 additions & 1 deletion lms/djangoapps/learner_dashboard/tests/test_programs.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from edx_toggles.toggles.testutils import override_waffle_flag

from lti_consumer.models import LtiConfiguration
from lti_consumer.utils import CONFIG_ON_DB
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory as ModuleStoreCourseFactory
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
Expand Down Expand Up @@ -332,7 +333,7 @@ def test_discussion_flags_exist(self):
provider_type="piazza",
)
discussion_config.lti_configuration = LtiConfiguration.objects.create(
config_store=LtiConfiguration.CONFIG_ON_DB,
config_store=CONFIG_ON_DB,
lti_1p1_launch_url='http://test.url',
lti_1p1_client_key='test_client_key',
lti_1p1_client_secret='test_client_secret',
Expand Down
3 changes: 2 additions & 1 deletion lms/djangoapps/learner_dashboard/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from django.urls import reverse_lazy
from edx_toggles.toggles.testutils import override_waffle_flag
from lti_consumer.models import LtiConfiguration
from lti_consumer.utils import CONFIG_ON_DB
from markupsafe import Markup
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory as ModuleStoreCourseFactory
Expand Down Expand Up @@ -109,7 +110,7 @@ def test_api_returns_discussions_iframe(self, staff):
provider_type="piazza",
)
discussion_config.lti_configuration = LtiConfiguration.objects.create(
config_store=LtiConfiguration.CONFIG_ON_DB,
config_store=CONFIG_ON_DB,
lti_1p1_launch_url='http://test.url',
lti_1p1_client_key='test_client_key',
lti_1p1_client_secret='test_client_secret',
Expand Down
3 changes: 2 additions & 1 deletion openedx/core/djangoapps/course_live/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.contrib.auth import get_user_model
from django.utils.translation import gettext_noop as _
from lti_consumer.models import LtiConfiguration
from lti_consumer.utils import CONFIG_ON_DB
from opaque_keys.edx.keys import CourseKey

from openedx.core.djangoapps.course_apps.plugins import CourseApp
Expand Down Expand Up @@ -51,7 +52,7 @@ def set_enabled(cls, course_key: CourseKey, enabled: bool, user: User) -> bool:
configuration.enabled = enabled
if not configuration.lti_configuration:
configuration.lti_configuration = LtiConfiguration.objects.create(
config_store=LtiConfiguration.CONFIG_ON_DB
config_store=CONFIG_ON_DB
)
configuration.save()
return configuration.enabled
Expand Down
5 changes: 3 additions & 2 deletions openedx/core/djangoapps/course_live/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from lti_consumer.models import LtiConfiguration
from lti_consumer.utils import CONFIG_ON_DB
from rest_framework import serializers

from .models import CourseLiveConfiguration
Expand Down Expand Up @@ -50,7 +51,7 @@ def create(self, validated_data):
lti_config = validated_data.pop('lti_config', None)
instance = LtiConfiguration()
instance.version = 'lti_1p1'
instance.config_store = LtiConfiguration.CONFIG_ON_DB
instance.config_store = CONFIG_ON_DB

for key, value in validated_data.items():
if key in set(self.Meta.fields).difference(self.Meta.read_only):
Expand All @@ -69,7 +70,7 @@ def update(self, instance: LtiConfiguration, validated_data: dict) -> LtiConfigu
"""
Create/update a model-backed instance
"""
instance.config_store = LtiConfiguration.CONFIG_ON_DB
instance.config_store = CONFIG_ON_DB
lti_config = validated_data.pop('lti_config', None)
if lti_config.get('additional_parameters', None):
instance.lti_config['additional_parameters'] = lti_config.get('additional_parameters', {})
Expand Down
3 changes: 2 additions & 1 deletion openedx/core/djangoapps/course_live/tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.contrib.auth.base_user import AbstractBaseUser
from django.utils.translation import gettext_lazy
from lti_consumer.models import LtiConfiguration
from lti_consumer.utils import CONFIG_ON_DB
from opaque_keys.edx.keys import CourseKey

from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole, GlobalStaff
Expand Down Expand Up @@ -73,7 +74,7 @@ def _get_lti_config(self, course: CourseBlock) -> LtiConfiguration:
lti_1p1_client_key=provider.key,
lti_1p1_client_secret=provider.secret,
version='lti_1p1',
config_store=LtiConfiguration.CONFIG_ON_DB,
config_store=CONFIG_ON_DB,
)
else:
raise ValueError("Provider does not support global credentials")
Expand Down
3 changes: 2 additions & 1 deletion openedx/core/djangoapps/course_live/tests/test_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import ddt
from django.test import RequestFactory
from lti_consumer.models import CourseAllowPIISharingInLTIFlag, LtiConfiguration
from lti_consumer.utils import CONFIG_ON_DB

from lms.djangoapps.courseware.tests.test_tabs import TabTestCase
from openedx.core.djangoapps.course_live.models import CourseLiveConfiguration
Expand All @@ -25,7 +26,7 @@ def setUp(self):
provider_type="zoom",
)
self.course_live_config.lti_configuration = LtiConfiguration.objects.create(
config_store=LtiConfiguration.CONFIG_ON_DB,
config_store=CONFIG_ON_DB,
lti_1p1_launch_url='http://test.url',
lti_1p1_client_key='test_client_key',
lti_1p1_client_secret='test_client_secret',
Expand Down
3 changes: 2 additions & 1 deletion openedx/core/djangoapps/course_live/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.test import RequestFactory
from django.urls import reverse
from lti_consumer.models import CourseAllowPIISharingInLTIFlag, LtiConfiguration
from lti_consumer.utils import CONFIG_ON_DB
from markupsafe import Markup
from rest_framework.test import APITestCase
from xmodule.modulestore import ModuleStoreEnum
Expand Down Expand Up @@ -414,7 +415,7 @@ def test_api_returns_live_iframe(self):
provider_type="zoom",
)
live_config.lti_configuration = LtiConfiguration.objects.create(
config_store=LtiConfiguration.CONFIG_ON_DB,
config_store=CONFIG_ON_DB,
lti_config={
"pii_share_username": 'true',
"pii_share_email": 'true',
Expand Down
3 changes: 2 additions & 1 deletion openedx/core/djangoapps/discussions/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.core.exceptions import ValidationError
from lti_consumer.api import get_lti_pii_sharing_state_for_course
from lti_consumer.models import LtiConfiguration
from lti_consumer.utils import CONFIG_ON_DB
from rest_framework import serializers
from xmodule.modulestore.django import modulestore

Expand Down Expand Up @@ -50,7 +51,7 @@ def update(self, instance: LtiConfiguration, validated_data: dict) -> LtiConfigu
Create/update a model-backed instance
"""
instance = instance or LtiConfiguration()
instance.config_store = LtiConfiguration.CONFIG_ON_DB
instance.config_store = CONFIG_ON_DB
pii_sharing_allowed = self.context.get('pii_sharing_allowed', False)
if validated_data:
for key, value in validated_data.items():
Expand Down
3 changes: 2 additions & 1 deletion openedx/features/lti_course_tab/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import ddt
from django.test import RequestFactory
from lti_consumer.utils import CONFIG_ON_DB
from lti_consumer.models import CourseAllowPIISharingInLTIFlag, LtiConfiguration

from lms.djangoapps.courseware.tests.test_tabs import TabTestCase
Expand All @@ -26,7 +27,7 @@ def setUp(self):
provider_type="yellowdig",
)
self.discussion_config.lti_configuration = LtiConfiguration.objects.create(
config_store=LtiConfiguration.CONFIG_ON_DB,
config_store=CONFIG_ON_DB,
lti_1p1_launch_url='http://test.url',
lti_1p1_client_key='test_client_key',
lti_1p1_client_secret='test_client_secret',
Expand Down
3 changes: 2 additions & 1 deletion requirements/edx/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ lazy==1.6
# lti-consumer-xblock
# ora2
# xblock
lti-consumer-xblock==10.0.0
lti-consumer-xblock @ git+https://github.com/open-craft/xblock-lti-consumer@navin/FAL-4318/reuse-config-data
# via -r requirements/edx/kernel.in
lxml[html-clean]==5.3.2
# via
Expand Down Expand Up @@ -846,6 +846,7 @@ openedx-events==10.5.0
# edx-event-bus-kafka
# edx-event-bus-redis
# event-tracking
# lti-consumer-xblock
# ora2
openedx-filters==2.1.0
# via
Expand Down
3 changes: 2 additions & 1 deletion requirements/edx/development.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1203,7 +1203,7 @@ libsass==0.10.0
# via
# -c requirements/constraints.txt
# -r requirements/edx/assets.txt
lti-consumer-xblock==10.0.0
lti-consumer-xblock @ git+https://github.com/open-craft/xblock-lti-consumer@navin/FAL-4318/reuse-config-data
# via
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
Expand Down Expand Up @@ -1408,6 +1408,7 @@ openedx-events==10.5.0
# edx-event-bus-kafka
# edx-event-bus-redis
# event-tracking
# lti-consumer-xblock
# ora2
openedx-filters==2.1.0
# via
Expand Down
3 changes: 2 additions & 1 deletion requirements/edx/doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ lazy==1.6
# lti-consumer-xblock
# ora2
# xblock
lti-consumer-xblock==10.0.0
lti-consumer-xblock @ git+https://github.com/open-craft/xblock-lti-consumer@navin/FAL-4318/reuse-config-data
# via -r requirements/edx/base.txt
lxml[html-clean]==5.3.2
# via
Expand Down Expand Up @@ -1026,6 +1026,7 @@ openedx-events==10.5.0
# edx-event-bus-kafka
# edx-event-bus-redis
# event-tracking
# lti-consumer-xblock
# ora2
openedx-filters==2.1.0
# via
Expand Down
2 changes: 1 addition & 1 deletion requirements/edx/kernel.in
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ jsonfield # Django model field for validated JSON; use
laboratory # Library for testing that code refactors/infrastructure changes produce identical results
importlib_metadata # Used to access entry_points in i18n_api plugin
lxml[html_clean] # XML parser
lti-consumer-xblock>=9.14.2
lti-consumer-xblock @ git+https://github.com/open-craft/xblock-lti-consumer@navin/FAL-4318/reuse-config-data
mako # Primary template language used for server-side page rendering
Markdown # Convert text markup to HTML; used in capa problems, forums, and course wikis
meilisearch # Library to access Meilisearch search engine (will replace ElasticSearch)
Expand Down
3 changes: 2 additions & 1 deletion requirements/edx/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ lazy==1.6
# lti-consumer-xblock
# ora2
# xblock
lti-consumer-xblock==10.0.0
lti-consumer-xblock @ git+https://github.com/open-craft/xblock-lti-consumer@navin/FAL-4318/reuse-config-data
# via -r requirements/edx/base.txt
lxml[html-clean]==5.3.2
# via
Expand Down Expand Up @@ -1075,6 +1075,7 @@ openedx-events==10.5.0
# edx-event-bus-kafka
# edx-event-bus-redis
# event-tracking
# lti-consumer-xblock
# ora2
openedx-filters==2.1.0
# via
Expand Down
7 changes: 7 additions & 0 deletions xmodule/modulestore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1425,3 +1425,10 @@ def _emit_item_deleted_signal(self, usage_key, user_id):
"""
if self.signal_handler:
self.signal_handler.send("item_deleted", usage_key=usage_key, user_id=user_id)

def _emit_pre_item_deleted_signal(self, usage_key, user_id):
"""
Helper method used to emit the item_deleted signal.
"""
if self.signal_handler:
self.signal_handler.send("pre_item_deleted", usage_key=usage_key, user_id=user_id)
10 changes: 9 additions & 1 deletion xmodule/modulestore/django.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,19 @@ def do_my_expensive_update(course_key):
course_deleted = SwitchedSignal("course_deleted")
library_updated = SwitchedSignal("library_updated")
item_deleted = SwitchedSignal("item_deleted")
pre_item_deleted = SwitchedSignal("pre_item_deleted")

_mapping = {
signal.name: signal
for signal
in [pre_publish, course_published, course_deleted, library_updated, item_deleted]
in [
pre_publish,
course_published,
course_deleted,
library_updated,
item_deleted,
pre_item_deleted,
]
}

def __init__(self, modulestore_class):
Expand Down
2 changes: 2 additions & 0 deletions xmodule/modulestore/split_mongo/split.py
Original file line number Diff line number Diff line change
Expand Up @@ -2523,6 +2523,8 @@ def delete_item(self, usage_locator, user_id, force=False): # lint-amnesty, pyl
# The supplied UsageKey is of the wrong type, so it can't possibly be stored in this modulestore.
raise ItemNotFoundError(usage_locator)

self._emit_pre_item_deleted_signal(usage_locator, user_id)

with self.bulk_operations(usage_locator.course_key):
original_structure = self._lookup_course(usage_locator.course_key).structure
block_key = BlockKey.from_usage_key(usage_locator)
Expand Down
6 changes: 3 additions & 3 deletions xmodule/modulestore/tests/test_mixed_modulestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,7 @@ def test_has_changes_missing_child(self, default_ms, default_branch):
# check CONTENT_TAGGING_AUTO CourseWaffleFlag
# Find: active_versions, 2 structures (published & draft), definition (unnecessary)
# Sends: updated draft and published structures and active_versions
@ddt.data((ModuleStoreEnum.Type.split, 5, 2, 3))
@ddt.data((ModuleStoreEnum.Type.split, 11, 2, 3))
@ddt.unpack
def test_delete_item(self, default_ms, num_mysql, max_find, max_send):
"""
Expand All @@ -1149,7 +1149,7 @@ def test_delete_item(self, default_ms, num_mysql, max_find, max_send):
# check CONTENT_TAGGING_AUTO CourseWaffleFlag
# find: draft and published structures, definition (unnecessary)
# sends: update published (why?), draft, and active_versions
@ddt.data((ModuleStoreEnum.Type.split, 5, 3, 3))
@ddt.data((ModuleStoreEnum.Type.split, 11, 3, 3))
@ddt.unpack
def test_delete_private_vertical(self, default_ms, num_mysql, max_find, max_send):
"""
Expand Down Expand Up @@ -1199,7 +1199,7 @@ def test_delete_private_vertical(self, default_ms, num_mysql, max_find, max_send
# check CONTENT_TAGGING_AUTO CourseWaffleFlag
# find: structure (cached)
# send: update structure and active_versions
@ddt.data((ModuleStoreEnum.Type.split, 5, 1, 2))
@ddt.data((ModuleStoreEnum.Type.split, 11, 1, 2))
@ddt.unpack
def test_delete_draft_vertical(self, default_ms, num_mysql, max_find, max_send):
"""
Expand Down
Loading