227 lines
8.5 KiB
Go
227 lines
8.5 KiB
Go
package jobs
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
"veza-backend-api/internal/database"
|
|
"veza-backend-api/internal/models"
|
|
)
|
|
|
|
// setupTestPasswordResetCleanupDB crée une base de données de test avec la table password_reset_tokens
|
|
func setupTestPasswordResetCleanupDB(t *testing.T) (*database.Database, *gorm.DB) {
|
|
// Créer une base de données GORM en mémoire
|
|
gormDB, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
require.NoError(t, err, "Failed to open test database")
|
|
|
|
// Auto-migrate pour créer la table users
|
|
err = gormDB.AutoMigrate(&models.User{})
|
|
require.NoError(t, err, "Failed to migrate users table")
|
|
|
|
// Créer la table password_reset_tokens manuellement
|
|
err = gormDB.Exec(`
|
|
CREATE TABLE password_reset_tokens (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
token TEXT NOT NULL UNIQUE,
|
|
expires_at TIMESTAMP NOT NULL,
|
|
used INTEGER NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`).Error
|
|
require.NoError(t, err, "Failed to create password_reset_tokens table")
|
|
|
|
// Créer un utilisateur de test
|
|
user := &models.User{
|
|
Email: "test@example.com",
|
|
Username: "testuser",
|
|
Role: "user",
|
|
IsActive: true,
|
|
}
|
|
err = gormDB.Create(user).Error
|
|
require.NoError(t, err, "Failed to create test user")
|
|
|
|
// Obtenir le sql.DB depuis GORM
|
|
sqlDB, err := gormDB.DB()
|
|
require.NoError(t, err, "Failed to get sql.DB from GORM")
|
|
|
|
// Créer un Database wrapper
|
|
testDB := &database.Database{
|
|
DB: sqlDB,
|
|
}
|
|
|
|
return testDB, gormDB
|
|
}
|
|
|
|
// TestCleanupExpiredPasswordResetTokens_ExpiredTokens supprime les tokens expirés
|
|
func TestCleanupExpiredPasswordResetTokens_ExpiredTokens(t *testing.T) {
|
|
testDB, gormDB := setupTestPasswordResetCleanupDB(t)
|
|
logger, _ := zap.NewDevelopment()
|
|
|
|
// Créer des tokens expirés
|
|
expiredTime := time.Now().Add(-25 * time.Hour) // Expiré il y a 25 heures
|
|
err := gormDB.Exec(`
|
|
INSERT INTO password_reset_tokens (user_id, token, expires_at, used, created_at)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`, 1, "expired_token_1", expiredTime, false, time.Now().Add(-26*time.Hour)).Error
|
|
require.NoError(t, err)
|
|
|
|
err = gormDB.Exec(`
|
|
INSERT INTO password_reset_tokens (user_id, token, expires_at, used, created_at)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`, 1, "expired_token_2", expiredTime, false, time.Now().Add(-26*time.Hour)).Error
|
|
require.NoError(t, err)
|
|
|
|
// Créer un token valide (non expiré)
|
|
validTime := time.Now().Add(24 * time.Hour)
|
|
err = gormDB.Exec(`
|
|
INSERT INTO password_reset_tokens (user_id, token, expires_at, used, created_at)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`, 1, "valid_token", validTime, false, time.Now()).Error
|
|
require.NoError(t, err)
|
|
|
|
// Exécuter le nettoyage
|
|
err = CleanupExpiredPasswordResetTokens(testDB, logger)
|
|
assert.NoError(t, err)
|
|
|
|
// Vérifier que les tokens expirés ont été supprimés
|
|
var count int64
|
|
err = gormDB.Raw("SELECT COUNT(*) FROM password_reset_tokens WHERE token IN ('expired_token_1', 'expired_token_2')").Scan(&count).Error
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(0), count, "Expired tokens should be deleted")
|
|
|
|
// Vérifier que le token valide est toujours présent
|
|
err = gormDB.Raw("SELECT COUNT(*) FROM password_reset_tokens WHERE token = 'valid_token'").Scan(&count).Error
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(1), count, "Valid token should still exist")
|
|
}
|
|
|
|
// TestCleanupExpiredPasswordResetTokens_UsedTokens supprime les tokens utilisés plus anciens que 7 jours
|
|
func TestCleanupExpiredPasswordResetTokens_UsedTokens(t *testing.T) {
|
|
testDB, gormDB := setupTestPasswordResetCleanupDB(t)
|
|
logger, _ := zap.NewDevelopment()
|
|
|
|
// Créer un token utilisé il y a 8 jours (devrait être supprimé)
|
|
eightDaysAgo := time.Now().Add(-8 * 24 * time.Hour)
|
|
err := gormDB.Exec(`
|
|
INSERT INTO password_reset_tokens (user_id, token, expires_at, used, created_at)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`, 1, "used_token_old", time.Now().Add(24*time.Hour), true, eightDaysAgo).Error
|
|
require.NoError(t, err)
|
|
|
|
// Créer un token utilisé il y a 5 jours (ne devrait pas être supprimé)
|
|
fiveDaysAgo := time.Now().Add(-5 * 24 * time.Hour)
|
|
err = gormDB.Exec(`
|
|
INSERT INTO password_reset_tokens (user_id, token, expires_at, used, created_at)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`, 1, "used_token_recent", time.Now().Add(24*time.Hour), true, fiveDaysAgo).Error
|
|
require.NoError(t, err)
|
|
|
|
// Exécuter le nettoyage
|
|
err = CleanupExpiredPasswordResetTokens(testDB, logger)
|
|
assert.NoError(t, err)
|
|
|
|
// Vérifier que le token utilisé ancien a été supprimé
|
|
var count int64
|
|
err = gormDB.Raw("SELECT COUNT(*) FROM password_reset_tokens WHERE token = 'used_token_old'").Scan(&count).Error
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(0), count, "Old used token should be deleted")
|
|
|
|
// Vérifier que le token utilisé récent est toujours présent
|
|
err = gormDB.Raw("SELECT COUNT(*) FROM password_reset_tokens WHERE token = 'used_token_recent'").Scan(&count).Error
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(1), count, "Recent used token should still exist")
|
|
}
|
|
|
|
// TestCleanupExpiredPasswordResetTokens_MixedTokens supprime les tokens expirés et utilisés anciens
|
|
func TestCleanupExpiredPasswordResetTokens_MixedTokens(t *testing.T) {
|
|
testDB, gormDB := setupTestPasswordResetCleanupDB(t)
|
|
logger, _ := zap.NewDevelopment()
|
|
|
|
// Créer un token expiré
|
|
expiredTime := time.Now().Add(-25 * time.Hour)
|
|
err := gormDB.Exec(`
|
|
INSERT INTO password_reset_tokens (user_id, token, expires_at, used, created_at)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`, 1, "expired_token", expiredTime, false, time.Now().Add(-26*time.Hour)).Error
|
|
require.NoError(t, err)
|
|
|
|
// Créer un token utilisé ancien
|
|
eightDaysAgo := time.Now().Add(-8 * 24 * time.Hour)
|
|
err = gormDB.Exec(`
|
|
INSERT INTO password_reset_tokens (user_id, token, expires_at, used, created_at)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`, 1, "used_token_old", time.Now().Add(24*time.Hour), true, eightDaysAgo).Error
|
|
require.NoError(t, err)
|
|
|
|
// Créer un token valide
|
|
validTime := time.Now().Add(24 * time.Hour)
|
|
err = gormDB.Exec(`
|
|
INSERT INTO password_reset_tokens (user_id, token, expires_at, used, created_at)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`, 1, "valid_token", validTime, false, time.Now()).Error
|
|
require.NoError(t, err)
|
|
|
|
// Compter les tokens avant le nettoyage
|
|
var countBefore int64
|
|
err = gormDB.Raw("SELECT COUNT(*) FROM password_reset_tokens").Scan(&countBefore).Error
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(3), countBefore)
|
|
|
|
// Exécuter le nettoyage
|
|
err = CleanupExpiredPasswordResetTokens(testDB, logger)
|
|
assert.NoError(t, err)
|
|
|
|
// Vérifier que seuls les tokens valides restent
|
|
var countAfter int64
|
|
err = gormDB.Raw("SELECT COUNT(*) FROM password_reset_tokens").Scan(&countAfter).Error
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(1), countAfter, "Only valid token should remain")
|
|
|
|
// Vérifier que c'est bien le token valide qui reste
|
|
var countValid int64
|
|
err = gormDB.Raw("SELECT COUNT(*) FROM password_reset_tokens WHERE token = 'valid_token'").Scan(&countValid).Error
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(1), countValid, "Valid token should still exist")
|
|
}
|
|
|
|
// TestCleanupExpiredPasswordResetTokens_NoTokensToClean ne fait rien s'il n'y a pas de tokens à nettoyer
|
|
func TestCleanupExpiredPasswordResetTokens_NoTokensToClean(t *testing.T) {
|
|
testDB, gormDB := setupTestPasswordResetCleanupDB(t)
|
|
logger, _ := zap.NewDevelopment()
|
|
|
|
// Créer uniquement des tokens valides
|
|
validTime := time.Now().Add(24 * time.Hour)
|
|
err := gormDB.Exec(`
|
|
INSERT INTO password_reset_tokens (user_id, token, expires_at, used, created_at)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`, 1, "valid_token_1", validTime, false, time.Now()).Error
|
|
require.NoError(t, err)
|
|
|
|
err = gormDB.Exec(`
|
|
INSERT INTO password_reset_tokens (user_id, token, expires_at, used, created_at)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`, 1, "valid_token_2", validTime, false, time.Now()).Error
|
|
require.NoError(t, err)
|
|
|
|
// Compter les tokens avant le nettoyage
|
|
var countBefore int64
|
|
err = gormDB.Raw("SELECT COUNT(*) FROM password_reset_tokens").Scan(&countBefore).Error
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(2), countBefore)
|
|
|
|
// Exécuter le nettoyage
|
|
err = CleanupExpiredPasswordResetTokens(testDB, logger)
|
|
assert.NoError(t, err)
|
|
|
|
// Vérifier que tous les tokens sont toujours présents
|
|
var countAfter int64
|
|
err = gormDB.Raw("SELECT COUNT(*) FROM password_reset_tokens").Scan(&countAfter).Error
|
|
require.NoError(t, err)
|
|
assert.Equal(t, countBefore, countAfter, "All valid tokens should still exist")
|
|
}
|