Skip to content

Commit fff101b

Browse files
committed
Add tests for OpaClient
1 parent 8ebfe05 commit fff101b

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from unittest.mock import AsyncMock, MagicMock, patch
2+
3+
import pytest
4+
from pydantic import HttpUrl
5+
6+
from blueapi.config import OpaConfig
7+
from blueapi.service.authorization import (
8+
OpaClient,
9+
)
10+
11+
# Reusable client patch decorator
12+
patch_client_session = patch(
13+
"blueapi.service.authorization.ClientSession",
14+
name="mock_client_session",
15+
spec=True,
16+
)
17+
18+
19+
@pytest.fixture(scope="module")
20+
def opa_config() -> OpaConfig:
21+
return OpaConfig(
22+
root=HttpUrl("http://auth.example.com"),
23+
)
24+
25+
26+
@patch_client_session
27+
async def test_session_closed(session: MagicMock, opa_config: OpaConfig):
28+
async with OpaClient.for_config("p45", opa_config):
29+
pass
30+
session().close.assert_called_once()
31+
32+
33+
@patch_client_session
34+
async def test_opa_client_for_config(session: MagicMock, opa_config: OpaConfig):
35+
async with OpaClient.for_config("p45", opa_config) as opa:
36+
assert opa is not None
37+
session.assert_called_once_with(base_url="http://auth.example.com/")
38+
39+
40+
@pytest.mark.parametrize("instrument", [None, "p99"])
41+
async def test_opa_client_without_config(instrument: str | None):
42+
async with OpaClient.for_config(instrument, None) as opa:
43+
assert opa is None
44+
45+
46+
async def test_opa_fails_without_instrument(opa_config: OpaConfig):
47+
with pytest.raises(ValueError, match="Instrument name is required"):
48+
OpaClient.for_config(None, opa_config)
49+
50+
51+
@patch_client_session
52+
async def test_opa_adds_input_fields(session: MagicMock, opa_config: OpaConfig):
53+
session.return_value.post = AsyncMock()
54+
async with OpaClient.for_config("p45", opa_config) as opa:
55+
assert opa is not None
56+
await opa._call_opa("foo/bar", data={"foo": "bar"})
57+
58+
session.assert_called_once()
59+
session().post.assert_called_once_with(
60+
"foo/bar",
61+
json={"input": {"beamline": "p45", "audience": "account", "foo": "bar"}},
62+
)

0 commit comments

Comments
 (0)