memos/store/test/user_test.go

258 lines
7.0 KiB
Go

package test
import (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/bcrypt"
"github.com/usememos/memos/store"
)
func TestUserStore(t *testing.T) {
ctx := context.Background()
ts := NewTestingStore(ctx, t)
user, err := createTestingHostUser(ctx, ts)
require.NoError(t, err)
users, err := ts.ListUsers(ctx, &store.FindUser{})
require.NoError(t, err)
require.Equal(t, 1, len(users))
require.Equal(t, store.RoleHost, users[0].Role)
require.Equal(t, user, users[0])
userPatchNickname := "test_nickname_2"
userPatch := &store.UpdateUser{
ID: user.ID,
Nickname: &userPatchNickname,
}
user, err = ts.UpdateUser(ctx, userPatch)
require.NoError(t, err)
require.Equal(t, userPatchNickname, user.Nickname)
err = ts.DeleteUser(ctx, &store.DeleteUser{
ID: user.ID,
})
require.NoError(t, err)
users, err = ts.ListUsers(ctx, &store.FindUser{})
require.NoError(t, err)
require.Equal(t, 0, len(users))
ts.Close()
}
func TestUserGetByID(t *testing.T) {
ctx := context.Background()
ts := NewTestingStore(ctx, t)
user, err := createTestingHostUser(ctx, ts)
require.NoError(t, err)
// Get user by ID
found, err := ts.GetUser(ctx, &store.FindUser{ID: &user.ID})
require.NoError(t, err)
require.NotNil(t, found)
require.Equal(t, user.ID, found.ID)
require.Equal(t, user.Username, found.Username)
// Get non-existent user
nonExistentID := int32(99999)
notFound, err := ts.GetUser(ctx, &store.FindUser{ID: &nonExistentID})
require.NoError(t, err)
require.Nil(t, notFound)
// Get system bot
systemBotID := store.SystemBotID
systemBot, err := ts.GetUser(ctx, &store.FindUser{ID: &systemBotID})
require.NoError(t, err)
require.NotNil(t, systemBot)
require.Equal(t, store.SystemBotID, systemBot.ID)
require.Equal(t, "system_bot", systemBot.Username)
ts.Close()
}
func TestUserGetByUsername(t *testing.T) {
ctx := context.Background()
ts := NewTestingStore(ctx, t)
user, err := createTestingHostUser(ctx, ts)
require.NoError(t, err)
// Get user by username
found, err := ts.GetUser(ctx, &store.FindUser{Username: &user.Username})
require.NoError(t, err)
require.NotNil(t, found)
require.Equal(t, user.Username, found.Username)
// Get non-existent username
nonExistent := "nonexistent"
notFound, err := ts.GetUser(ctx, &store.FindUser{Username: &nonExistent})
require.NoError(t, err)
require.Nil(t, notFound)
ts.Close()
}
func TestUserListByRole(t *testing.T) {
ctx := context.Background()
ts := NewTestingStore(ctx, t)
// Create users with different roles
_, err := createTestingHostUser(ctx, ts)
require.NoError(t, err)
adminUser, err := createTestingUserWithRole(ctx, ts, "admin_user", store.RoleAdmin)
require.NoError(t, err)
regularUser, err := createTestingUserWithRole(ctx, ts, "regular_user", store.RoleUser)
require.NoError(t, err)
// List all users
allUsers, err := ts.ListUsers(ctx, &store.FindUser{})
require.NoError(t, err)
require.Equal(t, 3, len(allUsers))
// List only HOST users
hostRole := store.RoleHost
hostUsers, err := ts.ListUsers(ctx, &store.FindUser{Role: &hostRole})
require.NoError(t, err)
require.Equal(t, 1, len(hostUsers))
require.Equal(t, store.RoleHost, hostUsers[0].Role)
// List only ADMIN users
adminRole := store.RoleAdmin
adminUsers, err := ts.ListUsers(ctx, &store.FindUser{Role: &adminRole})
require.NoError(t, err)
require.Equal(t, 1, len(adminUsers))
require.Equal(t, adminUser.ID, adminUsers[0].ID)
// List only USER role users
userRole := store.RoleUser
regularUsers, err := ts.ListUsers(ctx, &store.FindUser{Role: &userRole})
require.NoError(t, err)
require.Equal(t, 1, len(regularUsers))
require.Equal(t, regularUser.ID, regularUsers[0].ID)
ts.Close()
}
func TestUserUpdateRowStatus(t *testing.T) {
ctx := context.Background()
ts := NewTestingStore(ctx, t)
user, err := createTestingHostUser(ctx, ts)
require.NoError(t, err)
require.Equal(t, store.Normal, user.RowStatus)
// Archive user
archivedStatus := store.Archived
updated, err := ts.UpdateUser(ctx, &store.UpdateUser{
ID: user.ID,
RowStatus: &archivedStatus,
})
require.NoError(t, err)
require.Equal(t, store.Archived, updated.RowStatus)
// Verify by fetching
fetched, err := ts.GetUser(ctx, &store.FindUser{ID: &user.ID})
require.NoError(t, err)
require.Equal(t, store.Archived, fetched.RowStatus)
// Restore to normal
normalStatus := store.Normal
restored, err := ts.UpdateUser(ctx, &store.UpdateUser{
ID: user.ID,
RowStatus: &normalStatus,
})
require.NoError(t, err)
require.Equal(t, store.Normal, restored.RowStatus)
ts.Close()
}
func TestUserUpdateAllFields(t *testing.T) {
ctx := context.Background()
ts := NewTestingStore(ctx, t)
user, err := createTestingHostUser(ctx, ts)
require.NoError(t, err)
// Update all fields
newUsername := "updated_username"
newEmail := "updated@test.com"
newNickname := "Updated Nickname"
newAvatarURL := "https://example.com/avatar.png"
newDescription := "Updated description"
newRole := store.RoleAdmin
newPasswordHash := "new_password_hash"
updated, err := ts.UpdateUser(ctx, &store.UpdateUser{
ID: user.ID,
Username: &newUsername,
Email: &newEmail,
Nickname: &newNickname,
AvatarURL: &newAvatarURL,
Description: &newDescription,
Role: &newRole,
PasswordHash: &newPasswordHash,
})
require.NoError(t, err)
require.Equal(t, newUsername, updated.Username)
require.Equal(t, newEmail, updated.Email)
require.Equal(t, newNickname, updated.Nickname)
require.Equal(t, newAvatarURL, updated.AvatarURL)
require.Equal(t, newDescription, updated.Description)
require.Equal(t, newRole, updated.Role)
require.Equal(t, newPasswordHash, updated.PasswordHash)
// Verify by fetching again
fetched, err := ts.GetUser(ctx, &store.FindUser{ID: &user.ID})
require.NoError(t, err)
require.Equal(t, newUsername, fetched.Username)
ts.Close()
}
func TestUserListWithLimit(t *testing.T) {
ctx := context.Background()
ts := NewTestingStore(ctx, t)
// Create 5 users
for i := 0; i < 5; i++ {
role := store.RoleUser
if i == 0 {
role = store.RoleHost
}
_, err := createTestingUserWithRole(ctx, ts, fmt.Sprintf("user%d", i), role)
require.NoError(t, err)
}
// List with limit
limit := 3
users, err := ts.ListUsers(ctx, &store.FindUser{Limit: &limit})
require.NoError(t, err)
require.Equal(t, 3, len(users))
ts.Close()
}
func createTestingHostUser(ctx context.Context, ts *store.Store) (*store.User, error) {
return createTestingUserWithRole(ctx, ts, "test", store.RoleHost)
}
func createTestingUserWithRole(ctx context.Context, ts *store.Store, username string, role store.Role) (*store.User, error) {
userCreate := &store.User{
Username: username,
Role: role,
Email: username + "@test.com",
Nickname: username + "_nickname",
Description: username + "_description",
}
passwordHash, err := bcrypt.GenerateFromPassword([]byte("test_password"), bcrypt.DefaultCost)
if err != nil {
return nil, err
}
userCreate.PasswordHash = string(passwordHash)
user, err := ts.CreateUser(ctx, userCreate)
return user, err
}