Prepare reports for Promptkit migration
This commit is contained in:
@@ -174,12 +174,13 @@ func TestGenerateDetailedReturnsReportResult(t *testing.T) {
|
||||
cfg.Scriptorium.Binary = fakeScriptoriumBinary(t)
|
||||
collection := collectionForTest(t, cfg)
|
||||
collector := &recordingCollector{result: &collection}
|
||||
outputPath := filepath.Join(t.TempDir(), "three-day.md")
|
||||
outputPath := filepath.Join(t.TempDir(), "daily.md")
|
||||
|
||||
result, err := GenerateDetailed(context.Background(), GenerateRequest{
|
||||
Config: cfg,
|
||||
Report: ReportThreeDay,
|
||||
Report: ReportDaily,
|
||||
OutputPath: outputPath,
|
||||
Date: mustParse("2026-05-29T12:00:00-05:00"),
|
||||
Now: mustParse("2026-05-29T05:00:00-05:00"),
|
||||
Collector: collector,
|
||||
})
|
||||
@@ -189,8 +190,8 @@ func TestGenerateDetailedReturnsReportResult(t *testing.T) {
|
||||
if result == nil {
|
||||
t.Fatal("GenerateDetailed() result = nil, want report result")
|
||||
}
|
||||
if result.Metadata.ReportID != report.ThreeDay || result.Metadata.RunID == "" {
|
||||
t.Fatalf("metadata = %#v, want 3-day report metadata with run id", result.Metadata)
|
||||
if result.Metadata.ReportID != report.Daily || result.Metadata.RunID == "" {
|
||||
t.Fatalf("metadata = %#v, want daily report metadata with run id", result.Metadata)
|
||||
}
|
||||
if result.OutputPath != outputPath {
|
||||
t.Fatalf("OutputPath = %q, want requested output copy %q", result.OutputPath, outputPath)
|
||||
@@ -209,7 +210,8 @@ func TestGenerateReturnsUnderlyingErrorOnly(t *testing.T) {
|
||||
|
||||
err := Generate(context.Background(), GenerateRequest{
|
||||
Config: cfg,
|
||||
Report: ReportThreeDay,
|
||||
Report: ReportDaily,
|
||||
Date: mustParse("2026-05-29T12:00:00-05:00"),
|
||||
Now: mustParse("2026-05-29T05:00:00-05:00"),
|
||||
Collector: &recordingCollector{err: wantErr},
|
||||
})
|
||||
@@ -272,18 +274,11 @@ func TestGenerateReportWritesReportAndPreflight(t *testing.T) {
|
||||
Stdout: `{"prepared":true}`,
|
||||
ExitCode: 0,
|
||||
},
|
||||
runResult: &scriptorium.RunResult{
|
||||
Command: []string{"scriptorium", "run"},
|
||||
Stderr: "wrote report",
|
||||
ExitCode: 0,
|
||||
OutputPath: "",
|
||||
},
|
||||
structuredRunResult: &scriptorium.StructuredRunResult{
|
||||
Command: []string{"scriptorium", "run"},
|
||||
Stderr: "wrote generated text",
|
||||
ExitCode: 0,
|
||||
},
|
||||
runBody: "# Daily Report\n\nRain this morning.\n",
|
||||
}
|
||||
outputPath := filepath.Join(t.TempDir(), "daily.md")
|
||||
store := recordingFilesystemStore(t, cfg)
|
||||
@@ -306,9 +301,6 @@ func TestGenerateReportWritesReportAndPreflight(t *testing.T) {
|
||||
if renderer.structuredRunCalls != 1 {
|
||||
t.Fatalf("structured run calls = %d, want 1", renderer.structuredRunCalls)
|
||||
}
|
||||
if renderer.runCalls != 0 {
|
||||
t.Fatalf("markdown run calls = %d, want none", renderer.runCalls)
|
||||
}
|
||||
if renderer.renderRequest.PromptID != "weather.daily_generated_text" {
|
||||
t.Fatalf("render PromptID = %q, want weather.daily_generated_text", renderer.renderRequest.PromptID)
|
||||
}
|
||||
@@ -537,8 +529,8 @@ func TestGeneratedTemplateReportsUseRichArtifactsAndCuratedDataPackages(t *testi
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateReport() error = %v", err)
|
||||
}
|
||||
if renderer.renderCalls != 1 || renderer.structuredRunCalls != 1 || renderer.runCalls != 0 {
|
||||
t.Fatalf("renderer calls render=%d structured=%d run=%d, want generated-template workflow", renderer.renderCalls, renderer.structuredRunCalls, renderer.runCalls)
|
||||
if renderer.renderCalls != 1 || renderer.structuredRunCalls != 1 {
|
||||
t.Fatalf("renderer calls render=%d structured=%d, want generated-template workflow", renderer.renderCalls, renderer.structuredRunCalls)
|
||||
}
|
||||
if renderer.renderRequest.PromptID != tt.prompt || renderer.structuredRunRequest.PromptID != tt.prompt {
|
||||
t.Fatalf("prompt IDs render=%q structured=%q, want %q", renderer.renderRequest.PromptID, renderer.structuredRunRequest.PromptID, tt.prompt)
|
||||
@@ -655,9 +647,6 @@ func TestGenerateHourlyReportUsesGeneratedTextTemplateWorkflow(t *testing.T) {
|
||||
server := hourlyBundleServer(t)
|
||||
cfg := hourlyTestConfig(t, server)
|
||||
resolved := resolveGenerateForTest(t, cfg, GenerateRequest{Report: ReportHourly}, "2026-05-29T08:30:00-05:00")
|
||||
if resolved.Definition.GenerationMode != report.GenerationModeGeneratedTextTemplate {
|
||||
t.Fatalf("GenerationMode = %q, want generated text template", resolved.Definition.GenerationMode)
|
||||
}
|
||||
store := recordingFilesystemStore(t, cfg)
|
||||
renderer := &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{
|
||||
@@ -695,9 +684,6 @@ func TestGenerateHourlyReportUsesGeneratedTextTemplateWorkflow(t *testing.T) {
|
||||
if renderer.structuredRunCalls != 1 {
|
||||
t.Fatalf("structured run calls = %d, want 1", renderer.structuredRunCalls)
|
||||
}
|
||||
if renderer.runCalls != 0 {
|
||||
t.Fatalf("markdown run calls = %d, want none", renderer.runCalls)
|
||||
}
|
||||
if renderer.structuredRunRequest.OutputPath != result.GeneratedTextRawPath {
|
||||
t.Fatalf("structured run OutputPath = %q, want %q", renderer.structuredRunRequest.OutputPath, result.GeneratedTextRawPath)
|
||||
}
|
||||
@@ -779,9 +765,6 @@ func TestGenerateHourlyReportUsesGeneratedTextTemplateWorkflow(t *testing.T) {
|
||||
if result.StructuredRunResult == nil || result.StructuredRunResult.OutputPath != result.GeneratedTextRawPath {
|
||||
t.Fatalf("StructuredRunResult = %#v, want captured structured run result", result.StructuredRunResult)
|
||||
}
|
||||
if result.RunResult != nil {
|
||||
t.Fatalf("RunResult = %#v, want nil for generated-text template workflow", result.RunResult)
|
||||
}
|
||||
if len(result.RecentChanges) != 0 {
|
||||
t.Fatalf("RecentChanges = %#v, want none for hourly report", result.RecentChanges)
|
||||
}
|
||||
@@ -1016,72 +999,39 @@ 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: ReportThreeDay,
|
||||
}, mustParse("2026-05-29T05:00:00-05:00"))
|
||||
if err != nil {
|
||||
t.Fatalf("ResolveGenerate() error = %v", err)
|
||||
}
|
||||
func TestGenerateReportSavesFinalMetadata(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,
|
||||
Collection: collectionForTest(t, cfg),
|
||||
Resolved: resolved,
|
||||
Renderer: successfulRenderer("# 3-Day Outlook\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)
|
||||
}
|
||||
result, err := GenerateReport(context.Background(), ReportRequest{
|
||||
Config: cfg,
|
||||
Collection: collectionForTest(t, cfg),
|
||||
Resolved: resolved,
|
||||
Renderer: renderer,
|
||||
Store: store,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateReport() error = %v", err)
|
||||
}
|
||||
|
||||
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,
|
||||
Collection: collectionForTest(t, 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)
|
||||
}
|
||||
})
|
||||
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) {
|
||||
@@ -1615,11 +1565,7 @@ func TestGenerateReportIncludesRecentChangesFromPriorSnapshot(t *testing.T) {
|
||||
Report: ReportDaily,
|
||||
Date: mustParse("2026-05-29T12:00:00-05:00"),
|
||||
}, "2026-05-29T05:00:00-05:00")
|
||||
renderer := &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
runResult: &scriptorium.RunResult{ExitCode: 0},
|
||||
runBody: "# Daily Report\n",
|
||||
}
|
||||
renderer := successfulRenderer("")
|
||||
|
||||
result, err := GenerateReport(context.Background(), ReportRequest{
|
||||
Config: cfg,
|
||||
@@ -1843,142 +1789,6 @@ func TestDailyReportIgnoresPriorTomorrowSnapshot(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateThreeDayReportWritesReportAndRecentChanges(t *testing.T) {
|
||||
server := dailyBundleServer(t)
|
||||
cfg := dailyWorkspaceConfig(t, server)
|
||||
store := recordingFilesystemStore(t, cfg)
|
||||
priorResolved := resolveGenerateForTest(t, cfg, GenerateRequest{
|
||||
Report: ReportThreeDay,
|
||||
}, "2026-05-29T04:00:00-05:00")
|
||||
savePriorRun(t, store, priorResolved, priorOutlookModuleSnapshot(t, "2026-05-30"))
|
||||
currentResolved := resolveGenerateForTest(t, cfg, GenerateRequest{
|
||||
Report: ReportThreeDay,
|
||||
}, "2026-05-29T05:00:00-05:00")
|
||||
renderer := &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
runResult: &scriptorium.RunResult{ExitCode: 0},
|
||||
runBody: "# 3-Day Outlook\n",
|
||||
}
|
||||
|
||||
result, err := GenerateReport(context.Background(), ReportRequest{
|
||||
Config: cfg,
|
||||
Collection: collectionForTest(t, cfg),
|
||||
Resolved: currentResolved,
|
||||
Renderer: renderer,
|
||||
Store: store,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateReport() error = %v", err)
|
||||
}
|
||||
|
||||
dayparts, ok, err := module.StanzaValue[map[string]any](result.ModuleSnapshot, "derived_daypart_summaries")
|
||||
if err != nil {
|
||||
t.Fatalf("decode daypart summaries: %v", err)
|
||||
}
|
||||
if !ok || len(dayparts) == 0 {
|
||||
t.Fatalf("daypart summaries = %#v, want 3-day module content", dayparts)
|
||||
}
|
||||
if renderer.renderRequest.PromptID != "weather.three_day_outlook" {
|
||||
t.Fatalf("render PromptID = %q, want weather.three_day_outlook", renderer.renderRequest.PromptID)
|
||||
}
|
||||
if result.PriorSnapshot == nil {
|
||||
t.Fatal("PriorSnapshot = nil, want prior 3-day snapshot")
|
||||
}
|
||||
if len(result.RecentChanges) == 0 {
|
||||
t.Fatal("RecentChanges length = 0, want changes from prior 3-day snapshot")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateWeekendReportWritesReportAndRecentChanges(t *testing.T) {
|
||||
server := dailyBundleServer(t)
|
||||
cfg := dailyWorkspaceConfig(t, server)
|
||||
store := recordingFilesystemStore(t, cfg)
|
||||
priorResolved := resolveGenerateForTest(t, cfg, GenerateRequest{
|
||||
Report: ReportWeekend,
|
||||
}, "2026-05-29T04:00:00-05:00")
|
||||
savePriorRun(t, store, priorResolved, priorOutlookModuleSnapshot(t, "2026-05-30"))
|
||||
currentResolved := resolveGenerateForTest(t, cfg, GenerateRequest{
|
||||
Report: ReportWeekend,
|
||||
}, "2026-05-29T05:00:00-05:00")
|
||||
renderer := &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
runResult: &scriptorium.RunResult{ExitCode: 0},
|
||||
runBody: "# Weekend Outlook\n",
|
||||
}
|
||||
|
||||
result, err := GenerateReport(context.Background(), ReportRequest{
|
||||
Config: cfg,
|
||||
Collection: collectionForTest(t, cfg),
|
||||
Resolved: currentResolved,
|
||||
Renderer: renderer,
|
||||
Store: store,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateReport() error = %v", err)
|
||||
}
|
||||
|
||||
dayparts, ok, err := module.StanzaValue[map[string]any](result.ModuleSnapshot, "derived_daypart_summaries")
|
||||
if err != nil {
|
||||
t.Fatalf("decode daypart summaries: %v", err)
|
||||
}
|
||||
if !ok || len(dayparts) == 0 {
|
||||
t.Fatalf("daypart summaries = %#v, want weekend module content", dayparts)
|
||||
}
|
||||
if renderer.renderRequest.PromptID != "weather.weekend_outlook" {
|
||||
t.Fatalf("render PromptID = %q, want weather.weekend_outlook", renderer.renderRequest.PromptID)
|
||||
}
|
||||
if result.PriorSnapshot == nil {
|
||||
t.Fatal("PriorSnapshot = nil, want prior weekend snapshot")
|
||||
}
|
||||
if len(result.RecentChanges) == 0 {
|
||||
t.Fatal("RecentChanges length = 0, want changes from prior weekend snapshot")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateStormReportWritesReport(t *testing.T) {
|
||||
server := dailyBundleServer(t)
|
||||
cfg := dailyWorkspaceConfig(t, server)
|
||||
resolved := resolveGenerateForTest(t, cfg, GenerateRequest{
|
||||
Report: ReportStorm,
|
||||
StormStart: mustParse("2026-05-29T06:00:00-05:00"),
|
||||
StormEnd: mustParse("2026-05-29T10:00:00-05:00"),
|
||||
}, "2026-05-29T05:00:00-05:00")
|
||||
renderer := &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
runResult: &scriptorium.RunResult{ExitCode: 0},
|
||||
runBody: "# Storm Report\n",
|
||||
}
|
||||
outputPath := filepath.Join(t.TempDir(), "storm.md")
|
||||
|
||||
result, err := GenerateReport(context.Background(), ReportRequest{
|
||||
Config: cfg,
|
||||
Collection: collectionForTest(t, cfg),
|
||||
Resolved: resolved,
|
||||
OutputPath: outputPath,
|
||||
Renderer: renderer,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateReport() error = %v", err)
|
||||
}
|
||||
|
||||
if renderer.renderRequest.PromptID != "weather.storm_report" {
|
||||
t.Fatalf("render PromptID = %q, want weather.storm_report", renderer.renderRequest.PromptID)
|
||||
}
|
||||
if _, ok := result.ModuleSnapshot.LookupStanza("precip_timing"); !ok {
|
||||
t.Fatal("precip_timing stanza missing")
|
||||
}
|
||||
if _, err := os.Stat(outputPath); err != nil {
|
||||
t.Fatalf("expected requested report output %q: %v", outputPath, err)
|
||||
}
|
||||
data, err := os.ReadFile(result.DataPackagePath)
|
||||
if err != nil {
|
||||
t.Fatalf("read data package: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(data), "id: storm") || !strings.Contains(string(data), "prompt_id: weather.storm_report") || !strings.Contains(string(data), "precip_timing:") {
|
||||
t.Fatalf("data package missing storm content:\n%s", string(data))
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspectGeneratedReportArtifacts(t *testing.T) {
|
||||
server := dailyBundleServer(t)
|
||||
cfg := dailyWorkspaceConfig(t, server)
|
||||
@@ -1986,11 +1796,7 @@ func TestInspectGeneratedReportArtifacts(t *testing.T) {
|
||||
Report: ReportDaily,
|
||||
Date: mustParse("2026-05-29T12:00:00-05:00"),
|
||||
}, "2026-05-29T05:00:00-05:00")
|
||||
renderer := &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
runResult: &scriptorium.RunResult{ExitCode: 0},
|
||||
runBody: "# Daily Report\n",
|
||||
}
|
||||
renderer := successfulRenderer("")
|
||||
result, err := GenerateReport(context.Background(), ReportRequest{
|
||||
Config: cfg,
|
||||
Collection: collectionForTest(t, cfg),
|
||||
@@ -2053,11 +1859,7 @@ func TestInspectPriorSnapshot(t *testing.T) {
|
||||
Report: ReportDaily,
|
||||
Date: mustParse("2026-05-29T12:00:00-05:00"),
|
||||
}, "2026-05-29T05:00:00-05:00")
|
||||
renderer := &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
runResult: &scriptorium.RunResult{ExitCode: 0},
|
||||
runBody: "# Daily Report\n",
|
||||
}
|
||||
renderer := successfulRenderer("")
|
||||
if _, err := GenerateReport(context.Background(), ReportRequest{Config: cfg, Collection: collectionForTest(t, cfg), Resolved: priorResolved, Renderer: renderer, Store: store}); err != nil {
|
||||
t.Fatalf("GenerateReport(prior) error = %v", err)
|
||||
}
|
||||
@@ -2304,79 +2106,6 @@ const qualifyingConvectiveOutlooksResponse = `{"data":{"locationId":"home","loca
|
||||
|
||||
const lowerRiskConvectiveOutlooksResponse = `{"data":{"locationId":"home","locationName":"Brentwood","asOf":"2026-05-29T16:00:00Z","issuedAt":"2026-05-29T15:45:00Z","outlooks":[{"id":"day1-categorical","day":1,"outlookType":"categorical","label":"MRGL","labelText":"Marginal Risk","severityRank":2,"validFrom":"2026-05-29T11:00:00-05:00","validTo":"2026-05-30T07:00:00-05:00","containsLocation":true,"geometry":{"type":"Polygon","coordinates":[[[-91.0,38.0],[-90.0,38.0],[-90.0,39.0],[-91.0,39.0],[-91.0,38.0]]]}}],"discussions":[{"day":1,"headline":"Low-end severe threat","summary":"An isolated severe storm cannot be ruled out.","discussion":"Low-end severe threat discussion.","updatedAt":"2026-05-29T11:15:00-05:00"}]}}`
|
||||
|
||||
func TestResolveGenerateStorm(t *testing.T) {
|
||||
cfg := config.Defaults()
|
||||
cfg.WeatherAPI.Timezone = "America/Chicago"
|
||||
now := mustParse("2026-05-29T12:00:00-05:00")
|
||||
start := mustParse("2026-05-29T18:00:00-05:00")
|
||||
end := mustParse("2026-05-30T06:00:00-05:00")
|
||||
|
||||
resolved, err := ResolveGenerate(GenerateRequest{
|
||||
Config: cfg,
|
||||
Report: ReportStorm,
|
||||
StormStart: start,
|
||||
StormEnd: end,
|
||||
}, now)
|
||||
if err != nil {
|
||||
t.Fatalf("ResolveGenerate() error = %v", err)
|
||||
}
|
||||
if resolved.Definition.ID != report.Storm {
|
||||
t.Fatalf("ID = %q, want storm", resolved.Definition.ID)
|
||||
}
|
||||
if !resolved.ValidPeriod.Start.Equal(start) || !resolved.ValidPeriod.End.Equal(end) {
|
||||
t.Fatalf("period = %#v, want storm window", resolved.ValidPeriod)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDistributorTemplateValuesDeriveStormID(t *testing.T) {
|
||||
cfg := config.Defaults()
|
||||
cfg.WeatherAPI.Timezone = "America/Chicago"
|
||||
now := mustParse("2026-05-29T12:00:00-05:00")
|
||||
start := mustParse("2026-05-29T18:00:00-05:00")
|
||||
end := mustParse("2026-05-30T06:00:00-05:00")
|
||||
|
||||
resolved, err := ResolveGenerate(GenerateRequest{
|
||||
Config: cfg,
|
||||
Report: ReportStorm,
|
||||
StormStart: start,
|
||||
StormEnd: end,
|
||||
}, now)
|
||||
if err != nil {
|
||||
t.Fatalf("ResolveGenerate() error = %v", err)
|
||||
}
|
||||
values, err := distributorTemplateValuesForReport(cfg, resolved, "run", "")
|
||||
if err != nil {
|
||||
t.Fatalf("distributorTemplateValuesForReport() error = %v", err)
|
||||
}
|
||||
if values.StormID != "2026-05-29T1800-2026-05-30T0600" {
|
||||
t.Fatalf("StormID = %q, want storm valid-period stamp", values.StormID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDistributorTemplateValuesLeaveStormIDEmptyForOtherReports(t *testing.T) {
|
||||
cfg := config.Defaults()
|
||||
cfg.WeatherAPI.Timezone = "America/Chicago"
|
||||
location, err := timeutil.LoadLocation(cfg.WeatherAPI.Timezone)
|
||||
if err != nil {
|
||||
t.Fatalf("load location: %v", err)
|
||||
}
|
||||
resolved, err := report.Resolve(report.Today, report.ResolveRequest{
|
||||
Now: mustParse("2026-05-29T12:00:00-05:00"),
|
||||
Location: location,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Resolve() error = %v", err)
|
||||
}
|
||||
|
||||
values, err := distributorTemplateValuesForReport(cfg, resolved, "run", "")
|
||||
if err != nil {
|
||||
t.Fatalf("distributorTemplateValuesForReport() error = %v", err)
|
||||
}
|
||||
if values.StormID != "" {
|
||||
t.Fatalf("StormID = %q, want empty for %s", values.StormID, resolved.Definition.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildNotificationRequestUsesReportDefaultBundlePaths(t *testing.T) {
|
||||
cfg := config.Defaults()
|
||||
cfg.Location.ID = "home"
|
||||
@@ -2448,50 +2177,6 @@ func TestBuildNotificationRequestUsesReportDefaultBundlePaths(t *testing.T) {
|
||||
},
|
||||
source: "/managed/tomorrow.md",
|
||||
},
|
||||
{
|
||||
id: report.ThreeDay,
|
||||
req: report.ResolveRequest{
|
||||
Now: now,
|
||||
Location: location,
|
||||
},
|
||||
want: func(metadata state.Metadata) []string {
|
||||
return []string{
|
||||
"three-day/2026-05-29/" + metadata.RunID + ".md",
|
||||
"three-day/2026-05-29/index.md",
|
||||
}
|
||||
},
|
||||
source: "/managed/three-day.md",
|
||||
},
|
||||
{
|
||||
id: report.Weekend,
|
||||
req: report.ResolveRequest{
|
||||
Now: mustParse("2026-05-29T05:00:00-05:00"),
|
||||
Location: location,
|
||||
},
|
||||
want: func(metadata state.Metadata) []string {
|
||||
return []string{
|
||||
"weekend/2026-05-29/" + metadata.RunID + ".md",
|
||||
"weekend/2026-05-29/index.md",
|
||||
}
|
||||
},
|
||||
source: "/managed/weekend.md",
|
||||
},
|
||||
{
|
||||
id: report.Storm,
|
||||
req: report.ResolveRequest{
|
||||
Now: now,
|
||||
Location: location,
|
||||
StormStart: mustParse("2026-05-29T18:00:00-05:00"),
|
||||
StormEnd: mustParse("2026-05-30T06:00:00-05:00"),
|
||||
},
|
||||
want: func(metadata state.Metadata) []string {
|
||||
return []string{
|
||||
"storm/2026-05-29T1800-2026-05-30T0600/" + metadata.RunID + ".md",
|
||||
"storm/2026-05-29T1800-2026-05-30T0600/index.md",
|
||||
}
|
||||
},
|
||||
source: "/managed/storm.md",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@@ -3644,9 +3329,7 @@ EOF
|
||||
;;
|
||||
*)
|
||||
cat > "$output" <<'EOF'
|
||||
# Generated Report
|
||||
|
||||
Prepared report body.
|
||||
{"summary":"Showers are possible during the selected day.","forecast_discussion":["A front will keep rain chances in the forecast.","Temperatures stay seasonable by afternoon."],"precipitation_timing":"Rain is most likely during the afternoon.","confidence":"Medium"}
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
@@ -4004,16 +3687,13 @@ type recordingRenderer struct {
|
||||
runCalls int
|
||||
structuredRunCalls int
|
||||
renderRequest scriptorium.RenderRequest
|
||||
runRequest scriptorium.RunRequest
|
||||
structuredRunRequest scriptorium.StructuredRunRequest
|
||||
renderResult *scriptorium.RenderResult
|
||||
runResult *scriptorium.RunResult
|
||||
structuredRunResult *scriptorium.StructuredRunResult
|
||||
err error
|
||||
runErr error
|
||||
structuredRunErr error
|
||||
runBody string
|
||||
structuredRunBody string
|
||||
runBody string
|
||||
}
|
||||
|
||||
type recordingCollector struct {
|
||||
@@ -4080,12 +3760,10 @@ func (s *recordingStore) SaveMetadata(ctx context.Context, metadata state.Metada
|
||||
return s.Store.SaveMetadata(ctx, metadata)
|
||||
}
|
||||
|
||||
func successfulRenderer(body string) *recordingRenderer {
|
||||
func successfulRenderer(_ string) *recordingRenderer {
|
||||
return &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
runResult: &scriptorium.RunResult{ExitCode: 0},
|
||||
structuredRunResult: &scriptorium.StructuredRunResult{ExitCode: 0},
|
||||
runBody: body,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4173,16 +3851,6 @@ func (r *selectiveRenderer) Render(_ context.Context, req scriptorium.RenderRequ
|
||||
return &scriptorium.RenderResult{ExitCode: 0}, nil
|
||||
}
|
||||
|
||||
func (r *selectiveRenderer) Run(_ context.Context, req scriptorium.RunRequest) (*scriptorium.RunResult, error) {
|
||||
r.runCalls++
|
||||
if r.runBody != "" {
|
||||
if err := os.WriteFile(req.OutputPath, []byte(r.runBody), 0o600); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &scriptorium.RunResult{ExitCode: 0, OutputPath: req.OutputPath}, nil
|
||||
}
|
||||
|
||||
func (r *selectiveRenderer) StructuredRun(_ context.Context, req scriptorium.StructuredRunRequest) (*scriptorium.StructuredRunResult, error) {
|
||||
r.structuredRunCalls++
|
||||
body := validHourlyGeneratedTextJSON()
|
||||
@@ -4207,20 +3875,6 @@ func (r *recordingRenderer) Render(_ context.Context, req scriptorium.RenderRequ
|
||||
return r.renderResult, r.err
|
||||
}
|
||||
|
||||
func (r *recordingRenderer) Run(_ context.Context, req scriptorium.RunRequest) (*scriptorium.RunResult, error) {
|
||||
r.runCalls++
|
||||
r.runRequest = req
|
||||
if r.runBody != "" {
|
||||
if err := os.WriteFile(req.OutputPath, []byte(r.runBody), 0o600); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if r.runResult != nil {
|
||||
r.runResult.OutputPath = req.OutputPath
|
||||
}
|
||||
return r.runResult, r.runErr
|
||||
}
|
||||
|
||||
func (r *recordingRenderer) StructuredRun(_ context.Context, req scriptorium.StructuredRunRequest) (*scriptorium.StructuredRunResult, error) {
|
||||
r.structuredRunCalls++
|
||||
r.structuredRunRequest = req
|
||||
|
||||
Reference in New Issue
Block a user