package services import ( "encoding/json" "strings" "testing" "git.saqut.com/saqut/mwse/internal/testutil" ) // findReply scans the captured frames for a [payload, id] frame whose id slot is // the given number. This is how a peer's response/to answer reaches the original // requester: the numeric request id sits in the signal slot so the SDK's event // pool resolves the matching pending promise. func findReply(fc *testutil.FakeConn, id float64) (map[string]any, bool) { for _, raw := range fc.Writes() { var arr []any if json.Unmarshal(raw, &arr) != nil || len(arr) < 2 { continue } if n, ok := arr[1].(float64); ok && n == id { payload, _ := arr[0].(map[string]any) return payload, true } } return nil, false } // TestRequestResponseRoundTrip is the #30 (data tunneling) + #33 (WOM) core: a // request/to is answered out-of-band by the peer's response/to carrying the same // id. The request/to handler itself must return nil so the engine sends no // premature reply that would clobber the pending request. func TestRequestResponseRoundTrip(t *testing.T) { hub := newHub() a, fa := connect(hub, "a") b, fb := connect(hub, "b") // a sends a request to b with request id 7. if r := hub.Handle(a, msg("request/to", "to", "b", "pack", map[string]any{"q": "ping"})); r != nil { t.Fatalf("request/to must return nil (answered out-of-band), got %v", r) } // b receives the request signal, with a's id and the payload, but NO source IP. req := waitSignal(t, fb, "request") if req["from"] != "a" { t.Fatalf("request from = %v, want a", req["from"]) } assertNoAddressLeak(t, req) // b answers with response/to using the original request id. if r := hub.Handle(b, msg("response/to", "to", "a", "id", float64(7), "pack", map[string]any{"a": "pong"})); r != nil { t.Fatalf("response/to must return nil, got %v", r) } // a receives [ {from:"b", pack:{a:"pong"}}, 7 ] — resolving request id 7. waitFor(t, func() bool { _, ok := findReply(fa, 7); return ok }) ans, _ := findReply(fa, 7) if ans["from"] != "b" { t.Fatalf("answer from = %v, want b", ans["from"]) } pack := asMap(t, ans["pack"]) if pack["a"] != "pong" { t.Fatalf("answer pack = %v, want {a:pong}", pack) } _ = b } // TestTunnelDoesNotLeakSourceAddress verifies the virtualization requirement of // #30: a relayed pack carries only the logical sender id and the payload, never // the sender's real IP or device type. func TestTunnelDoesNotLeakSourceAddress(t *testing.T) { hub := newHub() a, _ := connect(hub, "a") _, fb := connect(hub, "b") hub.Handle(a, msg("pack/to", "to", "b", "pack", map[string]any{"hi": true})) got := waitSignal(t, fb, "pack") assertNoAddressLeak(t, got) if got["from"] != "a" { t.Fatalf("pack from = %v, want a", got["from"]) } } // TestTunnelLargePayloadIntact verifies #30's large-payload requirement: a big // pack is relayed byte-for-byte (the engine never truncates or mangles it). The // transport's MaxMessageSize default (16 MiB) comfortably covers chunked file // transfer frames. func TestTunnelLargePayloadIntact(t *testing.T) { hub := newHub() a, _ := connect(hub, "a") _, fb := connect(hub, "b") big := strings.Repeat("x", 1<<20) // 1 MiB chunk hub.Handle(a, msg("pack/to", "to", "b", "pack", map[string]any{"chunk": big})) got := waitSignal(t, fb, "pack") pack := asMap(t, got["pack"]) if s, _ := pack["chunk"].(string); len(s) != len(big) { t.Fatalf("relayed chunk length = %d, want %d", len(s), len(big)) } } // assertNoAddressLeak fails if a relayed payload exposes anything resembling the // sender's real network identity. func assertNoAddressLeak(t *testing.T, payload map[string]any) { t.Helper() for _, k := range []string{"ip", "address", "remoteAddr", "host", "device", "deviceType"} { if _, ok := payload[k]; ok { t.Fatalf("relayed payload leaked %q: %v", k, payload) } } }