package device 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 uniqueTestDeviceNoPrefix() string { return fmt.Sprintf("D%d", time.Now().UnixNano()%1000000000) } func TestDeviceService_BatchSetSeriesBinding(t *testing.T) { tx := testutils.NewTestTransaction(t) rdb := testutils.GetTestRedis(t) testutils.CleanTestRedisKeys(t, rdb) deviceStore := postgres.NewDeviceStore(tx, rdb) deviceSimBindingStore := postgres.NewDeviceSimBindingStore(tx, rdb) iotCardStore := postgres.NewIotCardStore(tx, rdb) shopStore := postgres.NewShopStore(tx, rdb) assetAllocationRecordStore := postgres.NewAssetAllocationRecordStore(tx, rdb) seriesAllocationStore := postgres.NewShopSeriesAllocationStore(tx) svc := New(tx, deviceStore, deviceSimBindingStore, iotCardStore, shopStore, assetAllocationRecordStore, seriesAllocationStore) 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 := uniqueTestDeviceNoPrefix() devices := []*model.Device{ {DeviceNo: prefix + "001", DeviceName: "测试设备1", Status: 1, ShopID: &shop.ID}, {DeviceNo: prefix + "002", DeviceName: "测试设备2", Status: 1, ShopID: &shop.ID}, {DeviceNo: prefix + "003", DeviceName: "测试设备3", Status: 1, ShopID: nil}, } require.NoError(t, deviceStore.CreateBatch(ctx, devices)) t.Run("成功设置系列绑定", func(t *testing.T) { req := &dto.BatchSetDeviceSeriesBindngRequest{ DeviceIDs: []uint{devices[0].ID, devices[1].ID}, SeriesAllocationID: allocation.ID, } resp, err := svc.BatchSetSeriesBinding(ctx, req, nil) require.NoError(t, err) assert.Equal(t, 2, resp.SuccessCount) assert.Equal(t, 0, resp.FailCount) var updatedDevices []*model.Device require.NoError(t, tx.Where("id IN ?", req.DeviceIDs).Find(&updatedDevices).Error) for _, device := range updatedDevices { require.NotNil(t, device.SeriesAllocationID) assert.Equal(t, allocation.ID, *device.SeriesAllocationID) } }) t.Run("设备不属于套餐系列分配的店铺", func(t *testing.T) { req := &dto.BatchSetDeviceSeriesBindngRequest{ DeviceIDs: []uint{devices[2].ID}, SeriesAllocationID: allocation.ID, } 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.BatchSetDeviceSeriesBindngRequest{ DeviceIDs: []uint{99999}, SeriesAllocationID: allocation.ID, } 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.BatchSetDeviceSeriesBindngRequest{ DeviceIDs: []uint{devices[0].ID}, SeriesAllocationID: 0, } resp, err := svc.BatchSetSeriesBinding(ctx, req, nil) require.NoError(t, err) assert.Equal(t, 1, resp.SuccessCount) var updatedDevice model.Device require.NoError(t, tx.First(&updatedDevice, devices[0].ID).Error) assert.Nil(t, updatedDevice.SeriesAllocationID) }) t.Run("代理用户只能操作自己店铺的设备", func(t *testing.T) { otherShopID := uint(99999) req := &dto.BatchSetDeviceSeriesBindngRequest{ DeviceIDs: []uint{devices[1].ID}, SeriesAllocationID: 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.BatchSetDeviceSeriesBindngRequest{ DeviceIDs: []uint{devices[1].ID}, SeriesAllocationID: 99999, } _, err := svc.BatchSetSeriesBinding(ctx, req, nil) require.Error(t, err) }) }