From afb65c220197bac316c007fa6bcf819fe33e20e2 Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 29 Aug 2026 15:38:33 +0200 Subject: [PATCH] A contract test for the token's field names The host defines the same wire format separately, because it requires nothing present and does not import this. A test on each side asserts the exact field names, so renaming one breaks both immediately rather than at enrolment on a real machine. --- internal/token/token_test.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/internal/token/token_test.go b/internal/token/token_test.go index 8fbfa16..86b8f10 100644 --- a/internal/token/token_test.go +++ b/internal/token/token_test.go @@ -2,6 +2,7 @@ package token import ( "crypto/ed25519" + "encoding/json" "strings" "testing" ) @@ -116,3 +117,26 @@ func mustDecodeBase64(t *testing.T, s string) []byte { } return raw } + +func TestTheWireFormatIsExactlyTheseFieldNames(t *testing.T) { + // The contract with the host, which defines this format separately because it requires + // nothing present and does not import this (novox/hq ADR 0005). There is a matching test on + // that side. Rename a field on either and both fail — the alternative is a rename that only + // shows up at enrolment, on a real machine. + raw, err := json.Marshal(complete(t)) + if err != nil { + t.Fatal(err) + } + var fields map[string]any + if err := json.Unmarshal(raw, &fields); err != nil { + t.Fatal(err) + } + for _, want := range []string{"v", "broker", "fingerprint", "signer", "secret"} { + if _, ok := fields[want]; !ok { + t.Errorf("the token has no %q field; the host reads that name", want) + } + } + if len(fields) != 5 { + t.Errorf("the token has %d fields, expected 5: %v", len(fields), fields) + } +}