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.
This commit is contained in:
Renn F
2026-05-06 00:32:52 +02:00
parent b6903490f1
commit 64c48356d0
46 changed files with 2994 additions and 206 deletions
+55
View File
@@ -0,0 +1,55 @@
"""utils.converters coverage."""
from __future__ import annotations
from uuid import uuid4
import pytest
from roboco.utils.converters import (
require_uuid,
to_python_uuid,
to_python_uuid_list,
)
def test_require_uuid_passes_through() -> None:
u = uuid4()
assert require_uuid(u) is u
def test_require_uuid_parses_string() -> None:
u = uuid4()
assert require_uuid(str(u)) == u
def test_require_uuid_raises_for_none() -> None:
with pytest.raises(ValueError, match="cannot be None"):
require_uuid(None)
def test_to_python_uuid_returns_none_for_none() -> None:
assert to_python_uuid(None) is None
def test_to_python_uuid_passes_through_uuid() -> None:
u = uuid4()
assert to_python_uuid(u) is u
def test_to_python_uuid_parses_string() -> None:
u = uuid4()
assert to_python_uuid(str(u)) == u
def test_to_python_uuid_list_returns_empty_for_none() -> None:
assert to_python_uuid_list(None) == []
def test_to_python_uuid_list_converts_strings() -> None:
u1, u2 = uuid4(), uuid4()
result = to_python_uuid_list([str(u1), str(u2)])
assert result == [u1, u2]
def test_to_python_uuid_list_empty() -> None:
assert to_python_uuid_list([]) == []
+53
View File
@@ -0,0 +1,53 @@
"""utils.crypto coverage — Fernet encrypt/decrypt round-trip."""
from __future__ import annotations
import pytest
from roboco.utils.crypto import (
EncryptionError,
decrypt_token,
encrypt_token,
is_encryption_configured,
)
def test_encrypt_decrypt_round_trip() -> None:
plaintext = "sk-secret-test-token-12345"
encrypted = encrypt_token(plaintext)
assert encrypted != plaintext
decrypted = decrypt_token(encrypted)
assert decrypted == plaintext
def test_encrypt_empty_string_raises() -> None:
with pytest.raises(EncryptionError, match="empty"):
encrypt_token("")
def test_decrypt_empty_string_raises() -> None:
with pytest.raises(EncryptionError, match="empty"):
decrypt_token("")
def test_decrypt_invalid_token_raises() -> None:
with pytest.raises(EncryptionError):
decrypt_token("not-a-valid-token-at-all")
def test_is_encryption_configured() -> None:
"""Encryption must be configured for tests to run."""
assert is_encryption_configured() is True
def test_encrypt_long_string() -> None:
plaintext = "a" * 1000
encrypted = encrypt_token(plaintext)
decrypted = decrypt_token(encrypted)
assert decrypted == plaintext
def test_encrypt_unicode() -> None:
plaintext = "héllo wörld 中文 🚀"
encrypted = encrypt_token(plaintext)
decrypted = decrypt_token(encrypted)
assert decrypted == plaintext