feat: remove last cs_comments service references (#37503)

This commit removes all remaining references to cs_comments_service
except the ForumsConfig model. The only purpose of keeping the model
and table around is so that the webapp processes don't start throwing
errors during deployment because they're running the old code for a
few minutes after the database migration has run. We can drop
ForumsConfig and add the drop-table migration after Ulmo is cut.

Also bumps the openedx-forum version to 0.3.7

---------

Co-authored-by: Taimoor  Ahmed <taimoor.ahmed@A006-01711.local>
This commit is contained in:
Taimoor Ahmed
2025-10-23 19:48:39 +05:00
committed by GitHub
parent 604a87c417
commit 86d9b08b5d
21 changed files with 46 additions and 267 deletions

View File

@@ -200,7 +200,7 @@ class AdminUserPageTest(TestCase):
Changing the username is still possible using the database or from the model directly.
However, changing the username might cause issues with the logs and/or the cs_comments_service since it
However, changing the username might cause issues with the logs and/or the forum service since it
stores the username in a different database.
"""
request = Mock()

View File

@@ -20,7 +20,6 @@ from common.djangoapps.student.models import CourseEnrollment
from common.djangoapps.student.tests.factories import UserFactory
from common.djangoapps.util.testing import UrlResetMixin
from lms.djangoapps.course_goals.models import UserActivity
from openedx.core.djangoapps.django_comment_common.models import ForumsConfig
from openedx.features.course_experience import ENABLE_COURSE_GOALS
User = get_user_model()
@@ -53,10 +52,6 @@ class UserActivityTests(UrlResetMixin, ModuleStoreTestCase):
self.request = RequestFactory().get('foo')
self.request.user = self.user
config = ForumsConfig.current()
config.enabled = True
config.save()
def test_mfe_tabs_call_user_activity(self):
'''
New style tabs call one of two metadata endpoints

View File

@@ -48,7 +48,6 @@ from lms.djangoapps.discussion.django_comment_client.tests.unicode import (
)
from lms.djangoapps.discussion.django_comment_client.tests.utils import (
CohortedTestCase,
ForumsEnableMixin,
)
from lms.djangoapps.teams.tests.factories import (
CourseTeamFactory,
@@ -397,7 +396,6 @@ class ViewsTestCaseMixin:
@disable_signal(views, "comment_flagged")
@disable_signal(views, "thread_flagged")
class ViewsTestCase(
ForumsEnableMixin,
MockForumApiMixin,
UrlResetMixin,
SharedModuleStoreTestCase,
@@ -1019,7 +1017,6 @@ class ViewsTestCase(
@disable_signal(views, "comment_endorsed")
class ViewPermissionsTestCase(
ForumsEnableMixin,
UrlResetMixin,
SharedModuleStoreTestCase,
MockForumApiMixin,
@@ -1733,7 +1730,7 @@ TEAM_COMMENTABLE_ID = "test-team-discussion"
@disable_signal(views, "comment_created")
@ddt.ddt
class ForumEventTestCase(
ForumsEnableMixin, SharedModuleStoreTestCase, MockForumApiMixin
SharedModuleStoreTestCase, MockForumApiMixin
):
"""
Forum actions are expected to launch analytics events. Test these here.
@@ -2018,7 +2015,6 @@ class ForumEventTestCase(
@disable_signal(views, "thread_edited")
class UpdateThreadUnicodeTestCase(
ForumsEnableMixin,
SharedModuleStoreTestCase,
UnicodeTestMixin,
MockForumApiMixin,
@@ -2084,7 +2080,7 @@ class UpdateThreadUnicodeTestCase(
class CreateThreadUnicodeTestCase(
ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin, MockForumApiMixin
SharedModuleStoreTestCase, UnicodeTestMixin, MockForumApiMixin
):
@classmethod
@@ -2136,7 +2132,7 @@ class CreateThreadUnicodeTestCase(
@disable_signal(views, "comment_created")
class CreateCommentUnicodeTestCase(
ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin, MockForumApiMixin
SharedModuleStoreTestCase, UnicodeTestMixin, MockForumApiMixin
):
@classmethod
@@ -2189,7 +2185,7 @@ class CreateCommentUnicodeTestCase(
@disable_signal(views, "comment_edited")
class UpdateCommentUnicodeTestCase(
ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin, MockForumApiMixin
SharedModuleStoreTestCase, UnicodeTestMixin, MockForumApiMixin
):
@classmethod
def setUpClass(cls): # pylint: disable=super-method-not-called
@@ -2236,7 +2232,7 @@ class UpdateCommentUnicodeTestCase(
@disable_signal(views, "comment_created")
class CreateSubCommentUnicodeTestCase(
ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin, MockForumApiMixin
SharedModuleStoreTestCase, UnicodeTestMixin, MockForumApiMixin
):
"""
Make sure comments under a response can handle unicode.
@@ -2294,7 +2290,7 @@ class CreateSubCommentUnicodeTestCase(
del Thread.commentable_id
class UsersEndpointTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, MockForumApiMixin):
class UsersEndpointTestCase(SharedModuleStoreTestCase, MockForumApiMixin):
@classmethod
def setUpClass(cls): # pylint: disable=super-method-not-called
@@ -2468,7 +2464,7 @@ def _create_and_transform_event(**kwargs):
@ddt.ddt
class ForumThreadViewedEventTransformerTestCase(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase):
class ForumThreadViewedEventTransformerTestCase(UrlResetMixin, ModuleStoreTestCase):
"""
Test that the ForumThreadViewedEventTransformer transforms events correctly
and without raising exceptions.

View File

@@ -39,12 +39,10 @@ from openedx.core.djangoapps.discussions.utils import (
)
from openedx.core.djangoapps.django_comment_common.comment_client.utils import (
CommentClientMaintenanceError,
perform_request,
)
from openedx.core.djangoapps.django_comment_common.models import (
CourseDiscussionSettings,
DiscussionsIdMapping,
ForumsConfig,
assign_role
)
from openedx.core.djangoapps.django_comment_common.utils import seed_permissions_roles
@@ -1650,35 +1648,6 @@ class GroupModeratorPermissionsTestCase(ModuleStoreTestCase):
'can_report': True}
class ClientConfigurationTestCase(TestCase):
"""Simple test cases to ensure enabling/disabling the use of the comment service works as intended."""
def test_disabled(self):
"""Ensures that an exception is raised when forums are disabled."""
config = ForumsConfig.current()
config.enabled = False
config.save()
with pytest.raises(CommentClientMaintenanceError):
perform_request('GET', 'http://www.google.com')
@patch('requests.request')
def test_enabled(self, mock_request):
"""Ensures that requests proceed normally when forums are enabled."""
config = ForumsConfig.current()
config.enabled = True
config.save()
response = Mock()
response.status_code = 200
response.json = lambda: {}
mock_request.return_value = response
result = perform_request('GET', 'http://www.google.com')
assert result == {}
def set_discussion_division_settings(
course_key, enable_cohorts=False, always_divide_inline_discussions=False,
divided_discussions=[], division_scheme=CourseDiscussionSettings.COHORT

View File

@@ -13,24 +13,12 @@ from xmodule.modulestore.tests.factories import CourseFactory
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from common.djangoapps.util.testing import UrlResetMixin
from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory
from openedx.core.djangoapps.django_comment_common.models import CourseDiscussionSettings, ForumsConfig, Role
from openedx.core.djangoapps.django_comment_common.models import CourseDiscussionSettings, Role
from openedx.core.djangoapps.django_comment_common.utils import seed_permissions_roles
from openedx.core.lib.teams_config import TeamsConfig
class ForumsEnableMixin:
"""
Ensures that the forums are enabled for a given test class.
"""
def setUp(self):
super().setUp()
config = ForumsConfig.current()
config.enabled = True
config.save()
class CohortedTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleStoreTestCase):
class CohortedTestCase(UrlResetMixin, SharedModuleStoreTestCase):
"""
Sets up a course with a student, a moderator and their cohorts.
"""

View File

@@ -20,7 +20,7 @@ from openedx.features.lti_course_tab.tab import DiscussionLtiCourseTab
class DiscussionTab(TabFragmentViewMixin, EnrolledTab):
"""
A tab for the cs_comments_service forums.
A tab for the forums.
"""
type = 'discussion'

View File

@@ -16,7 +16,6 @@ from xmodule.modulestore.tests.factories import CourseFactory
from common.djangoapps.student.tests.factories import (
UserFactory
)
from lms.djangoapps.discussion.django_comment_client.tests.utils import ForumsEnableMixin
from lms.djangoapps.discussion.rest_api.api import get_user_comments
from lms.djangoapps.discussion.rest_api.tests.utils import (
ForumMockUtilsMixin,
@@ -29,7 +28,7 @@ User = get_user_model()
@ddt.ddt
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class GetUserCommentsTest(ForumsEnableMixin, ForumMockUtilsMixin, SharedModuleStoreTestCase):
class GetUserCommentsTest(ForumMockUtilsMixin, SharedModuleStoreTestCase):
"""
Tests for get_user_comments.
"""

View File

@@ -43,9 +43,6 @@ from common.djangoapps.student.tests.factories import (
)
from common.djangoapps.util.testing import UrlResetMixin
from common.test.utils import MockSignalHandlerMixin, disable_signal
from lms.djangoapps.discussion.django_comment_client.tests.utils import (
ForumsEnableMixin,
)
from lms.djangoapps.discussion.tests.utils import (
make_minimal_cs_comment,
make_minimal_cs_thread,
@@ -183,7 +180,6 @@ def _set_course_discussion_blackout(course, user_id):
@disable_signal(api, "thread_voted")
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class CreateThreadTest(
ForumsEnableMixin,
UrlResetMixin,
SharedModuleStoreTestCase,
MockSignalHandlerMixin,
@@ -601,7 +597,6 @@ class CreateThreadTest(
new=mock.Mock(),
)
class CreateCommentTest(
ForumsEnableMixin,
UrlResetMixin,
SharedModuleStoreTestCase,
MockSignalHandlerMixin,
@@ -1039,7 +1034,6 @@ class CreateCommentTest(
@disable_signal(api, "thread_voted")
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class UpdateThreadTest(
ForumsEnableMixin,
UrlResetMixin,
SharedModuleStoreTestCase,
MockSignalHandlerMixin,
@@ -1699,7 +1693,6 @@ class UpdateThreadTest(
@disable_signal(api, "comment_voted")
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class UpdateCommentTest(
ForumsEnableMixin,
UrlResetMixin,
SharedModuleStoreTestCase,
MockSignalHandlerMixin,
@@ -2303,7 +2296,6 @@ class UpdateCommentTest(
@disable_signal(api, "thread_deleted")
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class DeleteThreadTest(
ForumsEnableMixin,
UrlResetMixin,
SharedModuleStoreTestCase,
MockSignalHandlerMixin,
@@ -2482,7 +2474,6 @@ class DeleteThreadTest(
@disable_signal(api, "comment_deleted")
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class DeleteCommentTest(
ForumsEnableMixin,
UrlResetMixin,
SharedModuleStoreTestCase,
MockSignalHandlerMixin,
@@ -2672,7 +2663,6 @@ class DeleteCommentTest(
@ddt.ddt
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class RetrieveThreadTest(
ForumsEnableMixin,
UrlResetMixin,
SharedModuleStoreTestCase,
ForumMockUtilsMixin,
@@ -2829,7 +2819,7 @@ class RetrieveThreadTest(
@ddt.ddt
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class GetThreadListTest(
ForumsEnableMixin, ForumMockUtilsMixin, UrlResetMixin, SharedModuleStoreTestCase
ForumMockUtilsMixin, UrlResetMixin, SharedModuleStoreTestCase
):
"""Test for get_thread_list"""
@@ -3464,7 +3454,7 @@ class GetThreadListTest(
@ddt.ddt
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class GetCommentListTest(
ForumsEnableMixin, SharedModuleStoreTestCase, ForumMockUtilsMixin
SharedModuleStoreTestCase, ForumMockUtilsMixin
):
"""Test for get_comment_list"""
@@ -4235,7 +4225,7 @@ class CourseTopicsV2Test(ModuleStoreTestCase):
@mock.patch.dict("django.conf.settings.FEATURES", {"DISABLE_START_DATES": False})
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class GetCourseTopicsTest(ForumMockUtilsMixin, ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase):
class GetCourseTopicsTest(ForumMockUtilsMixin, UrlResetMixin, ModuleStoreTestCase):
"""Test for get_course_topics"""
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
def setUp(self):
@@ -4673,7 +4663,7 @@ class GetCourseTopicsTest(ForumMockUtilsMixin, ForumsEnableMixin, UrlResetMixin,
@override_settings(DISCUSSION_MODERATION_EDIT_REASON_CODES={"test-edit-reason": "Test Edit Reason"})
@override_settings(DISCUSSION_MODERATION_CLOSE_REASON_CODES={"test-close-reason": "Test Close Reason"})
@ddt.ddt
class GetCourseTest(ForumsEnableMixin, UrlResetMixin, SharedModuleStoreTestCase):
class GetCourseTest(UrlResetMixin, SharedModuleStoreTestCase):
"""Test for get_course"""
@classmethod
def setUpClass(cls):
@@ -4754,7 +4744,7 @@ class GetCourseTest(ForumsEnableMixin, UrlResetMixin, SharedModuleStoreTestCase)
@ddt.ddt
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class GetCourseTestBlackouts(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase):
class GetCourseTestBlackouts(UrlResetMixin, ModuleStoreTestCase):
"""
Tests of get_course for courses that have blackout dates.
"""

View File

@@ -16,7 +16,6 @@ from xmodule.modulestore.tests.factories import CourseFactory
from common.djangoapps.student.tests.factories import UserFactory
from common.djangoapps.util.testing import UrlResetMixin
from lms.djangoapps.discussion.django_comment_client.tests.utils import ForumsEnableMixin
from lms.djangoapps.discussion.rest_api.serializers import CommentSerializer, ThreadSerializer, get_context
from lms.djangoapps.discussion.rest_api.tests.utils import (
ForumMockUtilsMixin,
@@ -36,7 +35,7 @@ from openedx.core.djangoapps.django_comment_common.models import (
@ddt.ddt
class CommentSerializerDeserializationTest(ForumsEnableMixin, ForumMockUtilsMixin, SharedModuleStoreTestCase):
class CommentSerializerDeserializationTest(ForumMockUtilsMixin, SharedModuleStoreTestCase):
"""Tests for ThreadSerializer deserialization."""
@classmethod
def setUpClass(cls):
@@ -387,7 +386,6 @@ class CommentSerializerDeserializationTest(ForumsEnableMixin, ForumMockUtilsMixi
@ddt.ddt
class ThreadSerializerDeserializationTest(
ForumsEnableMixin,
ForumMockUtilsMixin,
UrlResetMixin,
SharedModuleStoreTestCase
@@ -535,7 +533,7 @@ class ThreadSerializerDeserializationTest(
@ddt.ddt
class SerializerTestMixin(ForumsEnableMixin, UrlResetMixin, ForumMockUtilsMixin):
class SerializerTestMixin(UrlResetMixin, ForumMockUtilsMixin):
"""
Test Mixin for Serializer tests
"""

View File

@@ -11,7 +11,6 @@ from pytz import UTC
from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from lms.djangoapps.discussion.django_comment_client.tests.factories import RoleFactory
from lms.djangoapps.discussion.django_comment_client.tests.utils import ForumsEnableMixin
from lms.djangoapps.discussion.rest_api.tests.utils import CommentsServiceMockMixin
from lms.djangoapps.discussion.rest_api.utils import (
discussion_open_for_user,
@@ -182,7 +181,7 @@ class TestRemoveEmptySequentials(unittest.TestCase):
@ddt.ddt
class TestBlackoutDates(ForumsEnableMixin, CommentsServiceMockMixin, ModuleStoreTestCase):
class TestBlackoutDates(CommentsServiceMockMixin, ModuleStoreTestCase):
"""
Test for the is_posting_allowed function
"""

View File

@@ -21,9 +21,6 @@ from common.djangoapps.student.tests.factories import (
UserFactory
)
from common.djangoapps.util.testing import UrlResetMixin
from lms.djangoapps.discussion.django_comment_client.tests.utils import (
ForumsEnableMixin,
)
from lms.djangoapps.discussion.rest_api.tests.utils import (
ForumMockUtilsMixin,
make_minimal_cs_comment,
@@ -34,7 +31,6 @@ from lms.djangoapps.discussion.rest_api.tests.utils import (
@ddt.ddt
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class CommentViewSetListByUserTest(
ForumsEnableMixin,
ForumMockUtilsMixin,
UrlResetMixin,
ModuleStoreTestCase,
@@ -70,7 +66,7 @@ class CommentViewSetListByUserTest(
def register_mock_endpoints(self):
"""
Register cs_comments_service mocks for sample threads and comments.
Register forum service mocks for sample threads and comments.
"""
self.register_get_threads_response(
threads=[

View File

@@ -25,7 +25,6 @@ from rest_framework.parsers import JSONParser
from rest_framework.test import APIClient, APITestCase
from lms.djangoapps.discussion.django_comment_client.tests.utils import (
ForumsEnableMixin,
config_course_discussions,
topic_name_to_id,
)
@@ -72,7 +71,7 @@ from openedx.core.djangoapps.discussions.config.waffle import ENABLE_NEW_STRUCTU
from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_image_storage
class DiscussionAPIViewTestMixin(ForumsEnableMixin, ForumMockUtilsMixin, UrlResetMixin):
class DiscussionAPIViewTestMixin(ForumMockUtilsMixin, UrlResetMixin):
"""
Mixin for common code in tests of Discussion API views. This includes
creation of common structures (e.g. a course, user, and enrollment), logging
@@ -1814,7 +1813,7 @@ class LearnerThreadViewAPITest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
@ddt.ddt
@httpretty.activate
@override_waffle_flag(ENABLE_DISCUSSIONS_MFE, True)
class CourseActivityStatsTest(ForumsEnableMixin, UrlResetMixin, ForumMockUtilsMixin, APITestCase,
class CourseActivityStatsTest(UrlResetMixin, ForumMockUtilsMixin, APITestCase,
SharedModuleStoreTestCase):
"""
Tests for the course stats endpoint
@@ -2028,7 +2027,7 @@ class RetireViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase):
@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
class UploadFileViewTest(ForumsEnableMixin, ForumMockUtilsMixin, UrlResetMixin, ModuleStoreTestCase):
class UploadFileViewTest(ForumMockUtilsMixin, UrlResetMixin, ModuleStoreTestCase):
"""
Tests for UploadFileView.
"""

View File

@@ -36,7 +36,6 @@ from openedx.core.djangoapps.ace_common.template_context import (
from openedx.core.djangoapps.content.course_overviews.tests.factories import (
CourseOverviewFactory,
)
from openedx.core.djangoapps.django_comment_common.models import ForumsConfig
from openedx.core.djangoapps.django_comment_common.signals import comment_created
from openedx.core.djangoapps.site_configuration.tests.factories import (
SiteConfigurationFactory,
@@ -102,10 +101,6 @@ class TaskTestCase(
CourseEnrollmentFactory(user=cls.thread_author, course_id=cls.course.id)
CourseEnrollmentFactory(user=cls.comment_author, course_id=cls.course.id)
config = ForumsConfig.current()
config.enabled = True
config.save()
cls.create_threads_and_comments()
@classmethod

View File

@@ -31,7 +31,6 @@ from lms.djangoapps.discussion import views
from lms.djangoapps.discussion.django_comment_client.constants import TYPE_ENTRY, TYPE_SUBCATEGORY
from lms.djangoapps.discussion.django_comment_client.permissions import get_team
from lms.djangoapps.discussion.django_comment_client.tests.utils import (
ForumsEnableMixin,
config_course_discussions,
topic_name_to_id
)
@@ -41,7 +40,6 @@ from openedx.core.djangoapps.course_groups.tests.test_views import CohortViewsTe
from openedx.core.djangoapps.django_comment_common.comment_client.utils import CommentClientPaginatedResult
from openedx.core.djangoapps.django_comment_common.models import (
CourseDiscussionSettings,
ForumsConfig
)
from openedx.core.djangoapps.django_comment_common.utils import ThreadContext
from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES
@@ -82,9 +80,6 @@ class ViewsExceptionTestCase(UrlResetMixin, ModuleStoreTestCase): # lint-amnest
self.client = Client()
assert self.client.login(username=uname, password=password)
config = ForumsConfig.current()
config.enabled = True
config.save()
patcher = mock.patch(
"openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread"
)
@@ -317,7 +312,7 @@ class AllowPlusOrMinusOneInt(int):
@patch('requests.request', autospec=True)
class CommentsServiceRequestHeadersTestCase(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase): # lint-amnesty, pylint: disable=missing-class-docstring
class CommentsServiceRequestHeadersTestCase(UrlResetMixin, ModuleStoreTestCase): # lint-amnesty, pylint: disable=missing-class-docstring
CREATE_USER = False
@@ -391,7 +386,7 @@ class CommentsServiceRequestHeadersTestCase(ForumsEnableMixin, UrlResetMixin, Mo
self.assert_all_calls_have_header(mock_request, "X-Edx-Api-Key", "test_api_key")
class EnrollmentTestCase(ForumsEnableMixin, ModuleStoreTestCase):
class EnrollmentTestCase(ModuleStoreTestCase):
"""
Tests for the behavior of views depending on if the student is enrolled
in the course

View File

@@ -61,7 +61,6 @@ from lms.djangoapps.discussion.django_comment_client.tests.unicode import (
)
from lms.djangoapps.discussion.django_comment_client.tests.utils import (
CohortedTestCase,
ForumsEnableMixin,
config_course_discussions,
topic_name_to_id,
)
@@ -84,7 +83,6 @@ from openedx.core.djangoapps.django_comment_common.comment_client.utils import (
from openedx.core.djangoapps.django_comment_common.models import (
FORUM_ROLE_STUDENT,
CourseDiscussionSettings,
ForumsConfig,
)
from openedx.core.djangoapps.django_comment_common.utils import (
ThreadContext,
@@ -317,7 +315,7 @@ class ForumViewsUtilsMixin(MockForumApiMixin):
self.set_mock_side_effect("get_user", make_user_callback())
class SingleThreadTestCase(ForumsEnableMixin, ModuleStoreTestCase, ForumViewsUtilsMixin): # lint-amnesty, pylint: disable=missing-class-docstring
class SingleThreadTestCase(ModuleStoreTestCase, ForumViewsUtilsMixin): # lint-amnesty, pylint: disable=missing-class-docstring
CREATE_USER = False
@@ -727,7 +725,7 @@ class SingleThreadGroupIdTestCase(CohortedTestCase, GroupIdAssertionMixinV2, For
)
class SingleThreadContentGroupTestCase(ForumsEnableMixin, UrlResetMixin, ContentGroupTestCase, ForumViewsUtilsMixin): # lint-amnesty, pylint: disable=missing-class-docstring
class SingleThreadContentGroupTestCase(UrlResetMixin, ContentGroupTestCase, ForumViewsUtilsMixin): # lint-amnesty, pylint: disable=missing-class-docstring
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
def setUp(self):
@@ -897,7 +895,7 @@ class FollowedThreadsDiscussionGroupIdTestCase(CohortedTestCase, CohortedTopicGr
)
class SingleThreadUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin, ForumViewsUtilsMixin): # lint-amnesty, pylint: disable=missing-class-docstring
class SingleThreadUnicodeTestCase(SharedModuleStoreTestCase, UnicodeTestMixin, ForumViewsUtilsMixin): # lint-amnesty, pylint: disable=missing-class-docstring
@classmethod
def setUpClass(cls): # pylint: disable=super-method-not-called
@@ -934,7 +932,7 @@ class SingleThreadUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCase,
class ForumFormDiscussionContentGroupTestCase(
ForumsEnableMixin, ContentGroupTestCase, ForumViewsUtilsMixin
ContentGroupTestCase, ForumViewsUtilsMixin
):
"""
Tests `forum_form_discussion api` works with different content groups.
@@ -1030,7 +1028,6 @@ class ForumFormDiscussionContentGroupTestCase(
class ForumFormDiscussionUnicodeTestCase(
ForumsEnableMixin,
SharedModuleStoreTestCase,
UnicodeTestMixin,
ForumViewsUtilsMixin,
@@ -1076,7 +1073,6 @@ class ForumFormDiscussionUnicodeTestCase(
class EnterpriseConsentTestCase(
EnterpriseTestConsentRequired,
ForumsEnableMixin,
UrlResetMixin,
ModuleStoreTestCase,
ForumViewsUtilsMixin,
@@ -1198,7 +1194,7 @@ class InlineDiscussionGroupIdTestCase( # lint-amnesty, pylint: disable=missing-
class InlineDiscussionContextTestCase(
ForumsEnableMixin, ModuleStoreTestCase, ForumViewsUtilsMixin
ModuleStoreTestCase, ForumViewsUtilsMixin
): # lint-amnesty, pylint: disable=missing-class-docstring
def setUp(self):
@@ -1455,7 +1451,7 @@ class UserProfileDiscussionGroupIdTestCase(
@ddt.ddt
class ForumDiscussionXSSTestCase(
ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase, ForumViewsUtilsMixin
UrlResetMixin, ModuleStoreTestCase, ForumViewsUtilsMixin
): # lint-amnesty, pylint: disable=missing-class-docstring
@patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True})
@@ -1535,7 +1531,7 @@ class ForumDiscussionXSSTestCase(
class InlineDiscussionTestCase(
ForumsEnableMixin, ModuleStoreTestCase, ForumViewsUtilsMixin
ModuleStoreTestCase, ForumViewsUtilsMixin
): # lint-amnesty, pylint: disable=missing-class-docstring
def setUp(self):
@@ -1610,7 +1606,7 @@ class InlineDiscussionTestCase(
class ForumDiscussionSearchUnicodeTestCase(
ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin, ForumViewsUtilsMixin
SharedModuleStoreTestCase, UnicodeTestMixin, ForumViewsUtilsMixin
): # lint-amnesty, pylint: disable=missing-class-docstring
@classmethod
@@ -1652,7 +1648,7 @@ class ForumDiscussionSearchUnicodeTestCase(
class InlineDiscussionUnicodeTestCase(
ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin, ForumViewsUtilsMixin
SharedModuleStoreTestCase, UnicodeTestMixin, ForumViewsUtilsMixin
): # lint-amnesty, pylint: disable=missing-class-docstring
@classmethod
@@ -1743,7 +1739,7 @@ class ForumFormDiscussionGroupIdTestCase(
class UserProfileTestCase(
ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase, ForumViewsUtilsMixin
UrlResetMixin, ModuleStoreTestCase, ForumViewsUtilsMixin
): # lint-amnesty, pylint: disable=missing-class-docstring
TEST_THREAD_TEXT = "userprofile-test-text"
@@ -1882,7 +1878,7 @@ class UserProfileTestCase(
class ThreadViewedEventTestCase(
EventTestMixin, ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCase, ForumViewsUtilsMixin,
EventTestMixin, UrlResetMixin, ModuleStoreTestCase, ForumViewsUtilsMixin,
):
"""
Forum thread views are expected to launch analytics events. Test these here.
@@ -1979,7 +1975,6 @@ class ThreadViewedEventTestCase(
class FollowedThreadsUnicodeTestCase(
ForumsEnableMixin,
SharedModuleStoreTestCase,
UnicodeTestMixin,
ForumViewsUtilsMixin
@@ -2024,7 +2019,7 @@ class FollowedThreadsUnicodeTestCase(
assert response_data['discussion_data'][0]['body'] == text
class UserProfileUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, UnicodeTestMixin, ForumViewsUtilsMixin): # lint-amnesty, pylint: disable=missing-class-docstring
class UserProfileUnicodeTestCase(SharedModuleStoreTestCase, UnicodeTestMixin, ForumViewsUtilsMixin): # lint-amnesty, pylint: disable=missing-class-docstring
@classmethod
def setUpClass(cls):
@@ -2059,7 +2054,7 @@ class UserProfileUnicodeTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, U
assert response_data['discussion_data'][0]['body'] == text
class ForumMFETestCase(ForumsEnableMixin, SharedModuleStoreTestCase, ModuleStoreTestCase, MockForumApiMixin): # lint-amnesty, pylint: disable=missing-class-docstring
class ForumMFETestCase(SharedModuleStoreTestCase, ModuleStoreTestCase, MockForumApiMixin): # lint-amnesty, pylint: disable=missing-class-docstring
"""
Tests that the MFE upgrade banner and MFE is shown in the correct situation with the correct UI
"""

View File

@@ -41,7 +41,6 @@ from openedx.core.djangoapps.common_views.xblock import xblock_resource
from openedx.core.djangoapps.cors_csrf import views as cors_csrf_views
from openedx.core.djangoapps.course_groups import views as course_groups_views
from openedx.core.djangoapps.debug import views as openedx_debug_views
from openedx.core.djangoapps.django_comment_common.models import ForumsConfig
from openedx.core.djangoapps.lang_pref import views as lang_pref_views
from openedx.core.djangoapps.password_policy import compliance as password_policy_compliance
from openedx.core.djangoapps.password_policy.forms import PasswordPolicyAwareAdminAuthForm
@@ -917,7 +916,6 @@ if settings.FEATURES.get('ENABLE_LTI_PROVIDER'):
urlpatterns += [
path('config/programs', ConfigurationModelCurrentAPIView.as_view(model=ProgramsApiConfig)),
path('config/catalog', ConfigurationModelCurrentAPIView.as_view(model=CatalogIntegration)),
path('config/forums', ConfigurationModelCurrentAPIView.as_view(model=ForumsConfig)),
]
if settings.DEBUG:

View File

@@ -3,7 +3,7 @@ Discussions
This Discussions app is responsible for providing support for configuring
discussion tools in the Open edX platform. This includes the in-built forum
tool that uses the `cs_comments_service`, but also other LTI-based tools.
tool, but also other LTI-based tools.
Technical Overview
@@ -44,10 +44,9 @@ discussion configuration information such as the course key, the provider type,
whether in-context discussions are enabled, whether graded units are enabled,
when unit level visibility is enabled. Other plugin configuration and a list
of discussion contexts for which discussions are enabled. Each discussion
context has a usage key, a title (the units name) an external id
(the cs_comments_service id), it's ordering in the course, and additional
context. It then sends its own signal that has the discussion configuration
object attached.
context has a usage key, a title (the units name) an external id,
its ordering in the course, and additional context. It then sends its own
signal that has the discussion configuration object attached.
Finally, the handler for this discussion change signal, takes the information
from the discussion change signal and compares it to the topics in the

View File

@@ -1,10 +0,0 @@
"""
Admin for managing the connection to the Forums backend service.
"""
from django.contrib import admin
from .models import ForumsConfig
admin.site.register(ForumsConfig)

View File

@@ -3,7 +3,7 @@
import logging
from .utils import CommentClientRequestError, extract, perform_request, get_course_key
from .utils import CommentClientRequestError, extract, get_course_key
from forum import api as forum_api
log = logging.getLogger(__name__)
@@ -101,25 +101,6 @@ class Model:
def find(cls, id): # pylint: disable=redefined-builtin
return cls(id=id)
@classmethod
def retrieve_all(cls, params=None):
"""
Performs a GET request against the resource's listing endpoint.
Arguments:
params: A dictionary of parameters to be passed as the request's query string.
Returns:
The parsed JSON response from the backend.
"""
return perform_request(
'get',
cls.url(action='get_all'),
params,
metric_tags=[f'model_class:{cls.__name__}'],
metric_action='model.retrieve_all',
)
def _update_from_response(self, response_data):
for k, v in response_data.items():
if k in self.accessible_fields:

View File

@@ -33,7 +33,7 @@ class User(models.Model):
def read(self, source):
"""
Calls cs_comments_service to mark thread as read for the user
Calls forum service to mark thread as read for the user
"""
course_id = self.attributes.get("course_id")
course_key = utils.get_course_key(course_id)

View File

@@ -3,14 +3,10 @@
import logging
from uuid import uuid4
import requests
from django.utils.translation import get_language
import requests # pylint: disable=unused-import
from opaque_keys.edx.keys import CourseKey
from .settings import SERVICE_HOST as COMMENTS_SERVICE
log = logging.getLogger(__name__)
@@ -31,78 +27,6 @@ def extract(dic, keys):
return strip_none({k: dic.get(k) for k in keys})
def perform_request(method, url, data_or_params=None, raw=False,
metric_action=None, metric_tags=None, paged_results=False):
# To avoid dependency conflict
from openedx.core.djangoapps.django_comment_common.models import ForumsConfig
config = ForumsConfig.current()
if not config.enabled:
raise CommentClientMaintenanceError('service disabled')
if metric_tags is None:
metric_tags = []
metric_tags.append(f'method:{method}')
if metric_action:
metric_tags.append(f'action:{metric_action}')
if data_or_params is None:
data_or_params = {}
headers = {
'X-Edx-Api-Key': config.api_key,
'Accept-Language': get_language(),
}
request_id = uuid4()
request_id_dict = {'request_id': request_id}
if method in ['post', 'put', 'patch']:
data = data_or_params
params = request_id_dict
else:
data = None
params = data_or_params.copy()
params.update(request_id_dict)
response = requests.request(
method,
url,
data=data,
params=params,
headers=headers,
timeout=config.connection_timeout
)
metric_tags.append(f'status_code:{response.status_code}')
status_code = int(response.status_code)
if status_code > 200:
metric_tags.append('result:failure')
else:
metric_tags.append('result:success')
if 200 < status_code < 500: # lint-amnesty, pylint: disable=no-else-raise
log.info(f'Investigation Log: CommentClientRequestError for request with {method} and params {params}')
raise CommentClientRequestError(response.text, response.status_code)
# Heroku returns a 503 when an application is in maintenance mode
elif status_code == 503:
raise CommentClientMaintenanceError(response.text)
elif status_code == 500:
raise CommentClient500Error(response.text)
else:
if raw:
return response.text
else:
try:
data = response.json()
except ValueError:
raise CommentClientError( # lint-amnesty, pylint: disable=raise-missing-from
"Invalid JSON response for request {request_id}; first 100 characters: '{content}'".format(
request_id=request_id,
content=response.text[:100]
)
)
return data
def clean_forum_params(params):
"""Convert string booleans to actual booleans and remove None values and empty lists from forum parameters."""
result = {}
@@ -160,33 +84,6 @@ class SubscriptionsPaginatedResult:
self.corrected_text = corrected_text
def check_forum_heartbeat():
"""
Check the forum connection via its built-in heartbeat service and create an answer which can be used in the LMS
heartbeat django application.
This function can be connected to the LMS heartbeat checker through the HEARTBEAT_CHECKS variable.
"""
# To avoid dependency conflict
from openedx.core.djangoapps.django_comment_common.models import ForumsConfig
config = ForumsConfig.current()
if not config.enabled:
# If this check is enabled but forums disabled, don't connect, just report no error
return 'forum', True, 'OK'
try:
res = requests.get(
'%s/heartbeat' % COMMENTS_SERVICE,
timeout=config.connection_timeout
).json()
if res['OK']:
return 'forum', True, 'OK'
else:
return 'forum', False, res.get('check', 'Forum heartbeat failed')
except Exception as fail:
return 'forum', False, str(fail)
def get_course_key(course_id: CourseKey | str | None) -> CourseKey | None:
"""
Returns a CourseKey if the provided course_id is a valid string representation of a CourseKey.