Add Today report to morning batch
This commit is contained in:
@@ -1338,6 +1338,93 @@ func TestGenerateReportIncludesRecentChangesFromPriorSnapshot(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTodayReportUsesTodayIdentityAndRecentChanges(t *testing.T) {
|
||||
server := dailyBundleServer(t)
|
||||
cfg := config.Defaults()
|
||||
cfg.WeatherAPI.BaseURL = server.URL + "/"
|
||||
cfg.WeatherAPI.Timezone = "America/Chicago"
|
||||
cfg.Workspace.Root = t.TempDir()
|
||||
store, err := state.NewFilesystemStore(cfg.Workspace)
|
||||
if err != nil {
|
||||
t.Fatalf("NewFilesystemStore() error = %v", err)
|
||||
}
|
||||
priorResolved, err := ResolveGenerate(GenerateRequest{
|
||||
Config: cfg,
|
||||
Report: ReportKind(report.CommandNameToday),
|
||||
Date: mustParse("2026-05-29T12:00:00-05:00"),
|
||||
}, mustParse("2026-05-29T04:00:00-05:00"))
|
||||
if err != nil {
|
||||
t.Fatalf("ResolveGenerate(prior) error = %v", err)
|
||||
}
|
||||
savePriorRun(t, store, priorResolved, priorDailyModuleSnapshot(t, priorResolved))
|
||||
|
||||
currentResolved, err := ResolveGenerate(GenerateRequest{
|
||||
Config: cfg,
|
||||
Report: ReportKind(report.CommandNameToday),
|
||||
Date: mustParse("2026-05-29T12:00:00-05:00"),
|
||||
}, mustParse("2026-05-29T05:00:00-05:00"))
|
||||
if err != nil {
|
||||
t.Fatalf("ResolveGenerate(current) error = %v", err)
|
||||
}
|
||||
renderer := &recordingRenderer{
|
||||
renderResult: &scriptorium.RenderResult{ExitCode: 0},
|
||||
structuredRunResult: &scriptorium.StructuredRunResult{ExitCode: 0},
|
||||
structuredRunBody: validTodayGeneratedTextJSON(),
|
||||
}
|
||||
|
||||
result, err := GenerateReport(context.Background(), ReportRequest{
|
||||
Config: cfg,
|
||||
Resolved: currentResolved,
|
||||
Renderer: renderer,
|
||||
Store: store,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateReport() error = %v", err)
|
||||
}
|
||||
if renderer.runCalls != 0 || renderer.structuredRunCalls != 1 {
|
||||
t.Fatalf("renderer calls run=%d structured=%d, want generated-text flow", renderer.runCalls, renderer.structuredRunCalls)
|
||||
}
|
||||
if result.Metadata.ReportID != report.Today || result.Metadata.Variant != "today" || result.Metadata.GeneratedTextSchemaID != "today" {
|
||||
t.Fatalf("metadata = %#v, want Today generated-text metadata", result.Metadata)
|
||||
}
|
||||
if !strings.Contains(result.Metadata.RunID, "_today") {
|
||||
t.Fatalf("RunID = %q, want Today report ID suffix", result.Metadata.RunID)
|
||||
}
|
||||
if !strings.Contains(result.DataPackagePath, filepath.Join("data-packages", "today", "2026-05-29")) {
|
||||
t.Fatalf("DataPackagePath = %q, want Today artifact group", result.DataPackagePath)
|
||||
}
|
||||
if !strings.Contains(result.ReportPath, filepath.Join("reports", "today")) {
|
||||
t.Fatalf("ReportPath = %q, want Today report group", result.ReportPath)
|
||||
}
|
||||
if _, ok := result.ModuleSnapshot.LookupStanza("today_planning"); !ok {
|
||||
t.Fatal("today_planning stanza missing")
|
||||
}
|
||||
if _, ok := result.ModuleSnapshot.LookupStanza("tomorrow_planning"); ok {
|
||||
t.Fatal("tomorrow_planning stanza present, want Today-specific planning")
|
||||
}
|
||||
if result.PriorSnapshot == nil || len(result.RecentChanges) == 0 {
|
||||
t.Fatalf("prior=%#v recentChanges=%#v, want Today daily comparison changes", result.PriorSnapshot, result.RecentChanges)
|
||||
}
|
||||
data, err := os.ReadFile(result.DataPackagePath)
|
||||
if err != nil {
|
||||
t.Fatalf("read data package: %v", err)
|
||||
}
|
||||
for _, want := range []string{"id: today", "prompt_id: weather.today_generated_text", "today_planning:", "recent_changes:"} {
|
||||
if !strings.Contains(string(data), want) {
|
||||
t.Fatalf("data package missing %q:\n%s", want, string(data))
|
||||
}
|
||||
}
|
||||
reportData, err := os.ReadFile(result.ReportPath)
|
||||
if err != nil {
|
||||
t.Fatalf("read report: %v", err)
|
||||
}
|
||||
for _, want := range []string{"# Today's Weather", "Today starts with showers before improving."} {
|
||||
if !strings.Contains(string(reportData), want) {
|
||||
t.Fatalf("today report missing %q:\n%s", want, string(reportData))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTomorrowReportUsesTomorrowBriefingDate(t *testing.T) {
|
||||
server := dailyBundleServer(t)
|
||||
cfg := config.Defaults()
|
||||
@@ -2072,8 +2159,8 @@ func TestRunBatchContinuesAfterReportFailure(t *testing.T) {
|
||||
if result.Total != 3 || result.Succeeded != 2 || result.Failed != 1 {
|
||||
t.Fatalf("summary total/succeeded/failed = %d/%d/%d, want 3/2/1", result.Total, result.Succeeded, result.Failed)
|
||||
}
|
||||
if renderer.runCalls != 2 {
|
||||
t.Fatalf("run calls = %d, want successful reports to continue", renderer.runCalls)
|
||||
if renderer.runCalls != 1 || renderer.structuredRunCalls != 1 {
|
||||
t.Fatalf("renderer calls run=%d structured=%d, want successful reports to continue", renderer.runCalls, renderer.structuredRunCalls)
|
||||
}
|
||||
var failedThreeDay bool
|
||||
for _, item := range result.Reports {
|
||||
@@ -2316,6 +2403,10 @@ func validTomorrowGeneratedTextJSON() string {
|
||||
return `{"summary":"Tomorrow starts with showers before improving.","forecast_discussion":["Morning showers should taper as drier air arrives.","Afternoon conditions trend quieter."],"precipitation_timing":"The best rain chance is during the morning."}`
|
||||
}
|
||||
|
||||
func validTodayGeneratedTextJSON() string {
|
||||
return `{"summary":"Today starts with showers before improving.","forecast_discussion":["Morning showers should taper as drier air arrives.","Afternoon conditions trend quieter."],"precipitation_timing":"The best rain chance is during the morning."}`
|
||||
}
|
||||
|
||||
func generateDailyReportForTest(t *testing.T, cfg config.Config) *ReportResult {
|
||||
t.Helper()
|
||||
cfg.Workspace.Root = t.TempDir()
|
||||
@@ -2671,6 +2762,9 @@ func (r *selectiveRenderer) Run(_ context.Context, req scriptorium.RunRequest) (
|
||||
func (r *selectiveRenderer) StructuredRun(_ context.Context, req scriptorium.StructuredRunRequest) (*scriptorium.StructuredRunResult, error) {
|
||||
r.structuredRunCalls++
|
||||
body := validHourlyGeneratedTextJSON()
|
||||
if req.PromptID == "weather.today_generated_text" {
|
||||
body = validTodayGeneratedTextJSON()
|
||||
}
|
||||
if req.PromptID == "weather.tomorrow_generated_text" {
|
||||
body = validTomorrowGeneratedTextJSON()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user