You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
408 lines
9.5 KiB
408 lines
9.5 KiB
package model
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/driver/mysql"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// setupProfileModelTestDB 创建测试数据库(使用MySQL)
|
|
func setupProfileModelTestDB(t *testing.T) *gorm.DB {
|
|
t.Helper()
|
|
|
|
// 使用 MySQL 进行测试
|
|
dsn := "root:dev123456@tcp(219.159.132.177:17173)/base?charset=utf8mb4&parseTime=true&loc=Local"
|
|
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
|
require.NoError(t, err)
|
|
|
|
err = db.AutoMigrate(&User{}, &Profile{})
|
|
require.NoError(t, err)
|
|
|
|
// 清理所有测试数据(TRUNCATE)
|
|
db.Exec("SET FOREIGN_KEY_CHECKS = 0")
|
|
db.Exec("TRUNCATE TABLE profile")
|
|
db.Exec("TRUNCATE TABLE user")
|
|
db.Exec("SET FOREIGN_KEY_CHECKS = 1")
|
|
|
|
return db
|
|
}
|
|
|
|
// createTestUserProfile 创建测试用户和关联的个人资料
|
|
func createTestUserProfile(t *testing.T, db *gorm.DB) (int64, int64) {
|
|
t.Helper()
|
|
|
|
now := time.Now()
|
|
|
|
// 创建用户
|
|
user := &User{
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
Password: "encryptedpassword",
|
|
Phone: "13800138000",
|
|
Status: 1,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
err := db.Create(user).Error
|
|
require.NoError(t, err)
|
|
|
|
// 创建个人资料
|
|
profile := &Profile{
|
|
UserId: user.Id,
|
|
Avatar: "http://example.com/avatar.jpg",
|
|
Bio: "Test bio",
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
err = db.Create(profile).Error
|
|
require.NoError(t, err)
|
|
|
|
return user.Id, profile.Id
|
|
}
|
|
|
|
// TestInsertProfile 测试插入个人资料
|
|
func TestInsertProfile(t *testing.T) {
|
|
db := setupProfileModelTestDB(t)
|
|
|
|
ctx := context.Background()
|
|
|
|
// 先创建用户
|
|
now := time.Now()
|
|
user := &User{
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
Password: "encryptedpassword",
|
|
Status: 1,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
err := db.Create(user).Error
|
|
require.NoError(t, err)
|
|
|
|
// 创建个人资料
|
|
profile := &Profile{
|
|
UserId: user.Id,
|
|
Avatar: "http://example.com/avatar.jpg",
|
|
Bio: "Test bio",
|
|
}
|
|
|
|
id, err := InsertProfile(ctx, db, profile)
|
|
|
|
require.NoError(t, err)
|
|
assert.Greater(t, id, int64(0))
|
|
assert.Equal(t, id, profile.Id)
|
|
|
|
// 验证数据已保存
|
|
saved, err := FindOneProfile(ctx, db, id)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "http://example.com/avatar.jpg", saved.Avatar)
|
|
assert.Equal(t, "Test bio", saved.Bio)
|
|
}
|
|
|
|
// TestFindOneProfile 测试根据ID查询个人资料
|
|
func TestFindOneProfile(t *testing.T) {
|
|
db := setupProfileModelTestDB(t)
|
|
|
|
_, profileId := createTestUserProfile(t, db)
|
|
ctx := context.Background()
|
|
|
|
// 查询个人资料
|
|
found, err := FindOneProfile(ctx, db, profileId)
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, found)
|
|
assert.Equal(t, profileId, found.Id)
|
|
assert.Equal(t, "http://example.com/avatar.jpg", found.Avatar)
|
|
assert.Equal(t, "Test bio", found.Bio)
|
|
}
|
|
|
|
// TestFindOneProfile_NotFound 测试查询不存在的个人资料
|
|
func TestFindOneProfile_NotFound(t *testing.T) {
|
|
db := setupProfileModelTestDB(t)
|
|
|
|
ctx := context.Background()
|
|
|
|
found, err := FindOneProfile(ctx, db, 99999)
|
|
|
|
require.Error(t, err)
|
|
require.Nil(t, found)
|
|
assert.Equal(t, ErrNotFound, err)
|
|
}
|
|
|
|
// TestFindProfileByUserId 测试根据用户ID查询个人资料
|
|
func TestFindProfileByUserId(t *testing.T) {
|
|
db := setupProfileModelTestDB(t)
|
|
|
|
userId, _ := createTestUserProfile(t, db)
|
|
ctx := context.Background()
|
|
|
|
// 根据用户ID查询
|
|
found, err := FindProfileByUserId(ctx, db, userId)
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, found)
|
|
assert.Equal(t, userId, found.UserId)
|
|
assert.Equal(t, "http://example.com/avatar.jpg", found.Avatar)
|
|
}
|
|
|
|
// TestFindProfileByUserId_NotFound 测试查询不存在的用户个人资料
|
|
func TestFindProfileByUserId_NotFound(t *testing.T) {
|
|
db := setupProfileModelTestDB(t)
|
|
|
|
ctx := context.Background()
|
|
|
|
found, err := FindProfileByUserId(ctx, db, 99999)
|
|
|
|
require.Error(t, err)
|
|
require.Nil(t, found)
|
|
assert.Equal(t, ErrNotFound, err)
|
|
}
|
|
|
|
// TestUpdateProfile 测试更新个人资料
|
|
func TestUpdateProfile(t *testing.T) {
|
|
db := setupProfileModelTestDB(t)
|
|
|
|
_, profileId := createTestUserProfile(t, db)
|
|
ctx := context.Background()
|
|
|
|
// 获取个人资料
|
|
profile, err := FindOneProfile(ctx, db, profileId)
|
|
require.NoError(t, err)
|
|
|
|
// 修改数据
|
|
profile.Avatar = "http://example.com/newavatar.jpg"
|
|
profile.Bio = "Updated bio"
|
|
|
|
// 更新
|
|
err = UpdateProfile(ctx, db, profile)
|
|
|
|
require.NoError(t, err)
|
|
|
|
// 验证更新结果
|
|
updated, err := FindOneProfile(ctx, db, profileId)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "http://example.com/newavatar.jpg", updated.Avatar)
|
|
assert.Equal(t, "Updated bio", updated.Bio)
|
|
}
|
|
|
|
// TestDeleteProfile 测试删除个人资料
|
|
func TestDeleteProfile(t *testing.T) {
|
|
db := setupProfileModelTestDB(t)
|
|
|
|
_, profileId := createTestUserProfile(t, db)
|
|
ctx := context.Background()
|
|
|
|
// 删除个人资料
|
|
err := DeleteProfile(ctx, db, profileId)
|
|
|
|
require.NoError(t, err)
|
|
|
|
// 验证个人资料已被删除
|
|
_, err = FindOneProfile(ctx, db, profileId)
|
|
require.Error(t, err)
|
|
assert.Equal(t, ErrNotFound, err)
|
|
}
|
|
|
|
// TestProfile_UserProfileRelation 测试用户与个人资料的关联
|
|
func TestProfile_UserProfileRelation(t *testing.T) {
|
|
db := setupProfileModelTestDB(t)
|
|
ctx := context.Background()
|
|
|
|
// 创建多个用户
|
|
now := time.Now()
|
|
users := []User{
|
|
{Username: "user1", Email: "user1@example.com", Password: "pass", Status: 1, CreatedAt: now, UpdatedAt: now},
|
|
{Username: "user2", Email: "user2@example.com", Password: "pass", Status: 1, CreatedAt: now, UpdatedAt: now},
|
|
{Username: "user3", Email: "user3@example.com", Password: "pass", Status: 1, CreatedAt: now, UpdatedAt: now},
|
|
}
|
|
|
|
for _, u := range users {
|
|
err := db.Create(&u).Error
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// 只为 user1 和 user2 创建个人资料
|
|
profile1 := &Profile{UserId: users[0].Id, Avatar: "avatar1.jpg", Bio: "Bio 1", CreatedAt: now, UpdatedAt: now}
|
|
profile2 := &Profile{UserId: users[1].Id, Avatar: "avatar2.jpg", Bio: "Bio 2", CreatedAt: now, UpdatedAt: now}
|
|
|
|
err := db.Create(profile1).Error
|
|
require.NoError(t, err)
|
|
err = db.Create(profile2).Error
|
|
require.NoError(t, err)
|
|
|
|
// 验证 user1 有个人资料
|
|
found1, err := FindProfileByUserId(ctx, db, users[0].Id)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "avatar1.jpg", found1.Avatar)
|
|
|
|
// 验证 user2 有个人资料
|
|
found2, err := FindProfileByUserId(ctx, db, users[1].Id)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "avatar2.jpg", found2.Avatar)
|
|
|
|
// 验证 user3 没有个人资料
|
|
found3, err := FindProfileByUserId(ctx, db, users[2].Id)
|
|
require.Error(t, err)
|
|
require.Nil(t, found3)
|
|
}
|
|
|
|
// TestProfile_UniqueUserId 测试用户ID唯一性约束
|
|
func TestProfile_UniqueUserId(t *testing.T) {
|
|
db := setupProfileModelTestDB(t)
|
|
ctx := context.Background()
|
|
|
|
// 创建用户
|
|
now := time.Now()
|
|
user := &User{
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
Password: "encryptedpassword",
|
|
Status: 1,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
err := db.Create(user).Error
|
|
require.NoError(t, err)
|
|
|
|
// 创建第一个个人资料
|
|
profile1 := &Profile{
|
|
UserId: user.Id,
|
|
Avatar: "avatar1.jpg",
|
|
Bio: "Bio 1",
|
|
}
|
|
|
|
id, err := InsertProfile(ctx, db, profile1)
|
|
require.NoError(t, err)
|
|
assert.Greater(t, id, int64(0))
|
|
|
|
// 尝试为同一用户创建第二个个人资料(应该失败)
|
|
profile2 := &Profile{
|
|
UserId: user.Id,
|
|
Avatar: "avatar2.jpg",
|
|
Bio: "Bio 2",
|
|
}
|
|
|
|
_, err = InsertProfile(ctx, db, profile2)
|
|
|
|
// 验证结果 - 应该返回错误(违反唯一性约束)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
// TestProfile_EmptyFields 测试空字段
|
|
func TestProfile_EmptyFields(t *testing.T) {
|
|
db := setupProfileModelTestDB(t)
|
|
ctx := context.Background()
|
|
|
|
// 创建用户
|
|
now := time.Now()
|
|
user := &User{
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
Password: "encryptedpassword",
|
|
Status: 1,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
err := db.Create(user).Error
|
|
require.NoError(t, err)
|
|
|
|
// 创建空个人资料
|
|
profile := &Profile{
|
|
UserId: user.Id,
|
|
Avatar: "",
|
|
Bio: "",
|
|
}
|
|
|
|
id, err := InsertProfile(ctx, db, profile)
|
|
|
|
require.NoError(t, err)
|
|
assert.Greater(t, id, int64(0))
|
|
|
|
// 验证保存成功
|
|
saved, err := FindOneProfile(ctx, db, id)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "", saved.Avatar)
|
|
assert.Equal(t, "", saved.Bio)
|
|
}
|
|
|
|
// BenchmarkInsertProfile 性能测试
|
|
func BenchmarkInsertProfile(b *testing.B) {
|
|
db := setupProfileModelTestDB(&testing.T{})
|
|
ctx := context.Background()
|
|
|
|
// 创建测试用户
|
|
now := time.Now()
|
|
user := &User{
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
Password: "encryptedpassword",
|
|
Status: 1,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
err := db.Create(user).Error
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
profile := &Profile{
|
|
UserId: user.Id,
|
|
Avatar: "http://example.com/avatar.jpg",
|
|
Bio: "Test bio",
|
|
}
|
|
_, _ = InsertProfile(ctx, db, profile)
|
|
}
|
|
}
|
|
|
|
// BenchmarkFindProfileByUserId 性能测试
|
|
func BenchmarkFindProfileByUserId(b *testing.B) {
|
|
db := setupProfileModelTestDB(&testing.T{})
|
|
ctx := context.Background()
|
|
|
|
// 创建测试用户和个人资料
|
|
now := time.Now()
|
|
user := &User{
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
Password: "encryptedpassword",
|
|
Status: 1,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
err := db.Create(user).Error
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
profile := &Profile{
|
|
UserId: user.Id,
|
|
Avatar: "http://example.com/avatar.jpg",
|
|
Bio: "Test bio",
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
|
|
err = db.Create(profile).Error
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, _ = FindProfileByUserId(ctx, db, user.Id)
|
|
}
|
|
}
|
|
|