topfans/backend/services/galleryService/service/gallery_service_test.go
2026-05-16 02:42:32 +08:00

254 lines
7.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/topfans/backend/pkg/database"
"github.com/topfans/backend/pkg/models"
"github.com/topfans/backend/services/galleryService/client"
"github.com/topfans/backend/services/galleryService/repository"
"gorm.io/gorm"
)
// mockAssetRPCClient Mock Asset RPC客户端
type mockAssetRPCClient struct{}
func (m *mockAssetRPCClient) GetAssetForRPC(assetID, userID, starID int64) (*client.AssetInfo, error) {
return &client.AssetInfo{
AssetId: assetID,
OwnerUid: userID,
StarId: starID,
Name: "测试资产",
CoverUrl: "https://example.com/cover.jpg",
LikeCount: 10,
}, nil
}
func (m *mockAssetRPCClient) GetAssetInfo(assetID, userID, starID int64) (*client.AssetInfo, error) {
return &client.AssetInfo{
AssetId: assetID,
Name: "测试资产",
CoverUrl: "https://example.com/cover.jpg",
LikeCount: 10,
}, nil
}
func (m *mockAssetRPCClient) ClearAssetLikeRecords(assetID int64) error {
return nil
}
func (m *mockAssetRPCClient) GetAssetLikeCount(assetID int64) int {
return 10
}
// mockUserRPCClient Mock User RPC客户端
type mockUserRPCClient struct{}
func (m *mockUserRPCClient) GetFanProfile(userID, starID int64) (*client.FanProfile, error) {
return &client.FanProfile{
ID: userID*1000000 + starID, // 模拟真实的 fan_profile ID
UserID: userID,
StarID: starID,
Nickname: "测试用户",
Level: 5,
CrystalBalance: 1000,
}, nil
}
func (m *mockUserRPCClient) UpdateCrystalBalance(userID, starID int64, delta int64, changeType string, sourceID string, description string) (int64, error) {
// 简单返回更新后的余额1000 + delta
return 1000 + delta, nil
}
func (m *mockUserRPCClient) AddExhibitionHours(userID, starID int64, hours int64, sourceID string) (int32, int32, int64, error) {
// 简单返回模拟的升级结果
return 5, 0, 0, nil
}
// setupTestDB 设置测试数据库
func setupTestDB(t *testing.T) *gorm.DB {
dbConfig := database.Config{
Host: "localhost",
Port: 5432,
User: "haihuizhu",
Password: "admin",
DBName: "top-fans",
SSLMode: "disable",
TimeZone: "Asia/Shanghai",
}
if err := database.Init(dbConfig); err != nil {
t.Skipf("Skipping test: failed to connect to test database: %v", err)
}
db := database.GetDB()
// 迁移表
if err := db.AutoMigrate(&models.BoothSlot{}, &models.Exhibition{}); err != nil {
t.Logf("Warning: Failed to migrate tables: %v", err)
}
// 清理测试数据
cleanupTestDB(t, db)
return db
}
// cleanupTestDB 清理测试数据
func cleanupTestDB(t *testing.T, db *gorm.DB) {
db.Exec("DELETE FROM exhibitions WHERE occupier_uid IN (SELECT id FROM users WHERE mobile LIKE '199%')")
db.Exec("DELETE FROM booth_slots WHERE user_id IN (SELECT id FROM users WHERE mobile LIKE '199%')")
}
// createTestStar 创建测试明星
func createTestStar(t *testing.T, db *gorm.DB, identityID string) *models.Star {
var existingStar models.Star
if err := db.Where("identity_id = ?", identityID).First(&existingStar).Error; err == nil {
return &existingStar
}
star := &models.Star{
Name: "测试明星-" + identityID,
IdentityID: identityID,
IsActive: true,
}
if err := db.Create(star).Error; err != nil {
t.Fatalf("Failed to create test star: %v", err)
}
return star
}
// createTestUser 创建测试用户
func createTestUser(t *testing.T, db *gorm.DB, mobile string) *models.User {
user := &models.User{
Mobile: mobile,
PasswordHash: "test_hash",
IsActive: true,
}
if err := db.Create(user).Error; err != nil {
t.Fatalf("Failed to create test user: %v", err)
}
return user
}
// createTestFanProfile 创建测试粉丝档案
func createTestFanProfile(t *testing.T, db *gorm.DB, userID, starID int64, nickname string) *models.FanProfile {
profile := &models.FanProfile{
UserID: userID,
StarID: starID,
Nickname: nickname,
Level: 1,
}
if err := db.Create(profile).Error; err != nil {
t.Fatalf("Failed to create test fan profile: %v", err)
}
return profile
}
// TestGetMyGallery_LazyLoading 测试获取我的展馆(懒加载逻辑)
func TestGetMyGallery_LazyLoading(t *testing.T) {
db := setupTestDB(t)
defer cleanupTestDB(t, db)
repo := repository.NewGalleryRepository(db)
assetClient := &mockAssetRPCClient{}
userClient := &mockUserRPCClient{}
service := NewGalleryService(repo, assetClient, userClient)
// 创建测试用户和明星
star := createTestStar(t, db, "test_service_001")
user := createTestUser(t, db, "19900000011")
createTestFanProfile(t, db, user.ID, star.StarID, "测试用户011")
// 首次查询,应该触发懒加载
gallery, err := service.GetMyGallery(user.ID, star.StarID)
assert.NoError(t, err, "获取展馆应该成功")
assert.NotNil(t, gallery, "展馆数据不应该为空")
assert.Equal(t, int32(3), gallery.SlotTotal, "初始展位数应该为3")
assert.Len(t, gallery.Slots, 3, "展位列表长度应该为3")
// 验证展位状态
for _, slot := range gallery.Slots {
assert.True(t, slot.IsEnabled, "初始展位应该已解锁")
assert.Equal(t, "EMPTY", slot.Status, "初始展位应该为空")
}
}
// TestGetMyGallery_ExistingSlots 测试获取我的展馆(已有展位)
func TestGetMyGallery_ExistingSlots(t *testing.T) {
db := setupTestDB(t)
defer cleanupTestDB(t, db)
repo := repository.NewGalleryRepository(db)
assetClient := &mockAssetRPCClient{}
userClient := &mockUserRPCClient{}
service := NewGalleryService(repo, assetClient, userClient)
// 创建测试用户和明星
star := createTestStar(t, db, "test_service_002")
user := createTestUser(t, db, "19900000012")
createTestFanProfile(t, db, user.ID, star.StarID, "测试用户012")
// 预先创建展位(使用模拟的 hostProfileID
err := repo.CreateInitialSlots(user.ID, star.StarID, user.ID*1000000+star.StarID)
assert.NoError(t, err)
// 查询展馆
gallery, err := service.GetMyGallery(user.ID, star.StarID)
assert.NoError(t, err)
assert.NotNil(t, gallery)
assert.Equal(t, int32(3), gallery.SlotTotal)
}
// TestGetUserGallery 测试获取他人展馆
func TestGetUserGallery(t *testing.T) {
db := setupTestDB(t)
defer cleanupTestDB(t, db)
repo := repository.NewGalleryRepository(db)
assetClient := &mockAssetRPCClient{}
userClient := &mockUserRPCClient{}
service := NewGalleryService(repo, assetClient, userClient)
// 创建测试用户和明星
star := createTestStar(t, db, "test_service_003")
user := createTestUser(t, db, "19900000013")
createTestFanProfile(t, db, user.ID, star.StarID, "测试用户013")
// 预先创建展位(使用模拟的 hostProfileID
err := repo.CreateInitialSlots(user.ID, star.StarID, user.ID*1000000+star.StarID)
assert.NoError(t, err)
// 另一个用户查询该用户的展馆
otherUser := createTestUser(t, db, "19900000014")
gallery, err := service.GetUserGallery(otherUser.ID, star.StarID, user.ID)
assert.NoError(t, err)
assert.NotNil(t, gallery)
assert.Equal(t, int32(3), gallery.SlotTotal)
}
// TestGetUserGallery_EmptyGallery 测试获取他人展馆(空展馆)
func TestGetUserGallery_EmptyGallery(t *testing.T) {
db := setupTestDB(t)
defer cleanupTestDB(t, db)
repo := repository.NewGalleryRepository(db)
assetClient := &mockAssetRPCClient{}
userClient := &mockUserRPCClient{}
service := NewGalleryService(repo, assetClient, userClient)
// 创建测试用户和明星
star := createTestStar(t, db, "test_service_004")
user := createTestUser(t, db, "19900000015")
createTestFanProfile(t, db, user.ID, star.StarID, "测试用户015")
// 不创建展位,直接查询
otherUser := createTestUser(t, db, "19900000016")
gallery, err := service.GetUserGallery(otherUser.ID, star.StarID, user.ID)
assert.NoError(t, err)
assert.NotNil(t, gallery)
assert.Equal(t, int32(0), gallery.SlotTotal, "应该返回空展馆")
assert.Empty(t, gallery.Slots, "展位列表应该为空")
}