Skip to content
Merged
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
3 changes: 2 additions & 1 deletion src/feedback/extensions/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
from web_fragments.fragment import Fragment

try:
from cms.djangoapps.contentstore.utils import get_lms_link_for_item
from lms.djangoapps.courseware.block_render import get_block_by_usage_id, load_single_xblock
from openedx.core.djangoapps.enrollments.data import get_user_enrollments
from xmodule.modulestore.django import modulestore

from feedback.utils import get_lms_link_for_item
except ImportError:
load_single_xblock = None
get_block_by_usage_id = None
Expand Down
67 changes: 67 additions & 0 deletions src/feedback/feedbacktests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import sys
import types
from unittest.mock import Mock

from opaque_keys.edx.keys import UsageKey

from feedback.utils import get_lms_link_for_item


def test_get_lms_link_importerror(monkeypatch):
location = Mock(spec=UsageKey)
location.org = "edX"
location.course_key = "course-v1:edX+DemoX+2024"
location.__str__ = lambda self=location: "dummy"

monkeypatch.setitem(
sys.modules,
"openedx.core.djangoapps.site_configuration.models",
None,
)

monkeypatch.setattr("feedback.utils.settings", types.SimpleNamespace(LMS_ROOT_URL="https://example.com"))

result = get_lms_link_for_item(location)
assert result is None


def test_get_lms_link_with_null_lms_base(monkeypatch):
location = Mock(spec=UsageKey)
location.org = "edX"
location.course_key = "dummy"
location.__str__ = lambda self=location: "dummy"

class MockSiteConfiguration:
@staticmethod
def get_value_for_org(org, key, default):
return None # simulate LMS base not set

monkeypatch.setitem(
sys.modules,
"openedx.core.djangoapps.site_configuration.models",
types.SimpleNamespace(SiteConfiguration=MockSiteConfiguration),
)

result = get_lms_link_for_item(location)
assert result is None


def test_get_lms_link_with_preview(monkeypatch):
location = Mock(spec=UsageKey)
location.org = "edX"
location.course_key = "course-v1:edX+DemoX+2024"
location.__str__ = lambda self=location: "dummy"

class MockSiteConfiguration:
@staticmethod
def get_value_for_org(org, key, default):
return "https://fallback.com"

monkeypatch.setitem(
sys.modules,
"openedx.core.djangoapps.site_configuration.models",
types.SimpleNamespace(SiteConfiguration=MockSiteConfiguration),
)

result = get_lms_link_for_item(location, preview=True)
assert result == "https://fallback.com/courses/course-v1:edX+DemoX+2024/jump_to/dummy?preview=1"
2 changes: 2 additions & 0 deletions src/feedback/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@
}

SECRET_KEY = "fake-key"

LMS_ROOT_URL = "https://example.com"
42 changes: 42 additions & 0 deletions src/feedback/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,48 @@
"""Utilities for feedback app"""

import sys
from urllib.parse import urlencode, urlparse, urlunparse

from django.conf import settings
from opaque_keys.edx.keys import UsageKey


def _(text):
"""Dummy `gettext` replacement to make string extraction tools scrape strings marked for translation"""
return text


def get_lms_link_for_item(location, preview=False):
"""
Returns an LMS link to the course with a jump_to to the provided location.
"""
assert isinstance(location, UsageKey)

# Hack: Import SiteConfiguration from openedx-platform.
# Please note that XBlocks should not import core openedx-platform code. Do not
# replicate this pattern elsewhere. If you need information from the platform, it's better
# to catch an event, hook into a filter, or define and use an XBlock runtime service.
try:
# pylint: disable=import-outside-toplevel
from openedx.core.djangoapps.site_configuration.models import SiteConfiguration
except ImportError:
if "unittest" in sys.modules.keys():
# Fail silently when testing. We can't install openedx-platform for tests.
return None
# Otherwise, fail loudly, so that we will notice if the openedx-platform import path changes.
raise

lms_base = SiteConfiguration.get_value_for_org(location.org, "LMS_ROOT_URL", settings.LMS_ROOT_URL)

if lms_base is None:
return None

query_string = ""
if preview:
query_string = urlencode({"preview": "1"})

url_parts = list(urlparse(lms_base))
url_parts[2] = f"/courses/{location.course_key}/jump_to/{location}"
url_parts[4] = query_string

return urlunparse(url_parts)
Loading