package cart import ( "encoding/json" "testing" ) func TestCartItem_FlattensDynamicKeys(t *testing.T) { item := CartItem{ Id: 7, Sku: "YD10050921H11406", Quantity: 2, Extra: map[string]json.RawMessage{ "glas": json.RawMessage(`"V"`), "hangning": json.RawMessage(`"H"`), "deliveryWeek": json.RawMessage(`10`), }, } b, err := json.Marshal(&item) if err != nil { t.Fatalf("marshal: %v", err) } var flat map[string]json.RawMessage if err := json.Unmarshal(b, &flat); err != nil { t.Fatalf("unmarshal to map: %v", err) } // Typed field present at top level. if _, ok := flat["sku"]; !ok { t.Error("expected typed key \"sku\" at top level") } // Dynamic keys flattened to top level (not nested under \"extra\"). for _, k := range []string{"glas", "hangning", "deliveryWeek"} { if _, ok := flat[k]; !ok { t.Errorf("expected dynamic key %q flattened to top level", k) } } if string(flat["glas"]) != `"V"` { t.Errorf("glas = %s, want \"V\"", flat["glas"]) } } func TestCartItem_RoundTrip(t *testing.T) { original := CartItem{ Id: 3, Sku: "ABC", Quantity: 1, Extra: map[string]json.RawMessage{ "color": json.RawMessage(`"red"`), "weight": json.RawMessage(`12.5`), }, } b, err := json.Marshal(&original) if err != nil { t.Fatalf("marshal: %v", err) } var got CartItem if err := json.Unmarshal(b, &got); err != nil { t.Fatalf("unmarshal: %v", err) } if got.Sku != original.Sku || got.Id != original.Id || got.Quantity != original.Quantity { t.Errorf("typed fields not preserved: got %+v", got) } if len(got.Extra) != 2 { t.Fatalf("Extra len = %d, want 2 (%v)", len(got.Extra), got.Extra) } if string(got.Extra["color"]) != `"red"` { t.Errorf("color = %s, want \"red\"", got.Extra["color"]) } // A typed key must never leak into Extra. if _, leaked := got.Extra["sku"]; leaked { t.Error("typed key \"sku\" leaked into Extra") } } func TestCartItem_NoExtraIsCompact(t *testing.T) { item := CartItem{Id: 1, Sku: "X", Quantity: 1} b, err := json.Marshal(&item) if err != nil { t.Fatalf("marshal: %v", err) } var flat map[string]json.RawMessage if err := json.Unmarshal(b, &flat); err != nil { t.Fatalf("unmarshal: %v", err) } if _, ok := flat["sku"]; !ok { t.Error("expected \"sku\" in output") } }