topfans/backend/services/socialService/service/asset_like_service_test.go
2026-06-16 21:30:58 +08:00

116 lines
3.6 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 (
"context"
"errors"
"os"
"testing"
assetPb "github.com/topfans/backend/pkg/proto/asset"
"github.com/topfans/backend/pkg/logger"
"github.com/topfans/backend/services/socialService/client"
"github.com/stretchr/testify/assert"
)
// TestMain 在测试启动时初始化 loggerservice 代码内部使用 logger.Logger
func TestMain(m *testing.M) {
_ = logger.Init(logger.Config{ServiceName: "social-service-test", Environment: "test"})
os.Exit(m.Run())
}
// TestFireLikeNotification_OwnerUidZero_Skips
// 验证 owner_uid <= 0 时直接跳过,不调用 mock client
func TestFireLikeNotification_OwnerUidZero_Skips(t *testing.T) {
mock := &client.MockNotificationClient{}
svc := &AssetLikeService{notificationClient: mock}
ctx := context.Background()
asset := &assetPb.GetAssetForRPCResponse{
AssetId: 1,
OwnerUid: 0,
Name: "some-asset",
CoverUrl: "https://example.com/cover.png",
}
svc.fireLikeNotification(ctx, asset, 1, 2, 1)
assert.Equal(t, int32(0), mock.CreateCallCount, "notification client should NOT be called when owner_uid is invalid")
}
// TestFireLikeNotification_NilAsset_Skips
// 防御 nil asset 入参
func TestFireLikeNotification_NilAsset_Skips(t *testing.T) {
mock := &client.MockNotificationClient{}
svc := &AssetLikeService{notificationClient: mock}
ctx := context.Background()
svc.fireLikeNotification(ctx, nil, 1, 2, 1)
assert.Equal(t, int32(0), mock.CreateCallCount, "notification client should NOT be called when asset is nil")
}
// TestFireLikeNotification_NilClient_Skips
// 防御 nil notificationClient 配置
func TestFireLikeNotification_NilClient_Skips(t *testing.T) {
svc := &AssetLikeService{notificationClient: nil}
ctx := context.Background()
asset := &assetPb.GetAssetForRPCResponse{
AssetId: 1,
OwnerUid: 100,
Name: "x",
CoverUrl: "y",
}
// 应直接 return不 panic
svc.fireLikeNotification(ctx, asset, 1, 2, 1)
}
// TestFireLikeNotification_ClientErr_JustLogs
// 验证 notification client 报错时不 panic不影响主路径
// 这是核心需求:"通知调用失败不能影响点赞主路径"
func TestFireLikeNotification_ClientErr_JustLogs(t *testing.T) {
mock := &client.MockNotificationClient{CreateErr: errors.New("rpc down")}
svc := &AssetLikeService{notificationClient: mock}
ctx := context.Background()
asset := &assetPb.GetAssetForRPCResponse{
AssetId: 1,
OwnerUid: 100,
Name: "藏品A",
CoverUrl: "https://cdn.example.com/a.png",
}
// 不应 panic
svc.fireLikeNotification(ctx, asset, 1, 2, 1)
assert.Equal(t, int32(1), mock.CreateCallCount, "notification client should be called exactly once")
assert.NotNil(t, mock.LastRequest, "LastRequest should be recorded")
}
// TestFireLikeNotification_Success_BuildsCorrectRequest
// 验证 happy path构造的 request 字段全部正确
func TestFireLikeNotification_Success_BuildsCorrectRequest(t *testing.T) {
mock := &client.MockNotificationClient{}
svc := &AssetLikeService{notificationClient: mock}
ctx := context.Background()
asset := &assetPb.GetAssetForRPCResponse{
AssetId: 42,
OwnerUid: 100,
Name: "藏品X",
CoverUrl: "https://cdn.example.com/x.png",
}
svc.fireLikeNotification(ctx, asset, 42, 7, 3)
assert.Equal(t, int32(1), mock.CreateCallCount)
req := mock.LastRequest
if assert.NotNil(t, req) {
assert.Equal(t, int64(100), req.UserId, "通知收件人应为资产 owner")
assert.Equal(t, int64(3), req.StarId)
assert.Equal(t, "like", req.Type)
assert.Equal(t, "新点赞", req.Title)
assert.Contains(t, req.Content, "7", "Content 应包含 actor userID")
assert.NotNil(t, req.Data, "Data 结构体不能为空")
}
}