mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-09 08:21:50 +00:00
test(dashboard): direct unit coverage for internal WS credential + docstring fix
Some checks are pending
Deploy Site / deploy-vercel (push) Waiting to run
Deploy Site / deploy-docs (push) Waiting to run
Docker / shell lint / Lint Dockerfile (hadolint) (push) Waiting to run
Docker / shell lint / Lint docker/ shell scripts (shellcheck) (push) Waiting to run
Docker Build and Publish / build-amd64 (push) Waiting to run
Docker Build and Publish / build-arm64 (push) Waiting to run
Docker Build and Publish / merge (push) Blocked by required conditions
Lint (ruff + ty) / ruff + ty diff (push) Waiting to run
Lint (ruff + ty) / ruff enforcement (blocking) (push) Waiting to run
Lint (ruff + ty) / Windows footguns (blocking) (push) Waiting to run
Nix Lockfile Fix / auto-fix-main (push) Waiting to run
Nix Lockfile Fix / fix (push) Waiting to run
Nix / nix (macos-latest) (push) Waiting to run
Nix / nix (ubuntu-latest) (push) Waiting to run
OSV-Scanner / Scan lockfiles (push) Waiting to run
Tests / test (1) (push) Waiting to run
Tests / test (2) (push) Waiting to run
Tests / test (3) (push) Waiting to run
Tests / test (4) (push) Waiting to run
Tests / test (5) (push) Waiting to run
Tests / test (6) (push) Waiting to run
Tests / save-durations (push) Blocked by required conditions
Tests / e2e (push) Waiting to run
uv.lock check / uv lock --check (push) Waiting to run
Some checks are pending
Deploy Site / deploy-vercel (push) Waiting to run
Deploy Site / deploy-docs (push) Waiting to run
Docker / shell lint / Lint Dockerfile (hadolint) (push) Waiting to run
Docker / shell lint / Lint docker/ shell scripts (shellcheck) (push) Waiting to run
Docker Build and Publish / build-amd64 (push) Waiting to run
Docker Build and Publish / build-arm64 (push) Waiting to run
Docker Build and Publish / merge (push) Blocked by required conditions
Lint (ruff + ty) / ruff + ty diff (push) Waiting to run
Lint (ruff + ty) / ruff enforcement (blocking) (push) Waiting to run
Lint (ruff + ty) / Windows footguns (blocking) (push) Waiting to run
Nix Lockfile Fix / auto-fix-main (push) Waiting to run
Nix Lockfile Fix / fix (push) Waiting to run
Nix / nix (macos-latest) (push) Waiting to run
Nix / nix (ubuntu-latest) (push) Waiting to run
OSV-Scanner / Scan lockfiles (push) Waiting to run
Tests / test (1) (push) Waiting to run
Tests / test (2) (push) Waiting to run
Tests / test (3) (push) Waiting to run
Tests / test (4) (push) Waiting to run
Tests / test (5) (push) Waiting to run
Tests / test (6) (push) Waiting to run
Tests / save-durations (push) Blocked by required conditions
Tests / e2e (push) Waiting to run
uv.lock check / uv lock --check (push) Waiting to run
Follow-up to Ben's PR #37892. Adds a TestInternalCredential block to test_dashboard_auth_ws_tickets.py exercising the mint-once stability, multi-use, unminted-rejection, empty-value, wrong-value, reset-and-remint, and ticket-store-independence branches directly (previously only covered indirectly via _ws_auth_ok, which left the unminted and empty-value branches unexercised). Also corrects the consume_internal_credential docstring: the returned identity dict is discarded by the current _ws_auth_ok caller (which only needs the boolean outcome), so the prior 'carry it into its session log' wording over-promised.
This commit is contained in:
parent
fd1ec8033d
commit
e114b31eda
2 changed files with 75 additions and 3 deletions
|
|
@ -131,9 +131,11 @@ def consume_internal_credential(value: str) -> Dict[str, Any]:
|
|||
|
||||
Unlike :func:`consume_ticket` this is **not** single-use — the value is
|
||||
not removed on success, so a server-spawned child can present it on every
|
||||
(re)connect. Returns the fixed server-internal identity ``info`` dict so
|
||||
the WS handler can carry it into its session log, mirroring the shape
|
||||
``consume_ticket`` returns.
|
||||
(re)connect. Returns the fixed server-internal identity ``info`` dict
|
||||
(``{user_id, provider}``), mirroring the ``info`` shape ``consume_ticket``
|
||||
returns, so a caller that wants to record the connecting identity can; the
|
||||
current ``_ws_auth_ok`` caller validates for the boolean outcome only and
|
||||
discards the dict.
|
||||
|
||||
A constant-time compare against the (lazily-minted) credential avoids
|
||||
leaking length / prefix information on mismatch. If no internal
|
||||
|
|
|
|||
|
|
@ -159,3 +159,73 @@ class TestConcurrency:
|
|||
assert len(results) == 20
|
||||
# Every consume returns a distinct user_id (no cross-thread bleed).
|
||||
assert {r["user_id"] for r in results} == {f"u{i}" for i in range(20)}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Process-lifetime internal credential (server-spawned PTY child auth).
|
||||
# Direct unit coverage for internal_ws_credential / consume_internal_credential
|
||||
# — _ws_auth_ok exercises these indirectly, but the mint-once, unminted, and
|
||||
# empty-value branches are only reachable via direct calls.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestInternalCredential:
|
||||
def test_minted_once_is_stable(self):
|
||||
"""Successive calls return the same process-lifetime value."""
|
||||
first = ws_tickets.internal_ws_credential()
|
||||
second = ws_tickets.internal_ws_credential()
|
||||
assert first == second
|
||||
assert len(first) >= 32 # token_urlsafe(32)
|
||||
|
||||
def test_round_trip_identity(self):
|
||||
cred = ws_tickets.internal_ws_credential()
|
||||
info = ws_tickets.consume_internal_credential(cred)
|
||||
assert info["user_id"] == ws_tickets.INTERNAL_USER_ID
|
||||
assert info["provider"] == ws_tickets.INTERNAL_PROVIDER
|
||||
|
||||
def test_multi_use(self):
|
||||
"""Unlike a single-use ticket, the credential survives repeated consume."""
|
||||
cred = ws_tickets.internal_ws_credential()
|
||||
for _ in range(5):
|
||||
assert (
|
||||
ws_tickets.consume_internal_credential(cred)["provider"]
|
||||
== ws_tickets.INTERNAL_PROVIDER
|
||||
)
|
||||
|
||||
def test_rejected_before_mint(self):
|
||||
"""With nothing minted yet, any value is rejected (expected is None)."""
|
||||
# autouse _reset leaves _internal_credential == None at test start.
|
||||
with pytest.raises(TicketInvalid):
|
||||
ws_tickets.consume_internal_credential("anything")
|
||||
|
||||
def test_empty_value_rejected(self):
|
||||
ws_tickets.internal_ws_credential() # mint so expected is non-None
|
||||
with pytest.raises(TicketInvalid):
|
||||
ws_tickets.consume_internal_credential("")
|
||||
|
||||
def test_wrong_value_rejected(self):
|
||||
ws_tickets.internal_ws_credential()
|
||||
with pytest.raises(TicketInvalid):
|
||||
ws_tickets.consume_internal_credential("not-the-credential")
|
||||
|
||||
def test_reset_clears_and_remints(self):
|
||||
first = ws_tickets.internal_ws_credential()
|
||||
_reset_for_tests()
|
||||
# The old value no longer validates after reset.
|
||||
with pytest.raises(TicketInvalid):
|
||||
ws_tickets.consume_internal_credential(first)
|
||||
# A fresh mint produces a different value.
|
||||
second = ws_tickets.internal_ws_credential()
|
||||
assert second != first
|
||||
assert ws_tickets.consume_internal_credential(second)["user_id"] == (
|
||||
ws_tickets.INTERNAL_USER_ID
|
||||
)
|
||||
|
||||
def test_independent_of_ticket_store(self):
|
||||
"""The internal credential is not a ticket — minting tickets doesn't
|
||||
touch it, and consuming the credential doesn't consume tickets."""
|
||||
cred = ws_tickets.internal_ws_credential()
|
||||
ticket = mint_ticket(user_id="u1", provider="nous")
|
||||
# Consuming the internal credential leaves the ticket intact.
|
||||
ws_tickets.consume_internal_credential(cred)
|
||||
assert consume_ticket(ticket)["user_id"] == "u1"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue