package app import ( "os" "path/filepath" "testing" "gitea.maximumdirect.net/eric/weatherreporter/internal/testutil" ) func TestResolveComparisonOutputDirectory(t *testing.T) { workingDir := t.TempDir() configured := filepath.Join(workingDir, "configured") blocked := filepath.Join(workingDir, "not-a-directory") if err := os.WriteFile(blocked, []byte("blocked"), 0o600); err != nil { t.Fatal(err) } tests := []struct { name string override string configuredDir string reportOutputName string want string wantErr bool }{ {name: "working directory default", reportOutputName: "today.md", want: filepath.Join(workingDir, "comparison-today")}, {name: "configured relative directory", configuredDir: "configured", reportOutputName: "tomorrow.md", want: filepath.Join(configured, "comparison-tomorrow")}, {name: "configured absolute directory", configuredDir: configured, reportOutputName: "hourly.md", want: filepath.Join(configured, "comparison-hourly")}, {name: "relative explicit directory", override: "exact", configuredDir: blocked, reportOutputName: "daily-2026-08-24.md", want: filepath.Join(workingDir, "exact")}, {name: "absolute explicit directory", override: filepath.Join(workingDir, "absolute"), reportOutputName: "today.md", want: filepath.Join(workingDir, "absolute")}, {name: "invalid report suffix", reportOutputName: "today.txt", wantErr: true}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { got, err := resolveComparisonOutputDirectory(workingDir, test.override, test.configuredDir, test.reportOutputName) if (err != nil) != test.wantErr { t.Fatalf("resolveComparisonOutputDirectory() error = %v, want error %t", err, test.wantErr) } if !test.wantErr && got != test.want { t.Fatalf("resolveComparisonOutputDirectory() = %q, want %q", got, test.want) } }) } } func TestResolveOutputDirRejectsDanglingSymlinkComponents(t *testing.T) { workingDir := t.TempDir() dangling := filepath.Join(workingDir, "dangling") testutil.RequireSymlink(t, filepath.Join(workingDir, "missing"), dangling) for _, directory := range []string{dangling, filepath.Join(dangling, "reports")} { t.Run(filepath.Base(directory), func(t *testing.T) { if _, err := resolveOutputDir(workingDir, directory); err == nil { t.Fatalf("resolveOutputDir(%q) error = nil, want dangling symlink error", directory) } }) } } func TestResolveOutputDirAllowsMissingDirectoryBelowValidSymlink(t *testing.T) { workingDir := t.TempDir() target := t.TempDir() link := filepath.Join(workingDir, "linked") testutil.RequireSymlink(t, target, link) directory := filepath.Join(link, "reports") got, err := resolveOutputDir(workingDir, directory) if err != nil || got != directory { t.Fatalf("resolveOutputDir() = %q, %v, want %q, nil", got, err, directory) } }