130 lines
4.9 KiB
Go
130 lines
4.9 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/weatherreporter/internal/collect"
|
|
"gitea.maximumdirect.net/eric/weatherreporter/internal/config"
|
|
"gitea.maximumdirect.net/eric/weatherreporter/internal/report"
|
|
)
|
|
|
|
func TestResolveReportOutputPath(t *testing.T) {
|
|
workingDir := t.TempDir()
|
|
cfg := config.Defaults()
|
|
now := workflowTime("2026-05-29T08:30:00-05:00")
|
|
|
|
for _, test := range []struct {
|
|
report ReportKind
|
|
date string
|
|
name string
|
|
}{
|
|
{report: ReportDaily, date: "2026-05-30T12:00:00-05:00", name: "daily-2026-05-30.md"},
|
|
{report: ReportToday, date: "2026-05-29T12:00:00-05:00", name: "today.md"},
|
|
{report: ReportTomorrow, name: "tomorrow.md"},
|
|
{report: ReportHourly, name: "hourly.md"},
|
|
} {
|
|
t.Run(string(test.report), func(t *testing.T) {
|
|
req := GenerateRequest{Config: cfg, Report: test.report}
|
|
if test.date != "" {
|
|
req.Date = workflowTime(test.date)
|
|
}
|
|
resolved, err := ResolveGenerate(req, now)
|
|
if err != nil {
|
|
t.Fatalf("ResolveGenerate() error = %v", err)
|
|
}
|
|
path, err := resolveReportOutputPath(workingDir, "", resolved)
|
|
if err != nil {
|
|
t.Fatalf("resolveReportOutputPath() error = %v", err)
|
|
}
|
|
if path != filepath.Join(workingDir, test.name) {
|
|
t.Fatalf("path = %q, want %q", path, filepath.Join(workingDir, test.name))
|
|
}
|
|
})
|
|
}
|
|
|
|
resolved, err := ResolveGenerate(GenerateRequest{
|
|
Config: cfg, Report: ReportDaily, Date: workflowTime("2026-05-30T12:00:00-05:00"),
|
|
}, now)
|
|
if err != nil {
|
|
t.Fatalf("ResolveGenerate() error = %v", err)
|
|
}
|
|
absoluteDir := t.TempDir()
|
|
for _, test := range []struct {
|
|
override string
|
|
want string
|
|
}{
|
|
{override: filepath.Join("reports", "custom.md"), want: filepath.Join(workingDir, "reports", "custom.md")},
|
|
{override: filepath.Join(absoluteDir, "custom.md"), want: filepath.Join(absoluteDir, "custom.md")},
|
|
} {
|
|
path, err := resolveReportOutputPath(workingDir, test.override, resolved)
|
|
if err != nil {
|
|
t.Fatalf("resolveReportOutputPath(%q) error = %v", test.override, err)
|
|
}
|
|
if path != filepath.Clean(test.want) {
|
|
t.Fatalf("path = %q, want %q", path, filepath.Clean(test.want))
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGenerateDetailedRejectsInvalidOutputBeforeCollection(t *testing.T) {
|
|
cfg := workflowConfig(t)
|
|
collector := &workflowCollector{err: errors.New("collection must not run")}
|
|
_, err := GenerateDetailed(context.Background(), GenerateRequest{
|
|
Config: cfg, Report: ReportDaily, Date: workflowTime("2026-05-29T12:00:00-05:00"),
|
|
Now: workflowTime("2026-05-29T08:30:00-05:00"), WorkingDir: t.TempDir(), OutputPath: t.TempDir(),
|
|
Collector: collector,
|
|
})
|
|
if err == nil || collector.calls != 0 {
|
|
t.Fatalf("GenerateDetailed() error/calls = %v/%d, want invalid output before collection", err, collector.calls)
|
|
}
|
|
}
|
|
|
|
func TestGenerateDetailedPreservesExistingOutputWhenGenerationFails(t *testing.T) {
|
|
cfg := workflowConfig(t)
|
|
cfg.Notify.Distributor.Enabled = false
|
|
workingDir := t.TempDir()
|
|
outputPath := filepath.Join(workingDir, "daily-2026-05-29.md")
|
|
if err := os.WriteFile(outputPath, []byte("existing report"), 0o600); err != nil {
|
|
t.Fatalf("write existing output: %v", err)
|
|
}
|
|
bundle := workflowBundle(t)
|
|
result, err := GenerateDetailed(context.Background(), GenerateRequest{
|
|
Config: cfg, Report: ReportDaily, Date: workflowTime("2026-05-29T12:00:00-05:00"),
|
|
Now: workflowTime("2026-05-29T08:30:00-05:00"), WorkingDir: workingDir,
|
|
Collector: &workflowCollector{result: &collect.Result{Bundle: &bundle}},
|
|
Executor: &workflowExecutor{definition: report.DefaultRegistry().MustLookup(report.Daily), raw: []byte(`{}`)},
|
|
})
|
|
if err == nil || result == nil || result.OutputPath != "" {
|
|
t.Fatalf("result/error/output = %#v/%v/%q, want failed generation without output publication", result, err, result.OutputPath)
|
|
}
|
|
data, readErr := os.ReadFile(outputPath)
|
|
if readErr != nil || string(data) != "existing report" {
|
|
t.Fatalf("output after failure = %q, error %v, want preserved content", data, readErr)
|
|
}
|
|
}
|
|
|
|
func TestRunBatchDetailedUsesWorkingDirectoryForOutput(t *testing.T) {
|
|
cfg := assembledBatchConfig(t, false)
|
|
workingDir := t.TempDir()
|
|
bundle := assembledBatchBundle(t, "2026-05-31")
|
|
result, err := RunBatchDetailed(context.Background(), BatchRequest{
|
|
Config: cfg, Batch: BatchEvening, Now: workflowTime("2026-05-29T18:00:00-05:00"), WorkingDir: workingDir,
|
|
Collector: &workflowCollector{result: &collect.Result{Bundle: &bundle}},
|
|
Executor: newAssembledBatchExecutor(),
|
|
})
|
|
if err != nil || result == nil || result.Failed != 0 {
|
|
t.Fatalf("RunBatchDetailed() result/error = %#v/%v", result, err)
|
|
}
|
|
if len(result.Reports) != 2 {
|
|
t.Fatalf("reports = %#v, want Tomorrow and Daily", result.Reports)
|
|
}
|
|
if result.Reports[0].OutputPath != filepath.Join(workingDir, "tomorrow.md") ||
|
|
result.Reports[1].OutputPath != filepath.Join(workingDir, "daily-2026-05-31.md") {
|
|
t.Fatalf("output paths = %#v, want working-directory defaults", result.Reports)
|
|
}
|
|
}
|