Files
roboco/tests/integration/test_api_resources.py
T
Renn F 64c48356d0 test: lift coverage 41% → 76% (+1068 tests across 36 files)
Service-level tests now exercise provider, permissions, project, journal,
messaging, work_session, metrics, kanban, extraction, learning, notification,
dashboard, llm_routing, a2a, task, repository_base, audit, db_seed,
branch_name, indexed_document, query_helpers, agent. API route tests cover
provider, journal, project, sessions, dashboard, work_session, tasks, a2a,
groups, notifications, agents, channels, messages, kanban, api_resources.
Pure-function helpers covered: handlers, deps_helpers, middleware,
middleware_docs, transcription, pr templates, agents_config, errors,
logging, journal/notification/channel/a2a access, task_lifecycle,
streaming, converters, crypto, schemas (common + websocket), events,
permissions extras.

pyproject ruff per-file-ignores extended for tests so PLR2004 (status code
magic values), PLC0415 (lazy imports), PLR0913 (fixture params), ARG001
(unused fixture deps), SIM105, and E501 don't fight test idioms.
2026-05-06 00:32:52 +02:00

128 lines
3.6 KiB
Python

"""api.utils.resources coverage."""
from __future__ import annotations
from typing import TYPE_CHECKING
from uuid import uuid4
import pytest
from fastapi import HTTPException
from roboco.api.utils.resources import (
get_by_field_or_404,
get_or_404,
require_membership,
require_ownership,
require_recipient,
)
from roboco.db.tables import AgentTable
from roboco.models import AgentRole, AgentStatus, Team
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession
@pytest.mark.asyncio
async def test_get_or_404_finds_existing(db_session: AsyncSession) -> None:
agent = AgentTable(
id=uuid4(),
name="Dev",
slug=f"d-{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_or_404(db_session, AgentTable, agent.id)
assert fetched.id == agent.id
@pytest.mark.asyncio
async def test_get_or_404_raises_when_missing(db_session: AsyncSession) -> None:
with pytest.raises(HTTPException) as exc:
await get_or_404(db_session, AgentTable, uuid4(), "Agent")
assert exc.value.status_code == 404
@pytest.mark.asyncio
async def test_get_by_field_or_404_finds(db_session: AsyncSession) -> None:
agent = AgentTable(
id=uuid4(),
name="Dev2",
slug=f"d2-{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_by_field_or_404(
db_session, AgentTable, "slug", agent.slug, "Agent"
)
assert fetched.id == agent.id
@pytest.mark.asyncio
async def test_get_by_field_or_404_raises(db_session: AsyncSession) -> None:
with pytest.raises(HTTPException) as exc:
await get_by_field_or_404(db_session, AgentTable, "slug", "ghost-slug", "Agent")
assert exc.value.status_code == 404
# ---------------------------------------------------------------------------
# Ownership / Recipients / Membership
# ---------------------------------------------------------------------------
def test_require_ownership_passes_for_owner() -> None:
aid = uuid4()
resource = type("R", (), {"owner": aid})()
require_ownership(resource, "owner", aid, "edit")
def test_require_ownership_raises_for_other_agent() -> None:
resource = type("R", (), {"owner": uuid4()})()
with pytest.raises(HTTPException) as exc:
require_ownership(resource, "owner", uuid4(), "edit")
assert exc.value.status_code == 403
def test_require_ownership_no_owner_passes() -> None:
resource = type("R", (), {"owner": None})()
# Should not raise — no owner means open access.
require_ownership(resource, "owner", uuid4(), "edit")
def test_require_recipient_passes() -> None:
aid = uuid4()
require_recipient([uuid4(), aid, uuid4()], aid)
def test_require_recipient_raises() -> None:
with pytest.raises(HTTPException) as exc:
require_recipient([uuid4(), uuid4()], uuid4())
assert exc.value.status_code == 403
def test_require_membership_passes() -> None:
aid = uuid4()
require_membership([uuid4(), aid], aid, "channel")
def test_require_membership_raises() -> None:
with pytest.raises(HTTPException) as exc:
require_membership([uuid4()], uuid4(), "channel")
assert exc.value.status_code == 403