package provision import ( "encoding/json" "sort" "testing" ) // The bootstrap.json key set is a CROSS-REPO contract: it must match felhom-controller's // internal/bootstrap.Bootstrap exactly. This test pins the emitted key set; the controller's // bootstrap_test.go ingests the same shape. A drift here (or there) breaks provisioning. func TestDoc_ContractKeySet(t *testing.T) { d := Doc{ Schema: SchemaV1, Customer: DocCustomer{ID: "c", Name: "n", Domain: "d", Email: "e"}, Hub: DocHub{URL: "u", APIKey: "k", HostID: "h"}, LocalAPI: DocLocalAPI{Endpoint: "ep", Fingerprint: "fp", Token: "tok"}, } b, err := d.render() if err != nil { t.Fatal(err) } var m map[string]json.RawMessage if err := json.Unmarshal(b, &m); err != nil { t.Fatal(err) } assertKeys(t, "top", m, []string{"schema", "customer", "hub", "local_api"}) var full struct { Customer map[string]json.RawMessage `json:"customer"` Hub map[string]json.RawMessage `json:"hub"` LocalAPI map[string]json.RawMessage `json:"local_api"` } if err := json.Unmarshal(b, &full); err != nil { t.Fatal(err) } assertKeys(t, "customer", full.Customer, []string{"id", "name", "domain", "email"}) assertKeys(t, "hub", full.Hub, []string{"url", "api_key", "host_id"}) assertKeys(t, "local_api", full.LocalAPI, []string{"endpoint", "fingerprint", "token"}) if SchemaV1 != "felhom.bootstrap/v1" { t.Fatalf("schema drift: %q", SchemaV1) } } func assertKeys(t *testing.T, label string, m map[string]json.RawMessage, want []string) { t.Helper() got := make([]string, 0, len(m)) for k := range m { got = append(got, k) } sort.Strings(got) sort.Strings(want) if len(got) != len(want) { t.Fatalf("%s: key set %v, want %v", label, got, want) } for i := range want { if got[i] != want[i] { t.Fatalf("%s: key set %v, want %v", label, got, want) } } }