fix(market): marshal empty merge-plan buckets as [] not null
Nil slices in MergePlan.AutoApply/ReviewRequired/Rejected serialized to JSON null, causing the admin research panel to crash with "can't access property 'map', plan.review_required is null". Initialize the buckets as empty slices so the wire contract is always an array. Tightened the empty-buckets test to assert the JSON shape.
This commit is contained in:
@@ -145,8 +145,11 @@ func PlanMerge(m Market, r ResearchResult) MergePlan {
|
||||
}
|
||||
}
|
||||
|
||||
// Assign decisions.
|
||||
var autoApply, reviewRequired, rejected []FieldMerge
|
||||
// Assign decisions. Initialize as empty (not nil) so empty buckets
|
||||
// marshal to [] instead of null — the web UI calls .map() on them.
|
||||
autoApply := []FieldMerge{}
|
||||
reviewRequired := []FieldMerge{}
|
||||
rejected := []FieldMerge{}
|
||||
|
||||
for _, vs := range validated {
|
||||
fm := FieldMerge{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package market
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -177,6 +179,20 @@ func TestPlanMerge(t *testing.T) {
|
||||
if len(plan.AutoApply) != 0 || len(plan.ReviewRequired) != 0 || len(plan.Rejected) != 0 {
|
||||
t.Error("expected all buckets empty for empty suggestions")
|
||||
}
|
||||
|
||||
// Buckets must marshal to JSON arrays, never null — the web UI calls
|
||||
// .map() on them and crashes on null. Go's encoding/json renders nil
|
||||
// slices as null, so PlanMerge must return non-nil empty slices.
|
||||
raw, err := json.Marshal(plan)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal plan: %v", err)
|
||||
}
|
||||
got := string(raw)
|
||||
for _, key := range []string{`"auto_apply":null`, `"review_required":null`, `"rejected":null`} {
|
||||
if strings.Contains(got, key) {
|
||||
t.Errorf("plan JSON contains %s; expected []. Got: %s", key, got)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user