Skip to content

Commit ed08671

Browse files
committed
test(http): add comprehensive error handling tests for HTTP module
- Added tests for all HTTP functions: fetch_redirect_location, download_with_progress, get_content_sync - Comprehensive error handling coverage: timeouts, connection errors, generic exceptions - Tests for custom exception hierarchy and inheritance - Improved HTTP module coverage from 24% to 66% - Overall project coverage improved from 82% to 85%
1 parent 071feb0 commit ed08671

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

tests/test_http.py

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
"""Tests for HTTP utilities module.
2+
3+
This module tests the custom HTTP implementation that replaced the requests dependency.
4+
Focuses on error handling paths that were previously uncovered.
5+
"""
6+
7+
import socket
8+
from pathlib import Path
9+
from unittest.mock import patch
10+
from urllib.error import URLError
11+
12+
import pytest
13+
14+
from django_tailwind_cli.utils import http
15+
16+
17+
class TestFetchRedirectLocation:
18+
"""Test the fetch_redirect_location function error handling."""
19+
20+
def test_fetch_redirect_location_timeout_error(self):
21+
"""Test timeout error handling."""
22+
mock_error = URLError(socket.timeout("timeout"))
23+
24+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=mock_error):
25+
with pytest.raises(http.RequestTimeoutError, match="Request timeout"):
26+
http.fetch_redirect_location("https://example.com")
27+
28+
def test_fetch_redirect_location_connection_error(self):
29+
"""Test connection error handling."""
30+
mock_error = URLError(ConnectionRefusedError("connection refused"))
31+
32+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=mock_error):
33+
with pytest.raises(http.NetworkConnectionError, match="Connection error"):
34+
http.fetch_redirect_location("https://example.com")
35+
36+
def test_fetch_redirect_location_generic_error(self):
37+
"""Test generic URL error handling."""
38+
mock_error = URLError("generic error")
39+
40+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=mock_error):
41+
with pytest.raises(http.RequestError, match="URL error"):
42+
http.fetch_redirect_location("https://example.com")
43+
44+
def test_fetch_redirect_location_timeout_error_direct(self):
45+
"""Test direct timeout error handling."""
46+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=TimeoutError("timeout")):
47+
with pytest.raises(http.RequestTimeoutError, match="Socket timeout"):
48+
http.fetch_redirect_location("https://example.com")
49+
50+
def test_fetch_redirect_location_generic_exception(self):
51+
"""Test generic exception handling."""
52+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=ValueError("unexpected")):
53+
with pytest.raises(http.RequestError, match="Unexpected error"):
54+
http.fetch_redirect_location("https://example.com")
55+
56+
57+
class TestDownloadWithProgress:
58+
"""Test the download_with_progress function error handling."""
59+
60+
def test_download_with_progress_timeout_error(self, tmp_path: Path):
61+
"""Test download timeout error."""
62+
mock_error = URLError(socket.timeout("timeout"))
63+
filepath = tmp_path / "test_download.txt"
64+
65+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=mock_error):
66+
with pytest.raises(http.RequestTimeoutError, match="Download timeout"):
67+
http.download_with_progress("https://example.com/file.txt", filepath)
68+
69+
def test_download_with_progress_connection_error(self, tmp_path: Path):
70+
"""Test download connection error."""
71+
mock_error = URLError(ConnectionRefusedError("connection refused"))
72+
filepath = tmp_path / "test_download.txt"
73+
74+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=mock_error):
75+
with pytest.raises(http.NetworkConnectionError, match="Connection error"):
76+
http.download_with_progress("https://example.com/file.txt", filepath)
77+
78+
def test_download_with_progress_timeout_error_direct(self, tmp_path: Path):
79+
"""Test direct timeout error."""
80+
filepath = tmp_path / "test_download.txt"
81+
82+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=TimeoutError("timeout")):
83+
with pytest.raises(http.RequestTimeoutError, match="Download timeout"):
84+
http.download_with_progress("https://example.com/file.txt", filepath)
85+
86+
def test_download_with_progress_generic_exception(self, tmp_path: Path):
87+
"""Test generic exception during download."""
88+
filepath = tmp_path / "test_download.txt"
89+
90+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=ValueError("unexpected")):
91+
with pytest.raises(http.RequestError, match="Unexpected error"):
92+
http.download_with_progress("https://example.com/file.txt", filepath)
93+
94+
95+
class TestGetContentSync:
96+
"""Test the get_content_sync function error handling."""
97+
98+
def test_get_content_sync_timeout_error(self):
99+
"""Test content retrieval timeout."""
100+
mock_error = URLError(socket.timeout("timeout"))
101+
102+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=mock_error):
103+
with pytest.raises(http.RequestTimeoutError, match="Request timeout"):
104+
http.get_content_sync("https://example.com/api")
105+
106+
def test_get_content_sync_connection_error(self):
107+
"""Test content retrieval connection error."""
108+
mock_error = URLError(ConnectionRefusedError("connection refused"))
109+
110+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=mock_error):
111+
with pytest.raises(http.NetworkConnectionError, match="Connection error"):
112+
http.get_content_sync("https://example.com/api")
113+
114+
def test_get_content_sync_timeout_error_direct(self):
115+
"""Test direct timeout error."""
116+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=TimeoutError("timeout")):
117+
with pytest.raises(http.RequestTimeoutError, match="Request timeout"):
118+
http.get_content_sync("https://example.com/api")
119+
120+
def test_get_content_sync_generic_exception(self):
121+
"""Test generic exception during content retrieval."""
122+
with patch("django_tailwind_cli.utils.http.urlopen", side_effect=ValueError("unexpected")):
123+
with pytest.raises(http.RequestError, match="Unexpected error"):
124+
http.get_content_sync("https://example.com/api")
125+
126+
127+
class TestExceptionClasses:
128+
"""Test the custom exception classes."""
129+
130+
def test_request_error_is_base_exception(self):
131+
"""Test that RequestError is the base exception."""
132+
with pytest.raises(http.RequestError):
133+
raise http.RequestError("test error")
134+
135+
def test_http_error_inherits_from_request_error(self):
136+
"""Test HTTPError inheritance."""
137+
with pytest.raises(http.RequestError):
138+
raise http.HTTPError("http error")
139+
140+
def test_network_connection_error_inherits_from_request_error(self):
141+
"""Test NetworkConnectionError inheritance."""
142+
with pytest.raises(http.RequestError):
143+
raise http.NetworkConnectionError("connection error")
144+
145+
def test_request_timeout_error_inherits_from_request_error(self):
146+
"""Test RequestTimeoutError inheritance."""
147+
with pytest.raises(http.RequestError):
148+
raise http.RequestTimeoutError("timeout error")

0 commit comments

Comments
 (0)