Skip to content

test(routes): add comprehensive tests for GET /peers/{peer_id}/context endpoint#532

Open
KevinNatera wants to merge 1 commit intoplastic-labs:mainfrom
KevinNatera:test/add-peer-context-endpoint-tests
Open

test(routes): add comprehensive tests for GET /peers/{peer_id}/context endpoint#532
KevinNatera wants to merge 1 commit intoplastic-labs:mainfrom
KevinNatera:test/add-peer-context-endpoint-tests

Conversation

@KevinNatera
Copy link
Copy Markdown

@KevinNatera KevinNatera commented Apr 8, 2026

PR: test(routes): Add comprehensive tests for GET /peers/{peer_id}/context endpoint

What Changed

Added 20 new tests to tests/routes/test_peers.py covering the GET /workspaces/{workspace_id}/peers/{peer_id}/context endpoint (get_peer_context).

Why This Contribution

While exploring the codebase, I noticed the get_peer_context endpoint had zero test coverage. This endpoint is actually important — it was added specifically to let callers retrieve a peer's representation and peer card in a single round-trip rather than two separate requests, which is a meaningful latency optimization for real-world agent applications.

Without tests, any future refactor or change to this endpoint could silently break it. Given Honcho's production use and the fact that this is a convenience endpoint building on two other covered endpoints, it felt like exactly the kind of gap that's worth closing.

What Problem It Solves

  • Prevents silent regressions: The endpoint could break undetected across future PRs
  • Documents the contract: The tests serve as living documentation for what the endpoint accepts and returns
  • Validates query parameter constraints: Confirms that FastAPI's ge/le validation on search_top_k, search_max_distance, and max_conclusions actually enforces the expected 422 responses
  • Consistency guarantee: One test explicitly verifies that /context returns the same representation and peer_card values as calling /representation and /card separately — catching any divergence in logic

Test Coverage Added

Category Tests
Basic structure & self-observation default 3
Explicit target peer 2
Field type validation (str|None, list|None) 2
Empty initial state 1
Async: peer card seeded via DB 2
Query params (search_query, top_k, max_distance, include_most_frequent, max_conclusions) 6
Boundary values (min/max) 2
Out-of-range validation (422) 3
404 for nonexistent workspace/peer/target 3
Consistency: /context vs /representation + /card 2
Total 20

How to Review

All changes are confined to tests/routes/test_peers.py. The tests follow the same patterns as the existing test suite (same fixtures, same assertion style, same import patterns). No production code was modified.


Closes #(no issue — this is proactive test coverage for an untested endpoint)

cc @ajspig

Summary by CodeRabbit

  • Tests
    • Added comprehensive test suite for the peer context endpoint, verifying response structure, field types, default behaviors, target scoping, and query parameter handling including boundary validation.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 8, 2026

Walkthrough

A comprehensive test suite was added for the GET /v3/workspaces/{workspace}/peers/{peer}/context endpoint, covering response structure validation, default behavior, parameter scoping, field type assertions, query parameter handling with boundary cases, and consistency verification against related endpoints.

Changes

Cohort / File(s) Summary
Peer Context Endpoint Tests
tests/routes/test_peers.py
New test suite with 514 lines covering endpoint response structure, default target behavior (self-observation), target scoping for identifiers and cards, field type validation (representation as str|None, peer_card as list|None), card population via crud.set_peer_card, query parameters (search_query, search_top_k, search_max_distance, include_most_frequent, max_conclusions), boundary/out-of-range cases returning 422, and consistency checks against separate representation and card endpoints.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Poem

🐰 Hop, hop, tests abound!
Each case and boundary found,
Peer contexts verified,
Quality assured and tried,
Code now stands on solid ground!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding comprehensive tests for the GET /peers/{peer_id}/context endpoint, which matches the file changes and PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/routes/test_peers.py (1)

968-1006: Consider consolidating duplicate self-observation coverage.

test_get_peer_context_basic and test_get_peer_context_self_observation overlap heavily; parametrizing or merging would reduce maintenance noise.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/routes/test_peers.py` around lines 968 - 1006, Merge or parametrize the
duplicate assertions in test_get_peer_context_basic and
test_get_peer_context_self_observation by consolidating the shared checks
(response.status_code == 200, presence of "peer_id", "target_id",
"representation", "peer_card", and the self-observation assertions that peer_id
== target_id == test_peer.name) into a single test or a parametrized pytest
function; update or remove one of the tests so the shared validation logic for
the PeerContext schema and the default self-observation behavior is only
implemented once while preserving any unique assertions, referencing the
existing test functions test_get_peer_context_basic and
test_get_peer_context_self_observation and the PeerContext expectations when
refactoring.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/routes/test_peers.py`:
- Around line 1062-1063: The test currently allows any list for
data["peer_card"] but must enforce the schema that each item is a string; update
the assertion for peer_card so it remains allowed to be None or, if a list,
assert that every element in data["peer_card"] is an instance of str (e.g.,
using an all(...) check) to catch non-string regressions; locate and change the
assertion that references data["peer_card"] in tests/routes/test_peers.py.
- Around line 1443-1446: The POST that creates the target peer is currently
ignored; capture its response from
client.post(f"/v3/workspaces/{test_workspace.name}/peers", json={"name":
target_peer_name}) and assert success before proceeding: verify the
response.status_code (e.g., 201 or expected code) and that response.json()
contains the created peer (e.g., "name" == target_peer_name or expected id), so
downstream checks fail fast and show the real creation error.

---

Nitpick comments:
In `@tests/routes/test_peers.py`:
- Around line 968-1006: Merge or parametrize the duplicate assertions in
test_get_peer_context_basic and test_get_peer_context_self_observation by
consolidating the shared checks (response.status_code == 200, presence of
"peer_id", "target_id", "representation", "peer_card", and the self-observation
assertions that peer_id == target_id == test_peer.name) into a single test or a
parametrized pytest function; update or remove one of the tests so the shared
validation logic for the PeerContext schema and the default self-observation
behavior is only implemented once while preserving any unique assertions,
referencing the existing test functions test_get_peer_context_basic and
test_get_peer_context_self_observation and the PeerContext expectations when
refactoring.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b749867-980e-4f85-93b8-39aa298c710c

📥 Commits

Reviewing files that changed from the base of the PR and between 5b6bd59 and 8d531da.

📒 Files selected for processing (1)
  • tests/routes/test_peers.py

Comment on lines +1062 to +1063
# peer_card should be a list of strings or None (no card set yet)
assert data["peer_card"] is None or isinstance(data["peer_card"], list)
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.

⚠️ Potential issue | 🟡 Minor

Strengthen peer_card type validation to match schema contract.

This currently accepts any list type; it won’t catch regressions where non-string items are returned.

Suggested fix
-    assert data["peer_card"] is None or isinstance(data["peer_card"], list)
+    assert data["peer_card"] is None or (
+        isinstance(data["peer_card"], list)
+        and all(isinstance(item, str) for item in data["peer_card"])
+    )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# peer_card should be a list of strings or None (no card set yet)
assert data["peer_card"] is None or isinstance(data["peer_card"], list)
# peer_card should be a list of strings or None (no card set yet)
assert data["peer_card"] is None or (
isinstance(data["peer_card"], list)
and all(isinstance(item, str) for item in data["peer_card"])
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/routes/test_peers.py` around lines 1062 - 1063, The test currently
allows any list for data["peer_card"] but must enforce the schema that each item
is a string; update the assertion for peer_card so it remains allowed to be None
or, if a list, assert that every element in data["peer_card"] is an instance of
str (e.g., using an all(...) check) to catch non-string regressions; locate and
change the assertion that references data["peer_card"] in
tests/routes/test_peers.py.

Comment on lines +1443 to +1446
client.post(
f"/v3/workspaces/{test_workspace.name}/peers",
json={"name": target_peer_name},
)
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.

⚠️ Potential issue | 🟡 Minor

Assert target peer creation before using it in downstream checks.

The setup call result is ignored, which can obscure root cause when this test fails later.

Suggested fix
-    client.post(
+    create_target_response = client.post(
         f"/v3/workspaces/{test_workspace.name}/peers",
         json={"name": target_peer_name},
     )
+    assert create_target_response.status_code in [200, 201]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/routes/test_peers.py` around lines 1443 - 1446, The POST that creates
the target peer is currently ignored; capture its response from
client.post(f"/v3/workspaces/{test_workspace.name}/peers", json={"name":
target_peer_name}) and assert success before proceeding: verify the
response.status_code (e.g., 201 or expected code) and that response.json()
contains the created peer (e.g., "name" == target_peer_name or expected id), so
downstream checks fail fast and show the real creation error.

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.

1 participant