- 数据库: 重命名 series_allocation_id → series_id - Model: IotCard 和 Device 字段重命名 - DTO: 所有请求/响应字段统一为 series_id - Store: 方法重命名,新增 GetByShopAndSeries 查询 - Service: 业务逻辑优化,系列验证和权限验证分离 - 测试: 更新所有测试用例,新增 shop_series_allocation_store_test.go - 文档: 更新 API 文档说明参数变更 BREAKING CHANGE: API 参数从 series_allocation_id 改为 series_id
149 lines
4.5 KiB
Go
149 lines
4.5 KiB
Go
package iot_card
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/break/junhong_cmp_fiber/internal/model"
|
|
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
|
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
|
"github.com/break/junhong_cmp_fiber/tests/testutils"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func uniqueTestICCIDPrefix() string {
|
|
return fmt.Sprintf("T%d", time.Now().UnixNano()%1000000000)
|
|
}
|
|
|
|
func TestIotCardService_BatchSetSeriesBinding(t *testing.T) {
|
|
tx := testutils.NewTestTransaction(t)
|
|
rdb := testutils.GetTestRedis(t)
|
|
testutils.CleanTestRedisKeys(t, rdb)
|
|
|
|
iotCardStore := postgres.NewIotCardStore(tx, rdb)
|
|
shopStore := postgres.NewShopStore(tx, rdb)
|
|
assetAllocationRecordStore := postgres.NewAssetAllocationRecordStore(tx, rdb)
|
|
seriesAllocationStore := postgres.NewShopSeriesAllocationStore(tx)
|
|
|
|
packageSeriesStore := postgres.NewPackageSeriesStore(tx)
|
|
svc := New(tx, iotCardStore, shopStore, assetAllocationRecordStore, seriesAllocationStore, packageSeriesStore, nil, nil)
|
|
ctx := context.Background()
|
|
|
|
shop := &model.Shop{
|
|
ShopName: "测试店铺",
|
|
ShopCode: fmt.Sprintf("SHOP%d", time.Now().UnixNano()%1000000),
|
|
Level: 1,
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(shop).Error)
|
|
|
|
series := &model.PackageSeries{
|
|
SeriesCode: fmt.Sprintf("SERIES%d", time.Now().UnixNano()%1000000),
|
|
SeriesName: "测试系列",
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(series).Error)
|
|
|
|
allocation := &model.ShopSeriesAllocation{
|
|
ShopID: shop.ID,
|
|
SeriesID: series.ID,
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(allocation).Error)
|
|
|
|
prefix := uniqueTestICCIDPrefix()
|
|
cards := []*model.IotCard{
|
|
{ICCID: prefix + "001", CardType: "data_card", CarrierID: 1, Status: 1, ShopID: &shop.ID},
|
|
{ICCID: prefix + "002", CardType: "data_card", CarrierID: 1, Status: 1, ShopID: &shop.ID},
|
|
{ICCID: prefix + "003", CardType: "data_card", CarrierID: 1, Status: 1, ShopID: nil},
|
|
}
|
|
require.NoError(t, iotCardStore.CreateBatch(ctx, cards))
|
|
|
|
t.Run("成功设置系列绑定", func(t *testing.T) {
|
|
req := &dto.BatchSetCardSeriesBindngRequest{
|
|
ICCIDs: []string{prefix + "001", prefix + "002"},
|
|
SeriesID: allocation.SeriesID,
|
|
}
|
|
|
|
resp, err := svc.BatchSetSeriesBinding(ctx, req, nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 2, resp.SuccessCount)
|
|
assert.Equal(t, 0, resp.FailCount)
|
|
|
|
var updatedCards []*model.IotCard
|
|
require.NoError(t, tx.Where("iccid IN ?", req.ICCIDs).Find(&updatedCards).Error)
|
|
for _, card := range updatedCards {
|
|
require.NotNil(t, card.SeriesID)
|
|
assert.Equal(t, allocation.SeriesID, *card.SeriesID)
|
|
}
|
|
})
|
|
|
|
t.Run("卡不属于套餐系列分配的店铺", func(t *testing.T) {
|
|
req := &dto.BatchSetCardSeriesBindngRequest{
|
|
ICCIDs: []string{prefix + "003"},
|
|
SeriesID: allocation.SeriesID,
|
|
}
|
|
|
|
resp, err := svc.BatchSetSeriesBinding(ctx, req, nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, resp.SuccessCount)
|
|
assert.Equal(t, 1, resp.FailCount)
|
|
assert.Equal(t, "卡不属于套餐系列分配的店铺", resp.FailedItems[0].Reason)
|
|
})
|
|
|
|
t.Run("卡不存在", func(t *testing.T) {
|
|
req := &dto.BatchSetCardSeriesBindngRequest{
|
|
ICCIDs: []string{"NOTEXIST001"},
|
|
SeriesID: allocation.SeriesID,
|
|
}
|
|
|
|
resp, err := svc.BatchSetSeriesBinding(ctx, req, nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, resp.SuccessCount)
|
|
assert.Equal(t, 1, resp.FailCount)
|
|
assert.Equal(t, "卡不存在", resp.FailedItems[0].Reason)
|
|
})
|
|
|
|
t.Run("清除系列绑定", func(t *testing.T) {
|
|
req := &dto.BatchSetCardSeriesBindngRequest{
|
|
ICCIDs: []string{prefix + "001"},
|
|
SeriesID: 0,
|
|
}
|
|
|
|
resp, err := svc.BatchSetSeriesBinding(ctx, req, nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 1, resp.SuccessCount)
|
|
|
|
var updatedCard model.IotCard
|
|
require.NoError(t, tx.Where("iccid = ?", prefix+"001").First(&updatedCard).Error)
|
|
assert.Nil(t, updatedCard.SeriesID)
|
|
})
|
|
|
|
t.Run("代理用户只能操作自己店铺的卡", func(t *testing.T) {
|
|
otherShopID := uint(99999)
|
|
req := &dto.BatchSetCardSeriesBindngRequest{
|
|
ICCIDs: []string{prefix + "002"},
|
|
SeriesID: 0,
|
|
}
|
|
|
|
resp, err := svc.BatchSetSeriesBinding(ctx, req, &otherShopID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, resp.SuccessCount)
|
|
assert.Equal(t, 1, resp.FailCount)
|
|
assert.Equal(t, "无权操作此卡", resp.FailedItems[0].Reason)
|
|
})
|
|
|
|
t.Run("套餐系列分配不存在", func(t *testing.T) {
|
|
req := &dto.BatchSetCardSeriesBindngRequest{
|
|
ICCIDs: []string{prefix + "002"},
|
|
SeriesID: 99999,
|
|
}
|
|
|
|
_, err := svc.BatchSetSeriesBinding(ctx, req, nil)
|
|
require.Error(t, err)
|
|
})
|
|
}
|