1414from edx_ace .recipient import Recipient
1515from edx_ace .renderers import EmailRenderer
1616from edx_ace .utils import date
17+ from lms .djangoapps .discussion .django_comment_client .tests .mixins import (
18+ MockForumApiMixin ,
19+ )
1720from xmodule .modulestore .tests .django_utils import ModuleStoreTestCase
1821
1922import openedx .core .djangoapps .django_comment_common .comment_client as cc
@@ -69,13 +72,39 @@ def mock_request(method, url, **kwargs):
6972 return mock_request
7073
7174
75+ def make_subscribed_threads_callback (subscribed_thread_ids , per_page = 1 ):
76+ """
77+ Creates a callback function for simulating user data.
78+ """
79+
80+ def callback (* args , ** kwargs ): # lint-amnesty, pylint: disable=unused-argument
81+ subscribed_thread_collection = [
82+ {"id" : thread_id } for thread_id in subscribed_thread_ids
83+ ]
84+ page = kwargs .get ("page" , 1 )
85+ start_index = per_page * (page - 1 )
86+ end_index = per_page * page
87+ data = {
88+ "collection" : subscribed_thread_collection [start_index :end_index ],
89+ "page" : page ,
90+ "num_pages" : int (
91+ math .ceil (len (subscribed_thread_collection ) / float (per_page ))
92+ ),
93+ "thread_count" : len (subscribed_thread_collection ),
94+ }
95+ return data
96+
97+ return callback
98+
99+
72100@ddt .ddt
73- class TaskTestCase (ModuleStoreTestCase ): # lint-amnesty, pylint: disable=missing-class-docstring
101+ class TaskTestCase (ModuleStoreTestCase , MockForumApiMixin ): # lint-amnesty, pylint: disable=missing-class-docstring
74102
75103 @classmethod
76104 @mock .patch .dict ("django.conf.settings.FEATURES" , {"ENABLE_DISCUSSION_SERVICE" : True })
77105 def setUpClass (cls ):
78106 super ().setUpClass ()
107+ super ().setUpClassAndForumMock ()
79108 cls .discussion_id = 'dummy_discussion_id'
80109 cls .question_id = 'dummy_question_id'
81110 cls .course = CourseOverviewFactory .create (language = 'fr' )
@@ -109,6 +138,29 @@ def setUpClass(cls):
109138
110139 cls .create_threads_and_comments ()
111140
141+ @classmethod
142+ def tearDownClass (cls ):
143+ super ().tearDownClass ()
144+ super ().disposeForumMocks ()
145+
146+ def _set_forum_mocks (
147+ self ,
148+ subscribed_thread_ids = None ,
149+ thread_data = None ,
150+ comment_data = None ,
151+ per_page = 1 ,
152+ ):
153+ """mock threads and comments"""
154+ if subscribed_thread_ids is not None :
155+ self .set_mock_side_effect (
156+ "get_user_subscriptions" ,
157+ make_subscribed_threads_callback (subscribed_thread_ids , per_page ),
158+ )
159+ if thread_data :
160+ self .set_mock_return_value ("get_thread" , thread_data )
161+ if comment_data :
162+ self .set_mock_return_value ("get_parent_comment" , comment_data )
163+
112164 @classmethod
113165 def create_threads_and_comments (cls ): # lint-amnesty, pylint: disable=missing-function-docstring
114166 # Regular discussion threads and comments.
@@ -221,9 +273,6 @@ def create_threads_and_comments(cls): # lint-amnesty, pylint: disable=missing-f
221273
222274 def setUp (self ):
223275 super ().setUp ()
224- self .request_patcher = mock .patch ('requests.request' )
225- self .mock_request = self .request_patcher .start ()
226-
227276 self .ace_send_patcher = mock .patch ('edx_ace.ace.send' )
228277 self .mock_ace_send = self .ace_send_patcher .start ()
229278 self .mock_message_patcher = mock .patch ('lms.djangoapps.discussion.tasks.ResponseNotification' )
@@ -232,26 +281,11 @@ def setUp(self):
232281 thread_permalink = '/courses/discussion/dummy_discussion_id'
233282 self .permalink_patcher = mock .patch ('lms.djangoapps.discussion.tasks.permalink' , return_value = thread_permalink )
234283 self .mock_permalink = self .permalink_patcher .start ()
235- patcher = mock .patch (
236- 'openedx.core.djangoapps.discussions.config.waffle.ENABLE_FORUM_V2.is_enabled' ,
237- return_value = False
238- )
239- patcher .start ()
240- self .addCleanup (patcher .stop )
241- patcher = mock .patch (
242- "openedx.core.djangoapps.django_comment_common.comment_client.models.forum_api.get_course_id_by_comment"
243- )
244- self .mock_get_course_id_by_comment = patcher .start ()
245- self .addCleanup (patcher .stop )
246- patcher = mock .patch (
247- "openedx.core.djangoapps.django_comment_common.comment_client.thread.forum_api.get_course_id_by_thread"
248- )
249- self .mock_get_course_id_by_thread = patcher .start ()
250- self .addCleanup (patcher .stop )
284+ self .set_mock_return_value ("get_course_id_by_thread" , str (self .course .id ))
285+ self .set_mock_return_value ("get_course_id_by_comment" , str (self .course .id ))
251286
252287 def tearDown (self ):
253288 super ().tearDown ()
254- self .request_patcher .stop ()
255289 self .ace_send_patcher .stop ()
256290 self .mock_message_patcher .stop ()
257291 self .permalink_patcher .stop ()
@@ -279,7 +313,7 @@ def test_send_discussion_email_notification(self, user_subscribed):
279313 ]
280314 for thread , comment in examples :
281315 self .mock_ace_send .reset_mock ()
282- self .mock_request . side_effect = make_mock_responder (
316+ self ._set_forum_mocks (
283317 subscribed_thread_ids = subscribed_thread_ids ,
284318 comment_data = comment ,
285319 thread_data = thread ,
@@ -344,7 +378,7 @@ def run_should_not_send_email_test(self, thread, comment_dict):
344378 """
345379 assert email is not sent
346380 """
347- self .mock_request . side_effect = make_mock_responder (
381+ self ._set_forum_mocks (
348382 subscribed_thread_ids = [self .discussion_id , self .question_id ],
349383 comment_data = comment_dict ,
350384 thread_data = thread ,
0 commit comments