package discovery import ( "context" "errors" "testing" "time" ) func TestDuplicateJobsAndEventsAreIdempotent(t *testing.T) { store := NewMemoryStore() r := Runner{Store: store, MaxAttempts: 1} discover := func(context.Context) ([]Event, error) { return []Event{{SourceID: "s", DedupKey: "entity:1", Type: "changed", Summary: "changed", OccurredAt: time.Now().UTC()}}, nil } if err := r.Run(context.Background(), "source:s:window:1", discover); err != nil { t.Fatal(err) } if err := r.Run(context.Background(), "source:s:window:1", discover); err != nil { t.Fatal(err) } if len(store.Runs) != 1 || len(store.Events) != 1 { t.Fatalf("duplicate result: runs=%d events=%d", len(store.Runs), len(store.Events)) } } func TestRetryAndCancellationSafe(t *testing.T) { store := NewMemoryStore() attempts := 0 r := Runner{Store: store, MaxAttempts: 3, BaseRetry: time.Millisecond} err := r.Run(context.Background(), "retry", func(context.Context) ([]Event, error) { attempts++ if attempts < 3 { return nil, errors.New("temporary") } return nil, nil }) if err != nil || attempts != 3 || store.Runs[0].Status != "succeeded" { t.Fatalf("retry result err=%v attempts=%d runs=%+v", err, attempts, store.Runs) } } func TestManualRunRequiresAuthorizationAndAudits(t *testing.T) { store := NewMemoryStore() r := Runner{Store: store, MaxAttempts: 1} if err := r.RunManual(context.Background(), "user", func(context.Context, string) bool { return false }, nil, "manual", func(context.Context) ([]Event, error) { return nil, nil }); err == nil { t.Fatal("expected unauthorized error") } audited := false if err := r.RunManual(context.Background(), "user", func(context.Context, string) bool { return true }, func(context.Context, string, string) error { audited = true; return nil }, "manual", func(context.Context) ([]Event, error) { return nil, nil }); err != nil || !audited { t.Fatalf("manual run err=%v audited=%v", err, audited) } }