Files
weatherreporter/internal/report/period_test.go

141 lines
4.8 KiB
Go

package report
import (
"strings"
"testing"
"time"
"gitea.maximumdirect.net/eric/weatherreporter/internal/timeutil"
)
func TestResolveRetainedReportPeriods(t *testing.T) {
location := loadTestLocation(t)
now := parseTestTime("2026-05-29T17:45:00-05:00")
date := parseTestTime("2026-05-31T12:00:00-05:00")
tests := []struct {
id ID
request ResolveRequest
wantStart string
wantEnd string
}{
{Daily, ResolveRequest{Now: now, Location: location, Date: date}, "2026-05-31T00:00:00-05:00", "2026-06-01T00:00:00-05:00"},
{Today, ResolveRequest{Now: now, Location: location, Date: date}, "2026-05-31T00:00:00-05:00", "2026-06-01T00:00:00-05:00"},
{Tomorrow, ResolveRequest{Now: now, Location: location}, "2026-05-30T00:00:00-05:00", "2026-05-31T00:00:00-05:00"},
{Hourly, ResolveRequest{Now: now, Location: location}, "2026-05-29T17:45:00-05:00", "2026-05-29T23:45:00-05:00"},
}
for _, tt := range tests {
t.Run(string(tt.id), func(t *testing.T) {
resolved, err := Resolve(tt.id, tt.request)
if err != nil {
t.Fatalf("Resolve(%q) error = %v", tt.id, err)
}
assertTestPeriod(t, resolved.ValidPeriod, tt.wantStart, tt.wantEnd)
})
}
}
func TestResolveDailyRequiresDate(t *testing.T) {
_, err := Resolve(Daily, ResolveRequest{Now: parseTestTime("2026-05-29T17:45:00-05:00"), Location: loadTestLocation(t)})
if err == nil || !strings.Contains(err.Error(), "explicit date") {
t.Fatalf("Resolve(Daily) error = %v, want explicit-date error", err)
}
}
func TestRegistryContainsOnlyPromptBackedReports(t *testing.T) {
registry := DefaultRegistry()
definitions := registry.All()
if len(definitions) != 4 {
t.Fatalf("Registry.All() length = %d, want 4", len(definitions))
}
for _, definition := range definitions {
if definition.PromptVersion != "2.0.0" {
t.Fatalf("%s PromptVersion = %q, want 2.0.0", definition.ID, definition.PromptVersion)
}
if definition.PromptID == "" {
t.Fatalf("%s PromptID is empty", definition.ID)
}
if definition.TemplateID == "" || definition.GeneratedTextSchemaID == "" {
t.Fatalf("%s template/schema = %q/%q, want both set", definition.ID, definition.TemplateID, definition.GeneratedTextSchemaID)
}
}
if _, err := registry.Lookup(ID("three_day")); err == nil {
t.Fatal("Lookup(three_day) error = nil, want unknown report")
}
}
func TestCommandAndConfigurationNamesRejectRetiredReports(t *testing.T) {
if names := strings.Join(CommandNames(), ","); names != "daily,today,tomorrow,hourly" {
t.Fatalf("CommandNames() = %q", names)
}
for _, name := range []string{"three-day", "weekend", "storm"} {
if _, err := IDForCommandName(name); err == nil {
t.Fatalf("IDForCommandName(%q) error = nil, want unknown command", name)
}
}
for _, key := range []string{"three_day", "three_day_outlook", "weekend", "weekend_outlook", "storm", "storm_report"} {
if _, err := IDForConfigKey(key); err == nil {
t.Fatalf("IDForConfigKey(%q) error = nil, want unknown report", key)
}
}
}
func TestRegistryDefinitionsPreserveRetainedContracts(t *testing.T) {
tests := []struct {
id ID
morning bool
evening bool
outputName string
paths []string
}{
{Daily, false, false, "daily.md", []string{"daily/{valid_start_date}/{run_id}.md", "daily/{valid_start_date}/index.md"}},
{Today, true, false, "today.md", []string{"daily/{valid_start_date}/{run_id}.md", "daily/{valid_start_date}/index.md", "today/index.md"}},
{Tomorrow, false, true, "tomorrow.md", []string{"daily/{valid_start_date}/{run_id}.md", "daily/{valid_start_date}/index.md", "tomorrow/index.md"}},
{Hourly, false, false, "hourly.md", []string{"hourly/index.md"}},
}
registry := DefaultRegistry()
for _, tt := range tests {
t.Run(string(tt.id), func(t *testing.T) {
definition := registry.MustLookup(tt.id)
if definition.Morning != tt.morning || definition.Evening != tt.evening || definition.OutputName != tt.outputName {
t.Fatalf("definition = %#v, want retained report contract", definition)
}
if strings.Join(definition.DistributorPathTemplates, "|") != strings.Join(tt.paths, "|") {
t.Fatalf("DistributorPathTemplates = %#v, want %#v", definition.DistributorPathTemplates, tt.paths)
}
})
}
}
func assertTestPeriod(t *testing.T, period timeutil.Period, wantStart string, wantEnd string) {
t.Helper()
if got := period.Start.Format(time.RFC3339); got != wantStart {
t.Fatalf("period start = %q, want %q", got, wantStart)
}
if got := period.End.Format(time.RFC3339); got != wantEnd {
t.Fatalf("period end = %q, want %q", got, wantEnd)
}
}
func loadTestLocation(t *testing.T) *time.Location {
t.Helper()
location, err := timeutil.LoadLocation("America/Chicago")
if err != nil {
t.Fatalf("LoadLocation() error = %v", err)
}
return location
}
func parseTestTime(value string) time.Time {
parsed, err := time.Parse(time.RFC3339, value)
if err != nil {
panic(err)
}
return parsed
}