Skip to content

Commit eb26c43

Browse files
committed
Increase coverage of existing functions
1 parent 0f6ca86 commit eb26c43

7 files changed

Lines changed: 951 additions & 3 deletions

py_tests/test_authentication.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99

1010
import fsspec
1111
import pytest
12+
import requests
1213
from requests.adapters import HTTPAdapter
1314

1415
from fusion._legacy.authentication import (
1516
try_get_client_id,
1617
try_get_client_secret,
1718
)
1819
from fusion.authentication import (
20+
FusionAiohttpSession,
1921
FusionOAuthAdapter,
2022
)
2123
from fusion.credentials import FusionCredentials
@@ -264,3 +266,70 @@ def test_send_raises_api_response_error_on_connection_error() -> None:
264266
assert "Connection error while sending request" in str(exc_info.value)
265267
HTTP_STATUS_SERVICE_UNAVAILABLE = 503
266268
assert exc_info.value.status_code == HTTP_STATUS_SERVICE_UNAVAILABLE
269+
270+
271+
def test_fusion_oauth_adapter_uses_credentials_proxies_and_default_retry(credentials: FusionCredentials) -> None:
272+
default_retry_total = 20
273+
adapter = FusionOAuthAdapter(credentials=credentials)
274+
275+
assert adapter.proxies == credentials.proxies
276+
assert adapter.auth_retries.total == default_retry_total
277+
assert adapter.headers == {}
278+
279+
280+
def test_fusion_oauth_adapter_send_merges_auth_and_custom_headers() -> None:
281+
request = Mock()
282+
request.url = "https://example.com/catalogs/c1/datasets/d1"
283+
request.headers = {}
284+
285+
mock_credentials = Mock(spec=FusionCredentials)
286+
mock_credentials.proxies = {}
287+
mock_credentials.get_fusion_token_headers.return_value = {"Authorization": "Bearer abc"}
288+
289+
adapter = FusionOAuthAdapter(credentials=mock_credentials, headers={"X-Test": "1"})
290+
291+
response = requests.Response()
292+
response.status_code = 200
293+
response._content = b"ok"
294+
295+
with patch.object(HTTPAdapter, "send", return_value=response) as mock_send:
296+
result = adapter.send(request)
297+
298+
assert result is response
299+
assert request.headers["Authorization"] == "Bearer abc"
300+
assert request.headers["X-Test"] == "1"
301+
mock_send.assert_called_once()
302+
303+
304+
def test_send_raises_api_response_error_when_header_generation_fails() -> None:
305+
request = Mock()
306+
request.url = "https://example.com/data"
307+
request.headers = {}
308+
309+
mock_credentials = Mock(spec=FusionCredentials)
310+
mock_credentials.proxies = {}
311+
mock_credentials.get_fusion_token_headers.side_effect = RuntimeError("bad headers")
312+
313+
adapter = FusionOAuthAdapter(credentials=mock_credentials)
314+
315+
with pytest.raises(APIResponseError, match="Failed to generate Fusion token headers") as exc_info:
316+
adapter.send(request)
317+
318+
internal_server_error = 500
319+
assert exc_info.value.status_code == internal_server_error
320+
321+
322+
@pytest.mark.asyncio
323+
async def test_fusion_aiohttp_session_post_init_sets_state(credentials: FusionCredentials) -> None:
324+
refresh_within_seconds = 9
325+
session = FusionAiohttpSession()
326+
try:
327+
session.post_init(credentials=credentials, refresh_within_seconds=refresh_within_seconds)
328+
329+
assert session.credentials is credentials
330+
assert session.refresh_within_seconds == refresh_within_seconds
331+
assert session.number_token_refreshes == 0
332+
assert session.fusion_token_dict == {}
333+
assert session.fusion_token_expiry_dict == {}
334+
finally:
335+
await session.close()

py_tests/test_cli_and_shims.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
from __future__ import annotations
2+
3+
from pathlib import Path
4+
from queue import Queue
5+
from typing import TYPE_CHECKING, Any, get_args
6+
7+
if TYPE_CHECKING:
8+
import pytest
9+
10+
11+
class TestFusionMainModule:
12+
@staticmethod
13+
def _run_main_module() -> None:
14+
main_path = Path(__file__).resolve().parents[1] / "py_src" / "fusion" / "__main__.py"
15+
namespace = {"__file__": str(main_path), "__name__": "__main__"}
16+
exec(compile(main_path.read_text(), str(main_path), "exec"), namespace) # noqa: S102
17+
18+
def test_invokes_requested_method(self, monkeypatch: pytest.MonkeyPatch) -> None:
19+
import fusion
20+
21+
captured: dict[str, Any] = {}
22+
23+
class FakeFusion:
24+
def __init__(
25+
self,
26+
root_url: str | None = None,
27+
credentials: str | None = None,
28+
download_folder: str | None = None,
29+
log_level: str | None = None,
30+
log_path: str | None = None,
31+
) -> None:
32+
captured["init"] = {
33+
"root_url": root_url,
34+
"credentials": credentials,
35+
"download_folder": download_folder,
36+
"log_level": log_level,
37+
"log_path": log_path,
38+
}
39+
40+
def publish(self, dataset: str | None = None, overwrite: bool = False, dry_run: bool = True) -> None:
41+
captured["method"] = {
42+
"dataset": dataset,
43+
"overwrite": overwrite,
44+
"dry_run": dry_run,
45+
}
46+
47+
monkeypatch.setattr(fusion, "Fusion", FakeFusion)
48+
monkeypatch.setattr(
49+
"sys.argv",
50+
[
51+
"fusion",
52+
"--root_url",
53+
"https://example.test/api/v1/",
54+
"--credentials",
55+
"client_credentials.json",
56+
"--download_folder",
57+
"downloads-dir",
58+
"--log_level",
59+
"20",
60+
"--log_path",
61+
"logs",
62+
"--method",
63+
"publish",
64+
"--dataset",
65+
"prices",
66+
"--overwrite",
67+
"True",
68+
"--dry_run",
69+
"False",
70+
],
71+
)
72+
73+
self._run_main_module()
74+
75+
assert captured["init"] == {
76+
"root_url": "https://example.test/api/v1/",
77+
"credentials": "client_credentials.json",
78+
"download_folder": "downloads-dir",
79+
"log_level": "20",
80+
"log_path": "logs",
81+
}
82+
assert captured["method"] == {
83+
"dataset": "prices",
84+
"overwrite": True,
85+
"dry_run": False,
86+
}
87+
88+
def test_without_method_only_initializes_client(self, monkeypatch: pytest.MonkeyPatch) -> None:
89+
import fusion
90+
91+
captured: dict[str, Any] = {}
92+
93+
class FakeFusion:
94+
def __init__(
95+
self,
96+
root_url: str | None = None,
97+
credentials: str | None = None,
98+
download_folder: str | None = None,
99+
log_level: str | None = None,
100+
log_path: str | None = None,
101+
) -> None:
102+
captured["init"] = {
103+
"root_url": root_url,
104+
"credentials": credentials,
105+
"download_folder": download_folder,
106+
"log_level": log_level,
107+
"log_path": log_path,
108+
}
109+
110+
def publish(self, dataset: str | None = None) -> None:
111+
captured["method"] = dataset
112+
113+
monkeypatch.setattr(fusion, "Fusion", FakeFusion)
114+
monkeypatch.setattr("sys.argv", ["fusion", "--credentials", "client_credentials.json"])
115+
116+
self._run_main_module()
117+
118+
assert captured["init"] == {
119+
"root_url": None,
120+
"credentials": "client_credentials.json",
121+
"download_folder": None,
122+
"log_level": None,
123+
"log_path": None,
124+
}
125+
assert "method" not in captured
126+
127+
128+
class TestCompatibilityShims:
129+
def test_legacy_fusion_module_exports_fusion_credentials(self) -> None:
130+
shim_path = Path(__file__).resolve().parents[1] / "py_src" / "fusion" / "_fusion.py"
131+
namespace: dict[str, Any] = {"__file__": str(shim_path), "__name__": "fusion._fusion_py"}
132+
133+
exec(compile(shim_path.read_text(), str(shim_path), "exec"), namespace) # noqa: S102
134+
135+
assert namespace["FusionCredentials"].__name__ == "FusionCredentials"
136+
assert namespace["__all__"] == ["FusionCredentials"]
137+
138+
def test_types_aliases_are_available(self) -> None:
139+
from fusion.types import PyArrowFilterT, WorkerQueueT
140+
141+
assert WorkerQueueT == Queue[tuple[int, int, int]]
142+
assert get_args(PyArrowFilterT) == (list[tuple[Any]], list[list[tuple[Any]]])

0 commit comments

Comments
 (0)