test: align CI assertions with documented contracts

Two unrelated CI failures on this branch, one fix each:

- tests/integration/test_deck_vector_search.py: pass str(card.id) to
  get_chunk_with_context. The function's contract is doc_id: str
  (keyword-indexed in Qdrant), and real callers (viz_routes.py URL
  path, server/semantic.py via str(result.id)) all stringify. The
  test was the only int caller, hitting the .isdigit() guard added
  earlier on this branch.

- tests/server/login_flow/test_login_flow_integration.py:
  test_check_status_provisioned now accepts scopes=None as valid.
  Per ProvisionStatusResponse in models/auth.py, None is the
  documented sentinel for "all scopes granted" — and the web
  provisioning path (provision_routes.py, used by Astrolabe's
  "Enable Semantic Search" flow exercised by the new regression test
  added on this branch) stores exactly that. The previous
  is-not-None assertion hid behind test order until that flow ran.

- Replace anyio.sleep(0) with anyio.lowlevel.checkpoint()

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-05-09 15:28:15 +02:00
co-authored by Claude Opus 4.7
parent 64f0842977
commit 0c14501a2b
3 changed files with 16 additions and 7 deletions
+4 -1
View File
@@ -207,10 +207,13 @@ async def test_deck_card_chunk_context(nc_client):
# Fetch chunk context (simulates viz UI request)
# The chunk spans the title, so start=0 and end=len(card_title)
# doc_id is str — keyword-indexed in Qdrant payload; the real
# callers (viz_routes.py from URL path; server/semantic.py from
# str(result.id)) all stringify before reaching this entry point.
context = await get_chunk_with_context(
nc_client=nc_client,
user_id=nc_client.username,
doc_id=card.id,
doc_id=str(card.id),
doc_type="deck_card",
chunk_start=0,
chunk_end=len(card_title),
@@ -43,7 +43,13 @@ class TestLoginFlowAuthTools:
data = json.loads(result.content[0].text)
assert data["status"] == "provisioned"
assert data["username"] is not None
assert data["scopes"] is not None
# ``scopes`` may legitimately be ``None`` — per ProvisionStatusResponse
# in models/auth.py, ``None`` is the documented sentinel for "all
# scopes granted" and is what the web provisioning path
# (``provision_routes.py``, used by Astrolabe's "Enable Semantic
# Search" flow) stores. So accept either a non-empty list or None;
# the field's *presence* in the payload is what we care about here.
assert data["scopes"] is None or len(data["scopes"]) > 0
logger.info(f"Provisioned as: {data['username']}, scopes: {data['scopes']}")
async def test_provision_access_already_provisioned(
+5 -5
View File
@@ -237,7 +237,7 @@ async def test_ensure_payload_indexes_logs_and_returns_when_get_collection_raise
async def _get_collection_raises(*args, **kwargs):
# See _scroll_raises in the backfill section for why this is async.
await anyio.sleep(0)
await anyio.lowlevel.checkpoint()
raise RuntimeError("connection refused")
client.get_collection.side_effect = _get_collection_raises
@@ -494,11 +494,11 @@ async def test_backfill_logs_and_returns_when_scroll_raises(mocker, caplog):
# An async-callable side_effect lets AsyncMock await the coroutine
# before the exception propagates; assigning a bare exception class
# leaks an un-awaited coroutine and trips RuntimeWarning at gc time.
# The `await anyio.sleep(0)` is a no-op event-loop yield that
# The `await anyio.lowlevel.checkpoint()` is a no-op event-loop yield that
# satisfies static analysis ("async function uses no async features")
# without changing observable behavior.
async def _scroll_raises(*args, **kwargs):
await anyio.sleep(0)
await anyio.lowlevel.checkpoint()
raise RuntimeError("boom")
client.scroll.side_effect = _scroll_raises
@@ -538,7 +538,7 @@ async def test_backfill_logs_warning_when_sentinel_upsert_fails(mocker, caplog):
async def _upsert_raises(*args, **kwargs):
# See _scroll_raises above for why this is async + sleep(0).
await anyio.sleep(0)
await anyio.lowlevel.checkpoint()
raise RuntimeError("sentinel write blip")
client.upsert.side_effect = _upsert_raises
@@ -615,7 +615,7 @@ async def test_ensure_payload_indexes_summarises_failed_fields(mocker, caplog):
async def _create_index(*args, **kwargs):
# See _scroll_raises above for why this is async + sleep(0).
await anyio.sleep(0)
await anyio.lowlevel.checkpoint()
call_count["n"] += 1
if call_count["n"] != 2:
raise _make_unexpected(500, b'{"status":{"error":"boom"}}')