326 lines
8.4 KiB
Go
326 lines
8.4 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// setupTestRedisClient crée un client Redis de test
|
|
// Utilise Redis en mémoire ou un Redis de test si disponible
|
|
func setupTestRedisClient(t *testing.T) *redis.Client {
|
|
redisURL := os.Getenv("REDIS_TEST_URL")
|
|
if redisURL == "" {
|
|
redisURL = "redis://localhost:6379/15" // Utilise DB 15 pour les tests
|
|
}
|
|
|
|
opts, err := redis.ParseURL(redisURL)
|
|
if err != nil {
|
|
t.Skipf("Skipping test: failed to parse Redis URL: %v", err)
|
|
return nil
|
|
}
|
|
|
|
client := redis.NewClient(opts)
|
|
|
|
// Test de connexion
|
|
ctx := context.Background()
|
|
_, err = client.Ping(ctx).Result()
|
|
if err != nil {
|
|
t.Skipf("Skipping test: Redis not available: %v", err)
|
|
return nil
|
|
}
|
|
|
|
// Nettoyer la base de données de test
|
|
client.FlushDB(ctx)
|
|
|
|
// Cleanup: Flush DB après les tests
|
|
t.Cleanup(func() {
|
|
client.FlushDB(ctx)
|
|
client.Close()
|
|
})
|
|
|
|
return client
|
|
}
|
|
|
|
// setupTestTokenBlacklist crée un TokenBlacklist de test
|
|
func setupTestTokenBlacklist(t *testing.T) (*TokenBlacklist, *redis.Client) {
|
|
client := setupTestRedisClient(t)
|
|
if client == nil {
|
|
t.Skip("Redis not available")
|
|
return nil, nil
|
|
}
|
|
|
|
blacklist := NewTokenBlacklist(client)
|
|
return blacklist, client
|
|
}
|
|
|
|
// T0174: Tests pour TokenBlacklist
|
|
func TestTokenBlacklist_Add(t *testing.T) {
|
|
blacklist, _ := setupTestTokenBlacklist(t)
|
|
if blacklist == nil {
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
token := "test_token_123"
|
|
ttl := 1 * time.Hour
|
|
|
|
err := blacklist.Add(ctx, token, ttl)
|
|
assert.NoError(t, err)
|
|
|
|
// Vérifier que le token est dans la blacklist
|
|
isBlacklisted, err := blacklist.IsBlacklisted(ctx, token)
|
|
assert.NoError(t, err)
|
|
assert.True(t, isBlacklisted)
|
|
}
|
|
|
|
func TestTokenBlacklist_IsBlacklisted_True(t *testing.T) {
|
|
blacklist, _ := setupTestTokenBlacklist(t)
|
|
if blacklist == nil {
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
token := "test_token_456"
|
|
ttl := 1 * time.Hour
|
|
|
|
// Ajouter le token
|
|
err := blacklist.Add(ctx, token, ttl)
|
|
require.NoError(t, err)
|
|
|
|
// Vérifier qu'il est blacklisté
|
|
isBlacklisted, err := blacklist.IsBlacklisted(ctx, token)
|
|
assert.NoError(t, err)
|
|
assert.True(t, isBlacklisted)
|
|
}
|
|
|
|
func TestTokenBlacklist_IsBlacklisted_False(t *testing.T) {
|
|
blacklist, _ := setupTestTokenBlacklist(t)
|
|
if blacklist == nil {
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
token := "test_token_not_blacklisted"
|
|
|
|
// Vérifier qu'un token non ajouté n'est pas blacklisté
|
|
isBlacklisted, err := blacklist.IsBlacklisted(ctx, token)
|
|
assert.NoError(t, err)
|
|
assert.False(t, isBlacklisted)
|
|
}
|
|
|
|
func TestTokenBlacklist_Expiration(t *testing.T) {
|
|
blacklist, _ := setupTestTokenBlacklist(t)
|
|
if blacklist == nil {
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
token := "test_token_expiration"
|
|
ttl := 100 * time.Millisecond // TTL très court pour le test
|
|
|
|
// Ajouter le token avec un TTL court
|
|
err := blacklist.Add(ctx, token, ttl)
|
|
require.NoError(t, err)
|
|
|
|
// Vérifier qu'il est blacklisté immédiatement
|
|
isBlacklisted, err := blacklist.IsBlacklisted(ctx, token)
|
|
assert.NoError(t, err)
|
|
assert.True(t, isBlacklisted)
|
|
|
|
// Attendre que le TTL expire
|
|
time.Sleep(150 * time.Millisecond)
|
|
|
|
// Vérifier qu'il n'est plus blacklisté (expiré automatiquement)
|
|
isBlacklisted, err = blacklist.IsBlacklisted(ctx, token)
|
|
assert.NoError(t, err)
|
|
assert.False(t, isBlacklisted, "Token should be expired and removed from blacklist")
|
|
}
|
|
|
|
func TestTokenBlacklist_Remove(t *testing.T) {
|
|
blacklist, _ := setupTestTokenBlacklist(t)
|
|
if blacklist == nil {
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
token := "test_token_remove"
|
|
ttl := 1 * time.Hour
|
|
|
|
// Ajouter le token
|
|
err := blacklist.Add(ctx, token, ttl)
|
|
require.NoError(t, err)
|
|
|
|
// Vérifier qu'il est blacklisté
|
|
isBlacklisted, err := blacklist.IsBlacklisted(ctx, token)
|
|
assert.NoError(t, err)
|
|
assert.True(t, isBlacklisted)
|
|
|
|
// Supprimer le token
|
|
err = blacklist.Remove(ctx, token)
|
|
assert.NoError(t, err)
|
|
|
|
// Vérifier qu'il n'est plus blacklisté
|
|
isBlacklisted, err = blacklist.IsBlacklisted(ctx, token)
|
|
assert.NoError(t, err)
|
|
assert.False(t, isBlacklisted)
|
|
}
|
|
|
|
func TestTokenBlacklist_MultipleTokens(t *testing.T) {
|
|
blacklist, _ := setupTestTokenBlacklist(t)
|
|
if blacklist == nil {
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
token1 := "test_token_1"
|
|
token2 := "test_token_2"
|
|
token3 := "test_token_3"
|
|
ttl := 1 * time.Hour
|
|
|
|
// Ajouter plusieurs tokens
|
|
err := blacklist.Add(ctx, token1, ttl)
|
|
require.NoError(t, err)
|
|
err = blacklist.Add(ctx, token2, ttl)
|
|
require.NoError(t, err)
|
|
|
|
// Vérifier que les tokens ajoutés sont blacklistés
|
|
isBlacklisted1, err := blacklist.IsBlacklisted(ctx, token1)
|
|
assert.NoError(t, err)
|
|
assert.True(t, isBlacklisted1)
|
|
|
|
isBlacklisted2, err := blacklist.IsBlacklisted(ctx, token2)
|
|
assert.NoError(t, err)
|
|
assert.True(t, isBlacklisted2)
|
|
|
|
// Vérifier qu'un token non ajouté n'est pas blacklisté
|
|
isBlacklisted3, err := blacklist.IsBlacklisted(ctx, token3)
|
|
assert.NoError(t, err)
|
|
assert.False(t, isBlacklisted3)
|
|
}
|
|
|
|
func TestTokenBlacklist_HashToken(t *testing.T) {
|
|
blacklist, _ := setupTestTokenBlacklist(t)
|
|
if blacklist == nil {
|
|
return
|
|
}
|
|
|
|
token := "test_token_hash"
|
|
|
|
// Le hash devrait être déterministe
|
|
hash1 := blacklist.hashToken(token)
|
|
hash2 := blacklist.hashToken(token)
|
|
|
|
assert.Equal(t, hash1, hash2, "Hash should be deterministic")
|
|
assert.NotEqual(t, token, hash1, "Hash should be different from original token")
|
|
assert.Len(t, hash1, 64, "SHA256 hash should be 64 characters (hex)")
|
|
}
|
|
|
|
func TestTokenBlacklist_DifferentTokensDifferentHashes(t *testing.T) {
|
|
blacklist, _ := setupTestTokenBlacklist(t)
|
|
if blacklist == nil {
|
|
return
|
|
}
|
|
|
|
token1 := "test_token_1"
|
|
token2 := "test_token_2"
|
|
|
|
hash1 := blacklist.hashToken(token1)
|
|
hash2 := blacklist.hashToken(token2)
|
|
|
|
assert.NotEqual(t, hash1, hash2, "Different tokens should have different hashes")
|
|
}
|
|
|
|
func TestTokenBlacklist_AddWithDifferentTTL(t *testing.T) {
|
|
blacklist, _ := setupTestTokenBlacklist(t)
|
|
if blacklist == nil {
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
token1 := "test_token_ttl_1"
|
|
token2 := "test_token_ttl_2"
|
|
token3 := "test_token_ttl_3"
|
|
|
|
// Ajouter des tokens avec différents TTL
|
|
err := blacklist.Add(ctx, token1, 1*time.Second)
|
|
require.NoError(t, err)
|
|
err = blacklist.Add(ctx, token2, 2*time.Second)
|
|
require.NoError(t, err)
|
|
err = blacklist.Add(ctx, token3, 500*time.Millisecond)
|
|
require.NoError(t, err)
|
|
|
|
// Tous devraient être blacklistés immédiatement
|
|
isBlacklisted1, _ := blacklist.IsBlacklisted(ctx, token1)
|
|
assert.True(t, isBlacklisted1)
|
|
isBlacklisted2, _ := blacklist.IsBlacklisted(ctx, token2)
|
|
assert.True(t, isBlacklisted2)
|
|
isBlacklisted3, _ := blacklist.IsBlacklisted(ctx, token3)
|
|
assert.True(t, isBlacklisted3)
|
|
|
|
// Attendre que le premier expire
|
|
time.Sleep(600 * time.Millisecond)
|
|
isBlacklisted3, _ = blacklist.IsBlacklisted(ctx, token3)
|
|
assert.False(t, isBlacklisted3, "Token3 should be expired")
|
|
|
|
// Les autres devraient encore être là
|
|
isBlacklisted1, _ = blacklist.IsBlacklisted(ctx, token1)
|
|
assert.True(t, isBlacklisted1)
|
|
isBlacklisted2, _ = blacklist.IsBlacklisted(ctx, token2)
|
|
assert.True(t, isBlacklisted2)
|
|
|
|
// Attendre que token1 expire
|
|
time.Sleep(500 * time.Millisecond)
|
|
isBlacklisted1, _ = blacklist.IsBlacklisted(ctx, token1)
|
|
assert.False(t, isBlacklisted1, "Token1 should be expired")
|
|
|
|
// Token2 devrait encore être là
|
|
isBlacklisted2, _ = blacklist.IsBlacklisted(ctx, token2)
|
|
assert.True(t, isBlacklisted2)
|
|
|
|
// Attendre que token2 expire
|
|
time.Sleep(1 * time.Second)
|
|
isBlacklisted2, _ = blacklist.IsBlacklisted(ctx, token2)
|
|
assert.False(t, isBlacklisted2, "Token2 should be expired")
|
|
}
|
|
|
|
func TestTokenBlacklist_AddTwice(t *testing.T) {
|
|
blacklist, _ := setupTestTokenBlacklist(t)
|
|
if blacklist == nil {
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
token := "test_token_add_twice"
|
|
ttl := 1 * time.Hour
|
|
|
|
// Ajouter le token deux fois
|
|
err := blacklist.Add(ctx, token, ttl)
|
|
require.NoError(t, err)
|
|
err = blacklist.Add(ctx, token, ttl)
|
|
require.NoError(t, err) // Ne devrait pas retourner d'erreur
|
|
|
|
// Vérifier qu'il est toujours blacklisté
|
|
isBlacklisted, err := blacklist.IsBlacklisted(ctx, token)
|
|
assert.NoError(t, err)
|
|
assert.True(t, isBlacklisted)
|
|
}
|
|
|
|
func TestTokenBlacklist_RemoveNonExistent(t *testing.T) {
|
|
blacklist, _ := setupTestTokenBlacklist(t)
|
|
if blacklist == nil {
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
token := "test_token_not_exists"
|
|
|
|
// Supprimer un token qui n'existe pas ne devrait pas retourner d'erreur
|
|
err := blacklist.Remove(ctx, token)
|
|
assert.NoError(t, err)
|
|
}
|