package packagepkg import ( "context" "fmt" "testing" "time" "github.com/break/junhong_cmp_fiber/internal/model/dto" "github.com/break/junhong_cmp_fiber/internal/store/postgres" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" "github.com/break/junhong_cmp_fiber/pkg/middleware" "github.com/break/junhong_cmp_fiber/tests/testutils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func generateUniquePackageCode(prefix string) string { return fmt.Sprintf("%s_%d", prefix, time.Now().UnixNano()) } func TestPackageService_Create(t *testing.T) { tx := testutils.NewTestTransaction(t) packageStore := postgres.NewPackageStore(tx) packageSeriesStore := postgres.NewPackageSeriesStore(tx) svc := New(packageStore, packageSeriesStore) ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{ UserID: 1, UserType: constants.UserTypePlatform, }) t.Run("创建成功", func(t *testing.T) { req := &dto.CreatePackageRequest{ PackageCode: generateUniquePackageCode("PKG_CREATE"), PackageName: "创建测试套餐", PackageType: "formal", DurationMonths: 1, Price: 9900, } resp, err := svc.Create(ctx, req) require.NoError(t, err) assert.NotZero(t, resp.ID) assert.Equal(t, req.PackageCode, resp.PackageCode) assert.Equal(t, req.PackageName, resp.PackageName) assert.Equal(t, constants.StatusEnabled, resp.Status) assert.Equal(t, 2, resp.ShelfStatus) }) t.Run("编码重复失败", func(t *testing.T) { code := generateUniquePackageCode("PKG_DUP") req1 := &dto.CreatePackageRequest{ PackageCode: code, PackageName: "第一个套餐", PackageType: "formal", DurationMonths: 1, Price: 9900, } _, err := svc.Create(ctx, req1) require.NoError(t, err) req2 := &dto.CreatePackageRequest{ PackageCode: code, PackageName: "第二个套餐", PackageType: "formal", DurationMonths: 1, Price: 9900, } _, err = svc.Create(ctx, req2) require.Error(t, err) appErr, ok := err.(*errors.AppError) require.True(t, ok) assert.Equal(t, errors.CodeConflict, appErr.Code) }) t.Run("系列不存在失败", func(t *testing.T) { req := &dto.CreatePackageRequest{ PackageCode: generateUniquePackageCode("PKG_SERIES"), PackageName: "系列测试套餐", PackageType: "formal", DurationMonths: 1, Price: 9900, SeriesID: func() *uint { id := uint(99999); return &id }(), } _, err := svc.Create(ctx, req) require.Error(t, err) appErr, ok := err.(*errors.AppError) require.True(t, ok) assert.Equal(t, errors.CodeNotFound, appErr.Code) }) } func TestPackageService_UpdateStatus(t *testing.T) { tx := testutils.NewTestTransaction(t) packageStore := postgres.NewPackageStore(tx) packageSeriesStore := postgres.NewPackageSeriesStore(tx) svc := New(packageStore, packageSeriesStore) ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{ UserID: 1, UserType: constants.UserTypePlatform, }) req := &dto.CreatePackageRequest{ PackageCode: generateUniquePackageCode("PKG_STATUS"), PackageName: "状态测试套餐", PackageType: "formal", DurationMonths: 1, Price: 9900, } created, err := svc.Create(ctx, req) require.NoError(t, err) t.Run("禁用套餐时自动强制下架", func(t *testing.T) { err := svc.UpdateShelfStatus(ctx, created.ID, 1) require.NoError(t, err) pkg, err := svc.Get(ctx, created.ID) require.NoError(t, err) assert.Equal(t, 1, pkg.ShelfStatus) err = svc.UpdateStatus(ctx, created.ID, constants.StatusDisabled) require.NoError(t, err) pkg, err = svc.Get(ctx, created.ID) require.NoError(t, err) assert.Equal(t, constants.StatusDisabled, pkg.Status) assert.Equal(t, 2, pkg.ShelfStatus) }) t.Run("启用套餐时保持原上架状态", func(t *testing.T) { req2 := &dto.CreatePackageRequest{ PackageCode: generateUniquePackageCode("PKG_ENABLE"), PackageName: "启用测试套餐", PackageType: "formal", DurationMonths: 1, Price: 9900, } created2, err := svc.Create(ctx, req2) require.NoError(t, err) err = svc.UpdateShelfStatus(ctx, created2.ID, 1) require.NoError(t, err) err = svc.UpdateStatus(ctx, created2.ID, constants.StatusDisabled) require.NoError(t, err) pkg, err := svc.Get(ctx, created2.ID) require.NoError(t, err) assert.Equal(t, constants.StatusDisabled, pkg.Status) assert.Equal(t, 2, pkg.ShelfStatus) err = svc.UpdateStatus(ctx, created2.ID, constants.StatusEnabled) require.NoError(t, err) pkg, err = svc.Get(ctx, created2.ID) require.NoError(t, err) assert.Equal(t, constants.StatusEnabled, pkg.Status) assert.Equal(t, 2, pkg.ShelfStatus) }) } func TestPackageService_UpdateShelfStatus(t *testing.T) { tx := testutils.NewTestTransaction(t) packageStore := postgres.NewPackageStore(tx) packageSeriesStore := postgres.NewPackageSeriesStore(tx) svc := New(packageStore, packageSeriesStore) ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{ UserID: 1, UserType: constants.UserTypePlatform, }) t.Run("启用状态的套餐可以上架", func(t *testing.T) { req := &dto.CreatePackageRequest{ PackageCode: generateUniquePackageCode("PKG_SHELF_ENABLE"), PackageName: "上架测试-启用", PackageType: "formal", DurationMonths: 1, Price: 9900, } created, err := svc.Create(ctx, req) require.NoError(t, err) pkg, err := svc.Get(ctx, created.ID) require.NoError(t, err) assert.Equal(t, 1, pkg.Status) assert.Equal(t, 2, pkg.ShelfStatus) err = svc.UpdateShelfStatus(ctx, created.ID, 1) require.NoError(t, err) pkg, err = svc.Get(ctx, created.ID) require.NoError(t, err) assert.Equal(t, 1, pkg.ShelfStatus) }) t.Run("禁用状态的套餐不能上架", func(t *testing.T) { req := &dto.CreatePackageRequest{ PackageCode: generateUniquePackageCode("PKG_SHELF_DISABLE"), PackageName: "上架测试-禁用", PackageType: "formal", DurationMonths: 1, Price: 9900, } created, err := svc.Create(ctx, req) require.NoError(t, err) err = svc.UpdateStatus(ctx, created.ID, constants.StatusDisabled) require.NoError(t, err) err = svc.UpdateShelfStatus(ctx, created.ID, 1) require.Error(t, err) appErr, ok := err.(*errors.AppError) require.True(t, ok) assert.Equal(t, errors.CodeInvalidStatus, appErr.Code) pkg, err := svc.Get(ctx, created.ID) require.NoError(t, err) assert.Equal(t, 2, pkg.ShelfStatus) }) t.Run("下架成功", func(t *testing.T) { req := &dto.CreatePackageRequest{ PackageCode: generateUniquePackageCode("PKG_SHELF_OFF"), PackageName: "下架测试", PackageType: "formal", DurationMonths: 1, Price: 9900, } created, err := svc.Create(ctx, req) require.NoError(t, err) err = svc.UpdateShelfStatus(ctx, created.ID, 1) require.NoError(t, err) pkg, err := svc.Get(ctx, created.ID) require.NoError(t, err) assert.Equal(t, 1, pkg.ShelfStatus) err = svc.UpdateShelfStatus(ctx, created.ID, 2) require.NoError(t, err) pkg, err = svc.Get(ctx, created.ID) require.NoError(t, err) assert.Equal(t, 2, pkg.ShelfStatus) }) } func TestPackageService_Get(t *testing.T) { tx := testutils.NewTestTransaction(t) packageStore := postgres.NewPackageStore(tx) packageSeriesStore := postgres.NewPackageSeriesStore(tx) svc := New(packageStore, packageSeriesStore) ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{ UserID: 1, UserType: constants.UserTypePlatform, }) req := &dto.CreatePackageRequest{ PackageCode: generateUniquePackageCode("PKG_GET"), PackageName: "查询测试套餐", PackageType: "formal", DurationMonths: 1, Price: 9900, } created, err := svc.Create(ctx, req) require.NoError(t, err) t.Run("获取成功", func(t *testing.T) { resp, err := svc.Get(ctx, created.ID) require.NoError(t, err) assert.Equal(t, created.PackageCode, resp.PackageCode) assert.Equal(t, created.PackageName, resp.PackageName) assert.Equal(t, created.ID, resp.ID) }) t.Run("不存在返回错误", func(t *testing.T) { _, err := svc.Get(ctx, 99999) require.Error(t, err) appErr, ok := err.(*errors.AppError) require.True(t, ok) assert.Equal(t, errors.CodeNotFound, appErr.Code) }) } func TestPackageService_Update(t *testing.T) { tx := testutils.NewTestTransaction(t) packageStore := postgres.NewPackageStore(tx) packageSeriesStore := postgres.NewPackageSeriesStore(tx) svc := New(packageStore, packageSeriesStore) ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{ UserID: 1, UserType: constants.UserTypePlatform, }) req := &dto.CreatePackageRequest{ PackageCode: generateUniquePackageCode("PKG_UPDATE"), PackageName: "更新测试套餐", PackageType: "formal", DurationMonths: 1, Price: 9900, } created, err := svc.Create(ctx, req) require.NoError(t, err) t.Run("更新成功", func(t *testing.T) { newName := "更新后的套餐名称" newPrice := int64(19900) updateReq := &dto.UpdatePackageRequest{ PackageName: &newName, Price: &newPrice, } resp, err := svc.Update(ctx, created.ID, updateReq) require.NoError(t, err) assert.Equal(t, newName, resp.PackageName) assert.Equal(t, newPrice, resp.Price) }) t.Run("更新不存在的套餐", func(t *testing.T) { newName := "test" updateReq := &dto.UpdatePackageRequest{ PackageName: &newName, } _, err := svc.Update(ctx, 99999, updateReq) require.Error(t, err) appErr, ok := err.(*errors.AppError) require.True(t, ok) assert.Equal(t, errors.CodeNotFound, appErr.Code) }) } func TestPackageService_Delete(t *testing.T) { tx := testutils.NewTestTransaction(t) packageStore := postgres.NewPackageStore(tx) packageSeriesStore := postgres.NewPackageSeriesStore(tx) svc := New(packageStore, packageSeriesStore) ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{ UserID: 1, UserType: constants.UserTypePlatform, }) req := &dto.CreatePackageRequest{ PackageCode: generateUniquePackageCode("PKG_DELETE"), PackageName: "删除测试套餐", PackageType: "formal", DurationMonths: 1, Price: 9900, } created, err := svc.Create(ctx, req) require.NoError(t, err) t.Run("删除成功", func(t *testing.T) { err := svc.Delete(ctx, created.ID) require.NoError(t, err) _, err = svc.Get(ctx, created.ID) require.Error(t, err) }) t.Run("删除不存在的套餐", func(t *testing.T) { err := svc.Delete(ctx, 99999) require.Error(t, err) }) } func TestPackageService_List(t *testing.T) { tx := testutils.NewTestTransaction(t) packageStore := postgres.NewPackageStore(tx) packageSeriesStore := postgres.NewPackageSeriesStore(tx) svc := New(packageStore, packageSeriesStore) ctx := middleware.SetUserContext(context.Background(), &middleware.UserContextInfo{ UserID: 1, UserType: constants.UserTypePlatform, }) packages := []dto.CreatePackageRequest{ { PackageCode: generateUniquePackageCode("PKG_LIST_001"), PackageName: "列表测试套餐1", PackageType: "formal", DurationMonths: 1, Price: 9900, }, { PackageCode: generateUniquePackageCode("PKG_LIST_002"), PackageName: "列表测试套餐2", PackageType: "addon", DurationMonths: 1, Price: 4900, }, { PackageCode: generateUniquePackageCode("PKG_LIST_003"), PackageName: "列表测试套餐3", PackageType: "formal", DurationMonths: 12, Price: 99900, }, } for _, p := range packages { _, err := svc.Create(ctx, &p) require.NoError(t, err) } t.Run("列表查询", func(t *testing.T) { req := &dto.PackageListRequest{ Page: 1, PageSize: 10, } resp, total, err := svc.List(ctx, req) require.NoError(t, err) assert.Greater(t, total, int64(0)) assert.Greater(t, len(resp), 0) }) t.Run("按套餐类型过滤", func(t *testing.T) { packageType := "formal" req := &dto.PackageListRequest{ Page: 1, PageSize: 10, PackageType: &packageType, } resp, _, err := svc.List(ctx, req) require.NoError(t, err) for _, p := range resp { assert.Equal(t, packageType, p.PackageType) } }) t.Run("按状态过滤", func(t *testing.T) { status := constants.StatusEnabled req := &dto.PackageListRequest{ Page: 1, PageSize: 10, Status: &status, } resp, _, err := svc.List(ctx, req) require.NoError(t, err) for _, p := range resp { assert.Equal(t, status, p.Status) } }) }