package lagoon import ( "encoding/json" "strings" "testing" ) // hiddenMarshalFixture covers the HasHidden contract inside the framework // module. Enumerating fonoteka.go plugin models.All() from this package // would import the application into summercms.go, which CLAUDE.md forbids; // that registry walk lives in fonoteka.go (classes.TestHiddenNeverMarshals). type hiddenMarshalFixture struct { Name string `gorm:"column:name" json:"name"` CollectionID uint `gorm:"column:collection_id" json:"collection_id"` Secret string `gorm:"column:secret" json:"-"` } func (hiddenMarshalFixture) Hidden() []string { return []string{"secret"} } func TestHiddenNeverMarshals(t *testing.T) { row := hiddenMarshalFixture{Name: "ok", CollectionID: 3, Secret: hiddenSentinel} raw, err := json.Marshal(row) if err != nil { t.Fatal(err) } if strings.Contains(string(raw), hiddenSentinel) { t.Fatalf("hidden sentinel leaked: %s", raw) } var payload map[string]any if err := json.Unmarshal(raw, &payload); err != nil { t.Fatal(err) } if _, ok := payload["secret"]; ok { t.Fatalf("json:\"-\" field present: %s", raw) } if payload["name"] != "ok" { t.Fatalf("visible field missing: %s", raw) } } const hiddenSentinel = "HIDDEN-SENTINEL-05-06"