Apply configured output directories

This commit is contained in:
2026-08-02 01:38:06 +00:00
parent 0c4c575eea
commit 2af6a5cfd2
4 changed files with 327 additions and 103 deletions

View File

@@ -113,6 +113,108 @@ func TestGenerateDetailedPublishesOnlySelectedOutput(t *testing.T) {
}
}
func TestGenerateDetailedUsesConfiguredOutputDirectory(t *testing.T) {
tests := []struct {
name string
directory func(t *testing.T, workingDir string) string
wantDir func(t *testing.T, workingDir string, configuredDir string) string
}{
{
name: "absolute directory",
directory: func(t *testing.T, _ string) string {
return filepath.Join(t.TempDir(), "reports")
},
wantDir: func(_ *testing.T, _ string, configuredDir string) string {
return configuredDir
},
},
{
name: "relative directory",
directory: func(_ *testing.T, _ string) string {
return "configured/../reports"
},
wantDir: func(_ *testing.T, workingDir string, _ string) string {
return filepath.Join(workingDir, "reports")
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
workingDir := t.TempDir()
configuredDir := tt.directory(t, workingDir)
cfg := generationDistributorConfig()
cfg.Output.Directory = configuredDir
bundle := generationBundle(t)
notifier := &generationNotifier{}
result, err := GenerateDetailed(context.Background(), GenerateRequest{
Config: cfg, Report: ReportDaily,
Date: generationTime("2026-05-29T12:00:00-05:00"), Now: generationTime("2026-05-29T08:30:00-05:00"),
WorkingDir: workingDir, Collector: &generationCollector{bundle: &bundle}, Executor: &generationExecutor{}, Notifier: notifier,
})
wantPath := filepath.Join(tt.wantDir(t, workingDir, configuredDir), "daily-2026-05-29.md")
if err != nil || result == nil || result.OutputPath != wantPath || notifier.request.ReportPath != wantPath {
t.Fatalf("GenerateDetailed() result/error/notification = %#v/%v/%#v", result, err, notifier.request)
}
if info, statErr := os.Stat(filepath.Dir(wantPath)); statErr != nil || !info.IsDir() {
t.Fatalf("configured output directory info/error = %#v/%v", info, statErr)
}
if _, statErr := os.Stat(wantPath); statErr != nil {
t.Fatalf("output %q: %v", wantPath, statErr)
}
})
}
}
func TestGenerateDetailedExplicitOutputPathIgnoresConfiguredDirectory(t *testing.T) {
configuredPath := filepath.Join(t.TempDir(), "not-a-directory")
if err := os.WriteFile(configuredPath, []byte("not a directory"), 0o600); err != nil {
t.Fatal(err)
}
explicitPath := filepath.Join(t.TempDir(), "explicit.md")
cfg := generationConfig()
cfg.Output.Directory = configuredPath
bundle := generationBundle(t)
result, err := GenerateDetailed(context.Background(), GenerateRequest{
Config: cfg, Report: ReportDaily,
Date: generationTime("2026-05-29T12:00:00-05:00"), Now: generationTime("2026-05-29T08:30:00-05:00"),
WorkingDir: t.TempDir(), OutputPath: explicitPath, Collector: &generationCollector{bundle: &bundle}, Executor: &generationExecutor{},
})
if err != nil || result == nil || result.OutputPath != explicitPath {
t.Fatalf("GenerateDetailed() result/error = %#v/%v", result, err)
}
if _, statErr := os.Stat(explicitPath); statErr != nil {
t.Fatalf("explicit output %q: %v", explicitPath, statErr)
}
}
func TestGenerateDetailedRejectsConfiguredNonDirectoryBeforeWork(t *testing.T) {
configuredPath := filepath.Join(t.TempDir(), "not-a-directory")
if err := os.WriteFile(configuredPath, []byte("not a directory"), 0o600); err != nil {
t.Fatal(err)
}
cfg := generationDistributorConfig()
cfg.Output.Directory = configuredPath
bundle := generationBundle(t)
collector := &generationCollector{bundle: &bundle}
executor := &generationExecutor{}
notifier := &generationNotifier{}
result, err := GenerateDetailed(context.Background(), GenerateRequest{
Config: cfg, Report: ReportDaily,
Date: generationTime("2026-05-29T12:00:00-05:00"), Now: generationTime("2026-05-29T08:30:00-05:00"),
WorkingDir: t.TempDir(), Collector: collector, Executor: executor, Notifier: notifier,
})
if err == nil || result == nil || collector.called || executor.promptInspections != 0 || executor.called || notifier.calls != 0 {
t.Fatalf("GenerateDetailed() result/error/collector/executor/notifier = %#v/%v/%t/%#v/%#v", result, err, collector.called, executor, notifier)
}
if data, readErr := os.ReadFile(configuredPath); readErr != nil || string(data) != "not a directory" {
t.Fatalf("configured path = %q, error = %v", data, readErr)
}
}
func TestGenerateDetailedReturnsResolvedResultWhenCollectionFails(t *testing.T) {
cfg := config.Defaults()
cfg.WeatherAPI.Timezone, cfg.Location.ID = "America/Chicago", "home"
@@ -244,14 +346,19 @@ func generationBundlePointer(t *testing.T) *weatherdata.Bundle {
type generationNotifier struct {
err error
batchErr error
calls int
request NotificationRequest
batchRequest batchNotificationRequest
batchCalls int
}
func (n *generationNotifier) Notify(_ context.Context, request NotificationRequest) (*NotificationResult, error) {
n.calls++
n.request = request
return nil, n.err
if n.err != nil {
return nil, n.err
}
return &NotificationResult{Status: "succeeded"}, nil
}
func (n *generationNotifier) NotifyBatch(_ context.Context, request batchNotificationRequest) (*NotificationResult, error) {