2121# THE SOFTWARE.
2222
2323import asyncio
24- import types
2524import unittest
26- import warnings
2725from unittest import mock
2826
2927import kanboard
@@ -35,13 +33,8 @@ def setUp(self):
3533 self .client = kanboard .Client (self .url , "username" , "password" )
3634 self .request , self .urlopen = self ._create_mocks ()
3735
38- def ignore_warnings (test_func ):
39- def do_test (self , * args , ** kwargs ):
40- with warnings .catch_warnings ():
41- warnings .simplefilter ("ignore" )
42- test_func (self , * args , ** kwargs )
43-
44- return do_test
36+ def tearDown (self ):
37+ self .client .close ()
4538
4639 def test_api_call (self ):
4740 body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
@@ -106,13 +99,6 @@ def test_method_name_extracted_from_async_name(self):
10699 result = self .client .get_funcname_from_async_name (async_method_name )
107100 self .assertEqual (expected_method_name , result )
108101
109- # suppress a RuntimeWarning because coro is not awaited
110- # this is done on purpose
111- @ignore_warnings
112- def test_async_call_generates_coro (self ):
113- method = self .client .my_method_async ()
114- self .assertIsInstance (method , types .CoroutineType )
115-
116102 def test_async_call_returns_result (self ):
117103 body = b'{"jsonrpc": "2.0", "result": 42, "id": 123}'
118104 self .urlopen .return_value .read .return_value = body
@@ -125,16 +111,37 @@ def test_custom_event_loop(self):
125111 try :
126112 client = kanboard .Client (self .url , "username" , "password" , loop = custom_loop )
127113 self .assertIs (client ._event_loop , custom_loop )
114+ self .assertFalse (client ._owns_event_loop )
115+ finally :
116+ custom_loop .close ()
117+
118+ def test_close_owned_event_loop (self ):
119+ client = kanboard .Client (self .url , "username" , "password" )
120+ if client ._owns_event_loop :
121+ self .assertFalse (client ._event_loop .is_closed ())
122+ client .close ()
123+ self .assertTrue (client ._event_loop .is_closed ())
124+
125+ def test_close_does_not_close_external_loop (self ):
126+ custom_loop = asyncio .new_event_loop ()
127+ try :
128+ client = kanboard .Client (self .url , "username" , "password" , loop = custom_loop )
129+ client .close ()
130+ self .assertFalse (custom_loop .is_closed ())
128131 finally :
129132 custom_loop .close ()
130133
134+ def test_context_manager (self ):
135+ with kanboard .Client (self .url , "username" , "password" ) as client :
136+ self .assertIsNotNone (client ._event_loop )
137+
131138 def test_custom_user_agent (self ):
132- client = kanboard .Client (self .url , "username" , "password" , user_agent = "CustomAgent/1.0" )
133- body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
134- self .urlopen .return_value .read .return_value = body
135- client .remote_procedure ()
136- _ , kwargs = self .request .call_args
137- self .assertEqual ("CustomAgent/1.0" , kwargs ["headers" ]["User-Agent" ])
139+ with kanboard .Client (self .url , "username" , "password" , user_agent = "CustomAgent/1.0" ) as client :
140+ body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
141+ self .urlopen .return_value .read .return_value = body
142+ client .remote_procedure ()
143+ _ , kwargs = self .request .call_args
144+ self .assertEqual ("CustomAgent/1.0" , kwargs ["headers" ]["User-Agent" ])
138145
139146 def test_default_user_agent (self ):
140147 body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
@@ -145,30 +152,30 @@ def test_default_user_agent(self):
145152
146153 @mock .patch ("ssl.create_default_context" )
147154 def test_insecure_disables_ssl_verification (self , mock_ssl_context ):
148- client = kanboard .Client (self .url , "username" , "password" , insecure = True )
149- ctx = mock_ssl_context .return_value
150- body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
151- self .urlopen .return_value .read .return_value = body
152- client .remote_procedure ()
153- self .assertFalse (ctx .check_hostname )
154- self .assertEqual (ctx .verify_mode , __import__ ("ssl" ).CERT_NONE )
155+ with kanboard .Client (self .url , "username" , "password" , insecure = True ) as client :
156+ ctx = mock_ssl_context .return_value
157+ body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
158+ self .urlopen .return_value .read .return_value = body
159+ client .remote_procedure ()
160+ self .assertFalse (ctx .check_hostname )
161+ self .assertEqual (ctx .verify_mode , __import__ ("ssl" ).CERT_NONE )
155162
156163 @mock .patch ("ssl.create_default_context" )
157164 def test_ignore_hostname_verification (self , mock_ssl_context ):
158- client = kanboard .Client (self .url , "username" , "password" , ignore_hostname_verification = True )
159- ctx = mock_ssl_context .return_value
160- body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
161- self .urlopen .return_value .read .return_value = body
162- client .remote_procedure ()
163- self .assertFalse (ctx .check_hostname )
165+ with kanboard .Client (self .url , "username" , "password" , ignore_hostname_verification = True ) as client :
166+ ctx = mock_ssl_context .return_value
167+ body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
168+ self .urlopen .return_value .read .return_value = body
169+ client .remote_procedure ()
170+ self .assertFalse (ctx .check_hostname )
164171
165172 @mock .patch ("ssl.create_default_context" )
166173 def test_cafile_passed_to_ssl_context (self , mock_ssl_context ):
167- client = kanboard .Client (self .url , "username" , "password" , cafile = "/path/to/ca.pem" )
168- body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
169- self .urlopen .return_value .read .return_value = body
170- client .remote_procedure ()
171- mock_ssl_context .assert_called_once_with (cafile = "/path/to/ca.pem" )
174+ with kanboard .Client (self .url , "username" , "password" , cafile = "/path/to/ca.pem" ) as client :
175+ body = b'{"jsonrpc": "2.0", "result": true, "id": 123}'
176+ self .urlopen .return_value .read .return_value = body
177+ client .remote_procedure ()
178+ mock_ssl_context .assert_called_once_with (cafile = "/path/to/ca.pem" )
172179
173180 @staticmethod
174181 def _create_mocks ():
0 commit comments