325 lines
6.5 KiB
Go
325 lines
6.5 KiB
Go
|
|
package validators
|
||
|
|
|
||
|
|
import (
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"veza-backend-api/internal/models"
|
||
|
|
|
||
|
|
"github.com/stretchr/testify/assert"
|
||
|
|
"gorm.io/driver/sqlite"
|
||
|
|
"gorm.io/gorm"
|
||
|
|
)
|
||
|
|
|
||
|
|
// setupTestDB crée une base de données de test
|
||
|
|
func setupTestDB(t *testing.T) *gorm.DB {
|
||
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("Failed to open test database: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Auto-migrate
|
||
|
|
err = db.AutoMigrate(&models.User{})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("Failed to migrate: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
return db
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestEmailValidator_ValidateFormat(t *testing.T) {
|
||
|
|
db := setupTestDB(t)
|
||
|
|
validator := NewEmailValidator(db)
|
||
|
|
|
||
|
|
tests := []struct {
|
||
|
|
name string
|
||
|
|
email string
|
||
|
|
want bool
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "valid email",
|
||
|
|
email: "test@example.com",
|
||
|
|
want: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "valid email with subdomain",
|
||
|
|
email: "user@mail.example.com",
|
||
|
|
want: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "valid email with plus",
|
||
|
|
email: "user+tag@example.com",
|
||
|
|
want: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "valid email with dots",
|
||
|
|
email: "first.last@example.com",
|
||
|
|
want: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "valid email with numbers",
|
||
|
|
email: "user123@example.com",
|
||
|
|
want: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "valid email with underscore",
|
||
|
|
email: "user_name@example.com",
|
||
|
|
want: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - no @",
|
||
|
|
email: "invalidemail.com",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - no domain",
|
||
|
|
email: "invalid@",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - no local part",
|
||
|
|
email: "@example.com",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - no TLD",
|
||
|
|
email: "invalid@example",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - too long",
|
||
|
|
email: strings.Repeat("a", 250) + "@example.com",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - local part starts with dot",
|
||
|
|
email: ".user@example.com",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - local part ends with dot",
|
||
|
|
email: "user.@example.com",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - domain starts with dot",
|
||
|
|
email: "user@.example.com",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - domain ends with dot",
|
||
|
|
email: "user@example.com.",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - domain starts with hyphen",
|
||
|
|
email: "user@-example.com",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - domain ends with hyphen",
|
||
|
|
email: "user@example.com-",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - empty string",
|
||
|
|
email: "",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid email - only spaces",
|
||
|
|
email: " ",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "valid email - trimmed spaces",
|
||
|
|
email: " test@example.com ",
|
||
|
|
want: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "valid email - case insensitive",
|
||
|
|
email: "TEST@EXAMPLE.COM",
|
||
|
|
want: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "valid email - with percent",
|
||
|
|
email: "user%tag@example.com",
|
||
|
|
want: true,
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tt := range tests {
|
||
|
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
|
got := validator.ValidateFormat(tt.email)
|
||
|
|
assert.Equal(t, tt.want, got, "ValidateFormat(%q) = %v, want %v", tt.email, got, tt.want)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestEmailValidator_IsUnique(t *testing.T) {
|
||
|
|
db := setupTestDB(t)
|
||
|
|
validator := NewEmailValidator(db)
|
||
|
|
|
||
|
|
// Créer un utilisateur de test
|
||
|
|
user := &models.User{
|
||
|
|
Email: "existing@example.com",
|
||
|
|
Username: "existing",
|
||
|
|
Role: "user",
|
||
|
|
}
|
||
|
|
err := db.Create(user).Error
|
||
|
|
assert.NoError(t, err)
|
||
|
|
|
||
|
|
tests := []struct {
|
||
|
|
name string
|
||
|
|
email string
|
||
|
|
want bool
|
||
|
|
wantErr bool
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "unique email",
|
||
|
|
email: "new@example.com",
|
||
|
|
want: true,
|
||
|
|
wantErr: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "existing email",
|
||
|
|
email: "existing@example.com",
|
||
|
|
want: false,
|
||
|
|
wantErr: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "existing email - case insensitive",
|
||
|
|
email: "EXISTING@EXAMPLE.COM",
|
||
|
|
want: false,
|
||
|
|
wantErr: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "existing email - with spaces",
|
||
|
|
email: " existing@example.com ",
|
||
|
|
want: false,
|
||
|
|
wantErr: false,
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tt := range tests {
|
||
|
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
|
got, err := validator.IsUnique(tt.email)
|
||
|
|
if tt.wantErr {
|
||
|
|
assert.Error(t, err)
|
||
|
|
} else {
|
||
|
|
assert.NoError(t, err)
|
||
|
|
assert.Equal(t, tt.want, got, "IsUnique(%q) = %v, want %v", tt.email, got, tt.want)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestEmailValidator_Validate(t *testing.T) {
|
||
|
|
db := setupTestDB(t)
|
||
|
|
validator := NewEmailValidator(db)
|
||
|
|
|
||
|
|
// Créer un utilisateur de test
|
||
|
|
user := &models.User{
|
||
|
|
Email: "existing@example.com",
|
||
|
|
Username: "existing",
|
||
|
|
Role: "user",
|
||
|
|
}
|
||
|
|
err := db.Create(user).Error
|
||
|
|
assert.NoError(t, err)
|
||
|
|
|
||
|
|
tests := []struct {
|
||
|
|
name string
|
||
|
|
email string
|
||
|
|
wantErr bool
|
||
|
|
errMsg string
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "valid and unique email",
|
||
|
|
email: "new@example.com",
|
||
|
|
wantErr: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "invalid format",
|
||
|
|
email: "invalid-email",
|
||
|
|
wantErr: true,
|
||
|
|
errMsg: "invalid email format",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "existing email",
|
||
|
|
email: "existing@example.com",
|
||
|
|
wantErr: true,
|
||
|
|
errMsg: "email already exists",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "empty email",
|
||
|
|
email: "",
|
||
|
|
wantErr: true,
|
||
|
|
errMsg: "invalid email format",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "email with invalid format - no @",
|
||
|
|
email: "invalidemail.com",
|
||
|
|
wantErr: true,
|
||
|
|
errMsg: "invalid email format",
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tt := range tests {
|
||
|
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
|
err := validator.Validate(tt.email)
|
||
|
|
if tt.wantErr {
|
||
|
|
assert.Error(t, err)
|
||
|
|
if tt.errMsg != "" {
|
||
|
|
assert.Contains(t, err.Error(), tt.errMsg)
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
assert.NoError(t, err)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestEmailValidator_ValidateFormat_EdgeCases(t *testing.T) {
|
||
|
|
db := setupTestDB(t)
|
||
|
|
validator := NewEmailValidator(db)
|
||
|
|
|
||
|
|
tests := []struct {
|
||
|
|
name string
|
||
|
|
email string
|
||
|
|
want bool
|
||
|
|
}{
|
||
|
|
{
|
||
|
|
name: "email at max length (254 chars)",
|
||
|
|
email: strings.Repeat("a", 64) + "@" + strings.Repeat("b", 186) + ".co",
|
||
|
|
want: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "email over max length (255 chars)",
|
||
|
|
email: strings.Repeat("a", 64) + "@" + strings.Repeat("b", 187) + ".co",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "local part at max length (64 chars)",
|
||
|
|
email: strings.Repeat("a", 64) + "@example.com",
|
||
|
|
want: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "local part over max length (65 chars)",
|
||
|
|
email: strings.Repeat("a", 65) + "@example.com",
|
||
|
|
want: false,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: "domain at max length (253 chars)",
|
||
|
|
email: "user@" + strings.Repeat("a", 253),
|
||
|
|
want: false, // Domain doit avoir au moins un point
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, tt := range tests {
|
||
|
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
|
got := validator.ValidateFormat(tt.email)
|
||
|
|
assert.Equal(t, tt.want, got, "ValidateFormat(%q) = %v, want %v", tt.email, got, tt.want)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|