Skip to content

Commit d09191d

Browse files
committed
test(integration): add hybrid_search test; strengthen schema test
- test_hybrid_search_returns_results: creates two nodes connected by RELATED edge with embeddings, calls hybrid_search from start node, asserts results with distance and node fields - test_get_schema_text: now creates actual data (label + edge type) and verifies SchemaTestLabel and SCHEMA_EDGE appear in schema text output - Remove stale "graph RPC stubs not yet wired" comment in async test 25/25 integration tests pass
1 parent 02a5adf commit d09191d

1 file changed

Lines changed: 52 additions & 3 deletions

File tree

tests/integration/test_sdk.py

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,57 @@ def test_bool_not_serialised_as_vector(client):
201201

202202

203203
def test_get_schema_text(client):
204-
schema = client.get_schema_text()
205-
assert isinstance(schema, str)
204+
"""get_schema_text returns a non-empty string that lists labels and edge types."""
205+
tag = uid()
206+
client.cypher(
207+
"CREATE (a:SchemaTestLabel {tag: $tag})-[:SCHEMA_EDGE]->(b:SchemaTestLabel {tag: $tag})",
208+
params={"tag": tag},
209+
)
210+
try:
211+
schema = client.get_schema_text()
212+
assert isinstance(schema, str)
213+
assert len(schema) > 0, "schema text must not be empty after data creation"
214+
assert "SchemaTestLabel" in schema, f"label missing from schema text: {schema!r}"
215+
assert "SCHEMA_EDGE" in schema, f"edge type missing from schema text: {schema!r}"
216+
finally:
217+
client.cypher("MATCH (n:SchemaTestLabel {tag: $tag}) DETACH DELETE n", params={"tag": tag})
218+
219+
220+
# ── Hybrid search ─────────────────────────────────────────────────────────────
221+
222+
223+
def test_hybrid_search_returns_results(client):
224+
"""hybrid_search traverses graph edges then ranks neighbours by vector distance."""
225+
tag = uid()
226+
vec = [float(i) / 8 for i in range(8)]
227+
# Create two nodes connected by RELATED edge, both have embeddings.
228+
client.cypher(
229+
"CREATE (a:HybridTest {tag: $tag, embedding: $vec})"
230+
"-[:RELATED]->"
231+
"(b:HybridTest {tag: $tag, embedding: $vec})",
232+
params={"tag": tag, "vec": vec},
233+
)
234+
# Retrieve the start node id.
235+
# `a` in RETURN resolves to Value::Int(node_id) via NodeScan — no id() function needed.
236+
rows = client.cypher(
237+
"MATCH (a:HybridTest {tag: $tag})-[:RELATED]->(b) RETURN a AS aid",
238+
params={"tag": tag},
239+
)
240+
try:
241+
assert len(rows) >= 1, f"setup nodes not found: {rows}"
242+
start_id = rows[0]["aid"]
243+
results = client.hybrid_search(
244+
start_node_id=start_id,
245+
edge_type="RELATED",
246+
vector=vec,
247+
top_k=1,
248+
vector_property="embedding",
249+
)
250+
assert len(results) >= 1, f"hybrid_search returned no results"
251+
assert hasattr(results[0], "distance")
252+
assert hasattr(results[0], "node")
253+
finally:
254+
client.cypher("MATCH (n:HybridTest {tag: $tag}) DETACH DELETE n", params={"tag": tag})
206255

207256

208257
# ── Host:port string parsing ──────────────────────────────────────────────────
@@ -247,7 +296,7 @@ async def test_async_client_cypher():
247296

248297
@pytest.mark.asyncio
249298
async def test_async_create_node():
250-
# Use Cypher; graph RPC stubs not yet wired (see test_create_node_rpc_*).
299+
# Create node via Cypher to verify async client write path.
251300
tag = uid()
252301
async with AsyncCoordinodeClient(ADDR) as c:
253302
await c.cypher("CREATE (n:AsyncTest {tag: $tag})", params={"tag": tag})

0 commit comments

Comments
 (0)