11"""Tests for command handler module."""
22
3+ import asyncio
34import unittest
45import warnings
56from unittest .mock import AsyncMock , MagicMock , patch
6- import asyncio
7+
78from nio import MatrixRoom , RoomMessageText
9+
810from chatrixcd .commands import CommandHandler
911from chatrixcd .verification import SAS_AVAILABLE
1012
@@ -74,13 +76,17 @@ def tearDown(self):
7476 self .create_task_patcher .stop ()
7577
7678 # Cancel all pending tasks to prevent "coroutine not awaited" warnings
77- pending_tasks = [task for task in asyncio .all_tasks (self .loop ) if not task .done ()]
79+ pending_tasks = [
80+ task for task in asyncio .all_tasks (self .loop ) if not task .done ()
81+ ]
7882 for task in pending_tasks :
7983 task .cancel ()
8084
8185 # Wait for tasks to cancel
8286 if pending_tasks :
83- self .loop .run_until_complete (asyncio .gather (* pending_tasks , return_exceptions = True ))
87+ self .loop .run_until_complete (
88+ asyncio .gather (* pending_tasks , return_exceptions = True )
89+ )
8490
8591 self .loop .close ()
8692
@@ -137,13 +143,19 @@ def test_is_admin_url_encoded_username(self):
137143
138144 def test_is_admin_url_encoded_in_config_decoded_in_request (self ):
139145 """Test admin check when config has encoded username but request is decoded."""
140- self .handler .admin_users = ["@chrisw%40privacyinternational.org:privacyinternational.org" ]
141- result = self .handler .is_admin ("@chrisw@privacyinternational.org:privacyinternational.org" )
146+ self .handler .admin_users = [
147+ "@chrisw%40privacyinternational.org:privacyinternational.org"
148+ ]
149+ result = self .handler .is_admin (
150+ "@chrisw@privacyinternational.org:privacyinternational.org"
151+ )
142152 self .assertTrue (result )
143153
144154 def test_is_admin_decoded_in_config_encoded_in_request (self ):
145155 """Test admin check when config has decoded username but request is encoded."""
146- self .handler .admin_users = ["@chrisw@privacyinternational.org:privacyinternational.org" ]
156+ self .handler .admin_users = [
157+ "@chrisw@privacyinternational.org:privacyinternational.org"
158+ ]
147159 result = self .handler .is_admin (
148160 "@chrisw%40privacyinternational.org:privacyinternational.org"
149161 )
@@ -273,7 +285,9 @@ def test_list_templates_no_args(self):
273285 ]
274286 )
275287
276- self .loop .run_until_complete (self .handler .list_templates ("!test:example.com" , []))
288+ self .loop .run_until_complete (
289+ self .handler .list_templates ("!test:example.com" , [])
290+ )
277291
278292 # Should send usage message
279293 self .mock_bot .send_message .assert_called_once ()
@@ -282,7 +296,9 @@ def test_list_templates_no_args(self):
282296
283297 def test_list_templates_invalid_project_id (self ):
284298 """Test list templates with invalid project ID."""
285- self .loop .run_until_complete (self .handler .list_templates ("!test:example.com" , ["invalid" ]))
299+ self .loop .run_until_complete (
300+ self .handler .list_templates ("!test:example.com" , ["invalid" ])
301+ )
286302
287303 # Should send error message
288304 self .mock_bot .send_message .assert_called_once ()
@@ -298,7 +314,9 @@ def test_list_templates_success(self):
298314 ]
299315 )
300316
301- self .loop .run_until_complete (self .handler .list_templates ("!test:example.com" , ["1" ]))
317+ self .loop .run_until_complete (
318+ self .handler .list_templates ("!test:example.com" , ["1" ])
319+ )
302320
303321 # Should send templates list
304322 self .mock_bot .send_message .assert_called_once ()
@@ -310,7 +328,9 @@ def test_list_templates_empty(self):
310328 """Test list templates with no templates."""
311329 self .mock_semaphore .get_project_templates = AsyncMock (return_value = [])
312330
313- self .loop .run_until_complete (self .handler .list_templates ("!test:example.com" , ["1" ]))
331+ self .loop .run_until_complete (
332+ self .handler .list_templates ("!test:example.com" , ["1" ])
333+ )
314334
315335 # Should send empty message
316336 self .mock_bot .send_message .assert_called_once ()
@@ -358,7 +378,9 @@ def test_run_task_insufficient_args(self):
358378 def test_run_task_invalid_ids (self ):
359379 """Test run task with invalid IDs."""
360380 self .loop .run_until_complete (
361- self .handler .run_task ("!test:example.com" , "@user:example.com" , ["invalid" , "ids" ])
381+ self .handler .run_task (
382+ "!test:example.com" , "@user:example.com" , ["invalid" , "ids" ]
383+ )
362384 )
363385
364386 # Should send error message
@@ -371,7 +393,9 @@ def test_run_task_success(self, mock_create_task):
371393 """Test successful task start - now requests confirmation."""
372394 # Mock template data
373395 self .mock_semaphore .get_project_templates = AsyncMock (
374- return_value = [{"id" : 1 , "name" : "Template 1" , "description" : "Test template" }]
396+ return_value = [
397+ {"id" : 1 , "name" : "Template 1" , "description" : "Test template" }
398+ ]
375399 )
376400
377401 self .loop .run_until_complete (
@@ -419,7 +443,9 @@ def test_run_task_no_templates_single_arg(self):
419443 def test_run_task_no_templates_no_args (self ):
420444 """Test run task with zero templates when no args provided and one project."""
421445 # Mock to return one project with no templates
422- self .mock_semaphore .get_projects = AsyncMock (return_value = [{"id" : 1 , "name" : "Project 1" }])
446+ self .mock_semaphore .get_projects = AsyncMock (
447+ return_value = [{"id" : 1 , "name" : "Project 1" }]
448+ )
423449 self .mock_semaphore .get_project_templates = AsyncMock (return_value = [])
424450
425451 self .loop .run_until_complete (
@@ -443,7 +469,9 @@ def test_check_status_no_args(self):
443469
444470 def test_check_status_invalid_task_id (self ):
445471 """Test check status with invalid task ID."""
446- self .loop .run_until_complete (self .handler .check_status ("!test:example.com" , ["invalid" ]))
472+ self .loop .run_until_complete (
473+ self .handler .check_status ("!test:example.com" , ["invalid" ])
474+ )
447475
448476 # Should send error message
449477 self .mock_bot .send_message .assert_called_once ()
@@ -452,7 +480,9 @@ def test_check_status_invalid_task_id(self):
452480
453481 def test_check_status_task_not_found (self ):
454482 """Test check status for task not in active tasks."""
455- self .loop .run_until_complete (self .handler .check_status ("!test:example.com" , ["999" ]))
483+ self .loop .run_until_complete (
484+ self .handler .check_status ("!test:example.com" , ["999" ])
485+ )
456486
457487 # Should send not found message
458488 self .mock_bot .send_message .assert_called_once ()
@@ -475,7 +505,9 @@ def test_check_status_success(self):
475505 }
476506 )
477507
478- self .loop .run_until_complete (self .handler .check_status ("!test:example.com" , ["123" ]))
508+ self .loop .run_until_complete (
509+ self .handler .check_status ("!test:example.com" , ["123" ])
510+ )
479511
480512 # Should send status message
481513 self .mock_bot .send_message .assert_called_once ()
@@ -496,7 +528,9 @@ def test_stop_task_no_args(self):
496528 def test_stop_task_invalid_task_id (self ):
497529 """Test stop task with invalid task ID."""
498530 self .loop .run_until_complete (
499- self .handler .stop_task ("!test:example.com" , "@user:example.com" , ["invalid" ])
531+ self .handler .stop_task (
532+ "!test:example.com" , "@user:example.com" , ["invalid" ]
533+ )
500534 )
501535
502536 # Should send error message
@@ -567,7 +601,9 @@ def test_get_logs_no_args(self):
567601
568602 def test_get_logs_invalid_task_id (self ):
569603 """Test get logs with invalid task ID."""
570- self .loop .run_until_complete (self .handler .get_logs ("!test:example.com" , ["invalid" ]))
604+ self .loop .run_until_complete (
605+ self .handler .get_logs ("!test:example.com" , ["invalid" ])
606+ )
571607
572608 # Should send error message
573609 self .mock_bot .send_message .assert_called_once ()
@@ -576,7 +612,9 @@ def test_get_logs_invalid_task_id(self):
576612
577613 def test_get_logs_task_not_found (self ):
578614 """Test get logs for task not in active tasks."""
579- self .loop .run_until_complete (self .handler .get_logs ("!test:example.com" , ["999" ]))
615+ self .loop .run_until_complete (
616+ self .handler .get_logs ("!test:example.com" , ["999" ])
617+ )
580618
581619 # Should send not found message
582620 self .mock_bot .send_message .assert_called_once ()
@@ -594,7 +632,9 @@ def test_get_logs_success(self):
594632
595633 self .mock_semaphore .get_task_output = AsyncMock (return_value = "Task output logs" )
596634
597- self .loop .run_until_complete (self .handler .get_logs ("!test:example.com" , ["123" ]))
635+ self .loop .run_until_complete (
636+ self .handler .get_logs ("!test:example.com" , ["123" ])
637+ )
598638
599639 # Should send logs message
600640 self .mock_bot .send_message .assert_called_once ()
@@ -612,7 +652,9 @@ def test_get_logs_empty(self):
612652
613653 self .mock_semaphore .get_task_output = AsyncMock (return_value = None )
614654
615- self .loop .run_until_complete (self .handler .get_logs ("!test:example.com" , ["123" ]))
655+ self .loop .run_until_complete (
656+ self .handler .get_logs ("!test:example.com" , ["123" ])
657+ )
616658
617659 # Should send no logs message
618660 self .mock_bot .send_message .assert_called_once ()
@@ -631,7 +673,9 @@ def test_get_logs_truncation(self):
631673 long_logs = "\n " .join (["A" * 100 for _ in range (200 )])
632674 self .mock_semaphore .get_task_output = AsyncMock (return_value = long_logs )
633675
634- self .loop .run_until_complete (self .handler .get_logs ("!test:example.com" , ["123" ]))
676+ self .loop .run_until_complete (
677+ self .handler .get_logs ("!test:example.com" , ["123" ])
678+ )
635679
636680 # Should send logs message (truncation happens in HTML formatting)
637681 self .mock_bot .send_message .assert_called_once ()
@@ -686,7 +730,9 @@ def test_format_description_with_paragraph_symbol(self):
686730 # Test with ¶ symbol
687731 description = "First paragraph¶Second paragraph¶Third paragraph"
688732 result = self .handler ._format_description (description )
689- self .assertEqual (result , "First paragraph\n \n Second paragraph\n \n Third paragraph" )
733+ self .assertEqual (
734+ result , "First paragraph\n \n Second paragraph\n \n Third paragraph"
735+ )
690736
691737 # Test without ¶ symbol
692738 description = "Simple description"
@@ -1083,7 +1129,9 @@ def test_get_semaphore_info_respects_redact_flag(self):
10831129 )
10841130
10851131 self .loop .run_until_complete (
1086- handler_no_redact .get_semaphore_info ("!test:example.com" , "@user:example.com" )
1132+ handler_no_redact .get_semaphore_info (
1133+ "!test:example.com" , "@user:example.com"
1134+ )
10871135 )
10881136
10891137 call_args1 = self .mock_bot .send_message .call_args [0 ]
@@ -1142,7 +1190,9 @@ def test_verify_command_list(self):
11421190 )
11431191
11441192 self .loop .run_until_complete (
1145- self .handler .verify_device ("!room:example.com" , "@user:example.com" , ["list" ])
1193+ self .handler .verify_device (
1194+ "!room:example.com" , "@user:example.com" , ["list" ]
1195+ )
11461196 )
11471197
11481198 # Should call get_unverified_devices and send message
@@ -1162,7 +1212,9 @@ def test_verify_command_start(self):
11621212 }
11631213 ]
11641214 )
1165- self .mock_bot .verification_manager .start_verification = AsyncMock (return_value = MagicMock ())
1215+ self .mock_bot .verification_manager .start_verification = AsyncMock (
1216+ return_value = MagicMock ()
1217+ )
11661218
11671219 self .loop .run_until_complete (
11681220 self .handler .verify_device (
@@ -1202,10 +1254,14 @@ def test_sessions_command_list(self):
12021254 }
12031255 ]
12041256 )
1205- self .mock_bot .verification_manager .get_unverified_devices = AsyncMock (return_value = [])
1257+ self .mock_bot .verification_manager .get_unverified_devices = AsyncMock (
1258+ return_value = []
1259+ )
12061260
12071261 self .loop .run_until_complete (
1208- self .handler .manage_sessions ("!room:example.com" , "@user:example.com" , ["list" ])
1262+ self .handler .manage_sessions (
1263+ "!room:example.com" , "@user:example.com" , ["list" ]
1264+ )
12091265 )
12101266
12111267 # Should call device listing methods and send message
@@ -1258,7 +1314,7 @@ def test_cross_verify_bots(self):
12581314
12591315 # Should attempt to start verification with bot devices
12601316 verification_manager .start_verification .assert_called_once ()
1261- self .assertEqual (self .mock_bot .send_message .call_count , 2 ) # Initial message + result
1317+ self .assertEqual (self .mock_bot .send_message .call_count , 1 ) # Result message
12621318
12631319
12641320if __name__ == "__main__" :
0 commit comments