Skip to content

Commit 913c863

Browse files
Ali-Salman29Ali Salman
authored andcommitted
feat!: remove cs_comments_service support for forum's flag APIs
This will force the use of the new v2 forum's APIs for flaging/unflaging.
1 parent af5faf4 commit 913c863

File tree

12 files changed

+2307
-1004
lines changed

12 files changed

+2307
-1004
lines changed

lms/djangoapps/discussion/django_comment_client/base/tests.py

Lines changed: 2 additions & 364 deletions
Large diffs are not rendered by default.

lms/djangoapps/discussion/django_comment_client/base/tests_v2.py

Lines changed: 661 additions & 10 deletions
Large diffs are not rendered by default.

lms/djangoapps/discussion/django_comment_client/tests/mixins.py

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@
88
class MockForumApiMixin:
99
"""Mixin to mock forum_api across different test cases with a single mock instance."""
1010

11-
@classmethod
12-
def setUpClass(cls):
13-
"""Apply a single forum_api mock at the class level."""
14-
cls.setUpClassAndForumMock()
15-
1611
@classmethod
1712
def setUpClassAndForumMock(cls):
1813
"""
@@ -49,11 +44,6 @@ def disposeForumMocks(cls):
4944
for patcher in cls.forum_api_patchers:
5045
patcher.stop()
5146

52-
@classmethod
53-
def tearDownClass(cls):
54-
"""Stop patches after tests complete."""
55-
cls.disposeForumMocks()
56-
5747
def set_mock_return_value(self, function_name, return_value):
5848
"""
5949
Set a return value for a specific method in forum_api mock.
@@ -65,3 +55,50 @@ def set_mock_return_value(self, function_name, return_value):
6555
setattr(
6656
self.mock_forum_api, function_name, mock.Mock(return_value=return_value)
6757
)
58+
59+
def set_mock_side_effect(self, function_name, side_effect_fn):
60+
"""
61+
Set a side effect for a specific method in forum_api mock.
62+
63+
Args:
64+
function_name (str): The method name in the mock to set a side effect for.
65+
side_effect_fn (Callable): A function to be called when the mock is called.
66+
"""
67+
setattr(
68+
self.mock_forum_api, function_name, mock.Mock(side_effect=side_effect_fn)
69+
)
70+
71+
def check_mock_called_with(self, function_name, index, *parms, **kwargs):
72+
"""
73+
Check if a specific method in forum_api mock was called with the given parameters.
74+
75+
Args:
76+
function_name (str): The method name in the mock to check.
77+
parms (tuple): The parameters to check the method was called with.
78+
"""
79+
call_args = getattr(self.mock_forum_api, function_name).call_args_list[index]
80+
assert call_args == mock.call(*parms, **kwargs)
81+
82+
def check_mock_called(self, function_name):
83+
"""
84+
Check if a specific method in the forum_api mock was called.
85+
86+
Args:
87+
function_name (str): The method name in the mock to check.
88+
89+
Returns:
90+
bool: True if the method was called, False otherwise.
91+
"""
92+
return getattr(self.mock_forum_api, function_name).called
93+
94+
def get_mock_func_calls(self, function_name):
95+
"""
96+
Returns a list of call arguments for a specific method in the mock_forum_api.
97+
98+
Args:
99+
function_name (str): The name of the method in the mock_forum_api to retrieve call arguments for.
100+
101+
Returns:
102+
list: A list of call arguments for the specified method.
103+
"""
104+
return getattr(self.mock_forum_api, function_name).call_args_list

lms/djangoapps/discussion/rest_api/tests/test_api.py

Lines changed: 0 additions & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,18 +2150,6 @@ def test_following(self):
21502150
assert cs_request.method == 'POST'
21512151
assert parsed_body(cs_request) == {'source_type': ['thread'], 'source_id': ['test_id']}
21522152

2153-
def test_abuse_flagged(self):
2154-
self.register_post_thread_response({"id": "test_id", "username": self.user.username})
2155-
self.register_thread_flag_response("test_id")
2156-
data = self.minimal_data.copy()
2157-
data["abuse_flagged"] = "True"
2158-
result = create_thread(self.request, data)
2159-
assert result['abuse_flagged'] is True
2160-
cs_request = httpretty.last_request()
2161-
assert urlparse(cs_request.path).path == '/api/v1/threads/test_id/abuse_flag' # lint-amnesty, pylint: disable=no-member
2162-
assert cs_request.method == 'PUT'
2163-
assert parsed_body(cs_request) == {'user_id': [str(self.user.id)]}
2164-
21652153
def test_course_id_missing(self):
21662154
with pytest.raises(ValidationError) as assertion:
21672155
create_thread(self.request, {})
@@ -2510,18 +2498,6 @@ def test_endorsed(self, role_name, is_thread_author, thread_type):
25102498
except ValidationError:
25112499
assert expected_error
25122500

2513-
def test_abuse_flagged(self):
2514-
self.register_post_comment_response({"id": "test_comment", "username": self.user.username}, "test_thread")
2515-
self.register_comment_flag_response("test_comment")
2516-
data = self.minimal_data.copy()
2517-
data["abuse_flagged"] = "True"
2518-
result = create_comment(self.request, data)
2519-
assert result['abuse_flagged'] is True
2520-
cs_request = httpretty.last_request()
2521-
assert urlparse(cs_request.path).path == '/api/v1/comments/test_comment/abuse_flag' # lint-amnesty, pylint: disable=no-member
2522-
assert cs_request.method == 'PUT'
2523-
assert parsed_body(cs_request) == {'user_id': [str(self.user.id)]}
2524-
25252501
def test_thread_id_missing(self):
25262502
with pytest.raises(ValidationError) as assertion:
25272503
create_comment(self.request, {})
@@ -2957,108 +2933,6 @@ def test_vote_count_two_users(
29572933
assert result['vote_count'] == vote_count
29582934
self.register_get_user_response(self.user, upvoted_ids=[])
29592935

2960-
@ddt.data(*itertools.product([True, False], [True, False]))
2961-
@ddt.unpack
2962-
@mock.patch("eventtracking.tracker.emit")
2963-
def test_abuse_flagged(self, old_flagged, new_flagged, mock_emit):
2964-
"""
2965-
Test attempts to edit the "abuse_flagged" field.
2966-
2967-
old_flagged indicates whether the thread should be flagged at the start
2968-
of the test. new_flagged indicates the value for the "abuse_flagged"
2969-
field in the update. If old_flagged and new_flagged are the same, no
2970-
update should be made. Otherwise, a PUT should be made to the flag or
2971-
or unflag endpoint according to the new_flagged value.
2972-
"""
2973-
self.register_get_user_response(self.user)
2974-
self.register_thread_flag_response("test_thread")
2975-
self.register_thread({"abuse_flaggers": [str(self.user.id)] if old_flagged else []})
2976-
data = {"abuse_flagged": new_flagged}
2977-
result = update_thread(self.request, "test_thread", data)
2978-
assert result['abuse_flagged'] == new_flagged
2979-
last_request_path = urlparse(httpretty.last_request().path).path # lint-amnesty, pylint: disable=no-member
2980-
flag_url = "/api/v1/threads/test_thread/abuse_flag"
2981-
unflag_url = "/api/v1/threads/test_thread/abuse_unflag"
2982-
if old_flagged == new_flagged:
2983-
assert last_request_path != flag_url
2984-
assert last_request_path != unflag_url
2985-
else:
2986-
assert last_request_path == (flag_url if new_flagged else unflag_url)
2987-
assert httpretty.last_request().method == 'PUT'
2988-
assert parsed_body(httpretty.last_request()) == {'user_id': [str(self.user.id)]}
2989-
2990-
expected_event_name = 'edx.forum.thread.reported' if new_flagged else 'edx.forum.thread.unreported'
2991-
expected_event_data = {
2992-
'body': 'Original body',
2993-
'id': 'test_thread',
2994-
'content_type': 'Post',
2995-
'commentable_id': 'original_topic',
2996-
'url': '',
2997-
'user_course_roles': [],
2998-
'user_forums_roles': [FORUM_ROLE_STUDENT],
2999-
'target_username': self.user.username,
3000-
'title_truncated': False,
3001-
'title': 'Original Title',
3002-
'thread_type': 'discussion',
3003-
'group_id': None,
3004-
'truncated': False,
3005-
}
3006-
if not new_flagged:
3007-
expected_event_data['reported_status_cleared'] = False
3008-
3009-
actual_event_name, actual_event_data = mock_emit.call_args[0]
3010-
self.assertEqual(actual_event_name, expected_event_name)
3011-
self.assertEqual(actual_event_data, expected_event_data)
3012-
3013-
@ddt.data(
3014-
(False, True),
3015-
(True, True),
3016-
)
3017-
@ddt.unpack
3018-
@mock.patch("eventtracking.tracker.emit")
3019-
def test_thread_un_abuse_flag_for_moderator_role(self, is_author, remove_all, mock_emit):
3020-
"""
3021-
Test un-abuse flag for moderator role.
3022-
3023-
When moderator unflags a reported thread, it should
3024-
pass the "all" flag to the api. This will indicate
3025-
to the api to clear all abuse_flaggers, and mark the
3026-
thread as unreported.
3027-
"""
3028-
_assign_role_to_user(user=self.user, course_id=self.course.id, role=FORUM_ROLE_ADMINISTRATOR)
3029-
self.register_get_user_response(self.user)
3030-
self.register_thread_flag_response("test_thread")
3031-
self.register_thread({"abuse_flaggers": ["11"], "user_id": str(self.user.id) if is_author else "12"})
3032-
data = {"abuse_flagged": False}
3033-
update_thread(self.request, "test_thread", data)
3034-
assert httpretty.last_request().method == 'PUT'
3035-
query_params = {'user_id': [str(self.user.id)]}
3036-
if remove_all:
3037-
query_params.update({'all': ['True']})
3038-
assert parsed_body(httpretty.last_request()) == query_params
3039-
3040-
expected_event_name = 'edx.forum.thread.unreported'
3041-
expected_event_data = {
3042-
'body': 'Original body',
3043-
'id': 'test_thread',
3044-
'content_type': 'Post',
3045-
'commentable_id': 'original_topic',
3046-
'url': '',
3047-
'user_course_roles': [],
3048-
'user_forums_roles': [FORUM_ROLE_STUDENT, FORUM_ROLE_ADMINISTRATOR],
3049-
'target_username': self.user.username,
3050-
'title_truncated': False,
3051-
'title': 'Original Title',
3052-
'reported_status_cleared': False,
3053-
'thread_type': 'discussion',
3054-
'group_id': None,
3055-
'truncated': False,
3056-
}
3057-
3058-
actual_event_name, actual_event_data = mock_emit.call_args[0]
3059-
self.assertEqual(actual_event_name, expected_event_name)
3060-
self.assertEqual(actual_event_data, expected_event_data)
3061-
30622936
def test_invalid_field(self):
30632937
self.register_thread()
30642938
with pytest.raises(ValidationError) as assertion:
@@ -3566,100 +3440,6 @@ def test_vote_count_two_users(
35663440
assert result['vote_count'] == vote_count
35673441
self.register_get_user_response(self.user, upvoted_ids=[])
35683442

3569-
@ddt.data(*itertools.product([True, False], [True, False]))
3570-
@ddt.unpack
3571-
@mock.patch("eventtracking.tracker.emit")
3572-
def test_abuse_flagged(self, old_flagged, new_flagged, mock_emit):
3573-
"""
3574-
Test attempts to edit the "abuse_flagged" field.
3575-
3576-
old_flagged indicates whether the comment should be flagged at the start
3577-
of the test. new_flagged indicates the value for the "abuse_flagged"
3578-
field in the update. If old_flagged and new_flagged are the same, no
3579-
update should be made. Otherwise, a PUT should be made to the flag or
3580-
or unflag endpoint according to the new_flagged value.
3581-
"""
3582-
self.register_get_user_response(self.user)
3583-
self.register_comment_flag_response("test_comment")
3584-
self.register_comment({"abuse_flaggers": [str(self.user.id)] if old_flagged else []})
3585-
data = {"abuse_flagged": new_flagged}
3586-
result = update_comment(self.request, "test_comment", data)
3587-
assert result['abuse_flagged'] == new_flagged
3588-
last_request_path = urlparse(httpretty.last_request().path).path # lint-amnesty, pylint: disable=no-member
3589-
flag_url = "/api/v1/comments/test_comment/abuse_flag"
3590-
unflag_url = "/api/v1/comments/test_comment/abuse_unflag"
3591-
if old_flagged == new_flagged:
3592-
assert last_request_path != flag_url
3593-
assert last_request_path != unflag_url
3594-
else:
3595-
assert last_request_path == (flag_url if new_flagged else unflag_url)
3596-
assert httpretty.last_request().method == 'PUT'
3597-
assert parsed_body(httpretty.last_request()) == {'user_id': [str(self.user.id)]}
3598-
3599-
expected_event_name = 'edx.forum.response.reported' if new_flagged else 'edx.forum.response.unreported'
3600-
expected_event_data = {
3601-
'body': 'Original body',
3602-
'id': 'test_comment',
3603-
'content_type': 'Response',
3604-
'commentable_id': 'dummy',
3605-
'url': '',
3606-
'truncated': False,
3607-
'user_course_roles': [],
3608-
'user_forums_roles': [FORUM_ROLE_STUDENT],
3609-
'target_username': self.user.username,
3610-
}
3611-
if not new_flagged:
3612-
expected_event_data['reported_status_cleared'] = False
3613-
3614-
actual_event_name, actual_event_data = mock_emit.call_args[0]
3615-
self.assertEqual(actual_event_name, expected_event_name)
3616-
self.assertEqual(actual_event_data, expected_event_data)
3617-
3618-
@ddt.data(
3619-
(False, True),
3620-
(True, True),
3621-
)
3622-
@ddt.unpack
3623-
@mock.patch("eventtracking.tracker.emit")
3624-
def test_comment_un_abuse_flag_for_moderator_role(self, is_author, remove_all, mock_emit):
3625-
"""
3626-
Test un-abuse flag for moderator role.
3627-
3628-
When moderator unflags a reported comment, it should
3629-
pass the "all" flag to the api. This will indicate
3630-
to the api to clear all abuse_flaggers, and mark the
3631-
comment as unreported.
3632-
"""
3633-
_assign_role_to_user(user=self.user, course_id=self.course.id, role=FORUM_ROLE_ADMINISTRATOR)
3634-
self.register_get_user_response(self.user)
3635-
self.register_comment_flag_response("test_comment")
3636-
self.register_comment({"abuse_flaggers": ["11"], "user_id": str(self.user.id) if is_author else "12"})
3637-
data = {"abuse_flagged": False}
3638-
update_comment(self.request, "test_comment", data)
3639-
assert httpretty.last_request().method == 'PUT'
3640-
query_params = {'user_id': [str(self.user.id)]}
3641-
if remove_all:
3642-
query_params.update({'all': ['True']})
3643-
assert parsed_body(httpretty.last_request()) == query_params
3644-
3645-
expected_event_name = 'edx.forum.response.unreported'
3646-
expected_event_data = {
3647-
'body': 'Original body',
3648-
'id': 'test_comment',
3649-
'content_type': 'Response',
3650-
'commentable_id': 'dummy',
3651-
'truncated': False,
3652-
'url': '',
3653-
'user_course_roles': [],
3654-
'user_forums_roles': [FORUM_ROLE_STUDENT, FORUM_ROLE_ADMINISTRATOR],
3655-
'target_username': self.user.username,
3656-
'reported_status_cleared': False,
3657-
}
3658-
3659-
actual_event_name, actual_event_data = mock_emit.call_args[0]
3660-
self.assertEqual(actual_event_name, expected_event_name)
3661-
self.assertEqual(actual_event_data, expected_event_data)
3662-
36633443
@ddt.data(
36643444
FORUM_ROLE_ADMINISTRATOR,
36653445
FORUM_ROLE_MODERATOR,

0 commit comments

Comments
 (0)