diff --git a/cms/djangoapps/contentstore/rest_api/v1/serializers/home.py b/cms/djangoapps/contentstore/rest_api/v1/serializers/home.py index a81d391b3f69..fa2a651f8a28 100644 --- a/cms/djangoapps/contentstore/rest_api/v1/serializers/home.py +++ b/cms/djangoapps/contentstore/rest_api/v1/serializers/home.py @@ -66,6 +66,7 @@ class StudioHomeSerializer(serializers.Serializer): request_course_creator_url = serializers.CharField() rerun_creator_status = serializers.BooleanField() show_new_library_button = serializers.BooleanField() + show_new_library_v2_button = serializers.BooleanField() split_studio_home = serializers.BooleanField() studio_name = serializers.CharField() studio_short_name = serializers.CharField() diff --git a/cms/djangoapps/contentstore/rest_api/v1/views/home.py b/cms/djangoapps/contentstore/rest_api/v1/views/home.py index 06433d9f42d5..3de536d78092 100644 --- a/cms/djangoapps/contentstore/rest_api/v1/views/home.py +++ b/cms/djangoapps/contentstore/rest_api/v1/views/home.py @@ -66,6 +66,7 @@ def get(self, request: Request): "request_course_creator_url": "/request_course_creator", "rerun_creator_status": true, "show_new_library_button": true, + "show_new_library_v2_button": true, "split_studio_home": false, "studio_name": "Studio", "studio_short_name": "Studio", diff --git a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py index b8892f0e59b4..a4a6909c5dcb 100644 --- a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py +++ b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_home.py @@ -56,6 +56,7 @@ def setUp(self): "request_course_creator_url": "/request_course_creator", "rerun_creator_status": True, "show_new_library_button": True, + "show_new_library_v2_button": True, "split_studio_home": False, "studio_name": settings.STUDIO_NAME, "studio_short_name": settings.STUDIO_SHORT_NAME, diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index c0f656ec7059..7023bcaefaf7 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -1552,6 +1552,9 @@ def get_library_context(request, request_is_json=False): from cms.djangoapps.contentstore.views.library import ( user_can_view_create_library_button, ) + from openedx.core.djangoapps.content_libraries.api import ( + user_can_create_library, + ) libraries = _accessible_libraries_iter(request.user) if libraries_v1_enabled() else [] data = { @@ -1565,6 +1568,7 @@ def get_library_context(request, request_is_json=False): 'courses': [], 'libraries_enabled': libraries_v1_enabled(), 'show_new_library_button': user_can_view_create_library_button(request.user) and request.user.is_active, + 'show_new_library_v2_button': user_can_create_library(request.user), 'user': request.user, 'request_course_creator_url': reverse('request_course_creator'), 'course_creator_status': _get_course_creator_status(request.user), @@ -1686,6 +1690,9 @@ def get_home_context(request, no_course=False): from cms.djangoapps.contentstore.views.library import ( user_can_view_create_library_button, ) + from openedx.core.djangoapps.content_libraries.api import ( + user_can_create_library, + ) active_courses = [] archived_courses = [] @@ -1714,6 +1721,7 @@ def get_home_context(request, no_course=False): 'taxonomy_list_mfe_url': get_taxonomy_list_url(), 'libraries': libraries, 'show_new_library_button': user_can_view_create_library_button(user), + 'show_new_library_v2_button': user_can_create_library(user), 'user': user, 'request_course_creator_url': reverse('request_course_creator'), 'course_creator_status': _get_course_creator_status(user), diff --git a/cms/djangoapps/contentstore/views/tests/test_course_index.py b/cms/djangoapps/contentstore/views/tests/test_course_index.py index c3dcfe5305b7..a49273928062 100644 --- a/cms/djangoapps/contentstore/views/tests/test_course_index.py +++ b/cms/djangoapps/contentstore/views/tests/test_course_index.py @@ -433,13 +433,13 @@ def check_index_page(self, separate_archived_courses, org): @override_settings(FEATURES=FEATURES_WITHOUT_HOME_PAGE_COURSE_V2_API) @ddt.data( # Staff user has course staff access - (True, 'staff', None, 0, 21), - (False, 'staff', None, 0, 21), + (True, 'staff', None, 0, 23), + (False, 'staff', None, 0, 23), # Base user has global staff access - (True, 'user', ORG, 2, 21), - (False, 'user', ORG, 2, 21), - (True, 'user', None, 2, 21), - (False, 'user', None, 2, 21), + (True, 'user', ORG, 2, 23), + (False, 'user', ORG, 2, 23), + (True, 'user', None, 2, 23), + (False, 'user', None, 2, 23), ) @ddt.unpack def test_separate_archived_courses(self, separate_archived_courses, username, org, mongo_queries, sql_queries): @@ -464,13 +464,13 @@ def test_separate_archived_courses(self, separate_archived_courses, username, or @override_settings(FEATURES=FEATURES_WITH_HOME_PAGE_COURSE_V2_API) @ddt.data( # Staff user has course staff access - (True, 'staff', None, 0, 21), - (False, 'staff', None, 0, 21), + (True, 'staff', None, 0, 23), + (False, 'staff', None, 0, 23), # Base user has global staff access - (True, 'user', ORG, 0, 21), - (False, 'user', ORG, 0, 21), - (True, 'user', None, 0, 21), - (False, 'user', None, 0, 21), + (True, 'user', ORG, 0, 23), + (False, 'user', ORG, 0, 23), + (True, 'user', None, 0, 23), + (False, 'user', None, 0, 23), ) @ddt.unpack def test_separate_archived_courses_with_home_page_course_v2_api( diff --git a/docs/conf.py b/docs/conf.py index 604ca3755429..b755f3986c93 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -67,19 +67,21 @@ 'sphinx_design', 'code_annotations.contrib.sphinx.extensions.featuretoggles', 'code_annotations.contrib.sphinx.extensions.settings', - 'autoapi.extension', + # 'autoapi.extension', # Temporarily disabled ] -autoapi_type = 'python' -autoapi_dirs = ['../lms', '../openedx'] - -autoapi_ignore = [ - '*/migrations/*', - '*/tests/*', - '*.pyc', - '__init__.py', - '**/xblock_serializer/data.py', -] +# Temporarily disabling autoapi_dirs and the AutoAPI extension due to performance issues. +# This will unblock ReadTheDocs builds and will be revisited for optimization. +# autoapi_type = 'python' +# autoapi_dirs = ['../lms/djangoapps', '../openedx/core/djangoapps', "../openedx/features"] +# +# autoapi_ignore = [ +# '*/migrations/*', +# '*/tests/*', +# '*.pyc', +# '__init__.py', +# '**/xblock_serializer/data.py', +# ] # Rediraffe related settings. rediraffe_redirects = "redirects.txt" @@ -285,7 +287,7 @@ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { - 'django': ('https://docs.djangoproject.com/en/1.11/', 'https://docs.djangoproject.com/en/1.11/_objects/'), + 'django': ('https://docs.djangoproject.com/en/4.2/', 'https://docs.djangoproject.com/en/4.2/_objects/'), } # Start building a map of the directories relative to the repository root to diff --git a/docs/lms-openapi.yaml b/docs/lms-openapi.yaml index 4d318f8a2b62..ad3a4fc40db4 100644 --- a/docs/lms-openapi.yaml +++ b/docs/lms-openapi.yaml @@ -5847,7 +5847,7 @@ paths: operationId: grades_v1_submission_history_read description: |- Get submission history details. This submission history is related to only - ProblemBlock and it doesn't support LibraryContentBlock or ContentLibraries + ProblemBlock and it doesn't support LegacyLibraryContentBlock or ContentLibraries as of now. **Usecases**: @@ -7047,6 +7047,25 @@ paths: in: path required: true type: string + /mobile/{api_version}/users/{username}/enrollments_status/: + get: + operationId: mobile_users_enrollments_status_list + description: Gets user's enrollments status. + parameters: [] + responses: + '200': + description: '' + tags: + - mobile + parameters: + - name: api_version + in: path + required: true + type: string + - name: username + in: path + required: true + type: string /notifications/: get: operationId: notifications_list @@ -9868,7 +9887,94 @@ paths: required: true type: string pattern: ^[a-zA-Z0-9\-_]*$ - /xblock/v2/xblocks/{usage_key_str}/: + /xblock/v2/xblocks/{usage_key}/: + get: + operationId: xblock_v2_xblocks_read + summary: Get metadata about the specified block. + description: |- + Accepts the following query parameters: + + * "include": a comma-separated list of keys to include. + Valid keys are "index_dictionary" and "student_view_data". + parameters: [] + responses: + '200': + description: '' + tags: + - xblock + parameters: + - name: usage_key + in: path + required: true + type: string + /xblock/v2/xblocks/{usage_key}/fields/: + get: + operationId: xblock_v2_xblocks_fields_list + description: retrieves the xblock, returning display_name, data, and metadata + parameters: [] + responses: + '200': + description: '' + tags: + - xblock + post: + operationId: xblock_v2_xblocks_fields_create + description: edits the xblock, saving changes to data and metadata only (display_name + included in metadata) + parameters: [] + responses: + '201': + description: '' + tags: + - xblock + parameters: + - name: usage_key + in: path + required: true + type: string + /xblock/v2/xblocks/{usage_key}/handler_url/{handler_name}/: + get: + operationId: xblock_v2_xblocks_handler_url_read + summary: |- + Get an absolute URL which can be used (without any authentication) to call + the given XBlock handler. + description: The URL will expire but is guaranteed to be valid for a minimum + of 2 days. + parameters: [] + responses: + '200': + description: '' + tags: + - xblock + parameters: + - name: usage_key + in: path + required: true + type: string + - name: handler_name + in: path + required: true + type: string + /xblock/v2/xblocks/{usage_key}/view/{view_name}/: + get: + operationId: xblock_v2_xblocks_view_read + description: Get the HTML, JS, and CSS needed to render the given XBlock. + parameters: [] + responses: + '200': + description: '' + tags: + - xblock + parameters: + - name: usage_key + in: path + required: true + type: string + - name: view_name + in: path + required: true + type: string + /xblock/v2/xblocks/{usage_key}@{version}/: get: operationId: xblock_v2_xblocks_read summary: Get metadata about the specified block. @@ -9884,11 +9990,15 @@ paths: tags: - xblock parameters: - - name: usage_key_str + - name: usage_key in: path required: true type: string - /xblock/v2/xblocks/{usage_key_str}/fields/: + - name: version + in: path + required: true + type: string + /xblock/v2/xblocks/{usage_key}@{version}/fields/: get: operationId: xblock_v2_xblocks_fields_list description: retrieves the xblock, returning display_name, data, and metadata @@ -9909,11 +10019,15 @@ paths: tags: - xblock parameters: - - name: usage_key_str + - name: usage_key in: path required: true type: string - /xblock/v2/xblocks/{usage_key_str}/handler_url/{handler_name}/: + - name: version + in: path + required: true + type: string + /xblock/v2/xblocks/{usage_key}@{version}/handler_url/{handler_name}/: get: operationId: xblock_v2_xblocks_handler_url_read summary: |- @@ -9928,7 +10042,11 @@ paths: tags: - xblock parameters: - - name: usage_key_str + - name: usage_key + in: path + required: true + type: string + - name: version in: path required: true type: string @@ -9936,7 +10054,7 @@ paths: in: path required: true type: string - /xblock/v2/xblocks/{usage_key_str}/view/{view_name}/: + /xblock/v2/xblocks/{usage_key}@{version}/view/{view_name}/: get: operationId: xblock_v2_xblocks_view_read description: Get the HTML, JS, and CSS needed to render the given XBlock. @@ -9947,7 +10065,11 @@ paths: tags: - xblock parameters: - - name: usage_key_str + - name: usage_key + in: path + required: true + type: string + - name: version in: path required: true type: string @@ -10158,6 +10280,7 @@ definitions: - can_view_certificate - course_modes - is_new_discussion_sidebar_view_enabled + - has_course_author_access type: object properties: can_show_upgrade_sock: @@ -10237,6 +10360,9 @@ definitions: is_new_discussion_sidebar_view_enabled: title: Is new discussion sidebar view enabled type: boolean + has_course_author_access: + title: Has course author access + type: boolean DateSummary: required: - complete diff --git a/lms/djangoapps/discussion/django_comment_client/base/tests.py b/lms/djangoapps/discussion/django_comment_client/base/tests.py index df087fdc533e..62af24f0ee37 100644 --- a/lms/djangoapps/discussion/django_comment_client/base/tests.py +++ b/lms/djangoapps/discussion/django_comment_client/base/tests.py @@ -82,7 +82,6 @@ def _set_mock_request_data(self, mock_request, data): @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) -@patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) class CreateThreadGroupIdTestCase( MockRequestSetupMixin, CohortedTestCase, @@ -91,21 +90,7 @@ class CreateThreadGroupIdTestCase( ): cs_endpoint = "/threads" - def setUp(self): - super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - - def call_view(self, mock_is_forum_v2_enabled, mock_request, commentable_id, user, group_id, pass_group_id=True): - mock_is_forum_v2_enabled.return_value = False + def call_view(self, mock_request, commentable_id, user, group_id, pass_group_id=True): self._set_mock_request_data(mock_request, {}) request_data = {"body": "body", "title": "title", "thread_type": "discussion"} if pass_group_id: @@ -120,9 +105,8 @@ def call_view(self, mock_is_forum_v2_enabled, mock_request, commentable_id, user commentable_id=commentable_id ) - def test_group_info_in_response(self, mock_is_forum_v2_enabled, mock_request): + def test_group_info_in_response(self, mock_request): response = self.call_view( - mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.student, @@ -132,7 +116,6 @@ def test_group_info_in_response(self, mock_is_forum_v2_enabled, mock_request): @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) -@patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) @disable_signal(views, 'thread_edited') @disable_signal(views, 'thread_voted') @disable_signal(views, 'thread_deleted') @@ -144,18 +127,11 @@ class ThreadActionGroupIdTestCase( def call_view( self, view_name, - mock_is_forum_v2_enabled, mock_request, user=None, post_params=None, view_args=None ): - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - mock_is_forum_v2_enabled.return_value = False self._set_mock_request_data( mock_request, { @@ -178,58 +154,53 @@ def call_view( **(view_args or {}) ) - def test_update(self, mock_is_forum_v2_enabled, mock_request): + def test_update(self, mock_request): response = self.call_view( "update_thread", - mock_is_forum_v2_enabled, mock_request, post_params={"body": "body", "title": "title"} ) self._assert_json_response_contains_group_info(response) - def test_delete(self, mock_is_forum_v2_enabled, mock_request): - response = self.call_view("delete_thread", mock_is_forum_v2_enabled, mock_request) + def test_delete(self, mock_request): + response = self.call_view("delete_thread", mock_request) self._assert_json_response_contains_group_info(response) - def test_vote(self, mock_is_forum_v2_enabled, mock_request): + def test_vote(self, mock_request): response = self.call_view( "vote_for_thread", - mock_is_forum_v2_enabled, mock_request, view_args={"value": "up"} ) self._assert_json_response_contains_group_info(response) - response = self.call_view("undo_vote_for_thread", mock_is_forum_v2_enabled, mock_request) + response = self.call_view("undo_vote_for_thread", mock_request) self._assert_json_response_contains_group_info(response) - def test_flag(self, mock_is_forum_v2_enabled, mock_request): + def test_flag(self, mock_request): with mock.patch('openedx.core.djangoapps.django_comment_common.signals.thread_flagged.send') as signal_mock: - response = self.call_view("flag_abuse_for_thread", mock_is_forum_v2_enabled, mock_request) + response = self.call_view("flag_abuse_for_thread", mock_request) self._assert_json_response_contains_group_info(response) self.assertEqual(signal_mock.call_count, 1) - response = self.call_view("un_flag_abuse_for_thread", mock_is_forum_v2_enabled, mock_request) + response = self.call_view("un_flag_abuse_for_thread", mock_request) self._assert_json_response_contains_group_info(response) - def test_pin(self, mock_is_forum_v2_enabled, mock_request): + def test_pin(self, mock_request): response = self.call_view( "pin_thread", - mock_is_forum_v2_enabled, mock_request, user=self.moderator ) self._assert_json_response_contains_group_info(response) response = self.call_view( "un_pin_thread", - mock_is_forum_v2_enabled, mock_request, user=self.moderator ) self._assert_json_response_contains_group_info(response) - def test_openclose(self, mock_is_forum_v2_enabled, mock_request): + def test_openclose(self, mock_request): response = self.call_view( "openclose_thread", - mock_is_forum_v2_enabled, mock_request, user=self.moderator ) @@ -309,11 +280,10 @@ def _setup_mock_request(self, mock_request, include_depth=False): data["depth"] = 0 self._set_mock_request_data(mock_request, data) - def create_thread_helper(self, mock_is_forum_v2_enabled, mock_request, extra_request_data=None, extra_response_data=None): + def create_thread_helper(self, mock_request, extra_request_data=None, extra_response_data=None): """ Issues a request to create a thread and verifies the result. """ - mock_is_forum_v2_enabled.return_value = False self._set_mock_request_data(mock_request, { "thread_type": "discussion", "title": "Hello", @@ -380,11 +350,10 @@ def create_thread_helper(self, mock_is_forum_v2_enabled, mock_request, extra_req ) assert response.status_code == 200 - def update_thread_helper(self, mock_is_forum_v2_enabled, mock_request): + def update_thread_helper(self, mock_request): """ Issues a request to update a thread and verifies the result. """ - mock_is_forum_v2_enabled.return_value = False self._setup_mock_request(mock_request) # Mock out saving in order to test that content is correctly # updated. Otherwise, the call to thread.save() receives the @@ -407,7 +376,6 @@ def update_thread_helper(self, mock_is_forum_v2_enabled, mock_request): @ddt.ddt @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) -@patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) @disable_signal(views, 'thread_created') @disable_signal(views, 'thread_edited') class ViewsQueryCountTestCase( @@ -425,11 +393,6 @@ class ViewsQueryCountTestCase( @patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) def setUp(self): super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) def count_queries(func): # pylint: disable=no-self-argument """ @@ -451,23 +414,22 @@ def inner(self, default_store, block_count, mongo_calls, sql_queries, *args, **k ) @ddt.unpack @count_queries - def test_create_thread(self, mock_is_forum_v2_enabled, mock_request): - self.create_thread_helper(mock_is_forum_v2_enabled, mock_request) + def test_create_thread(self, mock_request): + self.create_thread_helper(mock_request) @ddt.data( (ModuleStoreEnum.Type.split, 3, 6, 41), ) @ddt.unpack @count_queries - def test_update_thread(self, mock_is_forum_v2_enabled, mock_request): - self.update_thread_helper(mock_is_forum_v2_enabled, mock_request) + def test_update_thread(self, mock_request): + self.update_thread_helper(mock_request) @ddt.ddt @disable_signal(views, 'comment_flagged') @disable_signal(views, 'thread_flagged') @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) -@patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) class ViewsTestCase( ForumsEnableMixin, UrlResetMixin, @@ -502,16 +464,7 @@ def setUp(self): # so we need to call super.setUp() which reloads urls.py (because # of the UrlResetMixin) super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) + # Patch the comment client user save method so it does not try # to create a new cc user when creating a django user with patch('common.djangoapps.student.models.user.cc.User.save'): @@ -544,11 +497,11 @@ def assert_discussion_signals(self, signal, user=None): with self.assert_signal_sent(views, signal, sender=None, user=user, exclude_args=('post',)): yield - def test_create_thread(self, mock_is_forum_v2_enabled, mock_request): + def test_create_thread(self, mock_request): with self.assert_discussion_signals('thread_created'): - self.create_thread_helper(mock_is_forum_v2_enabled, mock_request) + self.create_thread_helper(mock_request) - def test_create_thread_standalone(self, mock_is_forum_v2_enabled, mock_request): + def test_create_thread_standalone(self, mock_request): team = CourseTeamFactory.create( name="A Team", course_id=self.course_id, @@ -560,15 +513,15 @@ def test_create_thread_standalone(self, mock_is_forum_v2_enabled, mock_request): team.add_user(self.student) # create_thread_helper verifies that extra data are passed through to the comments service - self.create_thread_helper(mock_is_forum_v2_enabled, mock_request, extra_response_data={'context': ThreadContext.STANDALONE}) + self.create_thread_helper(mock_request, extra_response_data={'context': ThreadContext.STANDALONE}) @ddt.data( ('follow_thread', 'thread_followed'), ('unfollow_thread', 'thread_unfollowed'), ) @ddt.unpack - def test_follow_unfollow_thread_signals(self, view_name, signal, mock_is_forum_v2_enabled, mock_request): - self.create_thread_helper(mock_is_forum_v2_enabled, mock_request) + def test_follow_unfollow_thread_signals(self, view_name, signal, mock_request): + self.create_thread_helper(mock_request) with self.assert_discussion_signals(signal): response = self.client.post( @@ -579,8 +532,7 @@ def test_follow_unfollow_thread_signals(self, view_name, signal, mock_is_forum_v ) assert response.status_code == 200 - def test_delete_thread(self, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def test_delete_thread(self, mock_request): self._set_mock_request_data(mock_request, { "user_id": str(self.student.id), "closed": False, @@ -599,8 +551,7 @@ def test_delete_thread(self, mock_is_forum_v2_enabled, mock_request): assert response.status_code == 200 assert mock_request.called - def test_delete_comment(self, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def test_delete_comment(self, mock_request): self._set_mock_request_data(mock_request, { "user_id": str(self.student.id), "closed": False, @@ -622,13 +573,12 @@ def test_delete_comment(self, mock_is_forum_v2_enabled, mock_request): assert args[0] == 'delete' assert args[1].endswith(f"/{test_comment_id}") - def _test_request_error(self, view_name, view_kwargs, data, mock_is_forum_v2_enabled, mock_request): + def _test_request_error(self, view_name, view_kwargs, data, mock_request): """ Submit a request against the given view with the given data and ensure that the result is a 400 error and that no data was posted using mock_request """ - mock_is_forum_v2_enabled.return_value = False self._setup_mock_request(mock_request, include_depth=(view_name == "create_sub_comment")) response = self.client.post(reverse(view_name, kwargs=view_kwargs), data=data) @@ -636,97 +586,87 @@ def _test_request_error(self, view_name, view_kwargs, data, mock_is_forum_v2_ena for call in mock_request.call_args_list: assert call[0][0].lower() == 'get' - def test_create_thread_no_title(self, mock_is_forum_v2_enabled, mock_request): + def test_create_thread_no_title(self, mock_request): self._test_request_error( "create_thread", {"commentable_id": "dummy", "course_id": str(self.course_id)}, {"body": "foo"}, - mock_is_forum_v2_enabled, mock_request ) - def test_create_thread_empty_title(self, mock_is_forum_v2_enabled, mock_request): + def test_create_thread_empty_title(self, mock_request): self._test_request_error( "create_thread", {"commentable_id": "dummy", "course_id": str(self.course_id)}, {"body": "foo", "title": " "}, - mock_is_forum_v2_enabled, mock_request ) - def test_create_thread_no_body(self, mock_is_forum_v2_enabled, mock_request): + def test_create_thread_no_body(self, mock_request): self._test_request_error( "create_thread", {"commentable_id": "dummy", "course_id": str(self.course_id)}, {"title": "foo"}, - mock_is_forum_v2_enabled, mock_request ) - def test_create_thread_empty_body(self, mock_is_forum_v2_enabled, mock_request): + def test_create_thread_empty_body(self, mock_request): self._test_request_error( "create_thread", {"commentable_id": "dummy", "course_id": str(self.course_id)}, {"body": " ", "title": "foo"}, - mock_is_forum_v2_enabled, mock_request ) - def test_update_thread_no_title(self, mock_is_forum_v2_enabled, mock_request): + def test_update_thread_no_title(self, mock_request): self._test_request_error( "update_thread", {"thread_id": "dummy", "course_id": str(self.course_id)}, {"body": "foo"}, - mock_is_forum_v2_enabled, mock_request ) - def test_update_thread_empty_title(self, mock_is_forum_v2_enabled, mock_request): + def test_update_thread_empty_title(self, mock_request): self._test_request_error( "update_thread", {"thread_id": "dummy", "course_id": str(self.course_id)}, {"body": "foo", "title": " "}, - mock_is_forum_v2_enabled, mock_request ) - def test_update_thread_no_body(self, mock_is_forum_v2_enabled, mock_request): + def test_update_thread_no_body(self, mock_request): self._test_request_error( "update_thread", {"thread_id": "dummy", "course_id": str(self.course_id)}, {"title": "foo"}, - mock_is_forum_v2_enabled, mock_request ) - def test_update_thread_empty_body(self, mock_is_forum_v2_enabled, mock_request): + def test_update_thread_empty_body(self, mock_request): self._test_request_error( "update_thread", {"thread_id": "dummy", "course_id": str(self.course_id)}, {"body": " ", "title": "foo"}, - mock_is_forum_v2_enabled, mock_request ) - def test_update_thread_course_topic(self, mock_is_forum_v2_enabled, mock_request): + def test_update_thread_course_topic(self, mock_request): with self.assert_discussion_signals('thread_edited'): - self.update_thread_helper(mock_is_forum_v2_enabled, mock_request) + self.update_thread_helper(mock_request) @patch( 'lms.djangoapps.discussion.django_comment_client.utils.get_discussion_categories_ids', return_value=["test_commentable"], ) - def test_update_thread_wrong_commentable_id(self, mock_get_discussion_id_map, mock_is_forum_v2_enabled, mock_request): + def test_update_thread_wrong_commentable_id(self, mock_get_discussion_id_map, mock_request): self._test_request_error( "update_thread", {"thread_id": "dummy", "course_id": str(self.course_id)}, {"body": "foo", "title": "foo", "commentable_id": "wrong_commentable"}, - mock_is_forum_v2_enabled, mock_request ) - def test_create_comment(self, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def test_create_comment(self, mock_request): self._setup_mock_request(mock_request) with self.assert_discussion_signals('comment_created'): response = self.client.post( @@ -738,62 +678,55 @@ def test_create_comment(self, mock_is_forum_v2_enabled, mock_request): ) assert response.status_code == 200 - def test_create_comment_no_body(self, mock_is_forum_v2_enabled, mock_request): + def test_create_comment_no_body(self, mock_request): self._test_request_error( "create_comment", {"thread_id": "dummy", "course_id": str(self.course_id)}, {}, - mock_is_forum_v2_enabled, mock_request ) - def test_create_comment_empty_body(self, mock_is_forum_v2_enabled, mock_request): + def test_create_comment_empty_body(self, mock_request): self._test_request_error( "create_comment", {"thread_id": "dummy", "course_id": str(self.course_id)}, {"body": " "}, - mock_is_forum_v2_enabled, mock_request ) - def test_create_sub_comment_no_body(self, mock_is_forum_v2_enabled, mock_request): + def test_create_sub_comment_no_body(self, mock_request): self._test_request_error( "create_sub_comment", {"comment_id": "dummy", "course_id": str(self.course_id)}, {}, - mock_is_forum_v2_enabled, mock_request ) - def test_create_sub_comment_empty_body(self, mock_is_forum_v2_enabled, mock_request): + def test_create_sub_comment_empty_body(self, mock_request): self._test_request_error( "create_sub_comment", {"comment_id": "dummy", "course_id": str(self.course_id)}, {"body": " "}, - mock_is_forum_v2_enabled, mock_request ) - def test_update_comment_no_body(self, mock_is_forum_v2_enabled, mock_request): + def test_update_comment_no_body(self, mock_request): self._test_request_error( "update_comment", {"comment_id": "dummy", "course_id": str(self.course_id)}, {}, - mock_is_forum_v2_enabled, mock_request ) - def test_update_comment_empty_body(self, mock_is_forum_v2_enabled, mock_request): + def test_update_comment_empty_body(self, mock_request): self._test_request_error( "update_comment", {"comment_id": "dummy", "course_id": str(self.course_id)}, {"body": " "}, - mock_is_forum_v2_enabled, mock_request ) - def test_update_comment_basic(self, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def test_update_comment_basic(self, mock_request): self._setup_mock_request(mock_request) comment_id = "test_comment_id" updated_body = "updated body" @@ -815,14 +748,13 @@ def test_update_comment_basic(self, mock_is_forum_v2_enabled, mock_request): data={"body": updated_body} ) - def test_flag_thread_open(self, mock_is_forum_v2_enabled, mock_request): - self.flag_thread(mock_is_forum_v2_enabled, mock_request, False) + def test_flag_thread_open(self, mock_request): + self.flag_thread(mock_request, False) - def test_flag_thread_close(self, mock_is_forum_v2_enabled, mock_request): - self.flag_thread(mock_is_forum_v2_enabled, mock_request, True) + def test_flag_thread_close(self, mock_request): + self.flag_thread(mock_request, True) - def flag_thread(self, mock_is_forum_v2_enabled, mock_request, is_closed): - mock_is_forum_v2_enabled.return_value = False + def flag_thread(self, mock_request, is_closed): self._set_mock_request_data(mock_request, { "title": "Hello", "body": "this is a post", @@ -894,14 +826,13 @@ def flag_thread(self, mock_is_forum_v2_enabled, mock_request, is_closed): assert response.status_code == 200 - def test_un_flag_thread_open(self, mock_is_forum_v2_enabled, mock_request): - self.un_flag_thread(mock_is_forum_v2_enabled, mock_request, False) + def test_un_flag_thread_open(self, mock_request): + self.un_flag_thread(mock_request, False) - def test_un_flag_thread_close(self, mock_is_forum_v2_enabled, mock_request): - self.un_flag_thread(mock_is_forum_v2_enabled, mock_request, True) + def test_un_flag_thread_close(self, mock_request): + self.un_flag_thread(mock_request, True) - def un_flag_thread(self, mock_is_forum_v2_enabled, mock_request, is_closed): - mock_is_forum_v2_enabled.return_value = False + def un_flag_thread(self, mock_request, is_closed): self._set_mock_request_data(mock_request, { "title": "Hello", "body": "this is a post", @@ -974,14 +905,13 @@ def un_flag_thread(self, mock_is_forum_v2_enabled, mock_request, is_closed): assert response.status_code == 200 - def test_flag_comment_open(self, mock_is_forum_v2_enabled, mock_request): - self.flag_comment(mock_is_forum_v2_enabled, mock_request, False) + def test_flag_comment_open(self, mock_request): + self.flag_comment(mock_request, False) - def test_flag_comment_close(self, mock_is_forum_v2_enabled, mock_request): - self.flag_comment(mock_is_forum_v2_enabled, mock_request, True) + def test_flag_comment_close(self, mock_request): + self.flag_comment(mock_request, True) - def flag_comment(self, mock_is_forum_v2_enabled, mock_request, is_closed): - mock_is_forum_v2_enabled.return_value = False + def flag_comment(self, mock_request, is_closed): self._set_mock_request_data(mock_request, { "body": "this is a comment", "course_id": "MITx/999/Robot_Super_Course", @@ -1046,14 +976,13 @@ def flag_comment(self, mock_is_forum_v2_enabled, mock_request, is_closed): assert response.status_code == 200 - def test_un_flag_comment_open(self, mock_is_forum_v2_enabled, mock_request): - self.un_flag_comment(mock_is_forum_v2_enabled, mock_request, False) + def test_un_flag_comment_open(self, mock_request): + self.un_flag_comment(mock_request, False) - def test_un_flag_comment_close(self, mock_is_forum_v2_enabled, mock_request): - self.un_flag_comment(mock_is_forum_v2_enabled, mock_request, True) + def test_un_flag_comment_close(self, mock_request): + self.un_flag_comment(mock_request, True) - def un_flag_comment(self, mock_is_forum_v2_enabled, mock_request, is_closed): - mock_is_forum_v2_enabled.return_value = False + def un_flag_comment(self, mock_request, is_closed): self._set_mock_request_data(mock_request, { "body": "this is a comment", "course_id": "MITx/999/Robot_Super_Course", @@ -1125,8 +1054,7 @@ def un_flag_comment(self, mock_is_forum_v2_enabled, mock_request, is_closed): ('downvote_comment', 'comment_id', 'comment_voted') ) @ddt.unpack - def test_voting(self, view_name, item_id, signal, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def test_voting(self, view_name, item_id, signal, mock_request): self._setup_mock_request(mock_request) with self.assert_discussion_signals(signal): response = self.client.post( @@ -1137,8 +1065,7 @@ def test_voting(self, view_name, item_id, signal, mock_is_forum_v2_enabled, mock ) assert response.status_code == 200 - def test_endorse_comment(self, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def test_endorse_comment(self, mock_request): self._setup_mock_request(mock_request) self.client.login(username=self.moderator.username, password=self.password) with self.assert_discussion_signals('comment_endorsed', user=self.moderator): @@ -1152,7 +1079,6 @@ def test_endorse_comment(self, mock_is_forum_v2_enabled, mock_request): @patch("openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request", autospec=True) -@patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) @disable_signal(views, 'comment_endorsed') class ViewPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleStoreTestCase, MockRequestSetupMixin): @@ -1180,19 +1106,8 @@ def setUpTestData(cls): @patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) def setUp(self): super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - def test_pin_thread_as_student(self, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def test_pin_thread_as_student(self, mock_request): self._set_mock_request_data(mock_request, {}) self.client.login(username=self.student.username, password=self.password) response = self.client.post( @@ -1200,8 +1115,7 @@ def test_pin_thread_as_student(self, mock_is_forum_v2_enabled, mock_request): ) assert response.status_code == 401 - def test_pin_thread_as_moderator(self, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def test_pin_thread_as_moderator(self, mock_request): self._set_mock_request_data(mock_request, {}) self.client.login(username=self.moderator.username, password=self.password) response = self.client.post( @@ -1209,8 +1123,7 @@ def test_pin_thread_as_moderator(self, mock_is_forum_v2_enabled, mock_request): ) assert response.status_code == 200 - def test_un_pin_thread_as_student(self, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def test_un_pin_thread_as_student(self, mock_request): self._set_mock_request_data(mock_request, {}) self.client.login(username=self.student.username, password=self.password) response = self.client.post( @@ -1218,8 +1131,7 @@ def test_un_pin_thread_as_student(self, mock_is_forum_v2_enabled, mock_request): ) assert response.status_code == 401 - def test_un_pin_thread_as_moderator(self, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def test_un_pin_thread_as_moderator(self, mock_request): self._set_mock_request_data(mock_request, {}) self.client.login(username=self.moderator.username, password=self.password) response = self.client.post( @@ -1227,7 +1139,7 @@ def test_un_pin_thread_as_moderator(self, mock_is_forum_v2_enabled, mock_request ) assert response.status_code == 200 - def _set_mock_request_thread_and_comment(self, mock_is_forum_v2_enabled, mock_request, thread_data, comment_data): + def _set_mock_request_thread_and_comment(self, mock_request, thread_data, comment_data): def handle_request(*args, **kwargs): url = args[1] if "/threads/" in url: @@ -1236,12 +1148,10 @@ def handle_request(*args, **kwargs): return self._create_response_mock(comment_data) else: raise ArgumentError("Bad url to mock request") - mock_is_forum_v2_enabled.return_value = False mock_request.side_effect = handle_request - def test_endorse_response_as_staff(self, mock_is_forum_v2_enabled, mock_request): + def test_endorse_response_as_staff(self, mock_request): self._set_mock_request_thread_and_comment( - mock_is_forum_v2_enabled, mock_request, {"type": "thread", "thread_type": "question", "user_id": str(self.student.id), "commentable_id": "course"}, {"type": "comment", "thread_id": "dummy"} @@ -1252,9 +1162,8 @@ def test_endorse_response_as_staff(self, mock_is_forum_v2_enabled, mock_request) ) assert response.status_code == 200 - def test_endorse_response_as_student(self, mock_is_forum_v2_enabled, mock_request): + def test_endorse_response_as_student(self, mock_request): self._set_mock_request_thread_and_comment( - mock_is_forum_v2_enabled, mock_request, {"type": "thread", "thread_type": "question", "user_id": str(self.moderator.id), "commentable_id": "course"}, @@ -1266,9 +1175,8 @@ def test_endorse_response_as_student(self, mock_is_forum_v2_enabled, mock_reques ) assert response.status_code == 401 - def test_endorse_response_as_student_question_author(self, mock_is_forum_v2_enabled, mock_request): + def test_endorse_response_as_student_question_author(self, mock_request): self._set_mock_request_thread_and_comment( - mock_is_forum_v2_enabled, mock_request, {"type": "thread", "thread_type": "question", "user_id": str(self.student.id), "commentable_id": "course"}, {"type": "comment", "thread_id": "dummy"} @@ -1301,12 +1209,10 @@ def setUpTestData(cls): CourseEnrollmentFactory(user=cls.student, course_id=cls.course.id) @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def _test_unicode_data(self, text, mock_is_forum_v2_enabled, mock_request,): + def _test_unicode_data(self, text, mock_request,): """ Test to make sure unicode data in a thread doesn't break it. """ - mock_is_forum_v2_enabled.return_value = False self._set_mock_request_data(mock_request, {}) request = RequestFactory().post("dummy_url", {"thread_type": "discussion", "body": text, "title": text}) request.user = self.student @@ -1329,13 +1235,6 @@ class UpdateThreadUnicodeTestCase( UnicodeTestMixin, MockRequestSetupMixin ): - def setUp(self): - super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) @classmethod def setUpClass(cls): @@ -1356,9 +1255,7 @@ def setUpTestData(cls): return_value=["test_commentable"], ) @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def _test_unicode_data(self, text, mock_is_forum_v2_enabled, mock_request, mock_get_discussion_id_map): - mock_is_forum_v2_enabled.return_value = False + def _test_unicode_data(self, text, mock_request, mock_get_discussion_id_map): self._set_mock_request_data(mock_request, { "user_id": str(self.student.id), "closed": False, @@ -1383,13 +1280,6 @@ class CreateCommentUnicodeTestCase( UnicodeTestMixin, MockRequestSetupMixin ): - def setUp(self): - super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) @classmethod def setUpClass(cls): @@ -1406,9 +1296,7 @@ def setUpTestData(cls): CourseEnrollmentFactory(user=cls.student, course_id=cls.course.id) @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def _test_unicode_data(self, text, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def _test_unicode_data(self, text, mock_request): commentable_id = "non_team_dummy_id" self._set_mock_request_data(mock_request, { "closed": False, @@ -1439,13 +1327,6 @@ class UpdateCommentUnicodeTestCase( UnicodeTestMixin, MockRequestSetupMixin ): - def setUp(self): - super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) @classmethod def setUpClass(cls): @@ -1462,9 +1343,7 @@ def setUpTestData(cls): CourseEnrollmentFactory(user=cls.student, course_id=cls.course.id) @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def _test_unicode_data(self, text, mock_is_forum_v2_enabled, mock_request): - mock_is_forum_v2_enabled.return_value = False + def _test_unicode_data(self, text, mock_request): self._set_mock_request_data(mock_request, { "user_id": str(self.student.id), "closed": False, @@ -1480,7 +1359,6 @@ def _test_unicode_data(self, text, mock_is_forum_v2_enabled, mock_request): @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) -@patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) class CommentActionTestCase( MockRequestSetupMixin, CohortedTestCase, @@ -1489,18 +1367,11 @@ class CommentActionTestCase( def call_view( self, view_name, - mock_is_forum_v2_enabled, mock_request, user=None, post_params=None, view_args=None ): - mock_is_forum_v2_enabled.return_value = False - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) self._set_mock_request_data( mock_request, { @@ -1523,9 +1394,9 @@ def call_view( **(view_args or {}) ) - def test_flag(self, mock_is_forum_v2_enabled, mock_request): + def test_flag(self, mock_request): with mock.patch('openedx.core.djangoapps.django_comment_common.signals.comment_flagged.send') as signal_mock: - self.call_view("flag_abuse_for_comment", mock_is_forum_v2_enabled, mock_request) + self.call_view("flag_abuse_for_comment", mock_request) self.assertEqual(signal_mock.call_count, 1) @@ -1539,14 +1410,6 @@ class CreateSubCommentUnicodeTestCase( """ Make sure comments under a response can handle unicode. """ - def setUp(self): - super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - @classmethod def setUpClass(cls): # pylint: disable=super-method-not-called @@ -1562,12 +1425,10 @@ def setUpTestData(cls): CourseEnrollmentFactory(user=cls.student, course_id=cls.course.id) @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def _test_unicode_data(self, text, mock_is_forum_v2_enabled, mock_request): + def _test_unicode_data(self, text, mock_request): """ Create a comment with unicode in it. """ - mock_is_forum_v2_enabled.return_value = False self._set_mock_request_data(mock_request, { "closed": False, "depth": 1, @@ -1592,7 +1453,6 @@ def _test_unicode_data(self, text, mock_is_forum_v2_enabled, mock_request): @ddt.ddt @patch("openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request", autospec=True) -@patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) @disable_signal(views, 'thread_voted') @disable_signal(views, 'thread_edited') @disable_signal(views, 'comment_created') @@ -1702,24 +1562,13 @@ def create_users_and_enroll(coursemode): users=[cls.group_moderator, cls.cohorted] ) - @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) + @patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) def setUp(self): super().setUp() - def _setup_mock(self, user, mock_is_forum_v2_enabled, mock_request, data): + def _setup_mock(self, user, mock_request, data): user = getattr(self, user) - mock_is_forum_v2_enabled.return_value = False self._set_mock_request_data(mock_request, data) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.client.login(username=user.username, password=self.password) @ddt.data( @@ -1744,7 +1593,7 @@ def _setup_mock(self, user, mock_is_forum_v2_enabled, mock_request, data): ('group_moderator', 'cohorted', 'course_commentable_id', 401, CourseDiscussionSettings.NONE) ) @ddt.unpack - def test_update_thread(self, user, thread_author, commentable_id, status_code, division_scheme, mock_is_forum_v2_enabled, mock_request): + def test_update_thread(self, user, thread_author, commentable_id, status_code, division_scheme, mock_request): """ Verify that update_thread is limited to thread authors and privileged users (team membership does not matter). """ @@ -1754,7 +1603,7 @@ def test_update_thread(self, user, thread_author, commentable_id, status_code, d thread_author = getattr(self, thread_author) self._setup_mock( - user, mock_is_forum_v2_enabled, mock_request, # user is the person making the request. + user, mock_request, # user is the person making the request. { "user_id": str(thread_author.id), "closed": False, "commentable_id": commentable_id, @@ -1794,12 +1643,12 @@ def test_update_thread(self, user, thread_author, commentable_id, status_code, d ('group_moderator', 'cohorted', 'team_commentable_id', 401, CourseDiscussionSettings.NONE) ) @ddt.unpack - def test_delete_comment(self, user, comment_author, commentable_id, status_code, division_scheme, mock_is_forum_v2_enabled, mock_request): + def test_delete_comment(self, user, comment_author, commentable_id, status_code, division_scheme, mock_request): commentable_id = getattr(self, commentable_id) comment_author = getattr(self, comment_author) self.change_divided_discussion_settings(division_scheme) - self._setup_mock(user, mock_is_forum_v2_enabled, mock_request, { + self._setup_mock(user, mock_request, { "closed": False, "commentable_id": commentable_id, "user_id": str(comment_author.id), @@ -1822,12 +1671,12 @@ def test_delete_comment(self, user, comment_author, commentable_id, status_code, @ddt.data(*ddt_permissions_args) @ddt.unpack - def test_create_comment(self, user, commentable_id, status_code, mock_is_forum_v2_enabled, mock_request): + def test_create_comment(self, user, commentable_id, status_code, mock_request): """ Verify that create_comment is limited to members of the team or users with 'edit_content' permission. """ commentable_id = getattr(self, commentable_id) - self._setup_mock(user, mock_is_forum_v2_enabled, mock_request, {"closed": False, "commentable_id": commentable_id}) + self._setup_mock(user, mock_request, {"closed": False, "commentable_id": commentable_id}) response = self.client.post( reverse( @@ -1843,13 +1692,13 @@ def test_create_comment(self, user, commentable_id, status_code, mock_is_forum_v @ddt.data(*ddt_permissions_args) @ddt.unpack - def test_create_sub_comment(self, user, commentable_id, status_code, mock_is_forum_v2_enabled, mock_request): + def test_create_sub_comment(self, user, commentable_id, status_code, mock_request): """ Verify that create_subcomment is limited to members of the team or users with 'edit_content' permission. """ commentable_id = getattr(self, commentable_id) self._setup_mock( - user, mock_is_forum_v2_enabled, mock_request, + user, mock_request, {"closed": False, "commentable_id": commentable_id, "thread_id": "dummy_thread"}, ) response = self.client.post( @@ -1866,14 +1715,14 @@ def test_create_sub_comment(self, user, commentable_id, status_code, mock_is_for @ddt.data(*ddt_permissions_args) @ddt.unpack - def test_comment_actions(self, user, commentable_id, status_code, mock_is_forum_v2_enabled, mock_request): + def test_comment_actions(self, user, commentable_id, status_code, mock_request): """ Verify that voting and flagging of comments is limited to members of the team or users with 'edit_content' permission. """ commentable_id = getattr(self, commentable_id) self._setup_mock( - user, mock_is_forum_v2_enabled, mock_request, + user, mock_request, { "closed": False, "commentable_id": commentable_id, @@ -1893,14 +1742,14 @@ def test_comment_actions(self, user, commentable_id, status_code, mock_is_forum_ @ddt.data(*ddt_permissions_args) @ddt.unpack - def test_threads_actions(self, user, commentable_id, status_code, mock_is_forum_v2_enabled, mock_request): + def test_threads_actions(self, user, commentable_id, status_code, mock_request): """ Verify that voting, flagging, and following of threads is limited to members of the team or users with 'edit_content' permission. """ commentable_id = getattr(self, commentable_id) self._setup_mock( - user, mock_is_forum_v2_enabled, mock_request, + user, mock_request, {"closed": False, "commentable_id": commentable_id, "body": "dummy body", "course_id": str(self.course.id)} ) for action in ["upvote_thread", "downvote_thread", "un_flag_abuse_for_thread", "flag_abuse_for_thread", @@ -1923,19 +1772,6 @@ class ForumEventTestCase(ForumsEnableMixin, SharedModuleStoreTestCase, MockReque """ Forum actions are expected to launch analytics events. Test these here. """ - def setUp(self): - super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - @classmethod def setUpClass(cls): # pylint: disable=super-method-not-called @@ -1955,14 +1791,12 @@ def setUpTestData(cls): @patch('eventtracking.tracker.emit') @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def test_response_event(self, mock_is_forum_v2_enabled, mock_request, mock_emit): + def test_response_event(self, mock_request, mock_emit): """ Check to make sure an event is fired when a user responds to a thread. """ event_receiver = Mock() FORUM_THREAD_RESPONSE_CREATED.connect(event_receiver) - mock_is_forum_v2_enabled.return_value = False self._set_mock_request_data(mock_request, { "closed": False, "commentable_id": 'test_commentable_id', @@ -1999,14 +1833,12 @@ def test_response_event(self, mock_is_forum_v2_enabled, mock_request, mock_emit) @patch('eventtracking.tracker.emit') @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def test_comment_event(self, mock_is_forum_v2_enabled, mock_request, mock_emit): + def test_comment_event(self, mock_request, mock_emit): """ Ensure an event is fired when someone comments on a response. """ event_receiver = Mock() FORUM_RESPONSE_COMMENT_CREATED.connect(event_receiver) - mock_is_forum_v2_enabled.return_value = False self._set_mock_request_data(mock_request, { "closed": False, "depth": 1, @@ -2043,7 +1875,6 @@ def test_comment_event(self, mock_is_forum_v2_enabled, mock_request, mock_emit): @patch('eventtracking.tracker.emit') @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) @ddt.data(( 'create_thread', 'edx.forum.thread.created', { @@ -2065,7 +1896,7 @@ def test_comment_event(self, mock_is_forum_v2_enabled, mock_request, mock_emit): {'comment_id': 'dummy_comment_id'} )) @ddt.unpack - def test_team_events(self, view_name, event_name, view_data, view_kwargs, mock_is_forum_v2_enabled, mock_request, mock_emit): + def test_team_events(self, view_name, event_name, view_data, view_kwargs, mock_request, mock_emit): user = self.student team = CourseTeamFactory.create(discussion_topic_id=TEAM_COMMENTABLE_ID) CourseTeamMembershipFactory.create(team=team, user=user) @@ -2074,7 +1905,6 @@ def test_team_events(self, view_name, event_name, view_data, view_kwargs, mock_i forum_event = views.TRACKING_LOG_TO_EVENT_MAPS.get(event_name) forum_event.connect(event_receiver) - mock_is_forum_v2_enabled.return_value = False self._set_mock_request_data(mock_request, { 'closed': False, 'commentable_id': TEAM_COMMENTABLE_ID, @@ -2113,11 +1943,9 @@ def test_team_events(self, view_name, event_name, view_data, view_kwargs, mock_i @ddt.unpack @patch('eventtracking.tracker.emit') @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def test_thread_voted_event(self, view_name, obj_id_name, obj_type, mock_is_forum_v2_enabled, mock_request, mock_emit): + def test_thread_voted_event(self, view_name, obj_id_name, obj_type, mock_request, mock_emit): undo = view_name.startswith('undo') - mock_is_forum_v2_enabled.return_value = False self._set_mock_request_data(mock_request, { 'closed': False, 'commentable_id': 'test_commentable_id', @@ -2143,13 +1971,11 @@ def test_thread_voted_event(self, view_name, obj_id_name, obj_type, mock_is_foru @ddt.data('follow_thread', 'unfollow_thread',) @patch('eventtracking.tracker.emit') @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def test_thread_followed_event(self, view_name, mock_is_forum_v2_enabled, mock_request, mock_emit): + def test_thread_followed_event(self, view_name, mock_request, mock_emit): event_receiver = Mock() for signal in views.TRACKING_LOG_TO_EVENT_MAPS.values(): signal.connect(event_receiver) - mock_is_forum_v2_enabled.return_value = False self._set_mock_request_data(mock_request, { 'closed': False, 'commentable_id': 'test_commentable_id', @@ -2199,11 +2025,10 @@ def setUpTestData(cls): cls.other_user = UserFactory.create(username="other") CourseEnrollmentFactory(user=cls.other_user, course_id=cls.course.id) - def set_post_counts(self, mock_is_forum_v2_enabled, mock_request, threads_count=1, comments_count=1): + def set_post_counts(self, mock_request, threads_count=1, comments_count=1): """ sets up a mock response from the comments service for getting post counts for our other_user """ - mock_is_forum_v2_enabled.return_value = False self._set_mock_request_data(mock_request, { "threads_count": threads_count, "comments_count": comments_count, @@ -2217,17 +2042,15 @@ def make_request(self, method='get', course_id=None, **kwargs): return views.users(request, course_id=str(course_id)) @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def test_finds_exact_match(self, mock_is_forum_v2_enabled, mock_request): - self.set_post_counts(mock_is_forum_v2_enabled, mock_request) + def test_finds_exact_match(self, mock_request): + self.set_post_counts(mock_request) response = self.make_request(username="other") assert response.status_code == 200 assert json.loads(response.content.decode('utf-8'))['users'] == [{'id': self.other_user.id, 'username': self.other_user.username}] @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def test_finds_no_match(self, mock_is_forum_v2_enabled, mock_request): - self.set_post_counts(mock_is_forum_v2_enabled, mock_request) + def test_finds_no_match(self, mock_request): + self.set_post_counts(mock_request) response = self.make_request(username="othor") assert response.status_code == 200 assert json.loads(response.content.decode('utf-8'))['users'] == [] @@ -2263,9 +2086,8 @@ def test_requires_requestor_enrolled_in_course(self): assert 'users' not in content @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) - @patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) - def test_requires_matched_user_has_forum_content(self, mock_is_forum_v2_enabled, mock_request): - self.set_post_counts(mock_is_forum_v2_enabled, mock_request, 0, 0) + def test_requires_matched_user_has_forum_content(self, mock_request): + self.set_post_counts(mock_request, 0, 0) response = self.make_request(username="other") assert response.status_code == 200 assert json.loads(response.content.decode('utf-8'))['users'] == [] diff --git a/lms/djangoapps/discussion/django_comment_client/base/views.py b/lms/djangoapps/discussion/django_comment_client/base/views.py index 3df362bdf6d2..e3e52a5400a4 100644 --- a/lms/djangoapps/discussion/django_comment_client/base/views.py +++ b/lms/djangoapps/discussion/django_comment_client/base/views.py @@ -562,6 +562,7 @@ def create_thread(request, course_id, commentable_id): params['context'] = ThreadContext.STANDALONE else: params['context'] = ThreadContext.COURSE + thread = cc.Thread(**params) # Divide the thread if required diff --git a/lms/djangoapps/discussion/django_comment_client/tests/group_id.py b/lms/djangoapps/discussion/django_comment_client/tests/group_id.py index 0a5fbe491930..78853293ec46 100644 --- a/lms/djangoapps/discussion/django_comment_client/tests/group_id.py +++ b/lms/djangoapps/discussion/django_comment_client/tests/group_id.py @@ -60,76 +60,51 @@ class CohortedTopicGroupIdTestMixin(GroupIdAssertionMixin): Provides test cases to verify that views pass the correct `group_id` to the comments service when requesting content in cohorted discussions. """ - def call_view(self, mock_is_forum_v2_enabled, mock_request, commentable_id, user, group_id, pass_group_id=True): + def call_view(self, mock_request, commentable_id, user, group_id, pass_group_id=True): """ Call the view for the implementing test class, constructing a request from the parameters. """ pass # lint-amnesty, pylint: disable=unnecessary-pass - def test_cohorted_topic_student_without_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view(mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.student, '', pass_group_id=False) + def test_cohorted_topic_student_without_group_id(self, mock_request): + self.call_view(mock_request, "cohorted_topic", self.student, '', pass_group_id=False) self._assert_comments_service_called_with_group_id(mock_request, self.student_cohort.id) - def test_cohorted_topic_student_none_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view(mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.student, "") + def test_cohorted_topic_student_none_group_id(self, mock_request): + self.call_view(mock_request, "cohorted_topic", self.student, "") self._assert_comments_service_called_with_group_id(mock_request, self.student_cohort.id) - def test_cohorted_topic_student_with_own_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view(mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.student, self.student_cohort.id) + def test_cohorted_topic_student_with_own_group_id(self, mock_request): + self.call_view(mock_request, "cohorted_topic", self.student, self.student_cohort.id) self._assert_comments_service_called_with_group_id(mock_request, self.student_cohort.id) - def test_cohorted_topic_student_with_other_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view( - mock_is_forum_v2_enabled, - mock_request, - "cohorted_topic", - self.student, - self.moderator_cohort.id - ) + def test_cohorted_topic_student_with_other_group_id(self, mock_request): + self.call_view(mock_request, "cohorted_topic", self.student, self.moderator_cohort.id) self._assert_comments_service_called_with_group_id(mock_request, self.student_cohort.id) - def test_cohorted_topic_moderator_without_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view( - mock_is_forum_v2_enabled, - mock_request, - "cohorted_topic", - self.moderator, - '', - pass_group_id=False - ) + def test_cohorted_topic_moderator_without_group_id(self, mock_request): + self.call_view(mock_request, "cohorted_topic", self.moderator, '', pass_group_id=False) self._assert_comments_service_called_without_group_id(mock_request) - def test_cohorted_topic_moderator_none_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view(mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.moderator, "") + def test_cohorted_topic_moderator_none_group_id(self, mock_request): + self.call_view(mock_request, "cohorted_topic", self.moderator, "") self._assert_comments_service_called_without_group_id(mock_request) - def test_cohorted_topic_moderator_with_own_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view( - mock_is_forum_v2_enabled, - mock_request, - "cohorted_topic", - self.moderator, - self.moderator_cohort.id - ) + def test_cohorted_topic_moderator_with_own_group_id(self, mock_request): + self.call_view(mock_request, "cohorted_topic", self.moderator, self.moderator_cohort.id) self._assert_comments_service_called_with_group_id(mock_request, self.moderator_cohort.id) - def test_cohorted_topic_moderator_with_other_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view( - mock_is_forum_v2_enabled, - mock_request, - "cohorted_topic", - self.moderator, - self.student_cohort.id - ) + def test_cohorted_topic_moderator_with_other_group_id(self, mock_request): + self.call_view(mock_request, "cohorted_topic", self.moderator, self.student_cohort.id) self._assert_comments_service_called_with_group_id(mock_request, self.student_cohort.id) - def test_cohorted_topic_moderator_with_invalid_group_id(self, mock_is_forum_v2_enabled, mock_request): + def test_cohorted_topic_moderator_with_invalid_group_id(self, mock_request): invalid_id = self.student_cohort.id + self.moderator_cohort.id - response = self.call_view(mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.moderator, invalid_id) # lint-amnesty, pylint: disable=assignment-from-no-return + response = self.call_view(mock_request, "cohorted_topic", self.moderator, invalid_id) # lint-amnesty, pylint: disable=assignment-from-no-return assert response.status_code == 500 - def test_cohorted_topic_enrollment_track_invalid_group_id(self, mock_is_forum_v2_enabled, mock_request): + def test_cohorted_topic_enrollment_track_invalid_group_id(self, mock_request): CourseModeFactory.create(course_id=self.course.id, mode_slug=CourseMode.AUDIT) CourseModeFactory.create(course_id=self.course.id, mode_slug=CourseMode.VERIFIED) discussion_settings = CourseDiscussionSettings.get(self.course.id) @@ -140,7 +115,7 @@ def test_cohorted_topic_enrollment_track_invalid_group_id(self, mock_is_forum_v2 }) invalid_id = -1000 - response = self.call_view(mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.moderator, invalid_id) # lint-amnesty, pylint: disable=assignment-from-no-return + response = self.call_view(mock_request, "cohorted_topic", self.moderator, invalid_id) # lint-amnesty, pylint: disable=assignment-from-no-return assert response.status_code == 500 @@ -149,95 +124,57 @@ class NonCohortedTopicGroupIdTestMixin(GroupIdAssertionMixin): Provides test cases to verify that views pass the correct `group_id` to the comments service when requesting content in non-cohorted discussions. """ - def call_view(self, mock_is_forum_v2_enabled, mock_request, commentable_id, user, group_id, pass_group_id=True): + def call_view(self, mock_request, commentable_id, user, group_id, pass_group_id=True): """ Call the view for the implementing test class, constructing a request from the parameters. """ pass # lint-amnesty, pylint: disable=unnecessary-pass - def test_non_cohorted_topic_student_without_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view( - mock_is_forum_v2_enabled, - mock_request, - "non_cohorted_topic", - self.student, - '', - pass_group_id=False - ) + def test_non_cohorted_topic_student_without_group_id(self, mock_request): + self.call_view(mock_request, "non_cohorted_topic", self.student, '', pass_group_id=False) self._assert_comments_service_called_without_group_id(mock_request) - def test_non_cohorted_topic_student_none_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view(mock_is_forum_v2_enabled, mock_request, "non_cohorted_topic", self.student, '') + def test_non_cohorted_topic_student_none_group_id(self, mock_request): + self.call_view(mock_request, "non_cohorted_topic", self.student, '') self._assert_comments_service_called_without_group_id(mock_request) - def test_non_cohorted_topic_student_with_own_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view( - mock_is_forum_v2_enabled, - mock_request, - "non_cohorted_topic", - self.student, - self.student_cohort.id - ) + def test_non_cohorted_topic_student_with_own_group_id(self, mock_request): + self.call_view(mock_request, "non_cohorted_topic", self.student, self.student_cohort.id) self._assert_comments_service_called_without_group_id(mock_request) - def test_non_cohorted_topic_student_with_other_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view( - mock_is_forum_v2_enabled, - mock_request, - "non_cohorted_topic", - self.student, - self.moderator_cohort.id - ) + def test_non_cohorted_topic_student_with_other_group_id(self, mock_request): + self.call_view(mock_request, "non_cohorted_topic", self.student, self.moderator_cohort.id) self._assert_comments_service_called_without_group_id(mock_request) - def test_non_cohorted_topic_moderator_without_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view( - mock_is_forum_v2_enabled, - mock_request, - "non_cohorted_topic", - self.moderator, - "", - pass_group_id=False, - ) + def test_non_cohorted_topic_moderator_without_group_id(self, mock_request): + self.call_view(mock_request, "non_cohorted_topic", self.moderator, '', pass_group_id=False) self._assert_comments_service_called_without_group_id(mock_request) - def test_non_cohorted_topic_moderator_none_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view(mock_is_forum_v2_enabled, mock_request, "non_cohorted_topic", self.moderator, '') + def test_non_cohorted_topic_moderator_none_group_id(self, mock_request): + self.call_view(mock_request, "non_cohorted_topic", self.moderator, '') self._assert_comments_service_called_without_group_id(mock_request) - def test_non_cohorted_topic_moderator_with_own_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view( - mock_is_forum_v2_enabled, - mock_request, - "non_cohorted_topic", - self.moderator, - self.moderator_cohort.id, - ) + def test_non_cohorted_topic_moderator_with_own_group_id(self, mock_request): + self.call_view(mock_request, "non_cohorted_topic", self.moderator, self.moderator_cohort.id) self._assert_comments_service_called_without_group_id(mock_request) - def test_non_cohorted_topic_moderator_with_other_group_id(self, mock_is_forum_v2_enabled, mock_request): - self.call_view( - mock_is_forum_v2_enabled, - mock_request, - "non_cohorted_topic", - self.moderator, - self.student_cohort.id, - ) + def test_non_cohorted_topic_moderator_with_other_group_id(self, mock_request): + self.call_view(mock_request, "non_cohorted_topic", self.moderator, self.student_cohort.id) self._assert_comments_service_called_without_group_id(mock_request) - def test_non_cohorted_topic_moderator_with_invalid_group_id(self, mock_is_forum_v2_enabled, mock_request): + def test_non_cohorted_topic_moderator_with_invalid_group_id(self, mock_request): invalid_id = self.student_cohort.id + self.moderator_cohort.id - self.call_view(mock_is_forum_v2_enabled, mock_request, "non_cohorted_topic", self.moderator, invalid_id) + self.call_view(mock_request, "non_cohorted_topic", self.moderator, invalid_id) self._assert_comments_service_called_without_group_id(mock_request) - def test_team_discussion_id_not_cohorted(self, mock_is_forum_v2_enabled, mock_request): + def test_team_discussion_id_not_cohorted(self, mock_request): team = CourseTeamFactory( course_id=self.course.id, topic_id='topic-id' ) team.add_user(self.student) - self.call_view(mock_is_forum_v2_enabled, mock_request, team.discussion_topic_id, self.student, '') + self.call_view(mock_request, team.discussion_topic_id, self.student, '') self._assert_comments_service_called_without_group_id(mock_request) diff --git a/lms/djangoapps/discussion/rest_api/api.py b/lms/djangoapps/discussion/rest_api/api.py index a517e00dff34..19ccf26d19a4 100644 --- a/lms/djangoapps/discussion/rest_api/api.py +++ b/lms/djangoapps/discussion/rest_api/api.py @@ -199,7 +199,7 @@ def _get_course(course_key: CourseKey, user: User, check_tab: bool = True) -> Co return course -def _get_thread_and_context(request, thread_id, retrieve_kwargs=None, course_id=None): +def _get_thread_and_context(request, thread_id, retrieve_kwargs=None): """ Retrieve the given thread and build a serializer context for it, returning both. This function also enforces access control for the thread (checking @@ -213,7 +213,7 @@ def _get_thread_and_context(request, thread_id, retrieve_kwargs=None, course_id= retrieve_kwargs["with_responses"] = False if "mark_as_read" not in retrieve_kwargs: retrieve_kwargs["mark_as_read"] = False - cc_thread = Thread(id=thread_id).retrieve(course_id=course_id, **retrieve_kwargs) + cc_thread = Thread(id=thread_id).retrieve(**retrieve_kwargs) course_key = CourseKey.from_string(cc_thread["course_id"]) course = _get_course(course_key, request.user) context = get_context(course, request, cc_thread) @@ -1645,8 +1645,7 @@ def get_thread(request, thread_id, requested_fields=None, course_id=None): retrieve_kwargs={ "with_responses": True, "user_id": str(request.user.id), - }, - course_id=course_id, + } ) if course_id and course_id != cc_thread.course_id: raise ThreadNotFoundError("Thread not found.") diff --git a/lms/djangoapps/discussion/rest_api/discussions_notifications.py b/lms/djangoapps/discussion/rest_api/discussions_notifications.py index bd12e82adc50..88c7fea558c1 100644 --- a/lms/djangoapps/discussion/rest_api/discussions_notifications.py +++ b/lms/djangoapps/discussion/rest_api/discussions_notifications.py @@ -202,7 +202,7 @@ def send_response_on_followed_post_notification(self): while has_more_subscribers: - subscribers = Subscription.fetch(self.thread.id, self.course.id, query_params={'page': page}) + subscribers = Subscription.fetch(self.thread.id, query_params={'page': page}) if page <= subscribers.num_pages: for subscriber in subscribers.collection: # Check if the subscriber is not the thread creator or response creator diff --git a/lms/djangoapps/discussion/rest_api/serializers.py b/lms/djangoapps/discussion/rest_api/serializers.py index ff0c656baf28..f8868cbed8c8 100644 --- a/lms/djangoapps/discussion/rest_api/serializers.py +++ b/lms/djangoapps/discussion/rest_api/serializers.py @@ -68,7 +68,7 @@ def get_context(course, request, thread=None): moderator_user_ids = get_moderator_users_list(course.id) ta_user_ids = get_course_ta_users_list(course.id) requester = request.user - cc_requester = CommentClientUser.from_django_user(requester).retrieve(course_id=course.id) + cc_requester = CommentClientUser.from_django_user(requester).retrieve() cc_requester["course_id"] = course.id course_discussion_settings = CourseDiscussionSettings.get(course.id) is_global_staff = GlobalStaff().has_user(requester) diff --git a/lms/djangoapps/discussion/rest_api/tests/test_api.py b/lms/djangoapps/discussion/rest_api/tests/test_api.py index 62725cc47466..9a9041fd5fa4 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_api.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_api.py @@ -1248,22 +1248,6 @@ def setUp(self): httpretty.enable() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.maxDiff = None # pylint: disable=invalid-name self.user = UserFactory.create() self.register_get_user_response(self.user) @@ -1888,12 +1872,6 @@ def setUp(self): httpretty.enable() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) self.user = UserFactory.create() self.register_get_user_response(self.user) self.request = RequestFactory().get("/test_path") @@ -2220,22 +2198,6 @@ def setUp(self): self.course = CourseFactory.create() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.user = UserFactory.create() self.register_get_user_response(self.user) self.request = RequestFactory().get("/test_path") @@ -2627,17 +2589,6 @@ def setUp(self): httpretty.enable() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.user = UserFactory.create() self.register_get_user_response(self.user) @@ -3202,22 +3153,6 @@ def setUp(self): self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.user = UserFactory.create() self.register_get_user_response(self.user) self.request = RequestFactory().get("/test_path") @@ -3735,22 +3670,6 @@ def setUp(self): httpretty.enable() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.user = UserFactory.create() self.register_get_user_response(self.user) self.request = RequestFactory().get("/test_path") @@ -3904,22 +3823,6 @@ def setUp(self): httpretty.enable() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.user = UserFactory.create() self.register_get_user_response(self.user) self.request = RequestFactory().get("/test_path") @@ -4088,17 +3991,6 @@ def setUp(self): httpretty.enable() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.user = UserFactory.create() self.register_get_user_response(self.user) self.request = RequestFactory().get("/test_path") diff --git a/lms/djangoapps/discussion/rest_api/tests/test_serializers.py b/lms/djangoapps/discussion/rest_api/tests/test_serializers.py index 73b195e02fa6..8103eb692791 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_serializers.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_serializers.py @@ -54,12 +54,6 @@ def setUp(self): httpretty.enable() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) self.maxDiff = None # pylint: disable=invalid-name self.user = UserFactory.create() self.register_get_user_response(self.user) @@ -577,12 +571,6 @@ def setUp(self): httpretty.enable() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) self.user = UserFactory.create() self.register_get_user_response(self.user) self.request = RequestFactory().get("/dummy") @@ -814,22 +802,6 @@ def setUp(self): httpretty.enable() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.user = UserFactory.create() self.register_get_user_response(self.user) self.request = RequestFactory().get("/dummy") diff --git a/lms/djangoapps/discussion/rest_api/tests/test_tasks.py b/lms/djangoapps/discussion/rest_api/tests/test_tasks.py index 6aff0673cc73..ddfc120a8e4b 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_tasks.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_tasks.py @@ -58,27 +58,10 @@ def setUp(self): Setup test case """ super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) + # Creating a course self.course = CourseFactory.create() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread", - return_value=self.course.id - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment", - return_value=self.course.id - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) # Creating relative discussion and cohort settings CourseCohortsSettings.objects.create(course_id=str(self.course.id)) CourseDiscussionSettings.objects.create(course_id=str(self.course.id), _divided_discussions='[]') @@ -267,26 +250,8 @@ def setUp(self): super().setUp() httpretty.reset() httpretty.enable() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) self.course = CourseFactory.create() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread", - return_value=self.course.id - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment", - return_value=self.course.id - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) self.user_1 = UserFactory.create() CourseEnrollment.enroll(self.user_1, self.course.id) self.user_2 = UserFactory.create() @@ -571,26 +536,8 @@ def setUp(self): super().setUp() httpretty.reset() httpretty.enable() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) self.course = CourseFactory.create() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread", - return_value=self.course.id - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment", - return_value=self.course.id - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) self.user_1 = UserFactory.create() CourseEnrollment.enroll(self.user_1, self.course.id) self.user_2 = UserFactory.create() @@ -656,26 +603,8 @@ def setUp(self): super().setUp() httpretty.reset() httpretty.enable() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) self.course = CourseFactory.create() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread", - return_value=self.course.id - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment", - return_value=self.course.id - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) self.user_1 = UserFactory.create() CourseEnrollment.enroll(self.user_1, self.course.id) self.user_2 = UserFactory.create() diff --git a/lms/djangoapps/discussion/rest_api/tests/test_views.py b/lms/djangoapps/discussion/rest_api/tests/test_views.py index 9ae03986bb93..283117000712 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_views.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_views.py @@ -171,12 +171,6 @@ def setUp(self): self.user = UserFactory.create(password=self.TEST_PASSWORD) self.course = CourseFactory.create(org='a', course='b', run='c', start=datetime.now(UTC)) self.url = reverse("upload_file", kwargs={"course_id": str(self.course.id)}) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) def user_login(self): """ @@ -307,7 +301,6 @@ def test_file_upload_with_no_data(self): @ddt.ddt @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) -@mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_FORUM_V2": False}) class CommentViewSetListByUserTest( ForumsEnableMixin, CommentsServiceMockMixin, @@ -326,12 +319,6 @@ def setUp(self): httpretty.enable() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) self.user = UserFactory.create(password=self.TEST_PASSWORD) self.register_get_user_response(self.user) @@ -513,12 +500,6 @@ class CourseViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase): def setUp(self): super().setUp() self.url = reverse("discussion_course", kwargs={"course_id": str(self.course.id)}) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) def test_404(self): response = self.client.get( @@ -580,12 +561,6 @@ def setUp(self): self.superuser_client = APIClient() self.retired_username = get_retired_username_by_username(self.user.username) self.url = reverse("retire_discussion_user") - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) def assert_response_correct(self, response, expected_status, expected_content): """ @@ -656,12 +631,6 @@ def setUp(self): self.worker_client = APIClient() self.new_username = "test_username_replacement" self.url = reverse("replace_discussion_username") - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) def assert_response_correct(self, response, expected_status, expected_content): """ @@ -764,12 +733,6 @@ def setUp(self): "courseware-3": {"discussion": 7, "question": 2}, } self.register_get_course_commentable_counts_response(self.course.id, self.thread_counts_map) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) def create_course(self, blocks_count, module_store, topics): """ @@ -1025,12 +988,6 @@ def setUp(self) -> None: patcher.start() self.addCleanup(patcher.stop) self.url = reverse("course_topics_v3", kwargs={"course_id": str(self.course.id)}) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) def test_basic(self): response = self.client.get(self.url) @@ -1067,12 +1024,6 @@ def setUp(self): super().setUp() self.author = UserFactory.create() self.url = reverse("thread-list") - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) def create_source_thread(self, overrides=None): """ @@ -1414,12 +1365,6 @@ class ThreadViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase): def setUp(self): super().setUp() self.url = reverse("thread-list") - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) def test_basic(self): self.register_get_user_response(self.user) @@ -1492,17 +1437,6 @@ def setUp(self): self.unsupported_media_type = JSONParser.media_type super().setUp() self.url = reverse("thread-detail", kwargs={"thread_id": "test_thread"}) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) def test_basic(self): self.register_get_user_response(self.user) @@ -1647,17 +1581,6 @@ def setUp(self): super().setUp() self.url = reverse("thread-detail", kwargs={"thread_id": "test_thread"}) self.thread_id = "test_thread" - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) def test_basic(self): self.register_get_user_response(self.user) @@ -1758,12 +1681,6 @@ def setUp(self): ] self.url = reverse("discussion_learner_threads", kwargs={'course_id': str(self.course.id)}) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) def update_thread(self, thread): """ @@ -2006,17 +1923,6 @@ def setUp(self): self.url = reverse("comment-list") self.thread_id = "test_thread" self.storage = get_profile_image_storage() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) def create_source_comment(self, overrides=None): """ @@ -2471,22 +2377,6 @@ def setUp(self): super().setUp() self.url = reverse("comment-detail", kwargs={"comment_id": "test_comment"}) self.comment_id = "test_comment" - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) def test_basic(self): self.register_get_user_response(self.user) @@ -2526,23 +2416,6 @@ class CommentViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase): def setUp(self): super().setUp() self.url = reverse("comment-list") - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) def test_basic(self): self.register_get_user_response(self.user) @@ -2645,22 +2518,6 @@ def setUp(self): httpretty.enable() self.addCleanup(httpretty.reset) self.addCleanup(httpretty.disable) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.register_get_user_response(self.user) self.url = reverse("comment-detail", kwargs={"comment_id": "test_comment"}) @@ -2783,22 +2640,6 @@ def setUp(self): super().setUp() self.url = reverse("thread-detail", kwargs={"thread_id": "test_thread"}) self.thread_id = "test_thread" - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) def test_basic(self): self.register_get_user_response(self.user) @@ -2852,22 +2693,6 @@ def setUp(self): self.url = reverse("comment-detail", kwargs={"comment_id": "test_comment"}) self.thread_id = "test_thread" self.comment_id = "test_comment" - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) def make_comment_data(self, comment_id, parent_id=None, children=[]): # pylint: disable=W0102 """ @@ -3013,12 +2838,6 @@ def setUp(self): self.path = reverse('discussion_course_settings', kwargs={'course_id': str(self.course.id)}) self.password = self.TEST_PASSWORD self.user = UserFactory(username='staff', password=self.password, is_staff=True) - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) def _get_oauth_headers(self, user): """Return the OAuth headers for testing OAuth authentication""" @@ -3308,12 +3127,6 @@ class CourseDiscussionRolesAPIViewTest(APITestCase, UrlResetMixin, ModuleStoreTe @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) def setUp(self): super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) self.course = CourseFactory.create( org="x", course="y", @@ -3505,12 +3318,6 @@ class CourseActivityStatsTest(ForumsEnableMixin, UrlResetMixin, CommentsServiceM @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) def setUp(self) -> None: super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) self.course = CourseFactory.create() self.course_key = str(self.course.id) seed_permissions_roles(self.course.id) diff --git a/lms/djangoapps/discussion/tests/test_tasks.py b/lms/djangoapps/discussion/tests/test_tasks.py index 952a6c567a52..92dadac9d9ee 100644 --- a/lms/djangoapps/discussion/tests/test_tasks.py +++ b/lms/djangoapps/discussion/tests/test_tasks.py @@ -232,22 +232,6 @@ def setUp(self): thread_permalink = '/courses/discussion/dummy_discussion_id' self.permalink_patcher = mock.patch('lms.djangoapps.discussion.tasks.permalink', return_value=thread_permalink) self.mock_permalink = self.permalink_patcher.start() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) def tearDown(self): super().tearDown() diff --git a/lms/djangoapps/discussion/tests/test_views.py b/lms/djangoapps/discussion/tests/test_views.py index facdb368f14f..e0d3b869da3d 100644 --- a/lms/djangoapps/discussion/tests/test_views.py +++ b/lms/djangoapps/discussion/tests/test_views.py @@ -4,7 +4,6 @@ import json import logging from datetime import datetime -from unittest import mock from unittest.mock import ANY, Mock, call, patch import ddt @@ -110,20 +109,9 @@ def setUp(self): config = ForumsConfig.current() config.enabled = True config.save() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) @patch('common.djangoapps.student.models.user.cc.User.from_django_user') - @patch('openedx.core.djangoapps.django_comment_common.comment_client.user.User.active_threads') + @patch('common.djangoapps.student.models.user.cc.User.active_threads') def test_user_profile_exception(self, mock_threads, mock_from_django_user): # Mock the code that makes the HTTP requests to the cs_comment_service app @@ -335,17 +323,6 @@ class SingleThreadTestCase(ForumsEnableMixin, ModuleStoreTestCase): # lint-amne def setUp(self): super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.course = CourseFactory.create(discussion_topics={'dummy discussion': {'id': 'dummy_discussion_id'}}) self.student = UserFactory.create() @@ -536,20 +513,6 @@ class SingleThreadQueryCountTestCase(ForumsEnableMixin, ModuleStoreTestCase): Ensures the number of modulestore queries and number of sql queries are independent of the number of responses retrieved for a given discussion thread. """ - def setUp(self): - super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - @ddt.data( # split mongo: 3 queries, regardless of thread response size. (False, 1, 2, 2, 21, 8), @@ -619,20 +582,6 @@ def call_single_thread(): @patch('requests.request', autospec=True) class SingleCohortedThreadTestCase(CohortedTestCase): # lint-amnesty, pylint: disable=missing-class-docstring - def setUp(self): - super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - def _create_mock_cohorted_thread(self, mock_request): # lint-amnesty, pylint: disable=missing-function-docstring mock_text = "dummy content" mock_thread_id = "test_thread_id" @@ -695,20 +644,6 @@ def test_html(self, mock_request): @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) class SingleThreadAccessTestCase(CohortedTestCase): # lint-amnesty, pylint: disable=missing-class-docstring - def setUp(self): - super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - def call_view(self, mock_request, commentable_id, user, group_id, thread_group_id=None, pass_group_id=True): # lint-amnesty, pylint: disable=missing-function-docstring thread_id = "test_thread_id" mock_request.side_effect = make_mock_request_impl( @@ -811,20 +746,6 @@ def test_private_team_thread(self, mock_request): class SingleThreadGroupIdTestCase(CohortedTestCase, GroupIdAssertionMixin): # lint-amnesty, pylint: disable=missing-class-docstring cs_endpoint = "/threads/dummy_thread_id" - def setUp(self): - super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - def call_view(self, mock_request, commentable_id, user, group_id, pass_group_id=True, is_ajax=False): # lint-amnesty, pylint: disable=missing-function-docstring mock_request.side_effect = make_mock_request_impl( course=self.course, text="dummy context", group_id=self.student_cohort.id @@ -960,22 +881,6 @@ class SingleThreadContentGroupTestCase(ForumsEnableMixin, UrlResetMixin, Content @patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) def setUp(self): super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) def assert_can_access(self, user, discussion_id, thread_id, should_have_access): """ @@ -1141,7 +1046,6 @@ def test_private_team_discussion(self, mock_request): @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) -@patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) class InlineDiscussionGroupIdTestCase( # lint-amnesty, pylint: disable=missing-class-docstring CohortedTestCase, CohortedTopicGroupIdTestMixin, @@ -1152,22 +1056,8 @@ class InlineDiscussionGroupIdTestCase( # lint-amnesty, pylint: disable=missing- def setUp(self): super().setUp() self.cohorted_commentable_id = 'cohorted_topic' - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - - def call_view( - self, - mock_is_forum_v2_enabled, - mock_request, - commentable_id, - user, - group_id, - pass_group_id=True - ): # pylint: disable=arguments-differ - mock_is_forum_v2_enabled.return_value = False + + def call_view(self, mock_request, commentable_id, user, group_id, pass_group_id=True): kwargs = {'commentable_id': self.cohorted_commentable_id} if group_id: # avoid causing a server error when the LMS chokes attempting @@ -1194,9 +1084,8 @@ def call_view( commentable_id ) - def test_group_info_in_ajax_response(self, mock_is_forum_v2_enabled, mock_request): + def test_group_info_in_ajax_response(self, mock_request): response = self.call_view( - mock_is_forum_v2_enabled, mock_request, self.cohorted_commentable_id, self.student, @@ -1208,29 +1097,10 @@ def test_group_info_in_ajax_response(self, mock_is_forum_v2_enabled, mock_reques @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) -@patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) class ForumFormDiscussionGroupIdTestCase(CohortedTestCase, CohortedTopicGroupIdTestMixin): # lint-amnesty, pylint: disable=missing-class-docstring cs_endpoint = "/threads" - def setUp(self): - super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - - def call_view( - self, - mock_is_forum_v2_enabled, - mock_request, - commentable_id, - user, - group_id, - pass_group_id=True, - is_ajax=False - ): # pylint: disable=arguments-differ - mock_is_forum_v2_enabled.return_value = False + def call_view(self, mock_request, commentable_id, user, group_id, pass_group_id=True, is_ajax=False): # pylint: disable=arguments-differ kwargs = {} if group_id: kwargs['group_id'] = group_id @@ -1250,9 +1120,8 @@ def call_view( **headers ) - def test_group_info_in_html_response(self, mock_is_forum_v2_enabled, mock_request): + def test_group_info_in_html_response(self, mock_request): response = self.call_view( - mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.student, @@ -1260,9 +1129,8 @@ def test_group_info_in_html_response(self, mock_is_forum_v2_enabled, mock_reques ) self._assert_html_response_contains_group_info(response) - def test_group_info_in_ajax_response(self, mock_is_forum_v2_enabled, mock_request): + def test_group_info_in_ajax_response(self, mock_request): response = self.call_view( - mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.student, @@ -1275,38 +1143,16 @@ def test_group_info_in_ajax_response(self, mock_is_forum_v2_enabled, mock_reques @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) -@patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) class UserProfileDiscussionGroupIdTestCase(CohortedTestCase, CohortedTopicGroupIdTestMixin): # lint-amnesty, pylint: disable=missing-class-docstring cs_endpoint = "/active_threads" - def setUp(self): - super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - def call_view_for_profiled_user( - self, - mock_is_forum_v2_enabled, - mock_request, - requesting_user, - profiled_user, - group_id, - pass_group_id, - is_ajax=False + self, mock_request, requesting_user, profiled_user, group_id, pass_group_id, is_ajax=False ): """ Calls "user_profile" view method on behalf of "requesting_user" to get information about the user "profiled_user". """ - mock_is_forum_v2_enabled.return_value = False kwargs = {} if group_id: kwargs['group_id'] = group_id @@ -1326,23 +1172,13 @@ def call_view_for_profiled_user( **headers ) - def call_view( - self, - mock_is_forum_v2_enabled, - mock_request, - _commentable_id, - user, - group_id, - pass_group_id=True, - is_ajax=False - ): # pylint: disable=arguments-differ + def call_view(self, mock_request, _commentable_id, user, group_id, pass_group_id=True, is_ajax=False): # pylint: disable=arguments-differ return self.call_view_for_profiled_user( - mock_is_forum_v2_enabled, mock_request, user, user, group_id, pass_group_id=pass_group_id, is_ajax=is_ajax + mock_request, user, user, group_id, pass_group_id=pass_group_id, is_ajax=is_ajax ) - def test_group_info_in_html_response(self, mock_is_forum_v2_enabled, mock_request): + def test_group_info_in_html_response(self, mock_request): response = self.call_view( - mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.student, @@ -1351,9 +1187,8 @@ def test_group_info_in_html_response(self, mock_is_forum_v2_enabled, mock_reques ) self._assert_html_response_contains_group_info(response) - def test_group_info_in_ajax_response(self, mock_is_forum_v2_enabled, mock_request): + def test_group_info_in_ajax_response(self, mock_request): response = self.call_view( - mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.student, @@ -1365,14 +1200,7 @@ def test_group_info_in_ajax_response(self, mock_is_forum_v2_enabled, mock_reques ) def _test_group_id_passed_to_user_profile( - self, - mock_is_forum_v2_enabled, - mock_request, - expect_group_id_in_request, - requesting_user, - profiled_user, - group_id, - pass_group_id + self, mock_request, expect_group_id_in_request, requesting_user, profiled_user, group_id, pass_group_id ): """ Helper method for testing whether or not group_id was passed to the user_profile request. @@ -1393,11 +1221,10 @@ def get_params_from_user_info_call(for_specific_course): has_course_id = "course_id" in params if (for_specific_course and has_course_id) or (not for_specific_course and not has_course_id): return params - pytest.fail(f"Did not find appropriate user_profile call for 'for_specific_course'={for_specific_course}") + pytest.fail("Did not find appropriate user_profile call for 'for_specific_course'=" + for_specific_course) mock_request.reset_mock() self.call_view_for_profiled_user( - mock_is_forum_v2_enabled, mock_request, requesting_user, profiled_user, @@ -1416,7 +1243,7 @@ def get_params_from_user_info_call(for_specific_course): else: assert 'group_id' not in params_with_course_id - def test_group_id_passed_to_user_profile_student(self, mock_is_forum_v2_enabled, mock_request): + def test_group_id_passed_to_user_profile_student(self, mock_request): """ Test that the group id is always included when requesting user profile information for a particular course if the requester does not have discussion moderation privileges. @@ -1427,13 +1254,7 @@ def verify_group_id_always_present(profiled_user, pass_group_id): (non-privileged user). """ self._test_group_id_passed_to_user_profile( - mock_is_forum_v2_enabled, - mock_request, - True, - self.student, - profiled_user, - self.student_cohort.id, - pass_group_id + mock_request, True, self.student, profiled_user, self.student_cohort.id, pass_group_id ) # In all these test cases, the requesting_user is the student (non-privileged user). @@ -1443,7 +1264,7 @@ def verify_group_id_always_present(profiled_user, pass_group_id): verify_group_id_always_present(profiled_user=self.moderator, pass_group_id=True) verify_group_id_always_present(profiled_user=self.moderator, pass_group_id=False) - def test_group_id_user_profile_moderator(self, mock_is_forum_v2_enabled, mock_request): + def test_group_id_user_profile_moderator(self, mock_request): """ Test that the group id is only included when a privileged user requests user profile information for a particular course and user if the group_id is explicitly passed in. @@ -1453,13 +1274,7 @@ def verify_group_id_present(profiled_user, pass_group_id, requested_cohort=self. Helper method to verify that group_id is present. """ self._test_group_id_passed_to_user_profile( - mock_is_forum_v2_enabled, - mock_request, - True, - self.moderator, - profiled_user, - requested_cohort.id, - pass_group_id + mock_request, True, self.moderator, profiled_user, requested_cohort.id, pass_group_id ) def verify_group_id_not_present(profiled_user, pass_group_id, requested_cohort=self.moderator_cohort): @@ -1467,13 +1282,7 @@ def verify_group_id_not_present(profiled_user, pass_group_id, requested_cohort=s Helper method to verify that group_id is not present. """ self._test_group_id_passed_to_user_profile( - mock_is_forum_v2_enabled, - mock_request, - False, - self.moderator, - profiled_user, - requested_cohort.id, - pass_group_id + mock_request, False, self.moderator, profiled_user, requested_cohort.id, pass_group_id ) # In all these test cases, the requesting_user is the moderator (privileged user). @@ -1492,28 +1301,10 @@ def verify_group_id_not_present(profiled_user, pass_group_id, requested_cohort=s @patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True) -@patch('openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', autospec=True) class FollowedThreadsDiscussionGroupIdTestCase(CohortedTestCase, CohortedTopicGroupIdTestMixin): # lint-amnesty, pylint: disable=missing-class-docstring cs_endpoint = "/subscribed_threads" - def setUp(self): - super().setUp() - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - - def call_view( - self, - mock_is_forum_v2_enabled, - mock_request, - commentable_id, - user, - group_id, - pass_group_id=True - ): # pylint: disable=arguments-differ - mock_is_forum_v2_enabled.return_value = False + def call_view(self, mock_request, commentable_id, user, group_id, pass_group_id=True): kwargs = {} if group_id: kwargs['group_id'] = group_id @@ -1534,9 +1325,8 @@ def call_view( user.id ) - def test_group_info_in_ajax_response(self, mock_is_forum_v2_enabled, mock_request): + def test_group_info_in_ajax_response(self, mock_request): response = self.call_view( - mock_is_forum_v2_enabled, mock_request, "cohorted_topic", self.student, @@ -1738,22 +1528,6 @@ class CommentsServiceRequestHeadersTestCase(ForumsEnableMixin, UrlResetMixin, Mo @patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) def setUp(self): super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment" - ) - self.mock_get_course_id_by_comment = patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) username = "foo" password = "bar" @@ -1968,20 +1742,6 @@ def setUpClass(cls): with super().setUpClassAndTestData(): cls.course = CourseFactory.create(discussion_topics={'dummy_discussion_id': {'id': 'dummy_discussion_id'}}) - def setUp(self): - super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) - @classmethod def setUpTestData(cls): super().setUpTestData() @@ -2098,17 +1858,7 @@ class EnterpriseConsentTestCase(EnterpriseTestConsentRequired, ForumsEnableMixin def setUp(self): # Invoke UrlResetMixin setUp super().setUp() - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) + username = "foo" password = "bar" @@ -2445,17 +2195,6 @@ class ThreadViewedEventTestCase(EventTestMixin, ForumsEnableMixin, UrlResetMixin def setUp(self): # pylint: disable=arguments-differ super().setUp('lms.djangoapps.discussion.django_comment_client.base.views.tracker') - patcher = mock.patch( - 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled', - return_value=False - ) - patcher.start() - self.addCleanup(patcher.stop) - patcher = mock.patch( - "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread" - ) - self.mock_get_course_id_by_thread = patcher.start() - self.addCleanup(patcher.stop) self.course = CourseFactory.create( teams_configuration=TeamsConfig({ 'topics': [{ diff --git a/lms/djangoapps/discussion/toggles.py b/lms/djangoapps/discussion/toggles.py index a01a3b6a0a59..a1c292a4734f 100644 --- a/lms/djangoapps/discussion/toggles.py +++ b/lms/djangoapps/discussion/toggles.py @@ -1,7 +1,6 @@ """ Discussions feature toggles """ - from openedx.core.djangoapps.discussions.config.waffle import WAFFLE_FLAG_NAMESPACE from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag @@ -12,6 +11,4 @@ # .. toggle_use_cases: temporary, open_edx # .. toggle_creation_date: 2021-11-05 # .. toggle_target_removal_date: 2022-12-05 -ENABLE_DISCUSSIONS_MFE = CourseWaffleFlag( - f"{WAFFLE_FLAG_NAMESPACE}.enable_discussions_mfe", __name__ -) +ENABLE_DISCUSSIONS_MFE = CourseWaffleFlag(f'{WAFFLE_FLAG_NAMESPACE}.enable_discussions_mfe', __name__) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index 85cd2f2c06e8..5195826468c2 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -308,6 +308,13 @@ class LibraryXBlockType: # ============ +def user_can_create_library(user: AbstractUser) -> bool: + """ + Check if the user has permission to create a content library. + """ + return user.has_perm(permissions.CAN_CREATE_CONTENT_LIBRARY) + + def get_libraries_for_user(user, org=None, text_search=None, order=None): """ Return content libraries that the user has permission to view. diff --git a/openedx/core/djangoapps/content_libraries/permissions.py b/openedx/core/djangoapps/content_libraries/permissions.py index 17671b5659f8..4e72381986ed 100644 --- a/openedx/core/djangoapps/content_libraries/permissions.py +++ b/openedx/core/djangoapps/content_libraries/permissions.py @@ -48,6 +48,12 @@ def is_studio_request(_): return settings.SERVICE_VARIANT == "cms" +@blanket_rule +def is_course_creator(user): + from cms.djangoapps.course_creators.views import get_course_creator_status + + return get_course_creator_status(user) == 'granted' + ########################### Permissions ########################### # Is the user allowed to view XBlocks from the specified content library @@ -68,7 +74,10 @@ def is_studio_request(_): # Is the user allowed to create content libraries? CAN_CREATE_CONTENT_LIBRARY = 'content_libraries.create_library' -perms[CAN_CREATE_CONTENT_LIBRARY] = is_user_active +if settings.FEATURES.get('ENABLE_CREATOR_GROUP', False): + perms[CAN_CREATE_CONTENT_LIBRARY] = is_global_staff | (is_user_active & is_course_creator) +else: + perms[CAN_CREATE_CONTENT_LIBRARY] = is_global_staff # Is the user allowed to view the specified content library in Studio, # including to view the raw OLX and asset files? @@ -76,8 +85,8 @@ def is_studio_request(_): perms[CAN_VIEW_THIS_CONTENT_LIBRARY] = is_user_active & ( # Global staff can access any library is_global_staff | - # Some libraries allow anyone to view them in Studio: - Attribute('allow_public_read', True) | + # Libraries with "public read" permissions can be accessed only by course creators + (Attribute('allow_public_read', True) & is_course_creator) | # Otherwise the user must be part of the library's team has_explicit_read_permission_for_library ) diff --git a/openedx/core/djangoapps/content_libraries/tests/base.py b/openedx/core/djangoapps/content_libraries/tests/base.py index 638c053f62c3..77de1c028aa7 100644 --- a/openedx/core/djangoapps/content_libraries/tests/base.py +++ b/openedx/core/djangoapps/content_libraries/tests/base.py @@ -71,7 +71,7 @@ class ContentLibrariesRestApiTest(APITransactionTestCase): def setUp(self): super().setUp() - self.user = UserFactory.create(username="Bob", email="bob@example.com", password="edx") + self.user = UserFactory.create(username="Bob", email="bob@example.com", password="edx", is_staff=True) # Create an organization self.organization, _ = Organization.objects.get_or_create( short_name="CL-TEST", diff --git a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py index 18d4ec591604..83b277604071 100644 --- a/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py +++ b/openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py @@ -259,6 +259,8 @@ def test_library_blocks(self): # pylint: disable=too-many-statements Tests with some non-ASCII chars in slugs, titles, descriptions. """ + admin = UserFactory.create(username="Admin", email="admin@example.com", is_staff=True) + lib = self._create_library(slug="téstlꜟط", title="A Tést Lꜟطrary", description="Tésting XBlocks") lib_id = lib["id"] assert lib['has_unpublished_changes'] is False @@ -531,7 +533,7 @@ def test_library_permissions(self): # pylint: disable=too-many-statements Learning Core data models. """ # Create a few users to use for all of these tests: - admin = UserFactory.create(username="Admin", email="admin@example.com") + admin = UserFactory.create(username="Admin", email="admin@example.com", is_staff=True) author = UserFactory.create(username="Author", email="author@example.com") reader = UserFactory.create(username="Reader", email="reader@example.com") group = Group.objects.create(name="group1") @@ -653,14 +655,15 @@ def test_library_permissions(self): # pylint: disable=too-many-statements self._get_library_block_asset(block3_key, file_name="static/whatever.png", expect_response=403) # Nor can they preview the block: self._render_block_view(block3_key, view_name="student_view", expect_response=403) - # But if we grant allow_public_read, then they can: + # Even if we grant allow_public_read, then they can't: with self.as_user(admin): self._update_library(lib_id, allow_public_read=True) self._set_library_block_asset(block3_key, "static/whatever.png", b"data") with self.as_user(random_user): - self._get_library_block_olx(block3_key) + self._get_library_block_olx(block3_key, expect_response=403) + self._get_library_block_fields(block3_key, expect_response=403) + # But he can preview the block: self._render_block_view(block3_key, view_name="student_view") - f = self._get_library_block_fields(block3_key) # self._get_library_block_assets(block3_key) # self._get_library_block_asset(block3_key, file_name="whatever.png") @@ -702,7 +705,7 @@ def test_no_lockout(self): """ Test that administrators cannot be removed if they are the only administrator granted access. """ - admin = UserFactory.create(username="Admin", email="admin@example.com") + admin = UserFactory.create(username="Admin", email="admin@example.com", is_staff=True) successor = UserFactory.create(username="Successor", email="successor@example.com") with self.as_user(admin): lib = self._create_library(slug="permtest", title="Permission Test Library", description="Testing") @@ -1026,7 +1029,7 @@ def test_library_paste_clipboard(self): from openedx.core.djangoapps.content_staging.api import save_xblock_to_user_clipboard # Create user to perform tests on - author = UserFactory.create(username="Author", email="author@example.com") + author = UserFactory.create(username="Author", email="author@example.com", is_staff=True) with self.as_user(author): lib = self._create_library( slug="test_lib_paste_clipboard", diff --git a/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py b/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py index 463ea42d08e9..5a99868ece66 100644 --- a/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py +++ b/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py @@ -13,6 +13,7 @@ import ddt from django.contrib.auth import get_user_model from django.core.files.uploadedfile import SimpleUploadedFile +from edx_django_utils.cache import RequestCache from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator, LibraryCollectionLocator from openedx_tagging.core.tagging.models import Tag, Taxonomy from openedx_tagging.core.tagging.models.system_defined import SystemDefinedTaxonomy @@ -34,7 +35,6 @@ from openedx.core.djangoapps.content_libraries.api import AccessLevel, create_library, set_library_user_permissions from openedx.core.djangoapps.content_tagging import api as tagging_api from openedx.core.djangoapps.content_tagging.models import TaxonomyOrg -from openedx.core.djangoapps.content_tagging.utils import rules_cache from openedx.core.djangolib.testing.utils import skip_unless_cms from ....tests.test_objecttag_export_helpers import TaggedCourseMixin @@ -289,8 +289,8 @@ def setUp(self): self._setUp_taxonomies() self._setUp_collection() - # Clear the rules cache in between test runs to keep query counts consistent. - rules_cache.clear() + # Clear all request caches in between test runs to keep query counts consistent. + RequestCache.clear_all_namespaces() @skip_unless_cms @@ -510,12 +510,12 @@ def test_create_taxonomy(self, user_attr: str, expected_status: int) -> None: @ddt.data( ('staff', 11), - ("content_creatorA", 16), - ("library_staffA", 16), - ("library_userA", 16), - ("instructorA", 16), - ("course_instructorA", 16), - ("course_staffA", 16), + ("content_creatorA", 17), + ("library_staffA", 17), + ("library_userA", 17), + ("instructorA", 17), + ("course_instructorA", 17), + ("course_staffA", 17), ) @ddt.unpack def test_list_taxonomy_query_count(self, user_attr: str, expected_queries: int): @@ -1879,16 +1879,16 @@ def test_get_copied_tags(self): ('staff', 'courseA', 8), ('staff', 'libraryA', 8), ('staff', 'collection_key', 8), - ("content_creatorA", 'courseA', 11, False), - ("content_creatorA", 'libraryA', 11, False), - ("content_creatorA", 'collection_key', 11, False), - ("library_staffA", 'libraryA', 11, False), # Library users can only view objecttags, not change them? - ("library_staffA", 'collection_key', 11, False), - ("library_userA", 'libraryA', 11, False), - ("library_userA", 'collection_key', 11, False), - ("instructorA", 'courseA', 11), - ("course_instructorA", 'courseA', 11), - ("course_staffA", 'courseA', 11), + ("content_creatorA", 'courseA', 12, False), + ("content_creatorA", 'libraryA', 12, False), + ("content_creatorA", 'collection_key', 12, False), + ("library_staffA", 'libraryA', 12, False), # Library users can only view objecttags, not change them? + ("library_staffA", 'collection_key', 12, False), + ("library_userA", 'libraryA', 12, False), + ("library_userA", 'collection_key', 12, False), + ("instructorA", 'courseA', 12), + ("course_instructorA", 'courseA', 12), + ("course_staffA", 'courseA', 12), ) @ddt.unpack def test_object_tags_query_count( diff --git a/openedx/core/djangoapps/discussions/config/waffle.py b/openedx/core/djangoapps/discussions/config/waffle.py index 7b6395bb1c01..1d4c67e9e17b 100644 --- a/openedx/core/djangoapps/discussions/config/waffle.py +++ b/openedx/core/djangoapps/discussions/config/waffle.py @@ -2,7 +2,6 @@ This module contains various configuration settings via waffle switches for the discussions app. """ - from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag WAFFLE_FLAG_NAMESPACE = "discussions" @@ -44,19 +43,3 @@ ENABLE_NEW_STRUCTURE_DISCUSSIONS = CourseWaffleFlag( f"{WAFFLE_FLAG_NAMESPACE}.enable_new_structure_discussions", __name__ ) - -# .. toggle_name: discussions.enable_forum_v2 -# .. toggle_implementation: CourseWaffleFlag -# .. toggle_default: False -# .. toggle_description: Waffle flag to use the forum v2 instead of v1(cs_comment_service) -# .. toggle_use_cases: temporary, open_edx -# .. toggle_creation_date: 2024-9-26 -# .. toggle_target_removal_date: 2025-12-05 -ENABLE_FORUM_V2 = CourseWaffleFlag(f"{WAFFLE_FLAG_NAMESPACE}.enable_forum_v2", __name__) - - -def is_forum_v2_enabled(course_id): - """ - Returns a boolean if forum V2 is enabled on the course - """ - return ENABLE_FORUM_V2.is_enabled(course_id) diff --git a/openedx/core/djangoapps/django_comment_common/comment_client/comment.py b/openedx/core/djangoapps/django_comment_common/comment_client/comment.py index ba95c620496d..c86f7eb40515 100644 --- a/openedx/core/djangoapps/django_comment_common/comment_client/comment.py +++ b/openedx/core/djangoapps/django_comment_common/comment_client/comment.py @@ -4,9 +4,7 @@ from openedx.core.djangoapps.django_comment_common.comment_client import models, settings from .thread import Thread, _url_for_flag_abuse_thread, _url_for_unflag_abuse_thread -from .utils import CommentClientRequestError, get_course_key, perform_request -from forum import api as forum_api -from openedx.core.djangoapps.discussions.config.waffle import is_forum_v2_enabled +from .utils import CommentClientRequestError, perform_request class Comment(models.Model): @@ -70,21 +68,14 @@ def flagAbuse(self, user, voteable): url = _url_for_flag_abuse_comment(voteable.id) else: raise CommentClientRequestError("Can only flag/unflag threads or comments") - course_key = get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - if voteable.type == 'thread': - response = forum_api.update_thread_flag(voteable.id, "flag", user.id, str(course_key)) - else: - response = forum_api.update_comment_flag(voteable.id, "flag", user.id, str(course_key)) - else: - params = {'user_id': user.id} - response = perform_request( - 'put', - url, - params, - metric_tags=self._metric_tags, - metric_action='comment.abuse.flagged' - ) + params = {'user_id': user.id} + response = perform_request( + 'put', + url, + params, + metric_tags=self._metric_tags, + metric_action='comment.abuse.flagged' + ) voteable._update_from_response(response) def unFlagAbuse(self, user, voteable, removeAll): @@ -94,37 +85,18 @@ def unFlagAbuse(self, user, voteable, removeAll): url = _url_for_unflag_abuse_comment(voteable.id) else: raise CommentClientRequestError("Can flag/unflag for threads or comments") - course_key = get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - if voteable.type == "thread": - response = forum_api.update_thread_flag( - thread_id=voteable.id, - action="unflag", - user_id=user.id, - update_all=bool(removeAll), - course_id=str(course_key) - ) - else: - response = forum_api.update_comment_flag( - comment_id=voteable.id, - action="unflag", - user_id=user.id, - update_all=bool(removeAll), - course_id=str(course_key) - ) - else: - params = {'user_id': user.id} - - if removeAll: - params['all'] = True - - response = perform_request( - 'put', - url, - params, - metric_tags=self._metric_tags, - metric_action='comment.abuse.unflagged' - ) + params = {'user_id': user.id} + + if removeAll: + params['all'] = True + + response = perform_request( + 'put', + url, + params, + metric_tags=self._metric_tags, + metric_action='comment.abuse.unflagged' + ) voteable._update_from_response(response) @property diff --git a/openedx/core/djangoapps/django_comment_common/comment_client/course.py b/openedx/core/djangoapps/django_comment_common/comment_client/course.py index 8cbb580e7831..67d7efd22838 100644 --- a/openedx/core/djangoapps/django_comment_common/comment_client/course.py +++ b/openedx/core/djangoapps/django_comment_common/comment_client/course.py @@ -7,10 +7,8 @@ from edx_django_utils.monitoring import function_trace from opaque_keys.edx.keys import CourseKey -from forum import api as forum_api from openedx.core.djangoapps.django_comment_common.comment_client import settings from openedx.core.djangoapps.django_comment_common.comment_client.utils import perform_request -from openedx.core.djangoapps.discussions.config.waffle import is_forum_v2_enabled def get_course_commentable_counts(course_key: CourseKey) -> Dict[str, Dict[str, int]]: @@ -31,20 +29,17 @@ def get_course_commentable_counts(course_key: CourseKey) -> Dict[str, Dict[str, } """ - if is_forum_v2_enabled(course_key): - commentable_stats = forum_api.get_commentables_stats(str(course_key)) - else: - url = f"{settings.PREFIX}/commentables/{course_key}/counts" - commentable_stats = perform_request( - 'get', - url, - metric_tags=[ - f"course_key:{course_key}", - "function:get_course_commentable_counts", - ], - metric_action='commentable_stats.retrieve', - ) - return commentable_stats + url = f"{settings.PREFIX}/commentables/{course_key}/counts" + response = perform_request( + 'get', + url, + metric_tags=[ + f"course_key:{course_key}", + "function:get_course_commentable_counts", + ], + metric_action='commentable_stats.retrieve', + ) + return response @function_trace("get_course_user_stats") @@ -81,21 +76,17 @@ def get_course_user_stats(course_key: CourseKey, params: Optional[Dict] = None) """ if params is None: params = {} - if is_forum_v2_enabled(course_key): - course_stats = forum_api.get_user_course_stats(str(course_key), **params) - else: - url = f"{settings.PREFIX}/users/{course_key}/stats" - course_stats = perform_request( - 'get', - url, - params, - metric_action='user.course_stats', - metric_tags=[ - f"course_key:{course_key}", - "function:get_course_user_stats", - ], - ) - return course_stats + url = f"{settings.PREFIX}/users/{course_key}/stats" + return perform_request( + 'get', + url, + params, + metric_action='user.course_stats', + metric_tags=[ + f"course_key:{course_key}", + "function:get_course_user_stats", + ], + ) @function_trace("update_course_users_stats") @@ -109,17 +100,13 @@ def update_course_users_stats(course_key: CourseKey) -> Dict: Returns: dict: data returned by API. Contains count of users updated. """ - if is_forum_v2_enabled(course_key): - course_stats = forum_api.update_users_in_course(str(course_key)) - else: - url = f"{settings.PREFIX}/users/{course_key}/update_stats" - course_stats = perform_request( - 'post', - url, - metric_action='user.update_course_stats', - metric_tags=[ - f"course_key:{course_key}", - "function:update_course_users_stats", - ], - ) - return course_stats + url = f"{settings.PREFIX}/users/{course_key}/update_stats" + return perform_request( + 'post', + url, + metric_action='user.update_course_stats', + metric_tags=[ + f"course_key:{course_key}", + "function:update_course_users_stats", + ], + ) diff --git a/openedx/core/djangoapps/django_comment_common/comment_client/models.py b/openedx/core/djangoapps/django_comment_common/comment_client/models.py index 31256eb64735..4e602809c82a 100644 --- a/openedx/core/djangoapps/django_comment_common/comment_client/models.py +++ b/openedx/core/djangoapps/django_comment_common/comment_client/models.py @@ -3,9 +3,7 @@ import logging -from .utils import CommentClientRequestError, extract, perform_request, get_course_key -from forum import api as forum_api -from openedx.core.djangoapps.discussions.config.waffle import is_forum_v2_enabled +from .utils import CommentClientRequestError, extract, perform_request log = logging.getLogger(__name__) @@ -71,25 +69,14 @@ def retrieve(self, *args, **kwargs): return self def _retrieve(self, *args, **kwargs): - course_id = self.attributes.get("course_id") or kwargs.get("course_id") - if not course_id: - course_id = forum_api.get_course_id_by_comment(self.id) - course_key = get_course_key(course_id) - response = None - if is_forum_v2_enabled(course_key): - if self.type == "comment": - response = forum_api.get_parent_comment(comment_id=self.attributes["id"], course_id=str(course_key)) - if response is None: - raise CommentClientRequestError("Forum v2 API call is missing") - else: - url = self.url(action='get', params=self.attributes) - response = perform_request( - 'get', - url, - self.default_retrieve_params, - metric_tags=self._metric_tags, - metric_action='model.retrieve' - ) + url = self.url(action='get', params=self.attributes) + response = perform_request( + 'get', + url, + self.default_retrieve_params, + metric_tags=self._metric_tags, + metric_action='model.retrieve' + ) self._update_from_response(response) @property @@ -164,27 +151,33 @@ def save(self, params=None): """ self.before_save(self) if self.id: # if we have id already, treat this as an update - response = self.handle_update(params) - else: # otherwise, treat this as an insert - response = self.handle_create(params) - + request_params = self.updatable_attributes() + if params: + request_params.update(params) + url = self.url(action='put', params=self.attributes) + response = perform_request( + 'put', + url, + request_params, + metric_tags=self._metric_tags, + metric_action='model.update' + ) + else: # otherwise, treat this as an insert + url = self.url(action='post', params=self.attributes) + response = perform_request( + 'post', + url, + self.initializable_attributes(), + metric_tags=self._metric_tags, + metric_action='model.insert' + ) self.retrieved = True self._update_from_response(response) self.after_save(self) def delete(self): - course_key = get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - response = None - if self.type == "comment": - response = forum_api.delete_comment(comment_id=self.attributes["id"], course_id=str(course_key)) - elif self.type == "thread": - response = forum_api.delete_thread(thread_id=self.attributes["id"], course_id=str(course_key)) - if response is None: - raise CommentClientRequestError("Forum v2 API call is missing") - else: - url = self.url(action='delete', params=self.attributes) - response = perform_request('delete', url, metric_tags=self._metric_tags, metric_action='model.delete') + url = self.url(action='delete', params=self.attributes) + response = perform_request('delete', url, metric_tags=self._metric_tags, metric_action='model.delete') self.retrieved = True self._update_from_response(response) @@ -215,157 +208,3 @@ def url(cls, action, params=None): raise CommentClientRequestError(f"Cannot perform action {action} without id") # lint-amnesty, pylint: disable=raise-missing-from else: # action must be in DEFAULT_ACTIONS_WITHOUT_ID now return cls.url_without_id() - - def handle_update(self, params=None): - request_params = self.updatable_attributes() - if params: - request_params.update(params) - course_id = self.attributes.get("course_id") or request_params.get("course_id") - course_key = get_course_key(course_id) - if is_forum_v2_enabled(course_key): - response = None - if self.type == "comment": - response = self.handle_update_comment(request_params, str(course_key)) - elif self.type == "thread": - response = self.handle_update_thread(request_params, str(course_key)) - elif self.type == "user": - response = self.handle_update_user(request_params, str(course_key)) - if response is None: - raise CommentClientRequestError("Forum v2 API call is missing") - else: - response = self.perform_http_put_request(request_params) - return response - - def handle_update_user(self, request_params, course_id): - try: - username = request_params["username"] - external_id = str(request_params["external_id"]) - except KeyError as e: - raise e - response = forum_api.update_user( - external_id, - username=username, - course_id=course_id, - ) - return response - - def handle_update_comment(self, request_params, course_id): - request_data = { - "comment_id": self.attributes["id"], - "body": request_params.get("body"), - "course_id": request_params.get("course_id"), - "user_id": request_params.get("user_id"), - "anonymous": request_params.get("anonymous"), - "anonymous_to_peers": request_params.get("anonymous_to_peers"), - "endorsed": request_params.get("endorsed"), - "closed": request_params.get("closed"), - "editing_user_id": request_params.get("editing_user_id"), - "edit_reason_code": request_params.get("edit_reason_code"), - "endorsement_user_id": request_params.get("endorsement_user_id"), - "course_key": course_id - } - request_data = {k: v for k, v in request_data.items() if v is not None} - response = forum_api.update_comment(**request_data) - return response - - def handle_update_thread(self, request_params, course_id): - request_data = { - "thread_id": self.attributes["id"], - "title": request_params.get("title"), - "body": request_params.get("body"), - "course_id": request_params.get("course_id"), - "anonymous": request_params.get("anonymous"), - "anonymous_to_peers": request_params.get("anonymous_to_peers"), - "closed": request_params.get("closed"), - "commentable_id": request_params.get("commentable_id"), - "user_id": request_params.get("user_id"), - "editing_user_id": request_params.get("editing_user_id"), - "pinned": request_params.get("pinned"), - "thread_type": request_params.get("thread_type"), - "edit_reason_code": request_params.get("edit_reason_code"), - "close_reason_code": request_params.get("close_reason_code"), - "closing_user_id": request_params.get("closing_user_id"), - "endorsed": request_params.get("endorsed"), - "course_key": course_id - } - request_data = {k: v for k, v in request_data.items() if v is not None} - response = forum_api.update_thread(**request_data) - return response - - def perform_http_put_request(self, request_params): - url = self.url(action="put", params=self.attributes) - response = perform_request( - "put", - url, - request_params, - metric_tags=self._metric_tags, - metric_action="model.update", - ) - return response - - def perform_http_post_request(self): - url = self.url(action="post", params=self.attributes) - response = perform_request( - "post", - url, - self.initializable_attributes(), - metric_tags=self._metric_tags, - metric_action="model.insert", - ) - return response - - def handle_create(self, params=None): - course_id = self.attributes.get("course_id") or params.get("course_id") - course_key = get_course_key(course_id) - if is_forum_v2_enabled(course_key): - response = None - if self.type == "comment": - response = self.handle_create_comment(str(course_key)) - elif self.type == "thread": - response = self.handle_create_thread(str(course_key)) - if response is None: - raise CommentClientRequestError("Forum v2 API call is missing") - else: - response = self.perform_http_post_request() - return response - - def handle_create_comment(self, course_id): - request_data = self.initializable_attributes() - body = request_data["body"] - user_id = request_data["user_id"] - course_id = course_id or str(request_data["course_id"]) - if parent_id := self.attributes.get("parent_id"): - response = forum_api.create_child_comment( - parent_id, - body, - user_id, - course_id, - request_data.get("anonymous", False), - request_data.get("anonymous_to_peers", False), - ) - else: - response = forum_api.create_parent_comment( - self.attributes["thread_id"], - body, - user_id, - course_id, - request_data.get("anonymous", False), - request_data.get("anonymous_to_peers", False), - ) - return response - - def handle_create_thread(self, course_id): - request_data = self.initializable_attributes() - response = forum_api.create_thread( - title=request_data["title"], - body=request_data["body"], - course_id=course_id or str(request_data["course_id"]), - user_id=str(request_data["user_id"]), - anonymous=request_data.get("anonymous", False), - anonymous_to_peers=request_data.get("anonymous_to_peers", False), - commentable_id=request_data.get("commentable_id", "course"), - thread_type=request_data.get("thread_type", "discussion"), - group_id=request_data.get("group_id", None), - context=request_data.get("context", None), - ) - return response diff --git a/openedx/core/djangoapps/django_comment_common/comment_client/subscriptions.py b/openedx/core/djangoapps/django_comment_common/comment_client/subscriptions.py index 2130dfc56be6..545948a092cc 100644 --- a/openedx/core/djangoapps/django_comment_common/comment_client/subscriptions.py +++ b/openedx/core/djangoapps/django_comment_common/comment_client/subscriptions.py @@ -4,8 +4,6 @@ import logging from . import models, settings, utils -from forum import api as forum_api -from openedx.core.djangoapps.discussions.config.waffle import is_forum_v2_enabled log = logging.getLogger(__name__) @@ -23,7 +21,7 @@ class Subscription(models.Model): base_url = f"{settings.PREFIX}/threads" @classmethod - def fetch(cls, thread_id, course_id, query_params): + def fetch(cls, thread_id, query_params): """ Fetches the subscriptions for a given thread_id """ @@ -35,23 +33,14 @@ def fetch(cls, thread_id, course_id, query_params): params.update( utils.strip_blank(utils.strip_none(query_params)) ) - course_key = utils.get_course_key(course_id) - if is_forum_v2_enabled(course_key): - response = forum_api.get_thread_subscriptions( - thread_id=thread_id, - page=params["page"], - per_page=params["per_page"], - course_id=str(course_key) - ) - else: - response = utils.perform_request( - 'get', - cls.url(action='get', params=params) + "/subscriptions", - params, - metric_tags=[], - metric_action='subscription.get', - paged_results=True - ) + response = utils.perform_request( + 'get', + cls.url(action='get', params=params) + "/subscriptions", + params, + metric_tags=[], + metric_action='subscription.get', + paged_results=True + ) return utils.SubscriptionsPaginatedResult( collection=response.get('collection', []), page=response.get('page', 1), diff --git a/openedx/core/djangoapps/django_comment_common/comment_client/thread.py b/openedx/core/djangoapps/django_comment_common/comment_client/thread.py index 74aa8358f112..ef5accbad25d 100644 --- a/openedx/core/djangoapps/django_comment_common/comment_client/thread.py +++ b/openedx/core/djangoapps/django_comment_common/comment_client/thread.py @@ -6,8 +6,6 @@ from eventtracking import tracker from . import models, settings, utils -from forum import api as forum_api -from openedx.core.djangoapps.discussions.config.waffle import is_forum_v2_enabled log = logging.getLogger(__name__) @@ -61,35 +59,14 @@ def search(cls, query_params): url = cls.url(action='get_all', params=utils.extract(params, 'commentable_id')) if params.get('commentable_id'): del params['commentable_id'] - - if is_forum_v2_enabled(utils.get_course_key(query_params['course_id'])): - if query_params.get('text'): - search_params = utils.strip_none(params) - if user_id := search_params.get('user_id'): - search_params['user_id'] = str(user_id) - if group_ids := search_params.get('group_ids'): - search_params['group_ids'] = [int(group_id) for group_id in group_ids.split(',')] - elif group_id := search_params.get('group_id'): - search_params['group_ids'] = [int(group_id)] - search_params.pop('group_id', None) - if commentable_ids := search_params.get('commentable_ids'): - search_params['commentable_ids'] = commentable_ids.split(',') - elif commentable_id := search_params.get('commentable_id'): - search_params['commentable_ids'] = [commentable_id] - search_params.pop('commentable_id', None) - response = forum_api.search_threads(**search_params) - else: - response = forum_api.get_user_threads(**params) - else: - response = utils.perform_request( - 'get', - url, - params, - metric_tags=['course_id:{}'.format(query_params['course_id'])], - metric_action='thread.search', - paged_results=True - ) - + response = utils.perform_request( + 'get', + url, + params, + metric_tags=['course_id:{}'.format(query_params['course_id'])], + metric_action='thread.search', + paged_results=True + ) if query_params.get('text'): search_query = query_params['text'] course_id = query_params['course_id'] @@ -171,26 +148,14 @@ def _retrieve(self, *args, **kwargs): 'merge_question_type_responses': kwargs.get('merge_question_type_responses', False) } request_params = utils.strip_none(request_params) - course_id = kwargs.get("course_id") - if not course_id: - course_id = forum_api.get_course_id_by_thread(self.id) - course_key = utils.get_course_key(course_id) - if is_forum_v2_enabled(course_key): - if user_id := request_params.get('user_id'): - request_params['user_id'] = str(user_id) - response = forum_api.get_thread( - thread_id=self.id, - params=request_params, - course_id=str(course_key) - ) - else: - response = utils.perform_request( - 'get', - url, - request_params, - metric_action='model.retrieve', - metric_tags=self._metric_tags - ) + + response = utils.perform_request( + 'get', + url, + request_params, + metric_action='model.retrieve', + metric_tags=self._metric_tags + ) self._update_from_response(response) def flagAbuse(self, user, voteable): @@ -198,18 +163,14 @@ def flagAbuse(self, user, voteable): url = _url_for_flag_abuse_thread(voteable.id) else: raise utils.CommentClientRequestError("Can only flag/unflag threads or comments") - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - response = forum_api.update_thread_flag(voteable.id, "flag", user.id, str(course_key)) - else: - params = {'user_id': user.id} - response = utils.perform_request( - 'put', - url, - params, - metric_action='thread.abuse.flagged', - metric_tags=self._metric_tags - ) + params = {'user_id': user.id} + response = utils.perform_request( + 'put', + url, + params, + metric_action='thread.abuse.flagged', + metric_tags=self._metric_tags + ) voteable._update_from_response(response) def unFlagAbuse(self, user, voteable, removeAll): @@ -217,68 +178,42 @@ def unFlagAbuse(self, user, voteable, removeAll): url = _url_for_unflag_abuse_thread(voteable.id) else: raise utils.CommentClientRequestError("Can only flag/unflag for threads or comments") - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - response = forum_api.update_thread_flag( - thread_id=voteable.id, - action="unflag", - user_id=user.id, - update_all=bool(removeAll), - course_id=str(course_key) - ) - else: - params = {'user_id': user.id} - #if you're an admin, when you unflag, remove ALL flags - if removeAll: - params['all'] = True - - response = utils.perform_request( - 'put', - url, - params, - metric_tags=self._metric_tags, - metric_action='thread.abuse.unflagged' - ) + params = {'user_id': user.id} + #if you're an admin, when you unflag, remove ALL flags + if removeAll: + params['all'] = True + + response = utils.perform_request( + 'put', + url, + params, + metric_tags=self._metric_tags, + metric_action='thread.abuse.unflagged' + ) voteable._update_from_response(response) def pin(self, user, thread_id): - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - response = forum_api.pin_thread( - user_id=user.id, - thread_id=thread_id, - course_id=str(course_key) - ) - else: - url = _url_for_pin_thread(thread_id) - params = {'user_id': user.id} - response = utils.perform_request( - 'put', - url, - params, - metric_tags=self._metric_tags, - metric_action='thread.pin' - ) + url = _url_for_pin_thread(thread_id) + params = {'user_id': user.id} + response = utils.perform_request( + 'put', + url, + params, + metric_tags=self._metric_tags, + metric_action='thread.pin' + ) self._update_from_response(response) def un_pin(self, user, thread_id): - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - response = forum_api.unpin_thread( - user_id=user.id, - thread_id=thread_id, - course_id=str(course_key) - ) - else: - url = _url_for_un_pin_thread(thread_id) - params = {'user_id': user.id} - response = utils.perform_request( - 'put', - url, - params, - metric_tags=self._metric_tags, - metric_action='thread.unpin' - ) + url = _url_for_un_pin_thread(thread_id) + params = {'user_id': user.id} + response = utils.perform_request( + 'put', + url, + params, + metric_tags=self._metric_tags, + metric_action='thread.unpin' + ) self._update_from_response(response) diff --git a/openedx/core/djangoapps/django_comment_common/comment_client/user.py b/openedx/core/djangoapps/django_comment_common/comment_client/user.py index 2de4fbbfa95a..684469c9e787 100644 --- a/openedx/core/djangoapps/django_comment_common/comment_client/user.py +++ b/openedx/core/djangoapps/django_comment_common/comment_client/user.py @@ -1,10 +1,8 @@ # pylint: disable=missing-docstring,protected-access """ User model wrapper for comment service""" + from . import models, settings, utils -from forum import api as forum_api -from forum.utils import ForumV2RequestError, str_to_bool -from openedx.core.djangoapps.discussions.config.waffle import is_forum_v2_enabled class User(models.Model): @@ -36,55 +34,34 @@ def read(self, source): """ Calls cs_comments_service to mark thread as read for the user """ - course_id = self.attributes.get("course_id") - course_key = utils.get_course_key(course_id) - if is_forum_v2_enabled(course_key): - forum_api.mark_thread_as_read(self.id, source.id, course_id=str(course_id)) - else: - params = {'source_type': source.type, 'source_id': source.id} - utils.perform_request( - 'post', - _url_for_read(self.id), - params, - metric_action='user.read', - metric_tags=self._metric_tags + [f'target.type:{source.type}'], - ) + params = {'source_type': source.type, 'source_id': source.id} + utils.perform_request( + 'post', + _url_for_read(self.id), + params, + metric_action='user.read', + metric_tags=self._metric_tags + [f'target.type:{source.type}'], + ) def follow(self, source): - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - forum_api.create_subscription( - user_id=self.id, - source_id=source.id, - course_id=str(course_key) - ) - else: - params = {'source_type': source.type, 'source_id': source.id} - utils.perform_request( - 'post', - _url_for_subscription(self.id), - params, - metric_action='user.follow', - metric_tags=self._metric_tags + [f'target.type:{source.type}'], - ) + params = {'source_type': source.type, 'source_id': source.id} + utils.perform_request( + 'post', + _url_for_subscription(self.id), + params, + metric_action='user.follow', + metric_tags=self._metric_tags + [f'target.type:{source.type}'], + ) def unfollow(self, source): - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - forum_api.delete_subscription( - user_id=self.id, - source_id=source.id, - course_id=str(course_key) - ) - else: - params = {'source_type': source.type, 'source_id': source.id} - utils.perform_request( - 'delete', - _url_for_subscription(self.id), - params, - metric_action='user.unfollow', - metric_tags=self._metric_tags + [f'target.type:{source.type}'], - ) + params = {'source_type': source.type, 'source_id': source.id} + utils.perform_request( + 'delete', + _url_for_subscription(self.id), + params, + metric_action='user.unfollow', + metric_tags=self._metric_tags + [f'target.type:{source.type}'], + ) def vote(self, voteable, value): if voteable.type == 'thread': @@ -93,31 +70,14 @@ def vote(self, voteable, value): url = _url_for_vote_comment(voteable.id) else: raise utils.CommentClientRequestError("Can only vote / unvote for threads or comments") - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - if voteable.type == 'thread': - response = forum_api.update_thread_votes( - thread_id=voteable.id, - user_id=self.id, - value=value, - course_id=str(course_key) - ) - else: - response = forum_api.update_comment_votes( - comment_id=voteable.id, - user_id=self.id, - value=value, - course_id=str(course_key) - ) - else: - params = {'user_id': self.id, 'value': value} - response = utils.perform_request( - 'put', - url, - params, - metric_action='user.vote', - metric_tags=self._metric_tags + [f'target.type:{voteable.type}'], - ) + params = {'user_id': self.id, 'value': value} + response = utils.perform_request( + 'put', + url, + params, + metric_action='user.vote', + metric_tags=self._metric_tags + [f'target.type:{voteable.type}'], + ) voteable._update_from_response(response) def unvote(self, voteable): @@ -127,29 +87,14 @@ def unvote(self, voteable): url = _url_for_vote_comment(voteable.id) else: raise utils.CommentClientRequestError("Can only vote / unvote for threads or comments") - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - if voteable.type == 'thread': - response = forum_api.delete_thread_vote( - thread_id=voteable.id, - user_id=self.id, - course_id=str(course_key) - ) - else: - response = forum_api.delete_comment_vote( - comment_id=voteable.id, - user_id=self.id, - course_id=str(course_key) - ) - else: - params = {'user_id': self.id} - response = utils.perform_request( - 'delete', - url, - params, - metric_action='user.unvote', - metric_tags=self._metric_tags + [f'target.type:{voteable.type}'], - ) + params = {'user_id': self.id} + response = utils.perform_request( + 'delete', + url, + params, + metric_action='user.unvote', + metric_tags=self._metric_tags + [f'target.type:{voteable.type}'], + ) voteable._update_from_response(response) def active_threads(self, query_params=None): @@ -160,28 +105,14 @@ def active_threads(self, query_params=None): url = _url_for_user_active_threads(self.id) params = {'course_id': str(self.course_id)} params.update(query_params) - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - if user_id := params.get("user_id"): - params["user_id"] = str(user_id) - if page := params.get("page"): - params["page"] = int(page) - if per_page := params.get("per_page"): - params["per_page"] = int(per_page) - if count_flagged := params.get("count_flagged", False): - params["count_flagged"] = str_to_bool(count_flagged) - if not params.get("course_id"): - params["course_id"] = str(course_key) - response = forum_api.get_user_active_threads(**params) - else: - response = utils.perform_request( - 'get', - url, - params, - metric_action='user.active_threads', - metric_tags=self._metric_tags, - paged_results=True, - ) + response = utils.perform_request( + 'get', + url, + params, + metric_action='user.active_threads', + metric_tags=self._metric_tags, + paged_results=True, + ) return response.get('collection', []), response.get('page', 1), response.get('num_pages', 1) def subscribed_threads(self, query_params=None): @@ -194,28 +125,14 @@ def subscribed_threads(self, query_params=None): url = _url_for_user_subscribed_threads(self.id) params = {'course_id': str(self.course_id)} params.update(query_params) - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - if user_id := params.get("user_id"): - params["user_id"] = str(user_id) - if page := params.get("page"): - params["page"] = int(page) - if per_page := params.get("per_page"): - params["per_page"] = int(per_page) - if count_flagged := params.get("count_flagged", False): - params["count_flagged"] = str_to_bool(count_flagged) - if not params.get("course_id"): - params["course_id"] = str(course_key) - response = forum_api.get_user_threads(**params) - else: - response = utils.perform_request( - 'get', - url, - params, - metric_action='user.subscribed_threads', - metric_tags=self._metric_tags, - paged_results=True - ) + response = utils.perform_request( + 'get', + url, + params, + metric_action='user.subscribed_threads', + metric_tags=self._metric_tags, + paged_results=True + ) return utils.CommentClientPaginatedResult( collection=response.get('collection', []), page=response.get('page', 1), @@ -227,39 +144,23 @@ def _retrieve(self, *args, **kwargs): url = self.url(action='get', params=self.attributes) retrieve_params = self.default_retrieve_params.copy() retrieve_params.update(kwargs) - if self.attributes.get('course_id'): retrieve_params['course_id'] = str(self.course_id) if self.attributes.get('group_id'): retrieve_params['group_id'] = self.group_id - - # course key -> id conversation - course_id = retrieve_params.get('course_id') - if course_id: - course_id = str(course_id) - retrieve_params['course_id'] = course_id - course_key = utils.get_course_key(course_id) - - if is_forum_v2_enabled(course_key): - group_ids = [retrieve_params['group_id']] if 'group_id' in retrieve_params else [] - is_complete = retrieve_params['complete'] - try: - response = forum_api.get_user( - self.attributes["id"], - group_ids=group_ids, - course_id=course_id, - complete=is_complete - ) - except ForumV2RequestError as e: - self.save({"course_id": course_id}) - response = forum_api.get_user( - self.attributes["id"], - group_ids=group_ids, - course_id=course_id, - complete=is_complete - ) - else: - try: + try: + response = utils.perform_request( + 'get', + url, + retrieve_params, + metric_action='model.retrieve', + metric_tags=self._metric_tags, + ) + except utils.CommentClientRequestError as e: + if e.status_code == 404: + # attempt to gracefully recover from a previous failure + # to sync this user to the comments service. + self.save() response = utils.perform_request( 'get', url, @@ -267,52 +168,33 @@ def _retrieve(self, *args, **kwargs): metric_action='model.retrieve', metric_tags=self._metric_tags, ) - except utils.CommentClientRequestError as e: - if e.status_code == 404: - # attempt to gracefully recover from a previous failure - # to sync this user to the comments service. - self.save() - response = utils.perform_request( - 'get', - url, - retrieve_params, - metric_action='model.retrieve', - metric_tags=self._metric_tags, - ) - else: - raise + else: + raise self._update_from_response(response) def retire(self, retired_username): - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - forum_api.retire_user(user_id=self.id, retired_username=retired_username, course_id=str(course_key)) - else: - url = _url_for_retire(self.id) - params = {'retired_username': retired_username} - utils.perform_request( - 'post', - url, - params, - raw=True, - metric_action='user.retire', - metric_tags=self._metric_tags - ) + url = _url_for_retire(self.id) + params = {'retired_username': retired_username} + + utils.perform_request( + 'post', + url, + params, + raw=True, + metric_action='user.retire', + metric_tags=self._metric_tags + ) def replace_username(self, new_username): - course_key = utils.get_course_key(self.attributes.get("course_id")) - if is_forum_v2_enabled(course_key): - forum_api.update_username(user_id=self.id, new_username=new_username, course_id=str(course_key)) - else: - url = _url_for_username_replacement(self.id) - params = {"new_username": new_username} - - utils.perform_request( - 'post', - url, - params, - raw=True, - ) + url = _url_for_username_replacement(self.id) + params = {"new_username": new_username} + + utils.perform_request( + 'post', + url, + params, + raw=True, + ) def _url_for_vote_comment(comment_id): diff --git a/openedx/core/djangoapps/django_comment_common/comment_client/utils.py b/openedx/core/djangoapps/django_comment_common/comment_client/utils.py index e77f39e6277d..a67cdbdbc483 100644 --- a/openedx/core/djangoapps/django_comment_common/comment_client/utils.py +++ b/openedx/core/djangoapps/django_comment_common/comment_client/utils.py @@ -7,7 +7,6 @@ import requests from django.utils.translation import get_language -from opaque_keys.edx.keys import CourseKey from .settings import SERVICE_HOST as COMMENTS_SERVICE @@ -168,19 +167,3 @@ def check_forum_heartbeat(): 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. - If course_id is None or already a CourseKey object, it returns the course_id as is. - Args: - course_id (CourseKey | str | None): The course ID to be converted. - Returns: - CourseKey | None: The corresponding CourseKey object or None if the input is None. - Raises: - KeyError: If course_id is not a valid string representation of a CourseKey. - """ - if course_id and isinstance(course_id, str): - course_id = CourseKey.from_string(course_id) - return course_id diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 66b5bc4e4770..fbac41537117 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -57,9 +57,7 @@ backoff==1.10.0 bcrypt==4.2.1 # via paramiko beautifulsoup4==4.12.3 - # via - # openedx-forum - # pynliner + # via pynliner billiard==4.2.1 # via celery bleach[css]==6.2.0 @@ -236,7 +234,6 @@ django==4.2.17 # openedx-django-wiki # openedx-events # openedx-filters - # openedx-forum # openedx-learning # ora2 # social-auth-app-django @@ -386,7 +383,6 @@ djangorestframework==3.14.0 # edx-organizations # edx-proctoring # edx-submissions - # openedx-forum # openedx-learning # ora2 # super-csv @@ -520,9 +516,7 @@ edx-rest-api-client==6.0.0 # edx-enterprise # edx-proctoring edx-search==4.1.1 - # via - # -r requirements/edx/kernel.in - # openedx-forum + # via -r requirements/edx/kernel.in edx-sga==0.25.0 # via -r requirements/edx/bundled.in edx-submissions==3.8.3 @@ -555,7 +549,6 @@ elasticsearch==7.9.1 # via # -c requirements/edx/../common_constraints.txt # edx-search - # openedx-forum enmerkar==0.7.1 # via enmerkar-underscore enmerkar-underscore==2.3.1 @@ -781,9 +774,7 @@ multidict==6.1.0 # aiohttp # yarl mysqlclient==2.2.6 - # via - # -r requirements/edx/kernel.in - # openedx-forum + # via -r requirements/edx/kernel.in newrelic==10.3.1 # via edx-django-utils nh3==0.2.19 @@ -813,9 +804,7 @@ openai==0.28.1 # -c requirements/edx/../constraints.txt # edx-enterprise openedx-atlas==0.6.2 - # via - # -r requirements/edx/kernel.in - # openedx-forum + # via -r requirements/edx/kernel.in openedx-calc==4.0.1 # via -r requirements/edx/kernel.in openedx-django-pyfs==3.7.0 @@ -841,8 +830,6 @@ openedx-filters==1.11.0 # -r requirements/edx/kernel.in # lti-consumer-xblock # ora2 -openedx-forum==0.1.4 - # via -r requirements/edx/kernel.in openedx-learning==0.18.1 # via # -c requirements/edx/../constraints.txt @@ -979,7 +966,6 @@ pymongo==4.4.0 # edx-opaque-keys # event-tracking # mongoengine - # openedx-forum # openedx-mongodbproxy pynacl==1.5.0 # via @@ -1089,7 +1075,6 @@ requests==2.32.3 # mailsnake # meilisearch # openai - # openedx-forum # optimizely-sdk # pyjwkest # pylti1p3 diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 7336d25052b9..7cecf1109722 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -60,7 +60,7 @@ annotated-types==0.7.0 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # pydantic -anyio==4.6.2.post1 +anyio==4.7.0 # via # -r requirements/edx/testing.txt # starlette @@ -122,7 +122,6 @@ beautifulsoup4==4.12.3 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt - # openedx-forum # pydata-sphinx-theme # pynliner billiard==4.2.1 @@ -407,7 +406,6 @@ django==4.2.17 # openedx-django-wiki # openedx-events # openedx-filters - # openedx-forum # openedx-learning # ora2 # social-auth-app-django @@ -621,7 +619,6 @@ djangorestframework==3.14.0 # edx-organizations # edx-proctoring # edx-submissions - # openedx-forum # openedx-learning # ora2 # super-csv @@ -818,7 +815,6 @@ edx-search==4.1.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt - # openedx-forum edx-sga==0.25.0 # via # -r requirements/edx/doc.txt @@ -865,7 +861,6 @@ elasticsearch==7.9.1 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # edx-search - # openedx-forum enmerkar==0.7.1 # via # -r requirements/edx/doc.txt @@ -1309,7 +1304,6 @@ mysqlclient==2.2.6 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt - # openedx-forum newrelic==10.3.1 # via # -r requirements/edx/doc.txt @@ -1360,7 +1354,6 @@ openedx-atlas==0.6.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt - # openedx-forum openedx-calc==4.0.1 # via # -r requirements/edx/doc.txt @@ -1396,10 +1389,6 @@ openedx-filters==1.11.0 # -r requirements/edx/testing.txt # lti-consumer-xblock # ora2 -openedx-forum==0.1.4 - # via - # -r requirements/edx/doc.txt - # -r requirements/edx/testing.txt openedx-learning==0.18.1 # via # -c requirements/edx/../constraints.txt @@ -1670,7 +1659,6 @@ pymongo==4.4.0 # edx-opaque-keys # event-tracking # mongoengine - # openedx-forum # openedx-mongodbproxy pynacl==1.5.0 # via @@ -1867,7 +1855,6 @@ requests==2.32.3 # mailsnake # meilisearch # openai - # openedx-forum # optimizely-sdk # pact-python # pyjwkest @@ -2149,6 +2136,7 @@ typing-extensions==4.12.2 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt + # anyio # django-countries # django-stubs # django-stubs-ext diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 12dc31cd6bba..e59e698e15d7 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -89,7 +89,6 @@ bcrypt==4.2.1 beautifulsoup4==4.12.3 # via # -r requirements/edx/base.txt - # openedx-forum # pydata-sphinx-theme # pynliner billiard==4.2.1 @@ -293,7 +292,6 @@ django==4.2.17 # openedx-django-wiki # openedx-events # openedx-filters - # openedx-forum # openedx-learning # ora2 # social-auth-app-django @@ -459,7 +457,6 @@ djangorestframework==3.14.0 # edx-organizations # edx-proctoring # edx-submissions - # openedx-forum # openedx-learning # ora2 # super-csv @@ -604,9 +601,7 @@ edx-rest-api-client==6.0.0 # edx-enterprise # edx-proctoring edx-search==4.1.1 - # via - # -r requirements/edx/base.txt - # openedx-forum + # via -r requirements/edx/base.txt edx-sga==0.25.0 # via -r requirements/edx/base.txt edx-submissions==3.8.3 @@ -642,7 +637,6 @@ elasticsearch==7.9.1 # -c requirements/edx/../common_constraints.txt # -r requirements/edx/base.txt # edx-search - # openedx-forum enmerkar==0.7.1 # via # -r requirements/edx/base.txt @@ -943,9 +937,7 @@ multidict==6.1.0 # aiohttp # yarl mysqlclient==2.2.6 - # via - # -r requirements/edx/base.txt - # openedx-forum + # via -r requirements/edx/base.txt newrelic==10.3.1 # via # -r requirements/edx/base.txt @@ -981,9 +973,7 @@ openai==0.28.1 # -r requirements/edx/base.txt # edx-enterprise openedx-atlas==0.6.2 - # via - # -r requirements/edx/base.txt - # openedx-forum + # via -r requirements/edx/base.txt openedx-calc==4.0.1 # via -r requirements/edx/base.txt openedx-django-pyfs==3.7.0 @@ -1010,8 +1000,6 @@ openedx-filters==1.11.0 # -r requirements/edx/base.txt # lti-consumer-xblock # ora2 -openedx-forum==0.1.4 - # via -r requirements/edx/base.txt openedx-learning==0.18.1 # via # -c requirements/edx/../constraints.txt @@ -1183,7 +1171,6 @@ pymongo==4.4.0 # edx-opaque-keys # event-tracking # mongoengine - # openedx-forum # openedx-mongodbproxy pynacl==1.5.0 # via @@ -1309,7 +1296,6 @@ requests==2.32.3 # mailsnake # meilisearch # openai - # openedx-forum # optimizely-sdk # pyjwkest # pylti1p3 diff --git a/requirements/edx/kernel.in b/requirements/edx/kernel.in index 60f49c5917e1..7323c243accf 100644 --- a/requirements/edx/kernel.in +++ b/requirements/edx/kernel.in @@ -119,7 +119,6 @@ openedx-calc # Library supporting mathematical calculatio openedx-django-require openedx-events # Open edX Events from Hooks Extension Framework (OEP-50) openedx-filters # Open edX Filters from Hooks Extension Framework (OEP-50) -openedx-forum # Open edX forum v2 application openedx-learning # Open edX Learning core (experimental) openedx-mongodbproxy openedx-django-wiki diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 812b545be07d..8b11f61b77fb 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -39,7 +39,7 @@ annotated-types==0.7.0 # via # -r requirements/edx/base.txt # pydantic -anyio==4.6.2.post1 +anyio==4.7.0 # via starlette appdirs==1.4.4 # via @@ -87,7 +87,6 @@ beautifulsoup4==4.12.3 # via # -r requirements/edx/base.txt # -r requirements/edx/testing.in - # openedx-forum # pynliner billiard==4.2.1 # via @@ -319,7 +318,6 @@ django==4.2.17 # openedx-django-wiki # openedx-events # openedx-filters - # openedx-forum # openedx-learning # ora2 # social-auth-app-django @@ -485,7 +483,6 @@ djangorestframework==3.14.0 # edx-organizations # edx-proctoring # edx-submissions - # openedx-forum # openedx-learning # ora2 # super-csv @@ -627,9 +624,7 @@ edx-rest-api-client==6.0.0 # edx-enterprise # edx-proctoring edx-search==4.1.1 - # via - # -r requirements/edx/base.txt - # openedx-forum + # via -r requirements/edx/base.txt edx-sga==0.25.0 # via -r requirements/edx/base.txt edx-submissions==3.8.3 @@ -665,7 +660,6 @@ elasticsearch==7.9.1 # -c requirements/edx/../common_constraints.txt # -r requirements/edx/base.txt # edx-search - # openedx-forum enmerkar==0.7.1 # via # -r requirements/edx/base.txt @@ -988,9 +982,7 @@ multidict==6.1.0 # aiohttp # yarl mysqlclient==2.2.6 - # via - # -r requirements/edx/base.txt - # openedx-forum + # via -r requirements/edx/base.txt newrelic==10.3.1 # via # -r requirements/edx/base.txt @@ -1026,9 +1018,7 @@ openai==0.28.1 # -r requirements/edx/base.txt # edx-enterprise openedx-atlas==0.6.2 - # via - # -r requirements/edx/base.txt - # openedx-forum + # via -r requirements/edx/base.txt openedx-calc==4.0.1 # via -r requirements/edx/base.txt openedx-django-pyfs==3.7.0 @@ -1055,8 +1045,6 @@ openedx-filters==1.11.0 # -r requirements/edx/base.txt # lti-consumer-xblock # ora2 -openedx-forum==0.1.4 - # via -r requirements/edx/base.txt openedx-learning==0.18.1 # via # -c requirements/edx/../constraints.txt @@ -1263,7 +1251,6 @@ pymongo==4.4.0 # edx-opaque-keys # event-tracking # mongoengine - # openedx-forum # openedx-mongodbproxy pynacl==1.5.0 # via @@ -1420,7 +1407,6 @@ requests==2.32.3 # mailsnake # meilisearch # openai - # openedx-forum # optimizely-sdk # pact-python # pyjwkest @@ -1590,6 +1576,7 @@ tqdm==4.67.1 typing-extensions==4.12.2 # via # -r requirements/edx/base.txt + # anyio # django-countries # edx-opaque-keys # faker