package audit import ( "context" "errors" "testing" "ai-operator/internal/config" ) type failingRepo struct{} func (failingRepo) Health(context.Context) error { return errors.New("secret postgres://u:pass@localhost/db") } func (failingRepo) UpsertCall(context.Context, CallRecord) error { return errors.New("write failed") } func (failingRepo) EndCall(context.Context, string, string) error { return errors.New("write failed") } func (failingRepo) AddEvent(context.Context, EventRecord) error { return errors.New("write failed") } func (failingRepo) AddTranscript(context.Context, TranscriptRecord) error { return errors.New("write failed") } func (failingRepo) AddToolAudit(context.Context, ToolAuditRecord) error { return errors.New("write failed") } func (failingRepo) AddKBAudit(context.Context, KBAuditRecord) error { return errors.New("write failed") } func (failingRepo) AddHandoffAudit(context.Context, HandoffAuditRecord) error { return errors.New("write failed") } func (failingRepo) AddProviderAudit(context.Context, ProviderAuditRecord) error { return errors.New("write failed") } func (failingRepo) AddMediaAudit(context.Context, MediaAuditRecord) error { return errors.New("write failed") } func (failingRepo) ExportCall(context.Context, string) (CallAuditExport, error) { return CallAuditExport{}, errors.New("write failed") } func (failingRepo) Prune(context.Context, RetentionPruneRequest) (RetentionPruneResult, error) { return RetentionPruneResult{}, errors.New("write failed") } func TestAuditServiceFailOpen(t *testing.T) { svc := NewService(failingRepo{}, config.AuditConfig{Enabled: true, Sink: "postgres", FailClosed: false, RedactionEnabled: true, MaxEventMetadataChars: 100, MaxTranscriptChars: 100}, nil) if err := svc.AddEvent(context.Background(), EventRecord{CallID: "c", EventType: "call.started"}); err != nil { t.Fatalf("fail-open returned error: %v", err) } } func TestAuditServiceFailClosed(t *testing.T) { svc := NewService(failingRepo{}, config.AuditConfig{Enabled: true, Sink: "postgres", FailClosed: true, RedactionEnabled: true, MaxEventMetadataChars: 100, MaxTranscriptChars: 100}, nil) if err := svc.AddEvent(context.Background(), EventRecord{CallID: "c", EventType: "call.started"}); err == nil { t.Fatal("fail-closed did not return error") } } func TestNoopRepository(t *testing.T) { svc := NewService(NoopRepository{}, config.AuditConfig{Enabled: false}, nil) if err := svc.AddTranscript(context.Background(), TranscriptRecord{CallID: "c", Speaker: "user", EventType: "transcript.user.final", Text: "+77771234567"}); err != nil { t.Fatalf("noop returned error: %v", err) } }