Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import sys
from pathlib import Path

# Ensure src/ package takes precedence over the legacy root-level governs_ai/ directory
_src = str(Path(__file__).parent / "src")
if _src not in sys.path:
sys.path.insert(0, _src)
2 changes: 2 additions & 0 deletions governs_ai/exceptions/precheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
Precheck-specific exceptions.
"""

from typing import Any, Dict, Optional

from .base import GovernsAIError


Expand Down
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ dev = [
"mypy>=1.0.0",
]

[tool.setuptools.packages.find]
where = ["src"]

[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
pythonpath = ["src"]
addopts = "--import-mode=importlib"
markers = [
"integration: requires running local services (deselect with '-m not integration')",
]
Empty file added tests/integration/__init__.py
Empty file.
36 changes: 36 additions & 0 deletions tests/integration/test_precheck_integration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Integration tests for precheck() — require local precheck service on localhost:8000."""

import os

import pytest

from governs_ai.client import GovernsAIClient


@pytest.fixture
def client():
return GovernsAIClient(
api_key=os.getenv("GOVERNS_API_KEY", "dev-key"),
base_url=os.getenv("GOVERNS_BASE_URL", "http://localhost:8000"),
org_id=os.getenv("GOVERNS_ORG_ID", "org-dev"),
)


@pytest.mark.integration
def test_precheck_returns_real_decision(client):
"""precheck() against local service returns a valid decision."""
result = client.precheck(content="Hello from integration test", tool="model.chat")
assert result.decision in ("allow", "deny", "transform", "confirm")
assert isinstance(result.redacted_content, str)
assert isinstance(result.reasons, list)
assert result.latency_ms > 0


@pytest.mark.integration
async def test_async_precheck_returns_real_decision(client):
"""async_precheck() against local service returns a valid decision."""
result = await client.async_precheck(
content="Hello from async integration test", tool="model.chat"
)
assert result.decision in ("allow", "deny", "transform", "confirm")
assert result.latency_ms > 0
Loading