|
| 1 | +import json |
1 | 2 | import tempfile |
2 | 3 | import uuid |
3 | 4 | from pathlib import Path |
| 5 | +from unittest.mock import Mock |
4 | 6 |
|
5 | 7 | import pytest |
6 | 8 | from graphql import parse |
7 | 9 | from whenever import Instant |
8 | 10 |
|
| 11 | +from infrahub_sdk.exceptions import JsonDecodeError |
9 | 12 | from infrahub_sdk.utils import ( |
10 | 13 | base16decode, |
11 | 14 | base16encode, |
12 | 15 | base36decode, |
13 | 16 | base36encode, |
14 | 17 | calculate_time_diff, |
15 | 18 | compare_lists, |
| 19 | + decode_json, |
16 | 20 | deep_merge_dict, |
17 | 21 | dict_hash, |
18 | 22 | duplicates, |
@@ -227,3 +231,53 @@ def test_calculate_time_diff() -> None: |
227 | 231 |
|
228 | 232 | time5 = Instant.now().subtract(hours=77, minutes=12, seconds=34).format_common_iso() |
229 | 233 | assert calculate_time_diff(time5) == "3d and 5h ago" |
| 234 | + |
| 235 | + |
| 236 | +def test_decode_json_success() -> None: |
| 237 | + """Test decode_json with valid JSON response.""" |
| 238 | + mock_response = Mock() |
| 239 | + mock_response.json.return_value = {"status": "ok", "data": {"key": "value"}} |
| 240 | + |
| 241 | + result = decode_json(mock_response) |
| 242 | + assert result == {"status": "ok", "data": {"key": "value"}} |
| 243 | + |
| 244 | + |
| 245 | +def test_decode_json_failure_with_content() -> None: |
| 246 | + """Test decode_json with invalid JSON response includes server content in error message.""" |
| 247 | + mock_response = Mock() |
| 248 | + mock_response.json.side_effect = json.decoder.JSONDecodeError("Invalid JSON", "document", 0) |
| 249 | + mock_response.text = "Internal Server Error: Database connection failed" |
| 250 | + mock_response.url = "https://example.com/api/graphql" |
| 251 | + |
| 252 | + with pytest.raises(JsonDecodeError) as exc_info: |
| 253 | + decode_json(mock_response) |
| 254 | + |
| 255 | + error_message = str(exc_info.value) |
| 256 | + assert "Unable to decode response as JSON data from https://example.com/api/graphql" in error_message |
| 257 | + assert "Server response: Internal Server Error: Database connection failed" in error_message |
| 258 | + |
| 259 | + |
| 260 | +def test_decode_json_failure_without_content() -> None: |
| 261 | + """Test decode_json with invalid JSON response and no content.""" |
| 262 | + mock_response = Mock() |
| 263 | + mock_response.json.side_effect = json.decoder.JSONDecodeError("Invalid JSON", "document", 0) |
| 264 | + mock_response.text = "" |
| 265 | + mock_response.url = "https://example.com/api/graphql" |
| 266 | + |
| 267 | + with pytest.raises(JsonDecodeError) as exc_info: |
| 268 | + decode_json(mock_response) |
| 269 | + |
| 270 | + error_message = str(exc_info.value) |
| 271 | + assert "Unable to decode response as JSON data from https://example.com/api/graphql" in error_message |
| 272 | + # Should not include server response part when content is empty |
| 273 | + assert "Server response:" not in error_message |
| 274 | + |
| 275 | + |
| 276 | +def test_json_decode_error_custom_message() -> None: |
| 277 | + """Test JsonDecodeError with custom message does not override custom message.""" |
| 278 | + custom_message = "Custom error message" |
| 279 | + error = JsonDecodeError(message=custom_message, content="server error", url="https://example.com") |
| 280 | + |
| 281 | + assert str(error) == custom_message |
| 282 | + assert error.content == "server error" |
| 283 | + assert error.url == "https://example.com" |
0 commit comments