Initial MVP commit
This commit is contained in:
112
internal/adapters/outbound/postgres/repository_test.go
Normal file
112
internal/adapters/outbound/postgres/repository_test.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestMapObservationParentRowNullables(t *testing.T) {
|
||||
observedAt := time.Date(2026, 3, 19, 23, 45, 0, 0, time.FixedZone("CST", -6*3600))
|
||||
isDay := true
|
||||
temp := 18.25
|
||||
|
||||
obs := mapObservationParentRow(observationParentRow{
|
||||
StationID: sql.NullString{String: "KSTL", Valid: true},
|
||||
StationName: sql.NullString{String: "St. Louis", Valid: true},
|
||||
ObservedAt: observedAt,
|
||||
ConditionCode: 2,
|
||||
IsDay: sql.NullBool{Bool: isDay, Valid: true},
|
||||
TemperatureC: sql.NullFloat64{Float64: temp, Valid: true},
|
||||
TextDescription: sql.NullString{String: "Partly Cloudy", Valid: true},
|
||||
})
|
||||
|
||||
if obs.StationID != "KSTL" {
|
||||
t.Fatalf("expected station id KSTL, got %q", obs.StationID)
|
||||
}
|
||||
if obs.IsDay == nil || !*obs.IsDay {
|
||||
t.Fatalf("expected isDay pointer true, got %v", obs.IsDay)
|
||||
}
|
||||
if obs.TemperatureC == nil || *obs.TemperatureC != temp {
|
||||
t.Fatalf("expected temperature %v, got %v", temp, obs.TemperatureC)
|
||||
}
|
||||
if obs.DewpointC != nil {
|
||||
t.Fatalf("expected nil dewpoint, got %v", *obs.DewpointC)
|
||||
}
|
||||
if got := obs.Timestamp.Location().String(); got != "UTC" {
|
||||
t.Fatalf("expected UTC timestamp, got %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapObservationPresentWeatherRow(t *testing.T) {
|
||||
row := observationPresentWeatherRow{
|
||||
WeatherIndex: 1,
|
||||
RawText: sql.NullString{String: `{"code":61,"text":"rain"}`, Valid: true},
|
||||
}
|
||||
|
||||
pw, err := mapObservationPresentWeatherRow(row)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if pw.Raw == nil {
|
||||
t.Fatalf("expected raw map to be populated")
|
||||
}
|
||||
if got, ok := pw.Raw["text"].(string); !ok || got != "rain" {
|
||||
t.Fatalf("expected raw text rain, got %#v", pw.Raw["text"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapForecastPeriodRowNullables(t *testing.T) {
|
||||
start := time.Date(2026, 3, 20, 0, 0, 0, 0, time.UTC)
|
||||
end := start.Add(1 * time.Hour)
|
||||
period := mapForecastPeriodRow(forecastPeriodRow{
|
||||
StartTime: start,
|
||||
EndTime: end,
|
||||
ConditionCode: 80,
|
||||
Name: sql.NullString{String: "Midnight", Valid: true},
|
||||
TemperatureC: sql.NullFloat64{Float64: 12.5, Valid: true},
|
||||
TemperatureCMin: sql.NullFloat64{Valid: false},
|
||||
})
|
||||
|
||||
if period.Name != "Midnight" {
|
||||
t.Fatalf("expected period name Midnight, got %q", period.Name)
|
||||
}
|
||||
if period.TemperatureC == nil || *period.TemperatureC != 12.5 {
|
||||
t.Fatalf("expected temperature pointer 12.5, got %v", period.TemperatureC)
|
||||
}
|
||||
if period.TemperatureCMin != nil {
|
||||
t.Fatalf("expected nil TemperatureCMin, got %v", *period.TemperatureCMin)
|
||||
}
|
||||
if !period.StartTime.Equal(start) || !period.EndTime.Equal(end) {
|
||||
t.Fatalf("unexpected time range: %s - %s", period.StartTime, period.EndTime)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttachAlertReferencesPreservesOrder(t *testing.T) {
|
||||
sent1 := time.Date(2026, 3, 20, 1, 0, 0, 0, time.UTC)
|
||||
sent2 := sent1.Add(10 * time.Minute)
|
||||
|
||||
alerts := []indexedAlert{
|
||||
{Index: 4, Alert: mapAlertRow(alertRow{AlertIndex: 4, AlertID: "a-4"}).Alert},
|
||||
{Index: 9, Alert: mapAlertRow(alertRow{AlertIndex: 9, AlertID: "a-9"}).Alert},
|
||||
}
|
||||
references := []indexedAlertReference{
|
||||
mapAlertReferenceRow(alertReferenceRow{AlertIndex: 4, Identifier: sql.NullString{String: "r1", Valid: true}, Sent: sql.NullTime{Time: sent1, Valid: true}}),
|
||||
mapAlertReferenceRow(alertReferenceRow{AlertIndex: 4, Identifier: sql.NullString{String: "r2", Valid: true}, Sent: sql.NullTime{Time: sent2, Valid: true}}),
|
||||
mapAlertReferenceRow(alertReferenceRow{AlertIndex: 9, Identifier: sql.NullString{String: "r9", Valid: true}}),
|
||||
}
|
||||
|
||||
out := attachAlertReferences(alerts, references)
|
||||
if len(out) != 2 {
|
||||
t.Fatalf("expected 2 alerts, got %d", len(out))
|
||||
}
|
||||
if len(out[0].References) != 2 {
|
||||
t.Fatalf("expected first alert to have 2 references, got %d", len(out[0].References))
|
||||
}
|
||||
if out[0].References[0].Identifier != "r1" || out[0].References[1].Identifier != "r2" {
|
||||
t.Fatalf("unexpected first alert reference order: %+v", out[0].References)
|
||||
}
|
||||
if len(out[1].References) != 1 || out[1].References[0].Identifier != "r9" {
|
||||
t.Fatalf("unexpected second alert references: %+v", out[1].References)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user