254 lines
7.8 KiB
Go
254 lines
7.8 KiB
Go
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, "展位列表应该为空")
|
||
}
|