ui/phase-24: declare game.turn.ready as JSON-friendly catalog kind
ui-test / test (push) Failing after 40s

TestBuildClientPushEventCoversCatalog required every catalog kind to
encode through a FlatBuffers `preMarshaledEvent`. game.turn.ready
intentionally rides on the JSON fallback because its payload is just
`{game_id, turn}` and the only consumer (Phase 24 UI handler) parses
JSON inline. Make the policy explicit through a jsonFriendlyKinds
allow-list so the test still asserts each kind is covered and a future
producer that picks the wrong encoding fails loudly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Ilia Denisov
2026-05-11 17:27:29 +02:00
parent 5b07bb4e14
commit bbdcc36e05
+26 -4
View File
@@ -9,9 +9,25 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
) )
// jsonFriendlyKinds lists catalog kinds whose payload is small and
// stable enough that the gateway-bound encoding stays JSON instead of
// FlatBuffers. The default for new producers is still FB; declaring a
// kind here is a deliberate decision baked into the build target's
// payload contract.
//
// `game.turn.ready` ships `{game_id, turn}` only, the UI parses it
// inline in `routes/games/[id]/+layout.svelte` (Phase 24), and no
// other consumer reads the payload — adopting the FB encoder would
// require a new TS notification stub set and the regen tooling for
// `pkg/schema/fbs/notification.fbs` without buying anything.
var jsonFriendlyKinds = map[string]bool{
KindGameTurnReady: true,
}
// TestBuildClientPushEventCoversCatalog asserts that every catalog kind // TestBuildClientPushEventCoversCatalog asserts that every catalog kind
// returns a typed FB event (preMarshaledEvent) and that an unknown kind // is exercised by this test, that FB-typed kinds return a
// falls through to the JSON safety net. // `preMarshaledEvent`, and that JSON-friendly kinds (see
// `jsonFriendlyKinds` above) return a `push.JSONEvent`.
func TestBuildClientPushEventCoversCatalog(t *testing.T) { func TestBuildClientPushEventCoversCatalog(t *testing.T) {
t.Parallel() t.Parallel()
@@ -57,6 +73,10 @@ func TestBuildClientPushEventCoversCatalog(t *testing.T) {
"game_id": gameID.String(), "game_id": gameID.String(),
"reason": "missing engine version", "reason": "missing engine version",
}}, }},
{"game turn ready", KindGameTurnReady, map[string]any{
"game_id": gameID.String(),
"turn": int32(7),
}},
} }
seenKinds := map[string]bool{} seenKinds := map[string]bool{}
@@ -78,8 +98,10 @@ func TestBuildClientPushEventCoversCatalog(t *testing.T) {
if len(bytes) == 0 { if len(bytes) == 0 {
t.Fatalf("Marshal returned empty bytes") t.Fatalf("Marshal returned empty bytes")
} }
if _, isJSON := event.(push.JSONEvent); isJSON { _, isJSON := event.(push.JSONEvent)
t.Fatalf("expected typed FB event for %s, got JSONEvent", tt.kind) wantJSON := jsonFriendlyKinds[tt.kind]
if isJSON != wantJSON {
t.Fatalf("kind %s: JSONEvent=%v, want JSONEvent=%v", tt.kind, isJSON, wantJSON)
} }
}) })
seenKinds[tt.kind] = true seenKinds[tt.kind] = true