package weatherdata import ( "encoding/json" "testing" "time" ) func TestConvectiveOutlookRunJSONPreservesGeometry(t *testing.T) { severity := 3 validFrom := mustParseBundleTime("2026-06-12T13:00:00Z") validTo := mustParseBundleTime("2026-06-13T12:00:00Z") issuedAt := mustParseBundleTime("2026-06-12T12:30:00Z") updatedAt := mustParseBundleTime("2026-06-12T12:45:00Z") run := ConvectiveOutlookRun{ LocationID: "test-grid", LocationName: "Brentwood", AsOf: &updatedAt, IssuedAt: &issuedAt, Product: "convective_outlook", Outlooks: []ConvectiveOutlook{{ ID: "day1-categorical-slight", Provider: "spc", Product: "convective_outlook", Day: 1, OutlookType: "categorical", Label: "SLGT", LabelText: "Slight Risk", Forecaster: "Smith", SeverityRank: &severity, ValidFrom: validFrom, ValidTo: validTo, IssuedAt: &issuedAt, ExpiresAt: &validTo, SourceURL: "https://example.test/source", ImageURL: "https://example.test/image.png", ContainsLocation: true, Geometry: json.RawMessage(`{"type":"Polygon","coordinates":[[[-90.1,38.1],[-90.0,38.2],[-90.1,38.1]]]}`), }}, Discussions: []ConvectiveOutlookDiscussion{{ Day: 1, Headline: "Severe storms possible", Summary: "Scattered severe storms are possible.", Discussion: "Discussion text.", UpdatedAt: &updatedAt, }}, } data, err := json.Marshal(run) if err != nil { t.Fatalf("Marshal() error = %v", err) } var decoded ConvectiveOutlookRun if err := json.Unmarshal(data, &decoded); err != nil { t.Fatalf("Unmarshal() error = %v", err) } if len(decoded.Outlooks) != 1 || string(decoded.Outlooks[0].Geometry) == "" { t.Fatalf("decoded outlooks = %#v, want preserved geometry", decoded.Outlooks) } if got := string(decoded.Outlooks[0].Geometry); got != `{"type":"Polygon","coordinates":[[[-90.1,38.1],[-90.0,38.2],[-90.1,38.1]]]}` { t.Fatalf("Geometry = %s, want preserved GeoJSON coordinates", got) } if decoded.Outlooks[0].SeverityRank == nil || *decoded.Outlooks[0].SeverityRank != severity { t.Fatalf("SeverityRank = %#v, want %d", decoded.Outlooks[0].SeverityRank, severity) } if len(decoded.Discussions) != 1 || decoded.Discussions[0].Headline != "Severe storms possible" { t.Fatalf("Discussions = %#v, want decoded discussion", decoded.Discussions) } } func mustParseBundleTime(value string) time.Time { parsed, err := time.Parse(time.RFC3339, value) if err != nil { panic(err) } return parsed }