package audit

import (
	"context"
	"database/sql"
	"testing"
)

func failureEvent() AuditEvent {
	return AuditEvent{
		ObjectApiName: "Account",
		RecordId:      "001-record",
		Action:        ActionCreate,
		ChangedById:   "005-user",
		Entrypoint:    EntrypointRestAPI,
		Outcome:       OutcomeFailure,
		ErrorCode:     "VALIDATION",
		ChangesJSON:   `{"rejectionStage":"validation_rule","rule":"Block_Everything"}`,
	}
}

// TestNewDBFailureEmitter_NilDBFailsLoudly pins the typed-nil-in-interface
// trap. Callers assign the result to an audit.FailureSink; a nil
// *DBFailureEmitter stored in that interface would compare non-nil, pass
// every enabled-check, and then be dereferenced. So a nil db must produce a
// usable value that reports an error, not a nil pointer.
func TestNewDBFailureEmitter_NilDBFailsLoudly(t *testing.T) {
	var db *sql.DB
	emitter := NewDBFailureEmitter(db)
	if emitter == nil {
		t.Fatal("NewDBFailureEmitter(nil) = nil; a nil pointer in a FailureSink interface is not nil and would be dereferenced")
	}

	var sink FailureSink = emitter
	err := sink.EmitFailure(context.Background(), failureEvent())
	if err == nil {
		t.Fatal("EmitFailure() on a db-less emitter returned nil; want a loud error")
	}
}
