Skip to content

Commit c5faa4a

Browse files
committed
add tests
1 parent 410cf9a commit c5faa4a

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

tests/test_lifespan.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"""Tests for lifespan module."""
2+
3+
from dataclasses import dataclass
4+
from unittest.mock import patch
5+
6+
import pytest
7+
from starlette.middleware import Middleware
8+
from starlette.types import ASGIApp
9+
10+
from stac_auth_proxy.utils.lifespan import check_conformance, check_server_health
11+
from stac_auth_proxy.utils.middleware import required_conformance
12+
13+
14+
@required_conformance("http://example.com/conformance")
15+
@dataclass
16+
class TestMiddleware:
17+
"""Test middleware with required conformance."""
18+
19+
app: ASGIApp
20+
21+
22+
async def test_check_server_health_success(source_api_server):
23+
"""Test successful health check."""
24+
await check_server_health(source_api_server)
25+
26+
27+
async def test_check_server_health_failure():
28+
"""Test health check failure."""
29+
with patch("asyncio.sleep") as mock_sleep:
30+
with pytest.raises(RuntimeError) as exc_info:
31+
await check_server_health("http://localhost:9999")
32+
assert "failed to respond after" in str(exc_info.value)
33+
# Verify sleep was called with exponential backoff
34+
assert mock_sleep.call_count > 0
35+
# First call should be with base delay
36+
# NOTE: When testing individually, the mock_sleep strangely has a first call of
37+
# 0 seconds (possibly by httpx), however when running all tests, this does not
38+
# occur. So, we have to check for 1.0 in the first two calls.
39+
assert 1.0 in [mock_sleep.call_args_list[i][0][0] for i in range(2)]
40+
# Last call should be with max delay
41+
assert mock_sleep.call_args_list[-1][0][0] == 5.0
42+
43+
44+
async def test_check_conformance_success(source_api_server, source_api_responses):
45+
"""Test successful conformance check."""
46+
middleware = [Middleware(TestMiddleware)]
47+
await check_conformance(middleware, source_api_server)
48+
49+
50+
async def test_check_conformance_failure(source_api_server, source_api_responses):
51+
"""Test conformance check failure."""
52+
# Override the conformance response to not include required conformance
53+
source_api_responses["/conformance"]["GET"] = {"conformsTo": []}
54+
55+
middleware = [Middleware(TestMiddleware)]
56+
with pytest.raises(RuntimeError) as exc_info:
57+
await check_conformance(middleware, source_api_server)
58+
assert "missing the following conformance classes" in str(exc_info.value)
59+
60+
61+
async def test_check_conformance_multiple_middleware(source_api_server):
62+
"""Test conformance check with multiple middleware."""
63+
64+
@required_conformance("http://example.com/conformance")
65+
class TestMiddleware2:
66+
def __init__(self, app):
67+
self.app = app
68+
69+
middleware = [
70+
Middleware(TestMiddleware),
71+
Middleware(TestMiddleware2),
72+
]
73+
await check_conformance(middleware, source_api_server)
74+
75+
76+
async def test_check_conformance_no_required(source_api_server):
77+
"""Test conformance check with middleware that has no required conformances."""
78+
79+
class NoConformanceMiddleware:
80+
def __init__(self, app):
81+
self.app = app
82+
83+
middleware = [Middleware(NoConformanceMiddleware)]
84+
await check_conformance(middleware, source_api_server)

0 commit comments

Comments
 (0)