package jwt import ( "database/sql" "testing" "time" "github.com/DATA-DOG/go-sqlmock" "github.com/google/uuid" "github.com/stretchr/testify/require" ) func newGeneratorWithNoDB(t *testing.T) *TokenGenerator { gen, err := CreateGenerator(GeneratorConfig{ AccessExpireAfter: 15, RefreshExpireAfter: 60, FreshExpireAfter: 5, TrustedHost: "example.com", SecretKey: "supersecret", DB: nil, DBType: DatabaseType{Type: DatabasePostgreSQL, Version: "15"}, TableConfig: DefaultTableConfig(), }) require.NoError(t, err) return gen } func newGeneratorWithMockDB(t *testing.T) (*TokenGenerator, sqlmock.Sqlmock, func()) { db, mock, err := sqlmock.New() require.NoError(t, err) config := DefaultTableConfig() config.AutoCreate = false config.EnableAutoCleanup = false gen, err := CreateGenerator(GeneratorConfig{ AccessExpireAfter: 15, RefreshExpireAfter: 60, FreshExpireAfter: 5, TrustedHost: "example.com", SecretKey: "supersecret", DB: db, DBType: DatabaseType{Type: DatabasePostgreSQL, Version: "15"}, TableConfig: config, }) require.NoError(t, err) return gen, mock, func() { db.Close() } } func TestNoDBFail(t *testing.T) { jti := uuid.New() exp := time.Now().Add(time.Hour).Unix() token := AccessToken{ JTI: jti, EXP: exp, SUB: 42, gen: &TokenGenerator{}, } // Create a nil transaction (can't revoke without DB) var tx *sql.Tx = nil // Revoke should fail due to no DB err := token.Revoke(tx) require.Error(t, err) // CheckNotRevoked should fail _, err = token.CheckNotRevoked(tx) require.Error(t, err) } func TestRevokeAndCheckNotRevoked(t *testing.T) { gen, mock, cleanup := newGeneratorWithMockDB(t) defer cleanup() jti := uuid.New() exp := time.Now().Add(time.Hour).Unix() sub := 42 token := AccessToken{ JTI: jti, EXP: exp, SUB: sub, gen: gen, } // Revoke expectations mock.ExpectBegin() mock.ExpectExec(`INSERT INTO jwtblacklist`). WithArgs(jti.String(), exp, sub). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectQuery(`SELECT 1 FROM jwtblacklist`). WithArgs(jti.String()). WillReturnRows(sqlmock.NewRows([]string{"1"}).AddRow(1)) mock.ExpectCommit() tx, err := gen.db.Begin() defer tx.Rollback() require.NoError(t, err) err = token.Revoke(tx) require.NoError(t, err) valid, err := token.CheckNotRevoked(tx) require.NoError(t, err) require.False(t, valid) require.NoError(t, tx.Commit()) require.NoError(t, mock.ExpectationsWereMet()) }