Fix to ensure unique document IDs when batch reports are generated
This commit is contained in:
@@ -2409,6 +2409,97 @@ func TestRunBatchUsesOutputDirectory(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunBatchDynamicDailyReportsHaveDistinctIdentity(t *testing.T) {
|
||||
server := dailyBundleServer(t)
|
||||
cfg := dailyNotificationConfig(t, server)
|
||||
collection := collectionWithFutureDailyForTest(t, cfg, "2026-05-31", "2026-06-01")
|
||||
cfg.WeatherAPI.BaseURL = ""
|
||||
collector := &recordingCollector{result: &collection}
|
||||
notifier := &recordingNotifier{}
|
||||
outputDir := filepath.Join(t.TempDir(), "reports")
|
||||
|
||||
result, err := RunBatchDetailed(context.Background(), BatchRequest{
|
||||
Config: cfg,
|
||||
Batch: BatchEvening,
|
||||
Now: mustParse("2026-05-29T18:00:00-05:00"),
|
||||
OutputDir: outputDir,
|
||||
Collector: collector,
|
||||
Renderer: &selectiveRenderer{runBody: "# Batch Report\n"},
|
||||
Notifier: notifier,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("RunBatchDetailed() error = %v", err)
|
||||
}
|
||||
if result.Failed != 0 || len(result.Reports) != 3 {
|
||||
t.Fatalf("summary = %#v, want three successful reports", result)
|
||||
}
|
||||
if len(notifier.requests) != 3 {
|
||||
t.Fatalf("notification requests = %d, want one per report", len(notifier.requests))
|
||||
}
|
||||
|
||||
dailyByDate := map[string]BatchReportResult{}
|
||||
runIDs := map[string]struct{}{}
|
||||
reportPaths := map[string]struct{}{}
|
||||
metadataPaths := map[string]struct{}{}
|
||||
dataPackagePaths := map[string]struct{}{}
|
||||
for _, item := range result.Reports {
|
||||
if _, ok := runIDs[item.RunID]; ok {
|
||||
t.Fatalf("duplicate RunID in batch result: %q", item.RunID)
|
||||
}
|
||||
runIDs[item.RunID] = struct{}{}
|
||||
if _, ok := reportPaths[item.ReportPath]; ok {
|
||||
t.Fatalf("duplicate ReportPath in batch result: %q", item.ReportPath)
|
||||
}
|
||||
reportPaths[item.ReportPath] = struct{}{}
|
||||
if _, ok := metadataPaths[item.MetadataPath]; ok {
|
||||
t.Fatalf("duplicate MetadataPath in batch result: %q", item.MetadataPath)
|
||||
}
|
||||
metadataPaths[item.MetadataPath] = struct{}{}
|
||||
if _, ok := dataPackagePaths[item.DataPackagePath]; ok {
|
||||
t.Fatalf("duplicate DataPackagePath in batch result: %q", item.DataPackagePath)
|
||||
}
|
||||
dataPackagePaths[item.DataPackagePath] = struct{}{}
|
||||
if item.ReportID == report.Daily {
|
||||
if !strings.HasPrefix(item.RunID, "20260529T230000.000000000Z_daily_") {
|
||||
t.Fatalf("Daily RunID = %q, want dated daily run id", item.RunID)
|
||||
}
|
||||
date := strings.TrimPrefix(filepath.Base(item.OutputPath), "daily-")
|
||||
date = strings.TrimSuffix(date, ".md")
|
||||
dailyByDate[date] = item
|
||||
}
|
||||
}
|
||||
|
||||
for _, date := range []string{"2026-05-31", "2026-06-01"} {
|
||||
item, ok := dailyByDate[date]
|
||||
if !ok {
|
||||
t.Fatalf("daily outputs = %#v, want Daily output for %s", dailyByDate, date)
|
||||
}
|
||||
if item.RunID != "20260529T230000.000000000Z_daily_"+date {
|
||||
t.Fatalf("Daily %s RunID = %q, want date disambiguator", date, item.RunID)
|
||||
}
|
||||
if item.OutputPath != filepath.Join(outputDir, "daily-"+date+".md") {
|
||||
t.Fatalf("Daily %s OutputPath = %q, want date-qualified copy", date, item.OutputPath)
|
||||
}
|
||||
}
|
||||
|
||||
dailyKeys := map[string]struct{}{}
|
||||
for _, req := range notifier.requests {
|
||||
if req.ReportID != report.Daily {
|
||||
continue
|
||||
}
|
||||
if req.IdempotencyKey != req.BundleID+"."+req.RunID {
|
||||
t.Fatalf("Daily idempotency key = %q, want bundle id plus run id", req.IdempotencyKey)
|
||||
}
|
||||
if _, ok := dailyKeys[req.IdempotencyKey]; ok {
|
||||
t.Fatalf("duplicate Daily idempotency key: %q", req.IdempotencyKey)
|
||||
}
|
||||
dailyKeys[req.IdempotencyKey] = struct{}{}
|
||||
}
|
||||
if len(dailyKeys) != 2 {
|
||||
t.Fatalf("Daily notification keys = %#v, want two distinct keys", dailyKeys)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunBatchMorningUsesTodayOutputName(t *testing.T) {
|
||||
server := dailyBundleServer(t)
|
||||
cfg := dailyWorkspaceConfig(t, server)
|
||||
@@ -2514,11 +2605,13 @@ func collectionForTest(t *testing.T, cfg config.Config) collect.Result {
|
||||
return collect.Result{Bundle: bundle}
|
||||
}
|
||||
|
||||
func collectionWithFutureDailyForTest(t *testing.T, cfg config.Config, date string) collect.Result {
|
||||
func collectionWithFutureDailyForTest(t *testing.T, cfg config.Config, dates ...string) collect.Result {
|
||||
t.Helper()
|
||||
collection := collectionForTest(t, cfg)
|
||||
location := mustLoadTestLocation(t, cfg.WeatherAPI.Timezone)
|
||||
collection.Bundle.Hourly.Periods = append(collection.Bundle.Hourly.Periods, fullDayPeriods(t, date, location)...)
|
||||
for _, date := range dates {
|
||||
collection.Bundle.Hourly.Periods = append(collection.Bundle.Hourly.Periods, fullDayPeriods(t, date, location)...)
|
||||
}
|
||||
return collection
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user