Centralize final report finalization

This commit is contained in:
2026-06-15 12:28:54 +00:00
parent a02af0bce0
commit e8f1aa5caf
3 changed files with 223 additions and 72 deletions

View File

@@ -645,6 +645,73 @@ func TestGenerateHourlyReportNotificationFailureFailsReport(t *testing.T) {
}
}
func TestGenerateReportSavesFinalMetadataForMarkdownAndGeneratedTextReports(t *testing.T) {
t.Run("Markdown", func(t *testing.T) {
server := dailyBundleServer(t)
cfg := dailyTestConfig(t, server)
cfg.Workspace.Root = t.TempDir()
resolved, err := ResolveGenerate(GenerateRequest{
Config: cfg,
Report: ReportDaily,
Date: mustParse("2026-05-29T12:00:00-05:00"),
}, mustParse("2026-05-29T05:00:00-05:00"))
if err != nil {
t.Fatalf("ResolveGenerate() error = %v", err)
}
result, err := GenerateReport(context.Background(), ReportRequest{
Config: cfg,
Resolved: resolved,
Renderer: successfulRenderer("# Daily Report\n"),
})
if err != nil {
t.Fatalf("GenerateReport() error = %v", err)
}
saved := readMetadataForTest(t, result.MetadataPath)
if saved.RenderedReportPath != result.ReportPath || saved.NotificationPath != "" {
t.Fatalf("saved metadata = %#v, want final rendered path without notification", saved)
}
if saved.GeneratedTextSchemaID != "" || saved.GeneratedTextPath != "" || saved.RenderContextPath != "" {
t.Fatalf("saved markdown metadata has generated-text fields: %#v", saved)
}
})
t.Run("GeneratedTextTemplate", func(t *testing.T) {
server := hourlyBundleServer(t)
cfg := hourlyGeneratedTextConfig(t, server)
cfg.Notify.Distributor.Enabled = false
resolved, store, _, _ := resolveHourlyGeneratedTextFixture(t, cfg)
renderer := &recordingRenderer{
renderResult: &scriptorium.RenderResult{ExitCode: 0},
structuredRunResult: &scriptorium.StructuredRunResult{ExitCode: 0},
structuredRunBody: validHourlyGeneratedTextJSON(),
}
result, err := GenerateReport(context.Background(), ReportRequest{
Config: cfg,
Resolved: resolved,
Renderer: renderer,
Store: store,
})
if err != nil {
t.Fatalf("GenerateReport() error = %v", err)
}
saved := readMetadataForTest(t, result.MetadataPath)
if saved.RenderedReportPath != result.ReportPath || saved.NotificationPath != "" {
t.Fatalf("saved metadata = %#v, want final rendered path without notification", saved)
}
if saved.GeneratedTextSchemaID != "hourly" ||
saved.GeneratedTextRawPath != result.GeneratedTextRawPath ||
saved.GeneratedTextResultPath != result.GeneratedTextResultPath ||
saved.GeneratedTextPath != result.GeneratedTextPath ||
saved.RenderContextPath != result.RenderContextPath {
t.Fatalf("saved generated-text metadata = %#v, want generated-text artifact links", saved)
}
})
}
func TestGenerateTomorrowReportNotificationUsesTomorrowTemplateValues(t *testing.T) {
server := dailyBundleServer(t)
cfg := config.Defaults()
@@ -2065,6 +2132,28 @@ func TestRunBatchContinuesAfterNotificationFailure(t *testing.T) {
if !failedThreeDay {
t.Fatalf("reports = %#v, want notification failure on 3-day item", result.Reports)
}
cfg.Workspace.Root = t.TempDir()
err = RunBatch(context.Background(), BatchRequest{
Config: cfg,
Batch: BatchMorning,
Now: mustParse("2026-05-29T05:00:00-05:00"),
Renderer: &selectiveRenderer{
runBody: "# Batch Report\n",
},
Notifier: &recordingNotifier{
errByReport: map[report.ID]error{
report.ThreeDay: errors.New("distributor unavailable"),
},
},
})
var batchErr BatchError
if !errors.As(err, &batchErr) {
t.Fatalf("RunBatch() error = %T %v, want BatchError", err, err)
}
if batchErr.Result == nil || batchErr.Result.Failed != 1 || batchErr.Result.Succeeded != 2 {
t.Fatalf("RunBatch() result = %#v, want notification failure aggregate", batchErr.Result)
}
}
func TestRunBatchUsesOutputDirectory(t *testing.T) {
@@ -2095,6 +2184,17 @@ func TestRunBatchUsesOutputDirectory(t *testing.T) {
if _, err := os.Stat(want); err != nil {
t.Fatalf("expected output copy %q: %v", want, err)
}
reportData, err := os.ReadFile(result.Reports[0].ReportPath)
if err != nil {
t.Fatalf("read managed report: %v", err)
}
copyData, err := os.ReadFile(want)
if err != nil {
t.Fatalf("read output copy: %v", err)
}
if string(copyData) != string(reportData) {
t.Fatalf("batch output copy differs from managed report")
}
}
func TestBatchOutputPathUsesHourlyOutputName(t *testing.T) {
@@ -2286,6 +2386,19 @@ func hourlyArtifactPaths(t *testing.T, store state.Store, resolved report.Resolv
return paths
}
func readMetadataForTest(t *testing.T, path string) state.Metadata {
t.Helper()
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read metadata %q: %v", path, err)
}
var metadata state.Metadata
if err := json.Unmarshal(data, &metadata); err != nil {
t.Fatalf("decode metadata %q: %v", path, err)
}
return metadata
}
func assertGeneratedReportError(t *testing.T, err error, resolved report.Resolved, operation string) {
t.Helper()
if err == nil {