Skip to content

feat(tests): add integration tests for API endpoints #149#154

Open
Aharshi3614 wants to merge 7 commits into
TENET-DEV-AI:mainfrom
Aharshi3614:feat/integration-tests-149
Open

feat(tests): add integration tests for API endpoints #149#154
Aharshi3614 wants to merge 7 commits into
TENET-DEV-AI:mainfrom
Aharshi3614:feat/integration-tests-149

Conversation

@Aharshi3614

@Aharshi3614 Aharshi3614 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Description

Implements comprehensive integration tests for all TENET AI API endpoints as specified in issue #149.

Tests cover the full request/response cycle for both the Ingest (port 8000) and Analyzer (port 8100) services across 10 test classes:

  • TestHealthEndpoints - health checks for both services
  • TestAuthFlow - authentication and authorization edge cases
  • TestIngestEndpoint - full ingest happy path
  • TestIngestValidation - input validation and edge cases
  • TestAnalyzerEndpoint - analyzer verdict, schema, error handling
  • TestEventRetrieval - event retrieval by ID, pagination, org isolation
  • TestStatsAndCircuit - stats endpoint and circuit breaker status
  • TestThreatDetection - 12 parametrized accuracy test cases
  • TestPerformance - response time and batch request tests
  • TestErrorHandling - 404, 405, 422 error code verification

Related Issue

Fixes #149

Type of Change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Ran locally with both services running via uvicorn:

  • Integration tests
  • Manual testing
    pytest tests/integration/test_api_integration.py -v
    Result: 80 passed in 200s

Checklist

  • My code follows the project's code style
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Summary by cubic

Adds a comprehensive integration test suite for the Ingest and Analyzer APIs to validate end-to-end flows, auth, validation, events, stats/circuit, audit export, performance, and threat detection. Tests handle degraded Redis states and enforce consistent JSON errors, aligning with issue #149.

  • New Features

    • Adds tests/integration/test_api_integration.py covering health schemas, auth, ingest/analyze validation and verdicts, events (list/get with pagination and org isolation), stats, circuit status, audit export, and JSON error codes; auto-skips if services are unreachable.
    • Analyzer: verifies verdicts, risk_score/confidence in [0,1], threat_type in {prompt_injection, jailbreak, data_extraction}; accepts optional context.
    • Ingest: validates schema and limits, UUID event_id; detects injection/jailbreaks and flags data extraction. Includes 12 threat cases, performance checks (<3s), and a 10-request batch; configurable via INGEST_URL, ANALYZER_URL, API_KEY.
  • Dependencies

    • Sets numpy to >=2.4.6, adds prometheus-client >=0.21.0, and aligns python-dateutil to >=2.8.2; cleans up requirements.txt comments.

Written for commit a9d2ea3. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Tests
    • Added a comprehensive Python integration test suite for TENET AI API endpoints, configurable via environment variables.
    • Covers health checks, authentication/authorization, ingest and analyze schemas and validations (including injection detection), event listing/retrieval, utility endpoints, error handling, threat-detection expectations, and basic performance thresholds.
    • Tests automatically skip when required services are unreachable.
  • Chores
    • Updated several dependency version constraints and reorganized the requirements file for clarity.

@vercel

vercel Bot commented Jun 10, 2026

Copy link
Copy Markdown

@Aharshi3614 is attempting to deploy a commit to the s3dfx-cyber's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a Python integration test suite for TENET AI API endpoints and updates selected dependency versions in requirements.txt.

Changes

Integration Test Suite for TENET AI API Endpoints

Layer / File(s) Summary
Test Infrastructure Setup
tests/integration/test_api_integration.py
Module documentation, environment configuration for URLs and API keys, shared llm_payload() helper, _service_up() health probe, and require_services() autouse fixture that skips tests if either service is unreachable.
Health and Authentication Tests
tests/integration/test_api_integration.py
TestHealthEndpoints validates /health responses for both services without auth; TestAuthFlow checks missing, invalid, and valid API keys across protected ingest, analyzer, and utility routes.
Ingest Endpoint Tests
tests/integration/test_api_integration.py
TestIngestEndpoint covers /v1/events/llm outcomes, required fields, UUID validity, optional system_prompt/metadata, and malicious message checks. TestIngestValidation covers prompt validation, missing fields, max-length boundaries, non-JSON rejection, and injection detection.
Analyzer Endpoint Tests
tests/integration/test_api_integration.py
TestAnalyzerEndpoint validates /v1/analyze schema fields, verdict/threat type, numeric ranges, empty/missing prompt handling, and optional context.
Event Retrieval and Data Access
tests/integration/test_api_integration.py
TestEventRetrieval covers event listing, retrieval by ID after ingest, degraded/503/404 handling, nonexistent IDs, and org isolation with different API keys.
Utility Endpoints and Threat Detection
tests/integration/test_api_integration.py
TestStatsAndCircuit covers /v1/stats, /v1/circuit-status, and /v1/audit/export; TestThreatDetection asserts expected blocked/verdict results for known prompts.
Performance and Error Handling
tests/integration/test_api_integration.py
TestPerformance measures ingest/analyzer/health latency and batch success; TestErrorHandling checks unknown routes, wrong methods, query validation, and JSON-parsable auth errors.
Dependency Version Updates
requirements.txt
numpy, prometheus-client, and python-dateutil minimum versions change, with dependency sections reorganized and a new comment added.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Core issue #149 is mostly covered, but rate limiting behavior and CI/local run documentation are not addressed. Add coverage for rate limiting and update CI or docs so the integration suite is runnable in the pipeline and locally.
Docstring Coverage ⚠️ Warning Docstring coverage is 17.39% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The changes stay focused on integration tests and related dependency updates, with no obvious unrelated scope creep.
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding integration tests for API endpoints.
Description check ✅ Passed The description covers the issue, change type, testing, and checklist, though it does not use the template's exact Summary/Key Changes headings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Re-trigger cubic

@S3DFX-CYBER S3DFX-CYBER requested a review from Preetham404 June 10, 2026 12:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/integration/test_api_integration.py`:
- Around line 88-92: The test test_ingest_health_response_schema currently
asserts an exact version string ("0.1.0") which will break on normal version
bumps; change the assertion in test_ingest_health_response_schema (and the
similar assertions around lines 101-105) to validate the version more
flexibly—e.g., assert that data["version"] is a non-empty string or matches a
semantic version pattern, or compare it against the package/app runtime version
constant if available—so the test verifies format/presence rather than a
hard-coded value.
- Around line 150-167: The tests test_valid_key_accepted_on_ingest and
test_valid_key_accepted_on_analyzer currently assert a strict 200 response,
coupling auth checks to downstream availability; update both assertions to
accept successful auth responses even if downstream is degraded by asserting
r.status_code is in an allowed set (e.g., {200, 503}) or by asserting the
response is not an authentication failure (e.g., not 401/403), so the tests only
validate that VALID_HEADERS are accepted rather than the full service health.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: eae01221-6742-43f1-86e5-c725a7210263

📥 Commits

Reviewing files that changed from the base of the PR and between 721686f and 9d33a05.

📒 Files selected for processing (1)
  • tests/integration/test_api_integration.py

Comment thread tests/integration/test_api_integration.py
Comment thread tests/integration/test_api_integration.py
@S3DFX-CYBER

Copy link
Copy Markdown
Collaborator

@Aharshi3614 needs fixes

@S3DFX-CYBER

Copy link
Copy Markdown
Collaborator

Kindly make the fixes within 3-4 days or this pr will be closed as stale @Aharshi3614

@Aharshi3614 Aharshi3614 force-pushed the feat/integration-tests-149 branch 3 times, most recently from dbf42b5 to 9bab66a Compare June 29, 2026 02:00
@Aharshi3614

Copy link
Copy Markdown
Contributor Author

@S3DFX-CYBER done!

@S3DFX-CYBER

Copy link
Copy Markdown
Collaborator

@Aharshi3614 merge conflicts

@Aharshi3614

Copy link
Copy Markdown
Contributor Author

@S3DFX-CYBER resolved!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/integration/test_api_integration.py (2)

1-25: 🎯 Functional Correctness | 🔵 Trivial

No tests for rate limiting despite it being an explicit objective of issue #149.

The linked issue lists "Test rate limiting behavior" as a required deliverable, but this suite has no test exercising rate-limit responses (e.g., repeated requests triggering 429). Want me to draft a rate-limit test class (e.g., burst requests against /v1/events/llm asserting a 429 after the configured threshold)?

Also applies to: 657-703

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_api_integration.py` around lines 1 - 25, Add a
rate-limiting test to the integration suite because the current tests cover auth
and endpoint flow but not the required 429 behavior. Extend the existing test
module with a dedicated rate-limit test/class (for example alongside
TestAuthFlow) that targets a representative endpoint such as /v1/events/llm,
sends a burst of repeated requests using the configured API_KEY, and asserts
that once the limit is exceeded the response becomes 429. Keep the test aligned
with the current environment-variable setup and reuse the existing
request/session helpers in the integration file so it fits the rest of the
suite.

556-577: 🩺 Stability & Availability | 🔵 Trivial | ⚖️ Poor tradeoff

Fixed sleep(0.5) for eventual consistency is flaky and weakens assertions.

Both test_get_event_by_id_after_ingest and test_get_event_isolation_by_org use a hardcoded time.sleep(0.5) then accept multiple outcomes (200, 503, 404) as "acceptable," which means a real regression (e.g., writes never persisted) can pass silently. Consider a short polling/retry loop with a timeout instead of a fixed sleep, and narrow the accepted outcomes.

Also applies to: 588-607

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_api_integration.py` around lines 556 - 577, The event
retrieval integration tests rely on a fixed `time.sleep(0.5)` and overly broad
status acceptance, which can hide real persistence regressions. Update
`test_get_event_by_id_after_ingest` and `test_get_event_isolation_by_org` to use
a short polling/retry loop after the create request until the event becomes
available or a timeout is reached, and then tighten the assertions so `get_r`
only accepts the statuses that are genuinely expected for the behavior under
test. Use the existing `event_id`, `create_r`, and `get_r` flow to keep the
checks aligned with the current test structure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/integration/test_api_integration.py`:
- Around line 588-607: The org isolation test is using an invalid API key
instead of a second valid org key, so it only checks auth rejection rather than
cross-tenant visibility. Update test_get_event_isolation_by_org in
test_api_integration.py to create or load a second valid API key for a different
org (preferably via a fixture or env var), then fetch the created event with
that key and assert it returns 404. Keep the existing event creation flow with
llm_payload and requests.get/post, but change the retrieval step to exercise
true org isolation.

---

Nitpick comments:
In `@tests/integration/test_api_integration.py`:
- Around line 1-25: Add a rate-limiting test to the integration suite because
the current tests cover auth and endpoint flow but not the required 429
behavior. Extend the existing test module with a dedicated rate-limit test/class
(for example alongside TestAuthFlow) that targets a representative endpoint such
as /v1/events/llm, sends a burst of repeated requests using the configured
API_KEY, and asserts that once the limit is exceeded the response becomes 429.
Keep the test aligned with the current environment-variable setup and reuse the
existing request/session helpers in the integration file so it fits the rest of
the suite.
- Around line 556-577: The event retrieval integration tests rely on a fixed
`time.sleep(0.5)` and overly broad status acceptance, which can hide real
persistence regressions. Update `test_get_event_by_id_after_ingest` and
`test_get_event_isolation_by_org` to use a short polling/retry loop after the
create request until the event becomes available or a timeout is reached, and
then tighten the assertions so `get_r` only accepts the statuses that are
genuinely expected for the behavior under test. Use the existing `event_id`,
`create_r`, and `get_r` flow to keep the checks aligned with the current test
structure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3b7b8c81-2453-4601-96bc-5686b1ebb15c

📥 Commits

Reviewing files that changed from the base of the PR and between 0458927 and a9d2ea3.

📒 Files selected for processing (2)
  • requirements.txt
  • tests/integration/test_api_integration.py

Comment on lines +588 to +607
def test_get_event_isolation_by_org(self):
"""Events from one org should not be visible with a different API key."""
create_r = requests.post(
f"{INGEST_URL}/v1/events/llm",
headers=VALID_HEADERS,
json=llm_payload("Org isolation test"),
timeout=5,
)
if create_r.status_code != 200:
pytest.skip("Could not create event for isolation test")

event_id = create_r.json()["event_id"]
time.sleep(0.5)

get_r = requests.get(
f"{INGEST_URL}/v1/events/{event_id}",
headers=INVALID_HEADERS,
timeout=5,
)
assert get_r.status_code in (401, 404)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Org isolation test doesn't actually test org isolation.

test_get_event_isolation_by_org creates an event with VALID_HEADERS then retrieves it with INVALID_HEADERS (a garbage key), asserting 401 or 404. This only re-verifies invalid-key rejection (already covered by TestAuthFlow) — it doesn't confirm that a different valid org's API key can't see another org's event, which is the actual isolation guarantee the test name implies.

Consider adding a second valid API key for a different org (e.g., via env var or fixture) and asserting a 404 (not found for that org) when accessed with it, to truly exercise cross-tenant isolation.

🧰 Tools
🪛 ast-grep (0.44.1)

[warning] 589-594: Request-controlled URL passed to requests; validate against an allowlist to prevent SSRF.
Context: requests.post(
f"{INGEST_URL}/v1/events/llm",
headers=VALID_HEADERS,
json=llm_payload("Org isolation test"),
timeout=5,
)
Note: [CWE-918] Server-Side Request Forgery (SSRF).

(ssrf-requests)


[warning] 601-605: Request-controlled URL passed to requests; validate against an allowlist to prevent SSRF.
Context: requests.get(
f"{INGEST_URL}/v1/events/{event_id}",
headers=INVALID_HEADERS,
timeout=5,
)
Note: [CWE-918] Server-Side Request Forgery (SSRF).

(ssrf-requests)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_api_integration.py` around lines 588 - 607, The org
isolation test is using an invalid API key instead of a second valid org key, so
it only checks auth rejection rather than cross-tenant visibility. Update
test_get_event_isolation_by_org in test_api_integration.py to create or load a
second valid API key for a different org (preferably via a fixture or env var),
then fetch the created event with that key and assert it returns 404. Keep the
existing event creation flow with llm_payload and requests.get/post, but change
the retrieval step to exercise true org isolation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Integration Tests for TENET AI API Endpoints

2 participants