package model import ( "encoding/json" "strings" "testing" "time" ) func TestWeatherOutlookJSONShape(t *testing.T) { updatedAt := time.Date(2026, 6, 11, 16, 30, 0, 0, time.UTC) run := WeatherOutlookRun{ AsOf: time.Date(2026, 6, 11, 19, 45, 0, 0, time.UTC), Outlooks: []WeatherOutlook{{ ID: "outlook-1", Provider: "spc", Product: "convective", Day: 1, OutlookType: "categorical", Label: "SLGT", ValidFrom: time.Date(2026, 6, 11, 13, 0, 0, 0, time.UTC), ValidTo: time.Date(2026, 6, 12, 12, 0, 0, 0, time.UTC), IssuedAt: time.Date(2026, 6, 11, 12, 34, 56, 0, time.UTC), ExpiresAt: time.Date(2026, 6, 12, 12, 0, 0, 0, time.UTC), ContainsLocation: true, Geometry: json.RawMessage(`{"type":"Polygon","coordinates":[[[-91,38],[-90,38],[-90,39],[-91,39],[-91,38]]]}`), }}, Discussions: []WeatherOutlookDiscussion{{ Day: 1, Headline: "Day 1 Convective Outlook", Summary: "Severe thunderstorms are possible.", Discussion: "Full discussion text.", UpdatedAt: &updatedAt, }}, } raw, err := json.Marshal(run) if err != nil { t.Fatalf("Marshal(WeatherOutlookRun) error = %v", err) } got := string(raw) for _, want := range []string{`"outlooks"`, `"discussions"`, `"headline"`, `"summary"`, `"discussion"`, `"updatedAt"`} { if !strings.Contains(got, want) { t.Fatalf("WeatherOutlookRun JSON missing %s: %s", want, got) } } outlookStart := strings.Index(got, `"outlooks"`) discussionStart := strings.Index(got, `"discussions"`) if outlookStart == -1 || discussionStart == -1 || discussionStart <= outlookStart { t.Fatalf("WeatherOutlookRun JSON has unexpected outlook/discussion order: %s", got) } outlookJSON := got[outlookStart:discussionStart] for _, unwanted := range []string{`"headline"`, `"summary"`, `"discussion"`} { if strings.Contains(outlookJSON, unwanted) { t.Fatalf("WeatherOutlook JSON contains polygon-level prose key %s: %s", unwanted, got) } } }