mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-04-17 21:34:45 +08:00
198 lines
6.0 KiB
Go
198 lines
6.0 KiB
Go
|
|
//go:build unit
|
|||
|
|
|
|||
|
|
package service
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"context"
|
|||
|
|
"testing"
|
|||
|
|
|
|||
|
|
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
|
|||
|
|
"github.com/stretchr/testify/require"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// groupRepoStubForAdmin 用于测试 AdminService 的 GroupRepository Stub
|
|||
|
|
type groupRepoStubForAdmin struct {
|
|||
|
|
created *Group // 记录 Create 调用的参数
|
|||
|
|
updated *Group // 记录 Update 调用的参数
|
|||
|
|
getByID *Group // GetByID 返回值
|
|||
|
|
getErr error // GetByID 返回的错误
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) Create(_ context.Context, g *Group) error {
|
|||
|
|
s.created = g
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) Update(_ context.Context, g *Group) error {
|
|||
|
|
s.updated = g
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) GetByID(_ context.Context, _ int64) (*Group, error) {
|
|||
|
|
if s.getErr != nil {
|
|||
|
|
return nil, s.getErr
|
|||
|
|
}
|
|||
|
|
return s.getByID, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) Delete(_ context.Context, _ int64) error {
|
|||
|
|
panic("unexpected Delete call")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) DeleteCascade(_ context.Context, _ int64) ([]int64, error) {
|
|||
|
|
panic("unexpected DeleteCascade call")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) List(_ context.Context, _ pagination.PaginationParams) ([]Group, *pagination.PaginationResult, error) {
|
|||
|
|
panic("unexpected List call")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) ListWithFilters(_ context.Context, _ pagination.PaginationParams, _, _ string, _ *bool) ([]Group, *pagination.PaginationResult, error) {
|
|||
|
|
panic("unexpected ListWithFilters call")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) ListActive(_ context.Context) ([]Group, error) {
|
|||
|
|
panic("unexpected ListActive call")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) ListActiveByPlatform(_ context.Context, _ string) ([]Group, error) {
|
|||
|
|
panic("unexpected ListActiveByPlatform call")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) ExistsByName(_ context.Context, _ string) (bool, error) {
|
|||
|
|
panic("unexpected ExistsByName call")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) GetAccountCount(_ context.Context, _ int64) (int64, error) {
|
|||
|
|
panic("unexpected GetAccountCount call")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (s *groupRepoStubForAdmin) DeleteAccountGroupsByGroupID(_ context.Context, _ int64) (int64, error) {
|
|||
|
|
panic("unexpected DeleteAccountGroupsByGroupID call")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TestAdminService_CreateGroup_WithImagePricing 测试创建分组时 ImagePrice 字段正确传递
|
|||
|
|
func TestAdminService_CreateGroup_WithImagePricing(t *testing.T) {
|
|||
|
|
repo := &groupRepoStubForAdmin{}
|
|||
|
|
svc := &adminServiceImpl{groupRepo: repo}
|
|||
|
|
|
|||
|
|
price1K := 0.10
|
|||
|
|
price2K := 0.15
|
|||
|
|
price4K := 0.30
|
|||
|
|
|
|||
|
|
input := &CreateGroupInput{
|
|||
|
|
Name: "test-group",
|
|||
|
|
Description: "Test group",
|
|||
|
|
Platform: PlatformAntigravity,
|
|||
|
|
RateMultiplier: 1.0,
|
|||
|
|
ImagePrice1K: &price1K,
|
|||
|
|
ImagePrice2K: &price2K,
|
|||
|
|
ImagePrice4K: &price4K,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
group, err := svc.CreateGroup(context.Background(), input)
|
|||
|
|
require.NoError(t, err)
|
|||
|
|
require.NotNil(t, group)
|
|||
|
|
|
|||
|
|
// 验证 repo 收到了正确的字段
|
|||
|
|
require.NotNil(t, repo.created)
|
|||
|
|
require.NotNil(t, repo.created.ImagePrice1K)
|
|||
|
|
require.NotNil(t, repo.created.ImagePrice2K)
|
|||
|
|
require.NotNil(t, repo.created.ImagePrice4K)
|
|||
|
|
require.InDelta(t, 0.10, *repo.created.ImagePrice1K, 0.0001)
|
|||
|
|
require.InDelta(t, 0.15, *repo.created.ImagePrice2K, 0.0001)
|
|||
|
|
require.InDelta(t, 0.30, *repo.created.ImagePrice4K, 0.0001)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TestAdminService_CreateGroup_NilImagePricing 测试 ImagePrice 为 nil 时正常创建
|
|||
|
|
func TestAdminService_CreateGroup_NilImagePricing(t *testing.T) {
|
|||
|
|
repo := &groupRepoStubForAdmin{}
|
|||
|
|
svc := &adminServiceImpl{groupRepo: repo}
|
|||
|
|
|
|||
|
|
input := &CreateGroupInput{
|
|||
|
|
Name: "test-group",
|
|||
|
|
Description: "Test group",
|
|||
|
|
Platform: PlatformAntigravity,
|
|||
|
|
RateMultiplier: 1.0,
|
|||
|
|
// ImagePrice 字段全部为 nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
group, err := svc.CreateGroup(context.Background(), input)
|
|||
|
|
require.NoError(t, err)
|
|||
|
|
require.NotNil(t, group)
|
|||
|
|
|
|||
|
|
// 验证 ImagePrice 字段为 nil
|
|||
|
|
require.NotNil(t, repo.created)
|
|||
|
|
require.Nil(t, repo.created.ImagePrice1K)
|
|||
|
|
require.Nil(t, repo.created.ImagePrice2K)
|
|||
|
|
require.Nil(t, repo.created.ImagePrice4K)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TestAdminService_UpdateGroup_WithImagePricing 测试更新分组时 ImagePrice 字段正确更新
|
|||
|
|
func TestAdminService_UpdateGroup_WithImagePricing(t *testing.T) {
|
|||
|
|
existingGroup := &Group{
|
|||
|
|
ID: 1,
|
|||
|
|
Name: "existing-group",
|
|||
|
|
Platform: PlatformAntigravity,
|
|||
|
|
Status: StatusActive,
|
|||
|
|
}
|
|||
|
|
repo := &groupRepoStubForAdmin{getByID: existingGroup}
|
|||
|
|
svc := &adminServiceImpl{groupRepo: repo}
|
|||
|
|
|
|||
|
|
price1K := 0.12
|
|||
|
|
price2K := 0.18
|
|||
|
|
price4K := 0.36
|
|||
|
|
|
|||
|
|
input := &UpdateGroupInput{
|
|||
|
|
ImagePrice1K: &price1K,
|
|||
|
|
ImagePrice2K: &price2K,
|
|||
|
|
ImagePrice4K: &price4K,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
group, err := svc.UpdateGroup(context.Background(), 1, input)
|
|||
|
|
require.NoError(t, err)
|
|||
|
|
require.NotNil(t, group)
|
|||
|
|
|
|||
|
|
// 验证 repo 收到了更新后的字段
|
|||
|
|
require.NotNil(t, repo.updated)
|
|||
|
|
require.NotNil(t, repo.updated.ImagePrice1K)
|
|||
|
|
require.NotNil(t, repo.updated.ImagePrice2K)
|
|||
|
|
require.NotNil(t, repo.updated.ImagePrice4K)
|
|||
|
|
require.InDelta(t, 0.12, *repo.updated.ImagePrice1K, 0.0001)
|
|||
|
|
require.InDelta(t, 0.18, *repo.updated.ImagePrice2K, 0.0001)
|
|||
|
|
require.InDelta(t, 0.36, *repo.updated.ImagePrice4K, 0.0001)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TestAdminService_UpdateGroup_PartialImagePricing 测试仅更新部分 ImagePrice 字段
|
|||
|
|
func TestAdminService_UpdateGroup_PartialImagePricing(t *testing.T) {
|
|||
|
|
oldPrice2K := 0.15
|
|||
|
|
existingGroup := &Group{
|
|||
|
|
ID: 1,
|
|||
|
|
Name: "existing-group",
|
|||
|
|
Platform: PlatformAntigravity,
|
|||
|
|
Status: StatusActive,
|
|||
|
|
ImagePrice2K: &oldPrice2K, // 已有 2K 价格
|
|||
|
|
}
|
|||
|
|
repo := &groupRepoStubForAdmin{getByID: existingGroup}
|
|||
|
|
svc := &adminServiceImpl{groupRepo: repo}
|
|||
|
|
|
|||
|
|
// 只更新 1K 价格
|
|||
|
|
price1K := 0.10
|
|||
|
|
input := &UpdateGroupInput{
|
|||
|
|
ImagePrice1K: &price1K,
|
|||
|
|
// ImagePrice2K 和 ImagePrice4K 为 nil,不更新
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
group, err := svc.UpdateGroup(context.Background(), 1, input)
|
|||
|
|
require.NoError(t, err)
|
|||
|
|
require.NotNil(t, group)
|
|||
|
|
|
|||
|
|
// 验证:1K 被更新,2K 保持原值,4K 仍为 nil
|
|||
|
|
require.NotNil(t, repo.updated)
|
|||
|
|
require.NotNil(t, repo.updated.ImagePrice1K)
|
|||
|
|
require.InDelta(t, 0.10, *repo.updated.ImagePrice1K, 0.0001)
|
|||
|
|
require.NotNil(t, repo.updated.ImagePrice2K)
|
|||
|
|
require.InDelta(t, 0.15, *repo.updated.ImagePrice2K, 0.0001) // 原值保持
|
|||
|
|
require.Nil(t, repo.updated.ImagePrice4K)
|
|||
|
|
}
|