11import os
22import tempfile
3- from unittest .mock import patch , MagicMock , mock_open
3+ from unittest .mock import MagicMock , mock_open , patch
4+
45import pytest
6+
57from pycti import OpenCTIApiClient
68
79
@@ -22,12 +24,12 @@ class TestOpenCTIApiClient:
2224 @pytest .fixture
2325 def api_client (self ):
2426 """Create an API client instance without performing health check."""
25- with patch .object (OpenCTIApiClient , ' _setup_proxy_certificates' ):
27+ with patch .object (OpenCTIApiClient , " _setup_proxy_certificates" ):
2628 client = OpenCTIApiClient (
2729 url = "http://localhost:4000" ,
2830 token = "test-token" ,
2931 ssl_verify = False ,
30- perform_health_check = False
32+ perform_health_check = False ,
3133 )
3234 # Mock the logger
3335 client .app_logger = MagicMock ()
@@ -36,7 +38,7 @@ def api_client(self):
3638 def test_get_certificate_content_inline_pem (self , api_client ):
3739 """Test _get_certificate_content with inline PEM certificate."""
3840 result = api_client ._get_certificate_content (self .SAMPLE_CERTIFICATE )
39-
41+
4042 assert result == self .SAMPLE_CERTIFICATE
4143 api_client .app_logger .debug .assert_called_with (
4244 "HTTPS_CA_CERTIFICATES contains inline certificate content"
@@ -45,17 +47,19 @@ def test_get_certificate_content_inline_pem(self, api_client):
4547 def test_get_certificate_content_file_path (self , api_client ):
4648 """Test _get_certificate_content with a file path containing certificate."""
4749 # Create a temporary file with certificate content
48- with tempfile .NamedTemporaryFile (mode = 'w' , suffix = '.crt' , delete = False ) as cert_file :
50+ with tempfile .NamedTemporaryFile (
51+ mode = "w" , suffix = ".crt" , delete = False
52+ ) as cert_file :
4953 cert_file .write (self .SAMPLE_CERTIFICATE )
5054 cert_file_path = cert_file .name
5155
5256 try :
5357 result = api_client ._get_certificate_content (cert_file_path )
54-
58+
5559 assert result == self .SAMPLE_CERTIFICATE
5660 api_client .app_logger .debug .assert_called_with (
5761 "HTTPS_CA_CERTIFICATES contains valid certificate file path" ,
58- {"file_path" : cert_file_path }
62+ {"file_path" : cert_file_path },
5963 )
6064 finally :
6165 # Clean up
@@ -64,17 +68,19 @@ def test_get_certificate_content_file_path(self, api_client):
6468 def test_get_certificate_content_invalid_file_content (self , api_client ):
6569 """Test _get_certificate_content with a file containing invalid certificate."""
6670 # Create a temporary file with invalid content
67- with tempfile .NamedTemporaryFile (mode = 'w' , suffix = '.txt' , delete = False ) as invalid_file :
71+ with tempfile .NamedTemporaryFile (
72+ mode = "w" , suffix = ".txt" , delete = False
73+ ) as invalid_file :
6874 invalid_file .write (self .INVALID_CONTENT )
6975 invalid_file_path = invalid_file .name
7076
7177 try :
7278 result = api_client ._get_certificate_content (invalid_file_path )
73-
79+
7480 assert result is None
7581 api_client .app_logger .warning .assert_called_with (
7682 "File at HTTPS_CA_CERTIFICATES path does not contain valid certificate" ,
77- {"file_path" : invalid_file_path }
83+ {"file_path" : invalid_file_path },
7884 )
7985 finally :
8086 # Clean up
@@ -83,23 +89,23 @@ def test_get_certificate_content_invalid_file_content(self, api_client):
8389 def test_get_certificate_content_nonexistent_file (self , api_client ):
8490 """Test _get_certificate_content with a nonexistent file path."""
8591 nonexistent_path = "/tmp/nonexistent_certificate.crt"
86-
92+
8793 result = api_client ._get_certificate_content (nonexistent_path )
88-
94+
8995 assert result is None
9096
9197 def test_get_certificate_content_invalid_content (self , api_client ):
9298 """Test _get_certificate_content with invalid content (not PEM, not file)."""
9399 result = api_client ._get_certificate_content (self .INVALID_CONTENT )
94-
100+
95101 assert result is None
96102
97103 def test_get_certificate_content_whitespace_handling (self , api_client ):
98104 """Test _get_certificate_content handles whitespace correctly."""
99105 # Test with certificate content with leading/trailing whitespace
100106 cert_with_whitespace = f" \n { self .SAMPLE_CERTIFICATE } \n "
101107 result = api_client ._get_certificate_content (cert_with_whitespace )
102-
108+
103109 assert result == cert_with_whitespace # Should return as-is
104110 api_client .app_logger .debug .assert_called_with (
105111 "HTTPS_CA_CERTIFICATES contains inline certificate content"
@@ -108,20 +114,22 @@ def test_get_certificate_content_whitespace_handling(self, api_client):
108114 def test_get_certificate_content_file_read_permission_error (self , api_client ):
109115 """Test _get_certificate_content when file exists but can't be read."""
110116 # Create a temporary file
111- with tempfile .NamedTemporaryFile (mode = 'w' , suffix = '.crt' , delete = False ) as cert_file :
117+ with tempfile .NamedTemporaryFile (
118+ mode = "w" , suffix = ".crt" , delete = False
119+ ) as cert_file :
112120 cert_file .write (self .SAMPLE_CERTIFICATE )
113121 cert_file_path = cert_file .name
114122
115123 try :
116124 # Make file unreadable (on Unix systems)
117125 os .chmod (cert_file_path , 0o000 )
118-
126+
119127 result = api_client ._get_certificate_content (cert_file_path )
120-
128+
121129 assert result is None
122130 # Check that warning was logged about failed read
123131 assert any (
124- call [0 ][0 ] == "Failed to read certificate file"
132+ call [0 ][0 ] == "Failed to read certificate file"
125133 for call in api_client .app_logger .warning .call_args_list
126134 )
127135 finally :
@@ -133,62 +141,73 @@ def test_get_certificate_content_file_read_permission_error(self, api_client):
133141 def test_setup_proxy_certificates_no_env (self , api_client ):
134142 """Test _setup_proxy_certificates when HTTPS_CA_CERTIFICATES is not set."""
135143 api_client ._setup_proxy_certificates ()
136-
144+
137145 # Should return early without setting ssl_verify
138- assert not hasattr (api_client , ' ssl_verify' ) or api_client .ssl_verify is False
146+ assert not hasattr (api_client , " ssl_verify" ) or api_client .ssl_verify is False
139147
140148 @patch .dict (os .environ , {})
141149 def test_setup_proxy_certificates_env_not_present (self , api_client ):
142150 """Test _setup_proxy_certificates when HTTPS_CA_CERTIFICATES env var doesn't exist."""
143151 api_client ._setup_proxy_certificates ()
144-
145- # Should return early without setting ssl_verify
146- assert not hasattr (api_client , 'ssl_verify' ) or api_client .ssl_verify is False
147152
148- @patch ('tempfile.mkdtemp' )
149- @patch ('os.path.isfile' )
150- @patch ('builtins.open' , new_callable = mock_open )
151- @patch .dict (os .environ , {"HTTPS_CA_CERTIFICATES" : "-----BEGIN CERTIFICATE-----\n test\n -----END CERTIFICATE-----" })
152- def test_setup_proxy_certificates_with_inline_cert (self , mock_file , mock_isfile , mock_mkdtemp , api_client ):
153+ # Should return early without setting ssl_verify
154+ assert not hasattr (api_client , "ssl_verify" ) or api_client .ssl_verify is False
155+
156+ @patch ("tempfile.mkdtemp" )
157+ @patch ("os.path.isfile" )
158+ @patch ("builtins.open" , new_callable = mock_open )
159+ @patch .dict (
160+ os .environ ,
161+ {
162+ "HTTPS_CA_CERTIFICATES" : "-----BEGIN CERTIFICATE-----\n test\n -----END CERTIFICATE-----"
163+ },
164+ )
165+ def test_setup_proxy_certificates_with_inline_cert (
166+ self , mock_file , mock_isfile , mock_mkdtemp , api_client
167+ ):
153168 """Test _setup_proxy_certificates with inline certificate content."""
154169 # Setup mocks
155170 mock_mkdtemp .return_value = "/tmp/test_certs"
156- mock_isfile .side_effect = lambda path : path == "/etc/ssl/certs/ca-certificates.crt"
157-
171+ mock_isfile .side_effect = (
172+ lambda path : path == "/etc/ssl/certs/ca-certificates.crt"
173+ )
174+
158175 # Mock system certificate content
159- system_cert_content = "-----BEGIN CERTIFICATE-----\n system\n -----END CERTIFICATE-----"
160-
161- def open_side_effect (path , mode = 'r' ):
162- if path == "/etc/ssl/certs/ca-certificates.crt" and mode == 'r' :
176+ system_cert_content = (
177+ "-----BEGIN CERTIFICATE-----\n system\n -----END CERTIFICATE-----"
178+ )
179+
180+ def open_side_effect (path , mode = "r" ):
181+ if path == "/etc/ssl/certs/ca-certificates.crt" and mode == "r" :
163182 return mock_open (read_data = system_cert_content )()
164183 return mock_file ()
165-
166- with patch (' builtins.open' , side_effect = open_side_effect ):
184+
185+ with patch (" builtins.open" , side_effect = open_side_effect ):
167186 api_client ._setup_proxy_certificates ()
168-
187+
169188 # Verify proxy certificates were processed
170189 api_client .app_logger .info .assert_called ()
171190
172- @patch (' tempfile.mkdtemp' )
191+ @patch (" tempfile.mkdtemp" )
173192 @patch .dict (os .environ , {"HTTPS_CA_CERTIFICATES" : "/path/to/cert.crt" })
174193 def test_setup_proxy_certificates_with_invalid_path (self , mock_mkdtemp , api_client ):
175194 """Test _setup_proxy_certificates with invalid certificate file path."""
176195 mock_mkdtemp .return_value = "/tmp/test_certs"
177-
196+
178197 # Mock _get_certificate_content to return None (invalid)
179- with patch .object (api_client , ' _get_certificate_content' , return_value = None ):
198+ with patch .object (api_client , " _get_certificate_content" , return_value = None ):
180199 api_client ._setup_proxy_certificates ()
181-
200+
182201 # Should log warning and return early
183202 api_client .app_logger .warning .assert_called ()
184- assert not hasattr (api_client , ' ssl_verify' ) or api_client .ssl_verify is False
203+ assert not hasattr (api_client , " ssl_verify" ) or api_client .ssl_verify is False
185204
186205 def test_setup_proxy_certificates_exception_handling (self , api_client ):
187206 """Test _setup_proxy_certificates handles exceptions gracefully."""
188207 with patch .dict (os .environ , {"HTTPS_CA_CERTIFICATES" : self .SAMPLE_CERTIFICATE }):
189- with patch (' tempfile.mkdtemp' , side_effect = Exception ("Mock error" )):
208+ with patch (" tempfile.mkdtemp" , side_effect = Exception ("Mock error" )):
190209 api_client ._setup_proxy_certificates ()
191-
210+
192211 # Should log warning and continue
193212 api_client .app_logger .warning .assert_called_with (
194213 "Failed to setup proxy certificates" , {"error" : "Mock error" }
0 commit comments