package cli import ( "errors" "testing" "time" "gitea.maximumdirect.net/eric/weatherreporter/internal/app" ) func TestReportDatePolicy(t *testing.T) { location, err := time.LoadLocation("America/New_York") if err != nil { t.Fatal(err) } now := time.Date(2026, 5, 30, 2, 30, 0, 0, time.UTC) for _, tt := range []struct { name string report app.ReportKind value string wantDay string wantErr error malformed bool }{ {name: "DailyRequiresDate", report: app.ReportDaily, wantErr: errReportDateRequired}, {name: "DailyParsesDate", report: app.ReportDaily, value: "2026-05-30", wantDay: "2026-05-30"}, {name: "TodayDefaultsInConfiguredTimezone", report: app.ReportToday, wantDay: "2026-05-29"}, {name: "TodayParsesDate", report: app.ReportToday, value: "2026-05-30", wantDay: "2026-05-30"}, {name: "TodayRejectsMalformedDate", report: app.ReportToday, value: "not-a-date", malformed: true}, {name: "TomorrowHasNoDate", report: app.ReportTomorrow}, {name: "TomorrowRejectsDate", report: app.ReportTomorrow, value: "2026-05-30", wantErr: errReportDateNotAccepted}, {name: "HourlyHasNoDate", report: app.ReportHourly}, {name: "HourlyRejectsDate", report: app.ReportHourly, value: "2026-05-30", wantErr: errReportDateNotAccepted}, } { t.Run(tt.name, func(t *testing.T) { date, err := resolveReportDate(tt.report, tt.value, location, now) if tt.malformed { if err == nil { t.Fatal("resolveReportDate() error = nil") } return } if tt.wantErr != nil { if !errors.Is(err, tt.wantErr) { t.Fatalf("resolveReportDate() error = %v, want %v", err, tt.wantErr) } return } if err != nil { t.Fatalf("resolveReportDate() error = %v", err) } if tt.wantDay == "" { if !date.IsZero() { t.Fatalf("resolveReportDate() = %v, want zero date", date) } return } if date.Location() != location || date.Format("2006-01-02") != tt.wantDay { t.Fatalf("resolveReportDate() = %v, want %s in %s", date, tt.wantDay, location) } }) } } func TestReportDateFlagsFollowPolicy(t *testing.T) { for _, tt := range []struct { report app.ReportKind acceptsDate bool }{ {report: app.ReportDaily, acceptsDate: true}, {report: app.ReportToday, acceptsDate: true}, {report: app.ReportTomorrow}, {report: app.ReportHourly}, } { t.Run(string(tt.report), func(t *testing.T) { _, generateErr := parseGenerateFlags(tt.report, []string{"--date", "2026-05-30"}) _, comparisonErr := parseComparisonFlags(tt.report, []string{"--date", "2026-05-30"}) if tt.acceptsDate && (generateErr != nil || comparisonErr != nil) { t.Fatalf("date flag errors = %v/%v, want accepted", generateErr, comparisonErr) } if !tt.acceptsDate && (generateErr == nil || comparisonErr == nil) { t.Fatalf("date flag errors = %v/%v, want rejected", generateErr, comparisonErr) } }) } } func TestResolveActionReportDateKeepsActionSpecificMissingDateErrors(t *testing.T) { location := time.UTC now := time.Date(2026, 5, 30, 2, 30, 0, 0, time.UTC) for _, action := range []string{"generate", "compare"} { t.Run(action, func(t *testing.T) { _, err := resolveActionReportDate(action, app.ReportDaily, "", location, now) want := action + " daily requires --date YYYY-MM-DD" if err == nil || err.Error() != want { t.Fatalf("error = %v, want %q", err, want) } }) } }