"""query_helpers coverage.""" from __future__ import annotations from datetime import UTC, datetime, timedelta from typing import TYPE_CHECKING from uuid import uuid4 import pytest from roboco.db.tables import AgentTable from roboco.models import AgentRole, AgentStatus, Team from roboco.services.repositories.query_helpers import ( agent_id_filter, days_ago, get_agent_by_slug, get_agent_slug, pagination, resolve_agent_identity, resolve_agent_uuid, status_filter, team_filter, timestamp_filter, ) from sqlalchemy import select if TYPE_CHECKING: from sqlalchemy.ext.asyncio import AsyncSession # --------------------------------------------------------------------------- # Pure query-builder helpers # --------------------------------------------------------------------------- def test_days_ago_returns_past_datetime() -> None: out = days_ago(7) assert out < datetime.now(UTC) assert (datetime.now(UTC) - out) >= timedelta(days=6) def test_pagination_applies_limit_offset() -> None: q = select(AgentTable) out = pagination(q, limit=10, offset=20) # SQLAlchemy compiles the query; we just verify it doesn't crash. assert out is not None def test_status_filter_passes_through_when_none() -> None: q = select(AgentTable) assert status_filter(q, AgentTable, None) is q def test_status_filter_applies_when_provided() -> None: q = select(AgentTable) out = status_filter(q, AgentTable, AgentStatus.ACTIVE) assert out is not q # Different query. def test_team_filter_passes_through_when_none() -> None: q = select(AgentTable) assert team_filter(q, AgentTable, None) is q def test_team_filter_applies_when_provided() -> None: q = select(AgentTable) out = team_filter(q, AgentTable, Team.BACKEND) assert out is not q def test_agent_id_filter_passes_through_when_none() -> None: q = select(AgentTable) assert agent_id_filter(q, AgentTable, None) is q def test_agent_id_filter_applies_when_provided() -> None: q = select(AgentTable) out = agent_id_filter(q, AgentTable, uuid4(), field_name="id") assert out is not q def test_timestamp_filter_with_since_and_until() -> None: q = select(AgentTable) out = timestamp_filter( q, AgentTable, since=days_ago(7), until=datetime.now(UTC), ) assert out is not q def test_timestamp_filter_no_args_unchanged() -> None: q = select(AgentTable) out = timestamp_filter(q, AgentTable) # No filter applied. assert out is q # --------------------------------------------------------------------------- # Async DB resolvers # --------------------------------------------------------------------------- @pytest.mark.asyncio async def test_resolve_agent_uuid_with_uuid_string( db_session: AsyncSession, ) -> None: aid = uuid4() resolved = await resolve_agent_uuid(db_session, str(aid)) assert resolved == aid @pytest.mark.asyncio async def test_resolve_agent_uuid_with_slug( db_session: AsyncSession, ) -> None: agent = AgentTable( id=uuid4(), name="Dev", slug=f"q-dev-{uuid4().hex[:8]}", role=AgentRole.DEVELOPER, team=Team.BACKEND, status=AgentStatus.ACTIVE, model_config={}, system_prompt="x", capabilities=[], permissions={}, metrics={}, ) db_session.add(agent) await db_session.flush() resolved = await resolve_agent_uuid(db_session, agent.slug) assert resolved == agent.id @pytest.mark.asyncio async def test_resolve_agent_uuid_with_unknown_slug( db_session: AsyncSession, ) -> None: assert await resolve_agent_uuid(db_session, "ghost-slug") is None @pytest.mark.asyncio async def test_resolve_agent_identity_with_slug( db_session: AsyncSession, ) -> None: agent = AgentTable( id=uuid4(), name="Dev", slug=f"q-id-{uuid4().hex[:8]}", role=AgentRole.DEVELOPER, team=Team.BACKEND, status=AgentStatus.ACTIVE, model_config={}, system_prompt="x", capabilities=[], permissions={}, metrics={}, ) db_session.add(agent) await db_session.flush() out = await resolve_agent_identity(db_session, agent.slug) assert out is not None assert out[0] == agent.id @pytest.mark.asyncio async def test_resolve_agent_identity_unknown( db_session: AsyncSession, ) -> None: assert await resolve_agent_identity(db_session, "ghost") is None @pytest.mark.asyncio async def test_resolve_agent_identity_unknown_uuid( db_session: AsyncSession, ) -> None: assert await resolve_agent_identity(db_session, str(uuid4())) is None @pytest.mark.asyncio async def test_resolve_agent_identity_with_uuid( db_session: AsyncSession, ) -> None: """Line 215: passing a UUID resolves to (UUID, slug) tuple.""" agent = AgentTable( id=uuid4(), name="Dev", slug=f"q-uuid-{uuid4().hex[:8]}", role=AgentRole.DEVELOPER, team=Team.BACKEND, status=AgentStatus.ACTIVE, model_config={}, system_prompt="x", capabilities=[], permissions={}, metrics={}, ) db_session.add(agent) await db_session.flush() out = await resolve_agent_identity(db_session, str(agent.id)) assert out is not None assert out[0] == agent.id assert out[1] == agent.slug @pytest.mark.asyncio async def test_get_agent_slug_known(db_session: AsyncSession) -> None: agent = AgentTable( id=uuid4(), name="Dev", slug=f"slug-{uuid4().hex[:8]}", role=AgentRole.DEVELOPER, team=Team.BACKEND, status=AgentStatus.ACTIVE, model_config={}, system_prompt="x", capabilities=[], permissions={}, metrics={}, ) db_session.add(agent) await db_session.flush() slug = await get_agent_slug(db_session, agent.id) assert slug == agent.slug @pytest.mark.asyncio async def test_get_agent_slug_missing(db_session: AsyncSession) -> None: assert await get_agent_slug(db_session, uuid4()) is None @pytest.mark.asyncio async def test_get_agent_by_slug(db_session: AsyncSession) -> None: agent = AgentTable( id=uuid4(), name="Dev", slug=f"by-slug-{uuid4().hex[:8]}", role=AgentRole.DEVELOPER, team=Team.BACKEND, status=AgentStatus.ACTIVE, model_config={}, system_prompt="x", capabilities=[], permissions={}, metrics={}, ) db_session.add(agent) await db_session.flush() fetched = await get_agent_by_slug(db_session, agent.slug) assert fetched is not None assert fetched.id == agent.id @pytest.mark.asyncio async def test_get_agent_by_slug_missing(db_session: AsyncSession) -> None: assert await get_agent_by_slug(db_session, "ghost-slug") is None