133 lines
3.6 KiB
Go
133 lines
3.6 KiB
Go
package models
|
|
|
|
import (
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func setupAuthUserTestDB(t *testing.T) *gorm.DB {
|
|
dsn := filepath.Join(t.TempDir(), "test.db") + "?_busy_timeout=5000&_journal_mode=WAL"
|
|
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
|
|
require.NoError(t, err)
|
|
require.NoError(t, db.AutoMigrate(&AuthUser{}))
|
|
return db
|
|
}
|
|
|
|
func TestAuthUser_BeforeCreate(t *testing.T) {
|
|
db := setupAuthUserTestDB(t)
|
|
|
|
t.Run("generates UUID when empty", func(t *testing.T) {
|
|
user := &AuthUser{
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
PasswordHash: "hash",
|
|
}
|
|
require.NoError(t, db.Create(user).Error)
|
|
assert.NotEmpty(t, user.UUID)
|
|
assert.Len(t, user.UUID, 36) // UUID format
|
|
})
|
|
|
|
t.Run("keeps existing UUID", func(t *testing.T) {
|
|
customUUID := "custom-uuid-value"
|
|
user := &AuthUser{
|
|
UUID: customUUID,
|
|
Username: "testuser2",
|
|
Email: "test2@example.com",
|
|
PasswordHash: "hash",
|
|
}
|
|
require.NoError(t, db.Create(user).Error)
|
|
assert.Equal(t, customUUID, user.UUID)
|
|
})
|
|
}
|
|
|
|
func TestAuthUser_SetPassword(t *testing.T) {
|
|
t.Run("hashes password", func(t *testing.T) {
|
|
user := &AuthUser{}
|
|
err := user.SetPassword("mypassword123")
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, user.PasswordHash)
|
|
assert.NotEqual(t, "mypassword123", user.PasswordHash)
|
|
// bcrypt hashes start with $2a$ or $2b$
|
|
assert.Contains(t, user.PasswordHash, "$2a$")
|
|
})
|
|
|
|
t.Run("empty password", func(t *testing.T) {
|
|
user := &AuthUser{}
|
|
err := user.SetPassword("")
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, user.PasswordHash)
|
|
})
|
|
}
|
|
|
|
func TestAuthUser_CheckPassword(t *testing.T) {
|
|
user := &AuthUser{}
|
|
require.NoError(t, user.SetPassword("correctpassword"))
|
|
|
|
t.Run("correct password returns true", func(t *testing.T) {
|
|
assert.True(t, user.CheckPassword("correctpassword"))
|
|
})
|
|
|
|
t.Run("wrong password returns false", func(t *testing.T) {
|
|
assert.False(t, user.CheckPassword("wrongpassword"))
|
|
})
|
|
|
|
t.Run("empty password returns false", func(t *testing.T) {
|
|
assert.False(t, user.CheckPassword(""))
|
|
})
|
|
}
|
|
|
|
func TestAuthUser_HasRole(t *testing.T) {
|
|
t.Run("empty roles returns false", func(t *testing.T) {
|
|
user := &AuthUser{Roles: ""}
|
|
assert.False(t, user.HasRole("admin"))
|
|
})
|
|
|
|
t.Run("single role match", func(t *testing.T) {
|
|
user := &AuthUser{Roles: "admin"}
|
|
assert.True(t, user.HasRole("admin"))
|
|
assert.False(t, user.HasRole("user"))
|
|
})
|
|
|
|
t.Run("multiple roles", func(t *testing.T) {
|
|
user := &AuthUser{Roles: "admin,user,editor"}
|
|
assert.True(t, user.HasRole("admin"))
|
|
assert.True(t, user.HasRole("user"))
|
|
assert.True(t, user.HasRole("editor"))
|
|
assert.False(t, user.HasRole("guest"))
|
|
})
|
|
|
|
t.Run("roles with spaces", func(t *testing.T) {
|
|
user := &AuthUser{Roles: "admin, user, editor"}
|
|
assert.True(t, user.HasRole("admin"))
|
|
assert.True(t, user.HasRole("user"))
|
|
assert.True(t, user.HasRole("editor"))
|
|
})
|
|
}
|
|
|
|
func TestSplitRoles(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
expected []string
|
|
}{
|
|
{"empty string", "", []string{}},
|
|
{"single role", "admin", []string{"admin"}},
|
|
{"multiple roles", "admin,user", []string{"admin", "user"}},
|
|
{"with spaces", "admin, user, editor", []string{"admin", "user", "editor"}},
|
|
{"trailing comma", "admin,user,", []string{"admin", "user"}},
|
|
{"leading comma", ",admin,user", []string{"admin", "user"}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := splitRoles(tt.input)
|
|
assert.Equal(t, tt.expected, result)
|
|
})
|
|
}
|
|
}
|