veza/veza-backend-api/internal/services/permission_service_test.go
2025-12-16 11:23:49 -05:00

342 lines
9.5 KiB
Go

package services
import (
"context"
"testing"
"time"
"veza-backend-api/internal/models"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
// setupTestPermissionServiceDB crée une base de données de test pour PermissionService
func setupTestPermissionServiceDB(t *testing.T) *gorm.DB {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
require.NoError(t, err)
// Enable foreign keys for SQLite
db.Exec("PRAGMA foreign_keys = ON")
// Create tables manually to ensure all columns exist (AutoMigrate might miss some in SQLite)
db.Exec(`
CREATE TABLE IF NOT EXISTS roles (
id TEXT PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
display_name TEXT NOT NULL,
description TEXT,
is_system INTEGER DEFAULT 0,
is_active INTEGER DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`)
db.Exec(`
CREATE TABLE IF NOT EXISTS permissions (
id TEXT PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
resource TEXT,
action TEXT,
description TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`)
db.Exec(`
CREATE TABLE IF NOT EXISTS user_roles (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
role_id TEXT NOT NULL,
role TEXT NOT NULL,
assigned_at DATETIME DEFAULT CURRENT_TIMESTAMP,
assigned_by TEXT,
expires_at DATETIME,
is_active INTEGER DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE(user_id, role)
)
`)
db.Exec(`
CREATE TABLE IF NOT EXISTS role_permissions (
id TEXT PRIMARY KEY,
role_id TEXT NOT NULL,
permission_id TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE(role_id, permission_id)
)
`)
return db
}
// TestPermissionService_HasRole teste HasRole
// GO-007, GO-025: Test critique pour RBAC
func TestPermissionService_HasRole(t *testing.T) {
db := setupTestPermissionServiceDB(t)
service := NewPermissionService(db)
ctx := context.Background()
// Créer un rôle admin
adminRole := &models.Role{
ID: uuid.New(),
Name: "admin",
IsActive: true,
}
require.NoError(t, db.Create(adminRole).Error)
// Créer un rôle user
userRole := &models.Role{
ID: uuid.New(),
Name: "user",
IsActive: true,
}
require.NoError(t, db.Create(userRole).Error)
// Créer un utilisateur
userID := uuid.New()
// Test 1: Utilisateur sans rôle
hasRole, err := service.HasRole(ctx, userID, "admin")
require.NoError(t, err)
assert.False(t, hasRole, "User without role should not have admin role")
// Test 2: Utilisateur avec rôle admin
userRoleRecord := &models.UserRole{
ID: uuid.New(),
UserID: userID,
RoleID: adminRole.ID,
IsActive: true,
}
require.NoError(t, db.Create(userRoleRecord).Error)
hasRole, err = service.HasRole(ctx, userID, "admin")
require.NoError(t, err)
assert.True(t, hasRole, "User with admin role should have admin role")
// Test 3: Utilisateur avec rôle user (pas admin)
hasRole, err = service.HasRole(ctx, userID, "user")
require.NoError(t, err)
assert.False(t, hasRole, "User with admin role should not have user role")
// Test 4: Rôle inactif
userRoleRecord.IsActive = false
require.NoError(t, db.Save(userRoleRecord).Error)
hasRole, err = service.HasRole(ctx, userID, "admin")
require.NoError(t, err)
assert.False(t, hasRole, "User with inactive role should not have role")
// Test 5: Rôle expiré
userRoleRecord.IsActive = true
expiredTime := time.Now().Add(-1 * time.Hour)
userRoleRecord.ExpiresAt = &expiredTime
require.NoError(t, db.Save(userRoleRecord).Error)
hasRole, err = service.HasRole(ctx, userID, "admin")
require.NoError(t, err)
assert.False(t, hasRole, "User with expired role should not have role")
}
// TestPermissionService_HasPermission teste HasPermission
// GO-007, GO-025: Test critique pour RBAC
func TestPermissionService_HasPermission(t *testing.T) {
db := setupTestPermissionServiceDB(t)
service := NewPermissionService(db)
ctx := context.Background()
// Créer un rôle
role := &models.Role{
ID: uuid.New(),
Name: "admin",
IsActive: true,
}
require.NoError(t, db.Create(role).Error)
// Créer une permission
permission := &models.Permission{
ID: uuid.New(),
Name: "manage_users",
Resource: "users",
Action: "manage",
}
require.NoError(t, db.Create(permission).Error)
// Créer un utilisateur
userID := uuid.New()
// Test 1: Utilisateur sans permission
hasPermission, err := service.HasPermission(ctx, userID, "manage_users")
require.NoError(t, err)
assert.False(t, hasPermission, "User without permission should not have permission")
// Test 2: Assigner rôle à l'utilisateur
userRole := &models.UserRole{
ID: uuid.New(),
UserID: userID,
RoleID: role.ID,
IsActive: true,
}
require.NoError(t, db.Create(userRole).Error)
// Test 3: Permission non assignée au rôle
hasPermission, err = service.HasPermission(ctx, userID, "manage_users")
require.NoError(t, err)
assert.False(t, hasPermission, "User with role but without permission should not have permission")
// Test 4: Assigner permission au rôle
rolePermission := &models.RolePermission{
RoleID: role.ID,
PermissionID: permission.ID,
}
require.NoError(t, db.Create(rolePermission).Error)
hasPermission, err = service.HasPermission(ctx, userID, "manage_users")
require.NoError(t, err)
assert.True(t, hasPermission, "User with role and permission should have permission")
// Test 5: Permission inexistante
hasPermission, err = service.HasPermission(ctx, userID, "nonexistent_permission")
require.NoError(t, err)
assert.False(t, hasPermission, "User should not have nonexistent permission")
}
// TestPermissionService_GetRolePermissions teste GetRolePermissions
func TestPermissionService_GetRolePermissions(t *testing.T) {
db := setupTestPermissionServiceDB(t)
service := NewPermissionService(db)
ctx := context.Background()
// Créer un rôle
role := &models.Role{
ID: uuid.New(),
Name: "admin",
IsActive: true,
}
require.NoError(t, db.Create(role).Error)
// Créer des permissions
perm1 := &models.Permission{
ID: uuid.New(),
Name: "manage_users",
Resource: "users",
Action: "manage",
}
require.NoError(t, db.Create(perm1).Error)
perm2 := &models.Permission{
ID: uuid.New(),
Name: "manage_tracks",
Resource: "tracks",
Action: "manage",
}
require.NoError(t, db.Create(perm2).Error)
// Test 1: Rôle sans permissions
permissions, err := service.GetRolePermissions(ctx, role.ID)
require.NoError(t, err)
assert.Empty(t, permissions, "Role without permissions should return empty list")
// Test 2: Assigner permissions au rôle
rolePerm1 := &models.RolePermission{
RoleID: role.ID,
PermissionID: perm1.ID,
}
require.NoError(t, db.Create(rolePerm1).Error)
rolePerm2 := &models.RolePermission{
RoleID: role.ID,
PermissionID: perm2.ID,
}
require.NoError(t, db.Create(rolePerm2).Error)
permissions, err = service.GetRolePermissions(ctx, role.ID)
require.NoError(t, err)
assert.Len(t, permissions, 2, "Role should have 2 permissions")
}
// TestPermissionService_AssignPermissionToRole teste AssignPermissionToRole
func TestPermissionService_AssignPermissionToRole(t *testing.T) {
db := setupTestPermissionServiceDB(t)
service := NewPermissionService(db)
ctx := context.Background()
// Créer un rôle et une permission
role := &models.Role{
ID: uuid.New(),
Name: "admin",
IsActive: true,
}
require.NoError(t, db.Create(role).Error)
permission := &models.Permission{
ID: uuid.New(),
Name: "manage_users",
Resource: "users",
Action: "manage",
}
require.NoError(t, db.Create(permission).Error)
// Assigner permission au rôle
err := service.AssignPermissionToRole(ctx, role.ID, permission.ID)
require.NoError(t, err)
// Vérifier que l'assignation existe
var rolePermission models.RolePermission
err = db.Where("role_id = ? AND permission_id = ?", role.ID, permission.ID).First(&rolePermission).Error
require.NoError(t, err)
assert.Equal(t, role.ID, rolePermission.RoleID)
assert.Equal(t, permission.ID, rolePermission.PermissionID)
}
// TestPermissionService_RevokePermissionFromRole teste RevokePermissionFromRole
func TestPermissionService_RevokePermissionFromRole(t *testing.T) {
db := setupTestPermissionServiceDB(t)
service := NewPermissionService(db)
ctx := context.Background()
// Créer un rôle et une permission
role := &models.Role{
ID: uuid.New(),
Name: "admin",
IsActive: true,
}
require.NoError(t, db.Create(role).Error)
permission := &models.Permission{
ID: uuid.New(),
Name: "manage_users",
Resource: "users",
Action: "manage",
}
require.NoError(t, db.Create(permission).Error)
// Assigner permission au rôle
rolePermission := &models.RolePermission{
RoleID: role.ID,
PermissionID: permission.ID,
}
require.NoError(t, db.Create(rolePermission).Error)
// Révoquer permission
err := service.RevokePermissionFromRole(ctx, role.ID, permission.ID)
require.NoError(t, err)
// Vérifier que l'assignation n'existe plus
var count int64
db.Model(&models.RolePermission{}).
Where("role_id = ? AND permission_id = ?", role.ID, permission.ID).
Count(&count)
assert.Equal(t, int64(0), count, "Permission should be revoked")
// Test: Révoquer une permission inexistante
err = service.RevokePermissionFromRole(ctx, role.ID, permission.ID)
assert.Error(t, err, "Revoking nonexistent permission should return error")
assert.Contains(t, err.Error(), "not found")
}