test/refactor(audio-rooms): nostrnests wire-shape fixes + interop expansion (phase 4)

Wire-shape corrections discovered while scoping the interop test suite
against the real moq-rs relay:

  1. WebTransport CONNECT path is now /<moqNamespace> (matches the
     relay's claims.root prefix check). Previously hardcoded "/anon".
  2. JWT travels in the ?jwt=<token> query parameter, not the
     Authorization header — moq-rs only reads the query param. The
     bearer-token path on QuicWebTransportFactory is now unused for
     nests; left in place for non-nests WebTransport servers.
  3. Harness `moqEndpoint` is the relay base URL only; the connect
     helpers append /<namespace>?jwt=<token> themselves.

Interop test additions (all -DnestsInterop=true gated, default-skipped):

  - NostrNestsAuthFailureInteropTest — locks in the moq-auth sidecar's
    rejection paths (missing/wrong-scheme Authorization, NIP-98 signed
    for the wrong URL, malformed namespace per the strict regex,
    publish=true grant for any caller — sidecar does NOT gate by NIP-53
    hostlist).
  - NostrNestsAuthEndpointsInteropTest — /health, /.well-known/jwks.json
    shape (must contain ES256/P-256), 404 on unknown route.
  - NostrNestsMultiPeerInteropTest — multi-listener fan-out, multi-
    speaker isolation, subscribe-before-announce. Code is wired through
    production connectNestsSpeaker / connectNestsListener; will pass
    once the moq-lite gap (below) is resolved.

Major finding documented in nestsClient/plans/2026-04-26-moq-lite-gap.md:
nostrnests's stack uses moq-lite (kixelated's variant), NOT IETF
draft-ietf-moq-transport which `:nestsClient` currently implements. The
two are wire-incompatible — single-string broadcast/track names vs. byte
tuples, different ANNOUNCE/SUBSCRIBE framing. The wire-shape fixes here
make the WebTransport CONNECT itself succeed, but the post-CONNECT MoQ
framing layer still needs a moq-lite codec before round-trip / multi-peer
tests can pass against real nests. Pursued as a separate phase.
This commit is contained in:
Claude
2026-04-26 15:53:02 +00:00
parent 0ac8c0f791
commit 1887bd1fa7
7 changed files with 910 additions and 10 deletions
@@ -79,8 +79,12 @@ class NestsConnectTest {
assertEquals(MoqVersion.DRAFT_17, connected.negotiatedMoqVersion)
assertEquals("relay.example.com", transport.lastConnectedAuthority)
assertEquals("/moq", transport.lastConnectedPath)
assertEquals("tok-abc", transport.lastBearer)
assertEquals(
"/${room.moqNamespace()}?jwt=tok-abc",
transport.lastConnectedPath,
"moq-rs treats the WT path as the namespace literal and reads the JWT from `?jwt=`",
)
assertEquals(null, transport.lastBearer, "JWT goes in the query param, not Authorization")
assertEquals(false, httpClient.lastPublishFlag, "listener mints with publish=false")