All checks were successful
ci/woodpecker/push/build-image Pipeline was successful
91 lines
2.8 KiB
Go
91 lines
2.8 KiB
Go
package nws
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.maximumdirect.net/ejr/feedkit/event"
|
|
"gitea.maximumdirect.net/ejr/weatherfeeder/standards"
|
|
)
|
|
|
|
func TestBuildHourlyForecastUsesShortForecastAsTextDescription(t *testing.T) {
|
|
parsed := nwsHourlyForecastResponse{}
|
|
parsed.Properties.GeneratedAt = "2026-03-16T18:00:00Z"
|
|
parsed.Properties.Periods = []nwsHourlyForecastPeriod{
|
|
{
|
|
StartTime: "2026-03-16T19:00:00Z",
|
|
EndTime: "2026-03-16T20:00:00Z",
|
|
ShortForecast: " Mostly Cloudy ",
|
|
DetailedForecast: "Clouds increasing overnight.",
|
|
Icon: "https://example.invalid/icon",
|
|
},
|
|
}
|
|
|
|
run, effectiveAt, err := buildHourlyForecast(parsed)
|
|
if err != nil {
|
|
t.Fatalf("buildHourlyForecast() error = %v", err)
|
|
}
|
|
if len(run.Periods) != 1 {
|
|
t.Fatalf("periods len = %d, want 1", len(run.Periods))
|
|
}
|
|
if got, want := run.Periods[0].TextDescription, "Mostly Cloudy"; got != want {
|
|
t.Fatalf("TextDescription = %q, want %q", got, want)
|
|
}
|
|
|
|
wantIssued := time.Date(2026, 3, 16, 18, 0, 0, 0, time.UTC)
|
|
if !run.IssuedAt.Equal(wantIssued) {
|
|
t.Fatalf("IssuedAt = %s, want %s", run.IssuedAt.Format(time.RFC3339), wantIssued.Format(time.RFC3339))
|
|
}
|
|
if !effectiveAt.Equal(wantIssued) {
|
|
t.Fatalf("effectiveAt = %s, want %s", effectiveAt.Format(time.RFC3339), wantIssued.Format(time.RFC3339))
|
|
}
|
|
|
|
assertNoLegacyForecastDescriptionKeys(t, run.Periods[0])
|
|
}
|
|
|
|
func TestNormalizeForecastEventBySchemaRejectsUnsupportedSchema(t *testing.T) {
|
|
_, err := normalizeForecastEventBySchema(event.Event{
|
|
Schema: "raw.nws.daily.forecast.v1",
|
|
})
|
|
if err == nil {
|
|
t.Fatalf("normalizeForecastEventBySchema() expected unsupported schema error")
|
|
}
|
|
if !strings.Contains(err.Error(), "unsupported nws forecast schema") {
|
|
t.Fatalf("error = %q, want unsupported schema context", err)
|
|
}
|
|
}
|
|
|
|
func TestNormalizeForecastEventBySchemaRoutesHourly(t *testing.T) {
|
|
_, err := normalizeForecastEventBySchema(event.Event{
|
|
Schema: standards.SchemaRawNWSHourlyForecastV1,
|
|
Payload: map[string]any{"properties": map[string]any{}},
|
|
})
|
|
if err == nil {
|
|
t.Fatalf("normalizeForecastEventBySchema() expected build error for missing generatedAt")
|
|
}
|
|
if !strings.Contains(err.Error(), "missing properties.generatedAt") {
|
|
t.Fatalf("error = %q, want missing properties.generatedAt", err)
|
|
}
|
|
}
|
|
|
|
func assertNoLegacyForecastDescriptionKeys(t *testing.T, period any) {
|
|
t.Helper()
|
|
|
|
b, err := json.Marshal(period)
|
|
if err != nil {
|
|
t.Fatalf("json.Marshal(period) error = %v", err)
|
|
}
|
|
var got map[string]any
|
|
if err := json.Unmarshal(b, &got); err != nil {
|
|
t.Fatalf("json.Unmarshal(period) error = %v", err)
|
|
}
|
|
|
|
for _, key := range []string{"conditionText", "providerRawDescription", "detailedText", "iconUrl"} {
|
|
if _, ok := got[key]; ok {
|
|
t.Fatalf("unexpected legacy key %q in marshaled period: %#v", key, got)
|
|
}
|
|
}
|
|
}
|