Add batch notification app identity types

This commit is contained in:
2026-06-17 20:44:34 +00:00
parent f1d4e38414
commit a82f03feb8
3 changed files with 205 additions and 7 deletions

View File

@@ -2214,6 +2214,122 @@ func TestResolveGenerateStorm(t *testing.T) {
}
}
func TestBatchRunIDUsesUTCStartAndBatchName(t *testing.T) {
tests := []struct {
name string
startedAt time.Time
batch BatchKind
want string
}{
{
name: "morning",
startedAt: mustParse("2026-05-29T05:00:00-05:00"),
batch: BatchMorning,
want: "20260529T100000.000000000Z_morning",
},
{
name: "evening",
startedAt: mustParse("2026-05-29T18:30:45-05:00"),
batch: BatchEvening,
want: "20260529T233045.000000000Z_evening",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := batchRunID(tt.startedAt, tt.batch); got != tt.want {
t.Fatalf("batchRunID() = %q, want %q", got, tt.want)
}
})
}
}
func TestRenderBatchNotificationIdentity(t *testing.T) {
cfg := config.Defaults()
cfg.Location.ID = "home"
cfg.WeatherAPI.Timezone = "America/Chicago"
cfg.Notify.Distributor.Batch.PipelineIDTemplate = "weatherreporter.{batch_started_date}"
cfg.Notify.Distributor.Batch.BundleIDTemplate = "weatherreporter.{location_id}.{batch}"
cfg.Notify.Distributor.Batch.IdempotencyKeyTemplate = "{bundle_id}.{batch_run_id}"
startedAt := mustParse("2026-05-30T03:30:00Z")
runID := batchRunID(startedAt, BatchEvening)
identity, err := renderBatchNotificationIdentity(cfg, BatchEvening, runID, startedAt)
if err != nil {
t.Fatalf("renderBatchNotificationIdentity() error = %v", err)
}
if identity.PipelineID != "weatherreporter.2026-05-29" {
t.Fatalf("PipelineID = %q, want local batch date", identity.PipelineID)
}
if identity.BundleID != "weatherreporter.home.evening" {
t.Fatalf("BundleID = %q, want rendered bundle id", identity.BundleID)
}
wantKey := "weatherreporter.home.evening.20260530T033000.000000000Z_evening"
if identity.IdempotencyKey != wantKey {
t.Fatalf("IdempotencyKey = %q, want %q", identity.IdempotencyKey, wantKey)
}
}
func TestBatchResultJSONOmitsNilNotification(t *testing.T) {
data, err := json.Marshal(BatchResult{
Batch: BatchMorning,
Reports: []BatchReportResult{},
})
if err != nil {
t.Fatalf("Marshal() error = %v", err)
}
if strings.Contains(string(data), "notification") {
t.Fatalf("BatchResult JSON = %s, want no notification field", data)
}
}
func TestBatchResultJSONIncludesNotification(t *testing.T) {
result := BatchResult{
Batch: BatchEvening,
Notification: &BatchNotificationResult{
Status: "accepted",
RunID: "distributor-run",
PipelineID: "weatherreporter",
BundleID: "weatherreporter.home.evening",
IdempotencyKey: "weatherreporter.home.evening.20260529T233000.000000000Z_evening",
Path: "notifications/batches/evening/2026-05-29/20260529T233000.000000000Z_evening.distributor.json",
IncludedReports: []BatchNotificationReport{
{
ReportID: report.Tomorrow,
RunID: "20260529T233000.000000000Z_tomorrow",
SourcePath: "reports/tomorrow.md",
BundlePaths: []string{"tomorrow/index.md"},
},
},
},
Reports: []BatchReportResult{},
}
data, err := json.Marshal(result)
if err != nil {
t.Fatalf("Marshal() error = %v", err)
}
for _, want := range []string{
`"notification":{`,
`"status":"accepted"`,
`"runId":"distributor-run"`,
`"pipelineId":"weatherreporter"`,
`"bundleId":"weatherreporter.home.evening"`,
`"idempotencyKey":"weatherreporter.home.evening.20260529T233000.000000000Z_evening"`,
`"path":"notifications/batches/evening/2026-05-29/20260529T233000.000000000Z_evening.distributor.json"`,
`"includedReports":[`,
`"reportId":"tomorrow"`,
`"sourcePath":"reports/tomorrow.md"`,
`"bundlePaths":["tomorrow/index.md"]`,
} {
if !strings.Contains(string(data), want) {
t.Fatalf("BatchResult JSON = %s, want %s", data, want)
}
}
}
func TestRunBatchContinuesAfterReportFailure(t *testing.T) {
server := dailyBundleServer(t)
cfg := dailyWorkspaceConfig(t, server)