Implemented the weather forecast discussion product from weatherfeeder v0.8.3
All checks were successful
ci/woodpecker/push/build-image Pipeline was successful

This commit is contained in:
2026-03-28 17:36:35 -05:00
parent 291a9178c8
commit 0bccfc50d9
18 changed files with 651 additions and 3 deletions

View File

@@ -6,6 +6,8 @@ import (
"database/sql"
"testing"
"time"
"gitea.maximumdirect.net/ejr/weatherfeeder/model"
)
func TestMapObservationParentRowNullables(t *testing.T) {
@@ -84,6 +86,65 @@ func TestMapForecastPeriodRowNullables(t *testing.T) {
}
}
func TestMapDiscussionParentRowNullables(t *testing.T) {
issuedAt := time.Date(2026, 3, 28, 19, 24, 0, 0, time.FixedZone("CDT", -5*3600))
updatedAt := issuedAt.Add(time.Hour)
shortIssuedAt := issuedAt.Add(-5 * time.Minute)
discussion := mapDiscussionParentRow(discussionParentRow{
OfficeID: sql.NullString{String: "LSX", Valid: true},
OfficeName: sql.NullString{String: "National Weather Service Saint Louis MO", Valid: true},
IssuedAt: issuedAt,
UpdatedAt: sql.NullTime{Time: updatedAt, Valid: true},
Product: "afd",
ShortTermQualifier: sql.NullString{String: "(Tonight)", Valid: true},
ShortTermIssuedAt: sql.NullTime{Time: shortIssuedAt, Valid: true},
ShortTermText: sql.NullString{String: "Short term text", Valid: true},
})
if discussion.OfficeID != "LSX" {
t.Fatalf("expected office id LSX, got %q", discussion.OfficeID)
}
if discussion.Product != model.ForecastDiscussionProductAFD {
t.Fatalf("expected product afd, got %q", discussion.Product)
}
if discussion.UpdatedAt == nil || discussion.UpdatedAt.Location().String() != "UTC" {
t.Fatalf("expected updatedAt to be UTC-normalized, got %v", discussion.UpdatedAt)
}
if discussion.ShortTerm == nil {
t.Fatalf("expected shortTerm section to be populated")
}
if discussion.ShortTerm.Qualifier != "(Tonight)" || discussion.ShortTerm.Text != "Short term text" {
t.Fatalf("unexpected shortTerm section: %+v", discussion.ShortTerm)
}
if discussion.LongTerm != nil {
t.Fatalf("expected longTerm nil, got %+v", discussion.LongTerm)
}
}
func TestMapDiscussionSectionNilWhenAllFieldsMissing(t *testing.T) {
got := discussionSectionPtr(sql.NullString{}, sql.NullTime{}, sql.NullString{})
if got != nil {
t.Fatalf("expected nil discussion section, got %+v", got)
}
}
func TestMapDiscussionKeyMessagesPreserveOrder(t *testing.T) {
rows := []discussionKeyMessageRow{
{MessageIndex: 0, MessageText: sql.NullString{String: "first", Valid: true}},
{MessageIndex: 1, MessageText: sql.NullString{String: "second", Valid: true}},
}
got := make([]string, 0, len(rows))
for _, row := range rows {
got = append(got, mapDiscussionKeyMessageRow(row))
}
if len(got) != 2 || got[0] != "first" || got[1] != "second" {
t.Fatalf("unexpected key message order: %#v", got)
}
}
func TestAttachAlertReferencesPreservesOrder(t *testing.T) {
sent1 := time.Date(2026, 3, 20, 1, 0, 0, 0, time.UTC)
sent2 := sent1.Add(10 * time.Minute)