Skip to content

Commit 403846c

Browse files
committed
Add tests for tiled check
1 parent a3a1f15 commit 403846c

1 file changed

Lines changed: 91 additions & 2 deletions

File tree

tests/unit_tests/service/test_authorization.py

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
from unittest.mock import MagicMock, patch
1+
from contextlib import AbstractContextManager, nullcontext
2+
from unittest.mock import AsyncMock, MagicMock, Mock, patch
23

34
import pytest
45
from pydantic import HttpUrl
56

6-
from blueapi.config import OpaConfig
7+
from blueapi.config import OIDCConfig, OpaConfig, ServiceAccount
78
from blueapi.service.authorization import (
89
OpaClient,
10+
validate_tiled_config,
911
)
1012

1113
# Reusable client patch decorator
@@ -20,9 +22,50 @@
2022
def opa_config() -> OpaConfig:
2123
return OpaConfig(
2224
root=HttpUrl("http://auth.example.com"),
25+
tiled_service_account_check="/auth/tiled",
2326
)
2427

2528

29+
@patch_client_session
30+
@pytest.mark.parametrize(
31+
"result,context",
32+
[
33+
(False, pytest.raises(ValueError, match="Tiled service account is not valid ")),
34+
(True, nullcontext()),
35+
],
36+
)
37+
async def test_tiled_service_account(
38+
session: MagicMock,
39+
opa_config: OpaConfig,
40+
result: bool,
41+
context: AbstractContextManager,
42+
):
43+
session.return_value.post = AsyncMock(
44+
return_value=MagicMock(json=AsyncMock(return_value={"result": result}))
45+
)
46+
47+
client = OpaClient(instrument="p99", config=opa_config)
48+
49+
session.assert_called_once_with(base_url="http://auth.example.com/")
50+
with context:
51+
await client.require_tiled_service_account(token="foo_bar")
52+
session().post.assert_called_once_with(
53+
"/auth/tiled",
54+
json={"input": {"token": "foo_bar", "beamline": "p99", "audience": "account"}},
55+
)
56+
57+
58+
@patch_client_session
59+
async def test_exception_raised_when_opa_fails(
60+
session: MagicMock, opa_config: OpaConfig
61+
):
62+
session.return_value.post = AsyncMock(side_effect=RuntimeError("Connection failed"))
63+
async with OpaClient.for_config("p45", opa_config) as client:
64+
assert client is not None
65+
with pytest.raises(RuntimeError, match="Connection failed"):
66+
await client.require_tiled_service_account(token="foo_bar")
67+
68+
2669
@patch_client_session
2770
async def test_session_closed(session: MagicMock, opa_config: OpaConfig):
2871
async with OpaClient.for_config("p45", opa_config):
@@ -46,3 +89,49 @@ async def test_opa_client_without_config(instrument: str | None):
4689
async def test_opa_fails_without_instrument(opa_config: OpaConfig):
4790
with pytest.raises(ValueError, match="Instrument name is required"):
4891
OpaClient.for_config(None, opa_config)
92+
93+
94+
async def test_validate_tiled_config():
95+
opa = MagicMock(spec=OpaClient)
96+
tiled = ServiceAccount()
97+
oidc = Mock(spec=OIDCConfig)
98+
oidc.token_endpoint = "token-endpoint"
99+
with patch("blueapi.service.authorization.TiledAuth") as auth:
100+
auth.return_value.get_access_token.return_value = "tiled-token"
101+
await validate_tiled_config(tiled, oidc, opa)
102+
103+
auth.assert_called_once_with(tiled)
104+
opa.require_tiled_service_account.assert_called_once_with("tiled-token")
105+
106+
107+
@pytest.mark.parametrize(
108+
"tiled_auth,oidc,opa_client",
109+
[
110+
(None, None, MagicMock(spec=OpaClient)),
111+
(
112+
None,
113+
OIDCConfig(well_known_url="http://example.com", client_id="test-client"),
114+
MagicMock(spec=OpaClient),
115+
),
116+
("api_key", None, MagicMock(spec=OpaClient)),
117+
(
118+
"api_key",
119+
OIDCConfig(well_known_url="http://example.com", client_id="test-client"),
120+
MagicMock(spec=OpaClient),
121+
),
122+
(ServiceAccount(), None, MagicMock(spec=OpaClient)),
123+
(
124+
ServiceAccount(),
125+
OIDCConfig(well_known_url="http://example.com", client_id="test-client"),
126+
None,
127+
),
128+
],
129+
)
130+
async def test_validate_tiled_config_with_missing_config(
131+
tiled_auth: ServiceAccount | str | None,
132+
oidc: OIDCConfig | None,
133+
opa_client: MagicMock | None,
134+
):
135+
assert await validate_tiled_config(tiled_auth, oidc, opa_client) is None
136+
if opa_client is not None:
137+
opa_client.require_tiled_service_account.assert_not_called()

0 commit comments

Comments
 (0)