-
-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathtest_utils.py
More file actions
309 lines (244 loc) · 11.7 KB
/
test_utils.py
File metadata and controls
309 lines (244 loc) · 11.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
"""Test module for json2xml.utils functionality."""
import json
import tempfile
from typing import TYPE_CHECKING
from unittest.mock import Mock, patch
import pytest
from json2xml.utils import (
InvalidDataError,
JSONReadError,
StringReadError,
URLReadError,
readfromjson,
readfromstring,
readfromurl,
)
if TYPE_CHECKING:
from _pytest.capture import CaptureFixture
from _pytest.fixtures import FixtureRequest
from _pytest.logging import LogCaptureFixture
from _pytest.monkeypatch import MonkeyPatch
class TestExceptions:
"""Test custom exception classes."""
def test_json_read_error(self) -> None:
"""Test JSONReadError exception."""
with pytest.raises(JSONReadError) as exc_info:
raise JSONReadError("Test error message")
assert str(exc_info.value) == "Test error message"
def test_invalid_data_error(self) -> None:
"""Test InvalidDataError exception."""
with pytest.raises(InvalidDataError) as exc_info:
raise InvalidDataError("Invalid data")
assert str(exc_info.value) == "Invalid data"
def test_url_read_error(self) -> None:
"""Test URLReadError exception."""
with pytest.raises(URLReadError) as exc_info:
raise URLReadError("URL error")
assert str(exc_info.value) == "URL error"
def test_string_read_error(self) -> None:
"""Test StringReadError exception."""
with pytest.raises(StringReadError) as exc_info:
raise StringReadError("String error")
assert str(exc_info.value) == "String error"
class TestReadFromJson:
"""Test readfromjson function."""
def test_readfromjson_valid_file(self) -> None:
"""Test reading a valid JSON file."""
test_data = {"key": "value", "number": 42}
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
json.dump(test_data, f)
temp_filename = f.name
try:
result = readfromjson(temp_filename)
assert result == test_data
finally:
import os
os.unlink(temp_filename)
def test_readfromjson_invalid_json_content(self) -> None:
"""Test reading a file with invalid JSON content."""
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
f.write('{"invalid": json content}') # Invalid JSON
temp_filename = f.name
try:
with pytest.raises(JSONReadError, match="Invalid JSON File"):
readfromjson(temp_filename)
finally:
import os
os.unlink(temp_filename)
def test_readfromjson_file_not_found(self) -> None:
"""Test reading a non-existent file."""
with pytest.raises(JSONReadError, match="Invalid JSON File"):
readfromjson("non_existent_file.json")
@patch('builtins.open')
def test_readfromjson_permission_error(self, mock_open: Mock) -> None:
"""Test reading a file with permission issues."""
# Mock open to raise PermissionError
mock_open.side_effect = PermissionError("Permission denied")
with pytest.raises(JSONReadError, match="Invalid JSON File"):
readfromjson("some_file.json")
@patch('builtins.open')
def test_readfromjson_os_error(self, mock_open: Mock) -> None:
"""Test reading a file with OS error."""
# Mock open to raise OSError (covers line 34-35 in utils.py)
mock_open.side_effect = OSError("Device not ready")
with pytest.raises(JSONReadError, match="Invalid JSON File"):
readfromjson("some_file.json")
class TestReadFromUrl:
"""Test readfromurl function."""
@patch('json2xml.utils.urllib3.PoolManager')
def test_readfromurl_success(self, mock_pool_manager: Mock) -> None:
"""Test successful URL reading."""
# Mock response
mock_response = Mock()
mock_response.status = 200
mock_response.data = b'{"key": "value", "number": 42}'
# Mock PoolManager
mock_http = Mock()
mock_http.request.return_value = mock_response
mock_pool_manager.return_value = mock_http
result = readfromurl("http://example.com/data.json")
assert result == {"key": "value", "number": 42}
mock_pool_manager.assert_called_once()
mock_http.request.assert_called_once_with("GET", "http://example.com/data.json", fields=None)
@patch('json2xml.utils.urllib3.PoolManager')
def test_readfromurl_success_with_params(self, mock_pool_manager: Mock) -> None:
"""Test successful URL reading with parameters."""
# Mock response
mock_response = Mock()
mock_response.status = 200
mock_response.data = b'{"result": "success"}'
# Mock PoolManager
mock_http = Mock()
mock_http.request.return_value = mock_response
mock_pool_manager.return_value = mock_http
params = {"param1": "value1", "param2": "value2"}
result = readfromurl("http://example.com/api", params=params)
assert result == {"result": "success"}
mock_http.request.assert_called_once_with("GET", "http://example.com/api", fields=params)
@patch('json2xml.utils.urllib3.PoolManager')
def test_readfromurl_http_error(self, mock_pool_manager: Mock) -> None:
"""Test URL reading with HTTP error status."""
# Mock response with error status
mock_response = Mock()
mock_response.status = 404
# Mock PoolManager
mock_http = Mock()
mock_http.request.return_value = mock_response
mock_pool_manager.return_value = mock_http
with pytest.raises(URLReadError, match="URL is not returning correct response"):
readfromurl("http://example.com/nonexistent.json")
@patch('json2xml.utils.urllib3.PoolManager')
def test_readfromurl_server_error(self, mock_pool_manager: Mock) -> None:
"""Test URL reading with server error status."""
# Mock response with server error status
mock_response = Mock()
mock_response.status = 500
# Mock PoolManager
mock_http = Mock()
mock_http.request.return_value = mock_response
mock_pool_manager.return_value = mock_http
with pytest.raises(URLReadError, match="URL is not returning correct response"):
readfromurl("http://example.com/error.json")
@patch('json2xml.utils.urllib3.PoolManager')
def test_readfromurl_invalid_json_response(self, mock_pool_manager: Mock) -> None:
"""Test URL reading with invalid JSON response."""
# Mock response with invalid JSON
mock_response = Mock()
mock_response.status = 200
mock_response.data = b'invalid json content'
# Mock PoolManager
mock_http = Mock()
mock_http.request.return_value = mock_response
mock_pool_manager.return_value = mock_http
with pytest.raises(json.JSONDecodeError):
readfromurl("http://example.com/invalid.json")
class TestReadFromString:
"""Test readfromstring function."""
def test_readfromstring_valid_json(self) -> None:
"""Test reading valid JSON string."""
json_string = '{"key": "value", "number": 42, "boolean": true}'
result = readfromstring(json_string)
assert result == {"key": "value", "number": 42, "boolean": True}
def test_readfromstring_empty_object(self) -> None:
"""Test reading empty JSON object."""
json_string = '{}'
result = readfromstring(json_string)
assert result == {}
def test_readfromstring_complex_object(self) -> None:
"""Test reading complex JSON object."""
json_string = '{"users": [{"name": "John", "age": 30}, {"name": "Jane", "age": 25}], "total": 2}'
result = readfromstring(json_string)
expected = {
"users": [
{"name": "John", "age": 30},
{"name": "Jane", "age": 25}
],
"total": 2
}
assert result == expected
def test_readfromstring_invalid_type_int(self) -> None:
"""Test reading with integer input."""
with pytest.raises(StringReadError, match="Input is not a proper JSON string"):
readfromstring(123) # type: ignore[arg-type]
def test_readfromstring_invalid_type_list(self) -> None:
"""Test reading with list input."""
with pytest.raises(StringReadError, match="Input is not a proper JSON string"):
readfromstring(["not", "a", "string"]) # type: ignore[arg-type]
def test_readfromstring_invalid_type_dict(self) -> None:
"""Test reading with dict input."""
with pytest.raises(StringReadError, match="Input is not a proper JSON string"):
readfromstring({"not": "a string"}) # type: ignore[arg-type]
def test_readfromstring_invalid_type_none(self) -> None:
"""Test reading with None input."""
with pytest.raises(StringReadError, match="Input is not a proper JSON string"):
readfromstring(None) # type: ignore[arg-type]
def test_readfromstring_invalid_json_syntax(self) -> None:
"""Test reading string with invalid JSON syntax."""
with pytest.raises(StringReadError, match="Input is not a proper JSON string"):
readfromstring('{"invalid": json, syntax}')
def test_readfromstring_invalid_json_incomplete(self) -> None:
"""Test reading incomplete JSON string."""
with pytest.raises(StringReadError, match="Input is not a proper JSON string"):
readfromstring('{"incomplete":')
def test_readfromstring_invalid_json_extra_comma(self) -> None:
"""Test reading JSON string with trailing comma."""
with pytest.raises(StringReadError, match="Input is not a proper JSON string"):
readfromstring('{"key": "value",}')
def test_readfromstring_invalid_json_single_quotes(self) -> None:
"""Test reading JSON string with single quotes."""
with pytest.raises(StringReadError, match="Input is not a proper JSON string"):
readfromstring("{'key': 'value'}")
def test_readfromstring_empty_string(self) -> None:
"""Test reading empty string."""
with pytest.raises(StringReadError, match="Input is not a proper JSON string"):
readfromstring("")
def test_readfromstring_plain_text(self) -> None:
"""Test reading plain text."""
with pytest.raises(StringReadError, match="Input is not a proper JSON string"):
readfromstring("this is just plain text")
class TestIntegration:
"""Integration tests combining multiple utilities."""
def test_readfromstring_then_convert_to_xml(self) -> None:
"""Test reading JSON string and converting to XML."""
from json2xml import dicttoxml
json_string = '{"name": "test", "value": 123}'
data = readfromstring(json_string)
xml_result = dicttoxml.dicttoxml(data, attr_type=False, root=False)
assert b"<name>test</name>" in xml_result
assert b"<value>123</value>" in xml_result
@patch('json2xml.utils.urllib3.PoolManager')
def test_readfromurl_then_convert_to_xml(self, mock_pool_manager: Mock) -> None:
"""Test reading from URL and converting to XML."""
from json2xml import dicttoxml
# Mock response
mock_response = Mock()
mock_response.status = 200
mock_response.data = b'{"api": "response", "status": "ok"}'
# Mock PoolManager
mock_http = Mock()
mock_http.request.return_value = mock_response
mock_pool_manager.return_value = mock_http
data = readfromurl("http://example.com/api.json")
xml_result = dicttoxml.dicttoxml(data, attr_type=False, root=False)
assert b"<api>response</api>" in xml_result
assert b"<status>ok</status>" in xml_result