package jwt import ( "context" "testing" "github.com/DATA-DOG/go-sqlmock" "github.com/stretchr/testify/require" ) func TestNewTableManager(t *testing.T) { db, _, err := sqlmock.New() require.NoError(t, err) defer db.Close() dbType := DatabaseType{Type: DatabasePostgreSQL, Version: "15"} config := DefaultTableConfig() tm := NewTableManager(db, dbType, config) require.NotNil(t, tm) } func TestGetCreateTableSQL_PostgreSQL(t *testing.T) { db, _, err := sqlmock.New() require.NoError(t, err) defer db.Close() dbType := DatabaseType{Type: DatabasePostgreSQL, Version: "15"} config := DefaultTableConfig() tm := NewTableManager(db, dbType, config) sql, err := tm.getCreateTableSQL() require.NoError(t, err) require.Contains(t, sql, "CREATE TABLE IF NOT EXISTS jwtblacklist") require.Contains(t, sql, "jti UUID PRIMARY KEY") require.Contains(t, sql, "exp BIGINT NOT NULL") require.Contains(t, sql, "sub INTEGER NOT NULL") require.Contains(t, sql, "CREATE INDEX IF NOT EXISTS idx_jwtblacklist_exp") require.Contains(t, sql, "CREATE INDEX IF NOT EXISTS idx_jwtblacklist_sub") } func TestGetCreateTableSQL_MySQL(t *testing.T) { db, _, err := sqlmock.New() require.NoError(t, err) defer db.Close() dbType := DatabaseType{Type: DatabaseMySQL, Version: "8.0"} config := DefaultTableConfig() tm := NewTableManager(db, dbType, config) sql, err := tm.getCreateTableSQL() require.NoError(t, err) require.Contains(t, sql, "CREATE TABLE IF NOT EXISTS jwtblacklist") require.Contains(t, sql, "jti CHAR(36) PRIMARY KEY") require.Contains(t, sql, "exp BIGINT NOT NULL") require.Contains(t, sql, "sub INT NOT NULL") require.Contains(t, sql, "INDEX idx_exp") require.Contains(t, sql, "ENGINE=InnoDB") } func TestGetCreateTableSQL_SQLite(t *testing.T) { db, _, err := sqlmock.New() require.NoError(t, err) defer db.Close() dbType := DatabaseType{Type: DatabaseSQLite, Version: "3.42"} config := DefaultTableConfig() tm := NewTableManager(db, dbType, config) sql, err := tm.getCreateTableSQL() require.NoError(t, err) require.Contains(t, sql, "CREATE TABLE IF NOT EXISTS jwtblacklist") require.Contains(t, sql, "jti TEXT PRIMARY KEY") require.Contains(t, sql, "exp INTEGER NOT NULL") require.Contains(t, sql, "sub INTEGER NOT NULL") } func TestGetCreateTableSQL_CustomTableName(t *testing.T) { db, _, err := sqlmock.New() require.NoError(t, err) defer db.Close() dbType := DatabaseType{Type: DatabasePostgreSQL, Version: "15"} config := TableConfig{ TableName: "custom_blacklist", AutoCreate: true, EnableAutoCleanup: false, CleanupInterval: 24, } tm := NewTableManager(db, dbType, config) sql, err := tm.getCreateTableSQL() require.NoError(t, err) require.Contains(t, sql, "CREATE TABLE IF NOT EXISTS custom_blacklist") require.Contains(t, sql, "CREATE INDEX IF NOT EXISTS idx_custom_blacklist_exp") } func TestGetCreateTableSQL_UnsupportedDB(t *testing.T) { db, _, err := sqlmock.New() require.NoError(t, err) defer db.Close() dbType := DatabaseType{Type: "unsupported", Version: "1.0"} config := DefaultTableConfig() tm := NewTableManager(db, dbType, config) sql, err := tm.getCreateTableSQL() require.Error(t, err) require.Empty(t, sql) require.Contains(t, err.Error(), "unsupported database type") } func TestTableExists_PostgreSQL(t *testing.T) { db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() dbType := DatabaseType{Type: DatabasePostgreSQL, Version: "15"} config := DefaultTableConfig() tm := NewTableManager(db, dbType, config) // Test table exists mock.ExpectQuery("SELECT 1 FROM information_schema.tables"). WithArgs("jwtblacklist"). WillReturnRows(sqlmock.NewRows([]string{"1"}).AddRow(1)) exists, err := tm.tableExists(context.Background()) require.NoError(t, err) require.True(t, exists) // Test table doesn't exist mock.ExpectQuery("SELECT 1 FROM information_schema.tables"). WithArgs("jwtblacklist"). WillReturnRows(sqlmock.NewRows([]string{"1"})) exists, err = tm.tableExists(context.Background()) require.NoError(t, err) require.False(t, exists) require.NoError(t, mock.ExpectationsWereMet()) } func TestCreateTable_AlreadyExists(t *testing.T) { db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() dbType := DatabaseType{Type: DatabasePostgreSQL, Version: "15"} config := DefaultTableConfig() tm := NewTableManager(db, dbType, config) // Mock table exists check mock.ExpectQuery("SELECT 1 FROM information_schema.tables"). WithArgs("jwtblacklist"). WillReturnRows(sqlmock.NewRows([]string{"1"}).AddRow(1)) err = tm.CreateTable(context.Background()) require.NoError(t, err) require.NoError(t, mock.ExpectationsWereMet()) } func TestCreateTable_Success(t *testing.T) { db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() dbType := DatabaseType{Type: DatabasePostgreSQL, Version: "15"} config := DefaultTableConfig() tm := NewTableManager(db, dbType, config) // Mock table doesn't exist mock.ExpectQuery("SELECT 1 FROM information_schema.tables"). WithArgs("jwtblacklist"). WillReturnRows(sqlmock.NewRows([]string{"1"})) // Mock CREATE TABLE mock.ExpectExec("CREATE TABLE IF NOT EXISTS jwtblacklist"). WillReturnResult(sqlmock.NewResult(0, 0)) err = tm.CreateTable(context.Background()) require.NoError(t, err) require.NoError(t, mock.ExpectationsWereMet()) } func TestSetupAutoCleanup_Disabled(t *testing.T) { db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() dbType := DatabaseType{Type: DatabasePostgreSQL, Version: "15"} config := TableConfig{ TableName: "jwtblacklist", AutoCreate: true, EnableAutoCleanup: false, CleanupInterval: 24, } tm := NewTableManager(db, dbType, config) err = tm.SetupAutoCleanup(context.Background()) require.NoError(t, err) require.NoError(t, mock.ExpectationsWereMet()) } func TestSetupAutoCleanup_SQLite(t *testing.T) { db, mock, err := sqlmock.New() require.NoError(t, err) defer db.Close() dbType := DatabaseType{Type: DatabaseSQLite, Version: "3.42"} config := DefaultTableConfig() tm := NewTableManager(db, dbType, config) // SQLite doesn't support auto-cleanup, should return nil err = tm.SetupAutoCleanup(context.Background()) require.NoError(t, err) require.NoError(t, mock.ExpectationsWereMet()) }