Refactored stream observations and config refresh handling.
CI / Formatting (push) Successful in 6s
CI / Linting (push) Successful in 6s
CI / Tests (push) Successful in 27s
CI / Type Checking (push) Successful in 23s
CI / Spelling (push) Successful in 19s

This commit is contained in:
2026-05-21 19:44:29 -04:00
parent c837b916c0
commit 38e91add32
14 changed files with 1503 additions and 512 deletions
+48 -55
View File
@@ -25,13 +25,47 @@ from owncastsentry.types import (
AlreadySubscribedError,
InvalidOwncastInstanceError,
NotSubscribedError,
StreamState,
)
if TYPE_CHECKING:
from owncastsentry.repository import StreamRepository, SubscriptionRepository
class _StubOwncastClient:
"""Owncast client stub for validation-only manager tests."""
def __init__(self, *, valid: bool = True) -> None:
"""Initialize the stub with a fixed validation result."""
self.valid = valid
self.validated_domains: list[str] = []
async def validate_instance(self, domain: str) -> bool:
"""Record the domain and return the configured validation result."""
self.validated_domains.append(domain)
return self.valid
@pytest.fixture
def owncast_client() -> _StubOwncastClient:
"""Return a validation-only Owncast client stub."""
return _StubOwncastClient()
@pytest.fixture
def manager(
owncast_client: _StubOwncastClient,
stream_repo: StreamRepository,
subscription_repo: SubscriptionRepository,
) -> SubscriptionManager:
"""SubscriptionManager built directly for unit tests."""
return SubscriptionManager(
owncast_client=owncast_client, # type: ignore[arg-type]
stream_repo=stream_repo,
subscription_repo=subscription_repo,
logger=logging.getLogger("test"),
)
class TestDomainify:
"""Domain extraction and sanitization from user input."""
@@ -74,41 +108,6 @@ class TestDomainify:
assert _domainify(input_url) == expected
class _StubOwncastClient:
"""Owncast client stub for validation-only manager tests."""
def __init__(self, *, valid: bool = True) -> None:
"""Initialize the stub with a fixed validation result."""
self.valid = valid
self.validated_domains: list[str] = []
async def validate_instance(self, domain: str) -> bool:
"""Record the domain and return the configured validation result."""
self.validated_domains.append(domain)
return self.valid
@pytest.fixture
def owncast_client() -> _StubOwncastClient:
"""Return a validation-only Owncast client stub."""
return _StubOwncastClient()
@pytest.fixture
def manager(
owncast_client: _StubOwncastClient,
stream_repo: StreamRepository,
subscription_repo: SubscriptionRepository,
) -> SubscriptionManager:
"""SubscriptionManager built directly for unit tests."""
return SubscriptionManager(
owncast_client=owncast_client, # type: ignore[arg-type]
stream_repo=stream_repo,
subscription_repo=subscription_repo,
logger=logging.getLogger("test"),
)
class TestManagerSubscribe:
"""SubscriptionManager subscribe workflow."""
@@ -226,9 +225,9 @@ class TestManagerListings:
) -> None:
"""Return sorted room subscriptions and skip missing stream rows."""
await stream_repo.create("beta.example")
await stream_repo.update(StreamState(domain="beta.example", name="Beta"))
await stream_repo.update("beta.example", name="Beta")
await stream_repo.create("alpha.example")
await stream_repo.update(StreamState(domain="alpha.example", name="Alpha"))
await stream_repo.update("alpha.example", name="Alpha")
await subscription_repo.add("beta.example", "!room:example.com")
await subscription_repo.add("missing.example", "!room:example.com")
await subscription_repo.add("alpha.example", "!room:example.com")
@@ -253,29 +252,23 @@ class TestManagerListings:
"""Live listing includes only subscriptions with ONLINE stream status."""
await stream_repo.create("offline.example")
await stream_repo.update(
StreamState(
domain="offline.example",
name="Offline",
status_since="2026-01-01T00:00:00+00:00",
)
"offline.example",
name="Offline",
status_since="2026-01-01T00:00:00+00:00",
)
await stream_repo.create("online.example")
await stream_repo.update(
StreamState(
domain="online.example",
name="Online",
online=True,
status_since="2026-01-01T00:00:00+00:00",
)
"online.example",
name="Online",
online=True,
status_since="2026-01-01T00:00:00+00:00",
)
await stream_repo.create("unknown.example")
await stream_repo.update(
StreamState(
domain="unknown.example",
name="Unknown",
online=True,
status_since="2026-01-01T00:00:00+00:00",
)
"unknown.example",
name="Unknown",
online=True,
status_since="2026-01-01T00:00:00+00:00",
)
for _ in range(UNKNOWN_STATUS_THRESHOLD + 1):
await stream_repo.increment_failure_counter("unknown.example")