package webhookutil import ( "context" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/driver/sqlite" "gorm.io/gorm" "github.com/gochat/gochat/internal/model" ) func newTestDB(t *testing.T) *gorm.DB { t.Helper() db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) require.NoError(t, err) err = db.AutoMigrate(&model.InstallationConfig{}) require.NoError(t, err) return db } func TestTimeout_NilDB_ReturnsDefault(t *testing.T) { timeout := Timeout(context.Background(), nil) assert.Equal(t, DefaultTimeout, timeout) } func TestTimeout_NoConfigRow_ReturnsDefault(t *testing.T) { db := newTestDB(t) timeout := Timeout(context.Background(), db) assert.Equal(t, DefaultTimeout, timeout) } func TestTimeout_ValidConfig_ReturnsConfigured(t *testing.T) { db := newTestDB(t) err := db.Create(&model.InstallationConfig{ Name: TimeoutConfigName, Value: "10", }).Error require.NoError(t, err) timeout := Timeout(context.Background(), db) assert.Equal(t, 10*time.Second, timeout) } func TestTimeout_InvalidConfigValue_ReturnsDefault(t *testing.T) { db := newTestDB(t) err := db.Create(&model.InstallationConfig{ Name: TimeoutConfigName, Value: "not-a-number", }).Error require.NoError(t, err) timeout := Timeout(context.Background(), db) assert.Equal(t, DefaultTimeout, timeout) } func TestTimeout_ZeroOrNegative_ReturnsDefault(t *testing.T) { db := newTestDB(t) err := db.Create(&model.InstallationConfig{ Name: TimeoutConfigName, Value: "0", }).Error require.NoError(t, err) timeout := Timeout(context.Background(), db) assert.Equal(t, DefaultTimeout, timeout) } func TestTimeout_NegativeValue_ReturnsDefault(t *testing.T) { db := newTestDB(t) err := db.Create(&model.InstallationConfig{ Name: TimeoutConfigName, Value: "-5", }).Error require.NoError(t, err) timeout := Timeout(context.Background(), db) assert.Equal(t, DefaultTimeout, timeout) } func TestTimeout_WhitespaceValue_HandledCorrectly(t *testing.T) { db := newTestDB(t) err := db.Create(&model.InstallationConfig{ Name: TimeoutConfigName, Value: " 15 ", }).Error require.NoError(t, err) timeout := Timeout(context.Background(), db) assert.Equal(t, 15*time.Second, timeout) } func TestTimeout_DifferentConfigName_Ignored(t *testing.T) { db := newTestDB(t) err := db.Create(&model.InstallationConfig{ Name: "OTHER_CONFIG", Value: "99", }).Error require.NoError(t, err) timeout := Timeout(context.Background(), db) assert.Equal(t, DefaultTimeout, timeout) } func TestTimeout_ContextCancelled(t *testing.T) { db := newTestDB(t) ctx, cancel := context.WithCancel(context.Background()) cancel() // Even with cancelled context, should return default (db query will fail) timeout := Timeout(ctx, db) assert.Equal(t, DefaultTimeout, timeout) } func TestDefaultTimeout_Constant(t *testing.T) { assert.Equal(t, 5*time.Second, DefaultTimeout) } func TestTimeoutConfigName_Constant(t *testing.T) { assert.Equal(t, "WEBHOOK_TIMEOUT", TimeoutConfigName) }