<%- gettext('It is visible to learners, ensuring that all learners can view its contents.') %>
+From ac62e83958330e4d3e02867090b20fbc1458dbf4 Mon Sep 17 00:00:00 2001
From: mariagrimaldi
+ {loseAccessText} +
{bodyDeletion2}
{/* eslint-disable-next-line react/no-danger */} - ++ {loseAccessText} +
)} From acd2a917409fde08058ea0891a5bf591a8c79f57 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi- {loseAccessText} -
+{loseAccessText}
Date: Wed, 21 Feb 2024 15:02:29 -0400 Subject: [PATCH 04/20] refactor: address PR reviews --- .../components/StudentAccountDeletionModal.jsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lms/static/js/student_account/components/StudentAccountDeletionModal.jsx b/lms/static/js/student_account/components/StudentAccountDeletionModal.jsx index b8d7f712025a..dceffc9ff4c4 100644 --- a/lms/static/js/student_account/components/StudentAccountDeletionModal.jsx +++ b/lms/static/js/student_account/components/StudentAccountDeletionModal.jsx @@ -162,9 +162,7 @@ class StudentAccountDeletionConfirmationModal extends React.Component { {bodyDeletion2}
{/* eslint-disable-next-line react/no-danger */} -- {loseAccessText} -
+{loseAccessText}
)} From c0020a87691d0962028770e6ba987887ea643548 Mon Sep 17 00:00:00 2001 From: Blue{StringUtils.interpolate( - gettext('What can we help you with, {username}?'), - { username: userInformation.username }, + gettext('What can we help you with, {fullName}?'), + { fullName: userInformation.fullName }, )}
Test body
", - "endorsed": False, + "endorsed": True, "endorsed_by": None, "endorsed_by_label": None, "endorsed_at": None, @@ -1508,12 +1514,26 @@ def test_discussion_content(self): }, }, ] + return source_comments, expected_comments + + def test_discussion_content(self): + source_comments, expected_comments = self.get_source_and_expected_comments() actual_comments = self.get_comment_list( self.make_minimal_cs_thread({"children": source_comments}) ).data["results"] assert actual_comments == expected_comments - def test_question_content(self): + def test_question_content_with_merge_question_type_responses(self): + source_comments, expected_comments = self.get_source_and_expected_comments() + actual_comments = self.get_comment_list( + self.make_minimal_cs_thread({ + "thread_type": "question", + "children": source_comments, + "resp_total": len(source_comments) + }), merge_question_type_responses=True).data["results"] + assert actual_comments == expected_comments + + def test_question_content_(self): thread = self.make_minimal_cs_thread({ "thread_type": "question", "endorsed_responses": [make_minimal_cs_comment({"id": "endorsed_comment", "username": self.user.username})], @@ -1547,11 +1567,13 @@ def test_endorsed_by_anonymity(self): assert actual_comments[0]['endorsed_by'] is None @ddt.data( - ("discussion", None, "children", "resp_total"), - ("question", False, "non_endorsed_responses", "non_endorsed_resp_total"), + ("discussion", None, "children", "resp_total", False), + ("question", False, "non_endorsed_responses", "non_endorsed_resp_total", False), + ("question", None, "children", "resp_total", True), ) @ddt.unpack - def test_cs_pagination(self, thread_type, endorsed_arg, response_field, response_total_field): + def test_cs_pagination(self, thread_type, endorsed_arg, response_field, + response_total_field, merge_question_type_responses): """ Test cases in which pagination is done by the comments service. @@ -1571,22 +1593,26 @@ def test_cs_pagination(self, thread_type, endorsed_arg, response_field, response }) # Only page - actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=1, page_size=5).data + actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=1, page_size=5, + merge_question_type_responses=merge_question_type_responses).data assert actual['pagination']['next'] is None assert actual['pagination']['previous'] is None # First page of many - actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=1, page_size=2).data + actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=1, page_size=2, + merge_question_type_responses=merge_question_type_responses).data assert actual['pagination']['next'] == 'http://testserver/test_path?page=2' assert actual['pagination']['previous'] is None # Middle page of many - actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=2, page_size=2).data + actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=2, page_size=2, + merge_question_type_responses=merge_question_type_responses).data assert actual['pagination']['next'] == 'http://testserver/test_path?page=3' assert actual['pagination']['previous'] == 'http://testserver/test_path?page=1' # Last page of many - actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=3, page_size=2).data + actual = self.get_comment_list(thread, endorsed=endorsed_arg, page=3, page_size=2, + merge_question_type_responses=merge_question_type_responses).data assert actual['pagination']['next'] is None assert actual['pagination']['previous'] == 'http://testserver/test_path?page=2' @@ -1597,7 +1623,8 @@ def test_cs_pagination(self, thread_type, endorsed_arg, response_field, response response_total_field: 5 }) with pytest.raises(PageNotFoundError): - self.get_comment_list(thread, endorsed=endorsed_arg, page=2, page_size=5) + self.get_comment_list(thread, endorsed=endorsed_arg, page=2, page_size=5, + merge_question_type_responses=merge_question_type_responses) def test_question_endorsed_pagination(self): thread = self.make_minimal_cs_thread({ @@ -4078,6 +4105,7 @@ class CourseTopicsV2Test(ModuleStoreTestCase): """ Tests for discussions topic API v2 code. """ + def setUp(self) -> None: super().setUp() self.course = CourseFactory.create( diff --git a/lms/djangoapps/discussion/rest_api/tests/test_forms.py b/lms/djangoapps/discussion/rest_api/tests/test_forms.py index 04ff7f515212..3be65964b6b9 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_forms.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_forms.py @@ -207,7 +207,8 @@ def test_basic(self): 'page': 2, 'page_size': 13, 'flagged': False, - 'requested_fields': set() + 'requested_fields': set(), + 'merge_question_type_responses': False } def test_missing_thread_id(self): diff --git a/lms/djangoapps/discussion/rest_api/tests/test_views.py b/lms/djangoapps/discussion/rest_api/tests/test_views.py index 1ebed6380de4..af41e4b87174 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_views.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_views.py @@ -496,6 +496,7 @@ def test_request_with_empty_results_page(self): @override_settings(DISCUSSION_MODERATION_CLOSE_REASON_CODES={"test-close-reason": "Test Close Reason"}) class CourseViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase): """Tests for CourseView""" + def setUp(self): super().setUp() self.url = reverse("discussion_course", kwargs={"course_id": str(self.course.id)}) @@ -545,6 +546,7 @@ def test_basic(self): @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) class RetireViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase): """Tests for CourseView""" + def setUp(self): super().setUp() RetirementState.objects.create(state_name='PENDING', state_execution_order=1) @@ -620,6 +622,7 @@ def test_not_authenticated(self): @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) class ReplaceUsernamesViewTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase): """Tests for ReplaceUsernamesView""" + def setUp(self): super().setUp() self.worker = UserFactory() @@ -715,6 +718,7 @@ class CourseTopicsViewTest(DiscussionAPIViewTestMixin, CommentsServiceMockMixin, """ Tests for CourseTopicsView """ + def setUp(self): httpretty.reset() httpretty.enable() @@ -925,6 +929,7 @@ class CourseTopicsViewV3Test(DiscussionAPIViewTestMixin, CommentsServiceMockMixi """ Tests for CourseTopicsViewV3 """ + def setUp(self) -> None: super().setUp() self.password = self.TEST_PASSWORD @@ -1013,6 +1018,7 @@ def test_basic(self): @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) class ThreadViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, ProfileImageTestMixin): """Tests for ThreadViewSet list""" + def setUp(self): super().setUp() self.author = UserFactory.create() @@ -1354,6 +1360,7 @@ def test_profile_image_requested_field_anonymous_user(self): @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) class ThreadViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase): """Tests for ThreadViewSet create""" + def setUp(self): super().setUp() self.url = reverse("thread-list") @@ -1424,6 +1431,7 @@ def test_error(self): @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) class ThreadViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, PatchMediaTypeMixin): """Tests for ThreadViewSet partial_update""" + def setUp(self): self.unsupported_media_type = JSONParser.media_type super().setUp() @@ -1567,6 +1575,7 @@ def test_patch_read_non_owner_user(self): @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) class ThreadViewSetDeleteTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase): """Tests for ThreadViewSet delete""" + def setUp(self): super().setUp() self.url = reverse("thread-detail", kwargs={"thread_id": "test_thread"}) @@ -1906,6 +1915,7 @@ def test_status_by(self, post_status): @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) class CommentViewSetListTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, ProfileImageTestMixin): """Tests for CommentViewSet list""" + def setUp(self): super().setUp() self.author = UserFactory.create() @@ -2040,6 +2050,7 @@ def test_basic(self): "recursive": ["False"], "with_responses": ["True"], "reverse_order": ["False"], + "merge_question_type_responses": ["False"], } ) @@ -2075,9 +2086,37 @@ def test_pagination(self): "recursive": ["False"], "with_responses": ["True"], "reverse_order": ["False"], + "merge_question_type_responses": ["False"], } ) + def test_question_content_with_merge_question_type_responses(self): + self.register_get_user_response(self.user) + thread = self.make_minimal_cs_thread({ + "thread_type": "question", + "children": [make_minimal_cs_comment({ + "id": "endorsed_comment", + "user_id": self.user.id, + "username": self.user.username, + "endorsed": True, + }), + make_minimal_cs_comment({ + "id": "non_endorsed_comment", + "user_id": self.user.id, + "username": self.user.username, + "endorsed": False, + })], + "resp_total": 2, + }) + self.register_get_thread_response(thread) + response = self.client.get(self.url, { + "thread_id": thread["id"], + "merge_question_type_responses": True + }) + parsed_content = json.loads(response.content.decode('utf-8')) + assert parsed_content['results'][0]['id'] == "endorsed_comment" + assert parsed_content['results'][1]['id'] == "non_endorsed_comment" + @ddt.data( (True, "endorsed_comment"), ("true", "endorsed_comment"), @@ -2144,7 +2183,12 @@ def test_question_missing_endorsed(self): }} ) - def test_child_comments_count(self): + @ddt.data( + ("discussion", False), + ("question", True) + ) + @ddt.unpack + def test_child_comments_count(self, thread_type, merge_question_type_responses): self.register_get_user_response(self.user) response_1 = make_minimal_cs_comment({ "id": "test_response_1", @@ -2163,15 +2207,16 @@ def test_child_comments_count(self): thread = self.make_minimal_cs_thread({ "id": self.thread_id, "course_id": str(self.course.id), - "thread_type": "discussion", + "thread_type": thread_type, "children": [response_1, response_2], "resp_total": 2, "comments_count": 8, "unread_comments_count": 0, - }) self.register_get_thread_response(thread) - response = self.client.get(self.url, {"thread_id": self.thread_id}) + response = self.client.get(self.url, { + "thread_id": self.thread_id, + "merge_question_type_responses": merge_question_type_responses}) expected_comments = [ self.expected_response_comment(overrides={"id": "test_response_1", "child_count": 2, "can_delete": False}), self.expected_response_comment(overrides={"id": "test_response_2", "child_count": 3, "can_delete": False}), @@ -2316,6 +2361,7 @@ def test_reverse_order_sort(self): "recursive": ["False"], "with_responses": ["True"], "reverse_order": ["True"], + "merge_question_type_responses": ["False"], } ) @@ -2365,6 +2411,7 @@ def test_delete_nonexistent_comment(self): @mock.patch("lms.djangoapps.discussion.signals.handlers.send_response_notifications", new=mock.Mock()) class CommentViewSetCreateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase): """Tests for CommentViewSet create""" + def setUp(self): super().setUp() self.url = reverse("comment-list") @@ -2462,6 +2509,7 @@ def test_closed_thread(self): @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) class CommentViewSetPartialUpdateTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, PatchMediaTypeMixin): """Tests for CommentViewSet partial_update""" + def setUp(self): self.unsupported_media_type = JSONParser.media_type super().setUp() @@ -2586,6 +2634,7 @@ def test_closed_thread_error(self, field, value): @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) class ThreadViewSetRetrieveTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, ProfileImageTestMixin): """Tests for ThreadViewSet Retrieve""" + def setUp(self): super().setUp() self.url = reverse("thread-detail", kwargs={"thread_id": "test_thread"}) @@ -2637,6 +2686,7 @@ def test_profile_image_requested_field(self): @mock.patch.dict("django.conf.settings.FEATURES", {"ENABLE_DISCUSSION_SERVICE": True}) class CommentViewSetRetrieveTest(DiscussionAPIViewTestMixin, ModuleStoreTestCase, ProfileImageTestMixin): """Tests for CommentViewSet Retrieve""" + def setUp(self): super().setUp() self.url = reverse("comment-detail", kwargs={"comment_id": "test_comment"}) diff --git a/lms/djangoapps/discussion/rest_api/views.py b/lms/djangoapps/discussion/rest_api/views.py index b62356a45dba..905b4ab49038 100644 --- a/lms/djangoapps/discussion/rest_api/views.py +++ b/lms/djangoapps/discussion/rest_api/views.py @@ -948,6 +948,7 @@ def list_by_thread(self, request): form.cleaned_data["page_size"], form.cleaned_data["flagged"], form.cleaned_data["requested_fields"], + form.cleaned_data["merge_question_type_responses"] ) def list_by_user(self, request): 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 8122f96f226a..ef5accbad25d 100644 --- a/openedx/core/djangoapps/django_comment_common/comment_client/thread.py +++ b/openedx/core/djangoapps/django_comment_common/comment_client/thread.py @@ -145,6 +145,7 @@ def _retrieve(self, *args, **kwargs): 'resp_skip': kwargs.get('response_skip'), 'resp_limit': kwargs.get('response_limit'), 'reverse_order': kwargs.get('reverse_order', False), + 'merge_question_type_responses': kwargs.get('merge_question_type_responses', False) } request_params = utils.strip_none(request_params) From 547f7febcc79a6a748d31b0fb97c5ef4027e625d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 17:42:17 +0500 Subject: [PATCH 19/20] feat: Upgrade Python dependency edx-enterprise (#34312) fix: Proximus learner transmission data failures Commit generated by workflow `openedx/edx-platform/.github/workflows/upgrade-one-python-dependency.yml@refs/heads/master` Co-authored-by: sameenfatima78<%- gettext('It is visible to learners, ensuring that all learners can view its contents.') %>
+<%- gettext('It is intentionally hidden from standard navigation, ensuring that only individuals with the link can view its contents.') %>
+ <% if (hideFromTOC) { %> ++ <%- gettext('If you make this section visible in the table of content, learners will be able to see its content.') %> +
+ <% } %> + <% } %> +<%- gettext('It is intentionally hidden from learners, ensuring that only the course staff can view its contents.') %>
+ <% } %> <% if (hasExplicitStaffLock && !ancestorLocked) { %><% if (xblockInfo.isVertical()) { %> @@ -20,6 +48,7 @@ <%- interpolate(message, { xblockType: xblockType }, true) %> <% } %>
- <% } %> + <% } %> +