All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m18s
- 移除 IoT 卡和号卡的 card_type 字段(数据库迁移) - 优化账号列表查询,支持按店铺和企业筛选 - 账号响应增加店铺名称和企业名称字段 - 实现批量加载店铺和企业名称,避免 N+1 查询 - 更新权限检查中间件,完善权限验证逻辑 - 更新相关测试用例,确保功能正确性
914 lines
28 KiB
Go
914 lines
28 KiB
Go
package enterprise_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/pkg/constants"
|
|
"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"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func uniqueServiceTestPrefix() string {
|
|
return fmt.Sprintf("SVC%d", time.Now().UnixNano()%1000000000)
|
|
}
|
|
|
|
func createTestContext(userID uint, userType int, shopID uint, enterpriseID uint) context.Context {
|
|
ctx := context.Background()
|
|
return middleware.SetUserContext(ctx, &middleware.UserContextInfo{
|
|
UserID: userID,
|
|
UserType: userType,
|
|
ShopID: shopID,
|
|
EnterpriseID: enterpriseID,
|
|
})
|
|
}
|
|
|
|
type testEnv struct {
|
|
service *Service
|
|
enterprise *model.Enterprise
|
|
shop *model.Shop
|
|
devices []*model.Device
|
|
cards []*model.IotCard
|
|
bindings []*model.DeviceSimBinding
|
|
carrier *model.Carrier
|
|
}
|
|
|
|
func setupTestEnv(t *testing.T, prefix string) *testEnv {
|
|
tx := testutils.NewTestTransaction(t)
|
|
rdb := testutils.GetTestRedis(t)
|
|
testutils.CleanTestRedisKeys(t, rdb)
|
|
|
|
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
|
|
deviceStore := postgres.NewDeviceStore(tx, rdb)
|
|
deviceSimBindingStore := postgres.NewDeviceSimBindingStore(tx, rdb)
|
|
enterpriseDeviceAuthStore := postgres.NewEnterpriseDeviceAuthorizationStore(tx, rdb)
|
|
enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
|
|
logger := zap.NewNop()
|
|
|
|
svc := New(tx, enterpriseStore, deviceStore, deviceSimBindingStore, enterpriseDeviceAuthStore, enterpriseCardAuthStore, logger)
|
|
|
|
shop := &model.Shop{
|
|
ShopName: prefix + "_测试店铺",
|
|
ShopCode: prefix,
|
|
Level: 1,
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(shop).Error)
|
|
|
|
enterprise := &model.Enterprise{
|
|
EnterpriseName: prefix + "_测试企业",
|
|
EnterpriseCode: prefix,
|
|
OwnerShopID: &shop.ID,
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(enterprise).Error)
|
|
|
|
carrier := &model.Carrier{
|
|
CarrierName: "测试运营商",
|
|
CarrierType: "CMCC",
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(carrier).Error)
|
|
|
|
devices := make([]*model.Device, 3)
|
|
for i := 0; i < 3; i++ {
|
|
devices[i] = &model.Device{
|
|
DeviceNo: fmt.Sprintf("%s_D%03d", prefix, i+1),
|
|
DeviceName: fmt.Sprintf("测试设备%d", i+1),
|
|
Status: 2,
|
|
ShopID: &shop.ID,
|
|
}
|
|
require.NoError(t, tx.Create(devices[i]).Error)
|
|
}
|
|
|
|
cards := make([]*model.IotCard, 4)
|
|
for i := 0; i < 4; i++ {
|
|
cards[i] = &model.IotCard{
|
|
ICCID: fmt.Sprintf("%s%04d", prefix, i+1),
|
|
CarrierID: carrier.ID,
|
|
Status: 2,
|
|
ShopID: &shop.ID,
|
|
}
|
|
require.NoError(t, tx.Create(cards[i]).Error)
|
|
}
|
|
|
|
now := time.Now()
|
|
bindings := []*model.DeviceSimBinding{
|
|
{DeviceID: devices[0].ID, IotCardID: cards[0].ID, SlotPosition: 1, BindStatus: 1, BindTime: &now},
|
|
{DeviceID: devices[0].ID, IotCardID: cards[1].ID, SlotPosition: 2, BindStatus: 1, BindTime: &now},
|
|
{DeviceID: devices[1].ID, IotCardID: cards[2].ID, SlotPosition: 1, BindStatus: 1, BindTime: &now},
|
|
}
|
|
for _, b := range bindings {
|
|
require.NoError(t, tx.Create(b).Error)
|
|
}
|
|
|
|
return &testEnv{
|
|
service: svc,
|
|
enterprise: enterprise,
|
|
shop: shop,
|
|
devices: devices,
|
|
cards: cards,
|
|
bindings: bindings,
|
|
carrier: carrier,
|
|
}
|
|
}
|
|
|
|
func TestService_AllocateDevices(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
tests := []struct {
|
|
name string
|
|
ctx context.Context
|
|
req *dto.AllocateDevicesReq
|
|
wantSuccess int
|
|
wantFail int
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "平台用户成功授权设备",
|
|
ctx: createTestContext(1, constants.UserTypePlatform, 0, 0),
|
|
req: &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
Remark: "测试授权",
|
|
},
|
|
wantSuccess: 1,
|
|
wantFail: 0,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "代理用户成功授权自己店铺的设备",
|
|
ctx: createTestContext(2, constants.UserTypeAgent, env.shop.ID, 0),
|
|
req: &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[1].DeviceNo},
|
|
},
|
|
wantSuccess: 1,
|
|
wantFail: 0,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "设备不存在时记录失败",
|
|
ctx: createTestContext(1, constants.UserTypePlatform, 0, 0),
|
|
req: &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{"NOT_EXIST_DEVICE"},
|
|
},
|
|
wantSuccess: 0,
|
|
wantFail: 1,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "未授权用户返回错误",
|
|
ctx: context.Background(),
|
|
req: &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[2].DeviceNo},
|
|
},
|
|
wantSuccess: 0,
|
|
wantFail: 0,
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
resp, err := env.service.AllocateDevices(tt.ctx, env.enterprise.ID, tt.req)
|
|
if tt.wantErr {
|
|
require.Error(t, err)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.wantSuccess, resp.SuccessCount)
|
|
assert.Equal(t, tt.wantFail, resp.FailCount)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestService_AllocateDevices_DeviceStatusValidation(t *testing.T) {
|
|
tx := testutils.NewTestTransaction(t)
|
|
rdb := testutils.GetTestRedis(t)
|
|
testutils.CleanTestRedisKeys(t, rdb)
|
|
|
|
prefix := uniqueServiceTestPrefix()
|
|
|
|
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
|
|
deviceStore := postgres.NewDeviceStore(tx, rdb)
|
|
deviceSimBindingStore := postgres.NewDeviceSimBindingStore(tx, rdb)
|
|
enterpriseDeviceAuthStore := postgres.NewEnterpriseDeviceAuthorizationStore(tx, rdb)
|
|
enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
|
|
logger := zap.NewNop()
|
|
|
|
svc := New(tx, enterpriseStore, deviceStore, deviceSimBindingStore, enterpriseDeviceAuthStore, enterpriseCardAuthStore, logger)
|
|
|
|
enterprise := &model.Enterprise{
|
|
EnterpriseName: prefix + "_测试企业",
|
|
EnterpriseCode: prefix,
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(enterprise).Error)
|
|
|
|
inStockDevice := &model.Device{
|
|
DeviceNo: prefix + "_INSTOCK",
|
|
DeviceName: "在库设备",
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(inStockDevice).Error)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
|
|
t.Run("设备状态不是已分销时失败", func(t *testing.T) {
|
|
req := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{inStockDevice.DeviceNo},
|
|
}
|
|
|
|
resp, err := svc.AllocateDevices(ctx, enterprise.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, resp.SuccessCount)
|
|
assert.Equal(t, 1, resp.FailCount)
|
|
assert.Contains(t, resp.FailedItems[0].Reason, "状态不正确")
|
|
})
|
|
}
|
|
|
|
func TestService_AllocateDevices_AgentPermission(t *testing.T) {
|
|
tx := testutils.NewTestTransaction(t)
|
|
rdb := testutils.GetTestRedis(t)
|
|
testutils.CleanTestRedisKeys(t, rdb)
|
|
|
|
prefix := uniqueServiceTestPrefix()
|
|
|
|
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
|
|
deviceStore := postgres.NewDeviceStore(tx, rdb)
|
|
deviceSimBindingStore := postgres.NewDeviceSimBindingStore(tx, rdb)
|
|
enterpriseDeviceAuthStore := postgres.NewEnterpriseDeviceAuthorizationStore(tx, rdb)
|
|
enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
|
|
logger := zap.NewNop()
|
|
|
|
svc := New(tx, enterpriseStore, deviceStore, deviceSimBindingStore, enterpriseDeviceAuthStore, enterpriseCardAuthStore, logger)
|
|
|
|
shop1 := &model.Shop{ShopName: prefix + "_店铺1", ShopCode: prefix + "1", Level: 1, Status: 1}
|
|
require.NoError(t, tx.Create(shop1).Error)
|
|
|
|
shop2 := &model.Shop{ShopName: prefix + "_店铺2", ShopCode: prefix + "2", Level: 1, Status: 1}
|
|
require.NoError(t, tx.Create(shop2).Error)
|
|
|
|
enterprise := &model.Enterprise{
|
|
EnterpriseName: prefix + "_测试企业",
|
|
EnterpriseCode: prefix,
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(enterprise).Error)
|
|
|
|
device := &model.Device{
|
|
DeviceNo: prefix + "_D001",
|
|
DeviceName: "测试设备",
|
|
Status: 2,
|
|
ShopID: &shop1.ID,
|
|
}
|
|
require.NoError(t, tx.Create(device).Error)
|
|
|
|
t.Run("代理用户无法授权其他店铺的设备", func(t *testing.T) {
|
|
ctx := createTestContext(1, constants.UserTypeAgent, shop2.ID, 0)
|
|
req := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{device.DeviceNo},
|
|
}
|
|
|
|
resp, err := svc.AllocateDevices(ctx, enterprise.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, resp.SuccessCount)
|
|
assert.Equal(t, 1, resp.FailCount)
|
|
assert.Contains(t, resp.FailedItems[0].Reason, "无权操作")
|
|
})
|
|
}
|
|
|
|
func TestService_AllocateDevices_DuplicateAuthorization(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
|
|
req := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
}
|
|
resp, err := env.service.AllocateDevices(ctx, env.enterprise.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 1, resp.SuccessCount)
|
|
|
|
t.Run("重复授权同一设备时失败", func(t *testing.T) {
|
|
resp2, err := env.service.AllocateDevices(ctx, env.enterprise.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, resp2.SuccessCount)
|
|
assert.Equal(t, 1, resp2.FailCount)
|
|
assert.Contains(t, resp2.FailedItems[0].Reason, "已授权")
|
|
})
|
|
}
|
|
|
|
func TestService_AllocateDevices_CascadeCardAuthorization(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
|
|
t.Run("授权设备时级联授权绑定的卡", func(t *testing.T) {
|
|
req := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
}
|
|
|
|
resp, err := env.service.AllocateDevices(ctx, env.enterprise.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 1, resp.SuccessCount)
|
|
assert.Len(t, resp.AuthorizedDevices, 1)
|
|
assert.Equal(t, 2, resp.AuthorizedDevices[0].CardCount)
|
|
})
|
|
}
|
|
|
|
func TestService_RecallDevices(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
|
|
allocateReq := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo, env.devices[1].DeviceNo},
|
|
}
|
|
_, err := env.service.AllocateDevices(ctx, env.enterprise.ID, allocateReq)
|
|
require.NoError(t, err)
|
|
|
|
tests := []struct {
|
|
name string
|
|
req *dto.RecallDevicesReq
|
|
wantSuccess int
|
|
wantFail int
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "成功撤销授权",
|
|
req: &dto.RecallDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
},
|
|
wantSuccess: 1,
|
|
wantFail: 0,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "设备不存在时失败",
|
|
req: &dto.RecallDevicesReq{
|
|
DeviceNos: []string{"NOT_EXIST"},
|
|
},
|
|
wantSuccess: 0,
|
|
wantFail: 1,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "设备未授权时失败",
|
|
req: &dto.RecallDevicesReq{
|
|
DeviceNos: []string{env.devices[2].DeviceNo},
|
|
},
|
|
wantSuccess: 0,
|
|
wantFail: 1,
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
resp, err := env.service.RecallDevices(ctx, env.enterprise.ID, tt.req)
|
|
if tt.wantErr {
|
|
require.Error(t, err)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.wantSuccess, resp.SuccessCount)
|
|
assert.Equal(t, tt.wantFail, resp.FailCount)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestService_RecallDevices_Unauthorized(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
t.Run("未授权用户返回错误", func(t *testing.T) {
|
|
req := &dto.RecallDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
}
|
|
|
|
_, err := env.service.RecallDevices(context.Background(), env.enterprise.ID, req)
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func TestService_ListDevices(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
|
|
allocateReq := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo, env.devices[1].DeviceNo},
|
|
}
|
|
_, err := env.service.AllocateDevices(ctx, env.enterprise.ID, allocateReq)
|
|
require.NoError(t, err)
|
|
|
|
tests := []struct {
|
|
name string
|
|
req *dto.EnterpriseDeviceListReq
|
|
wantTotal int64
|
|
wantLen int
|
|
}{
|
|
{
|
|
name: "获取所有授权设备",
|
|
req: &dto.EnterpriseDeviceListReq{Page: 1, PageSize: 10},
|
|
wantTotal: 2,
|
|
wantLen: 2,
|
|
},
|
|
{
|
|
name: "分页查询",
|
|
req: &dto.EnterpriseDeviceListReq{Page: 1, PageSize: 1},
|
|
wantTotal: 2,
|
|
wantLen: 1,
|
|
},
|
|
{
|
|
name: "按设备号搜索",
|
|
req: &dto.EnterpriseDeviceListReq{Page: 1, PageSize: 10, DeviceNo: env.devices[0].DeviceNo},
|
|
wantTotal: 2,
|
|
wantLen: 1,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
resp, err := env.service.ListDevices(ctx, env.enterprise.ID, tt.req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.wantTotal, resp.Total)
|
|
assert.Len(t, resp.List, tt.wantLen)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestService_ListDevices_EnterpriseNotFound(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
|
|
t.Run("企业不存在返回错误", func(t *testing.T) {
|
|
req := &dto.EnterpriseDeviceListReq{Page: 1, PageSize: 10}
|
|
_, err := env.service.ListDevices(ctx, 99999, req)
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func TestService_ListDevicesForEnterprise(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
allocateReq := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
}
|
|
_, err := env.service.AllocateDevices(ctx, env.enterprise.ID, allocateReq)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("企业用户获取自己的授权设备", func(t *testing.T) {
|
|
enterpriseCtx := createTestContext(1, constants.UserTypeEnterprise, 0, env.enterprise.ID)
|
|
req := &dto.EnterpriseDeviceListReq{Page: 1, PageSize: 10}
|
|
|
|
resp, err := env.service.ListDevicesForEnterprise(enterpriseCtx, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(1), resp.Total)
|
|
})
|
|
|
|
t.Run("未设置企业ID返回错误", func(t *testing.T) {
|
|
req := &dto.EnterpriseDeviceListReq{Page: 1, PageSize: 10}
|
|
_, err := env.service.ListDevicesForEnterprise(context.Background(), req)
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func TestService_GetDeviceDetail(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
allocateReq := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
}
|
|
_, err := env.service.AllocateDevices(ctx, env.enterprise.ID, allocateReq)
|
|
require.NoError(t, err)
|
|
|
|
enterpriseCtx := createTestContext(1, constants.UserTypeEnterprise, 0, env.enterprise.ID)
|
|
|
|
t.Run("成功获取设备详情", func(t *testing.T) {
|
|
resp, err := env.service.GetDeviceDetail(enterpriseCtx, env.devices[0].ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, env.devices[0].ID, resp.Device.DeviceID)
|
|
assert.Equal(t, env.devices[0].DeviceNo, resp.Device.DeviceNo)
|
|
assert.Len(t, resp.Cards, 2)
|
|
})
|
|
|
|
t.Run("设备未授权时返回错误", func(t *testing.T) {
|
|
_, err := env.service.GetDeviceDetail(enterpriseCtx, env.devices[1].ID)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("未设置企业ID返回错误", func(t *testing.T) {
|
|
_, err := env.service.GetDeviceDetail(context.Background(), env.devices[0].ID)
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func TestService_SuspendCard(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
allocateReq := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
}
|
|
_, err := env.service.AllocateDevices(ctx, env.enterprise.ID, allocateReq)
|
|
require.NoError(t, err)
|
|
|
|
enterpriseCtx := createTestContext(1, constants.UserTypeEnterprise, 0, env.enterprise.ID)
|
|
|
|
t.Run("成功停机", func(t *testing.T) {
|
|
req := &dto.DeviceCardOperationReq{Reason: "测试停机"}
|
|
resp, err := env.service.SuspendCard(enterpriseCtx, env.devices[0].ID, env.cards[0].ID, req)
|
|
require.NoError(t, err)
|
|
assert.True(t, resp.Success)
|
|
})
|
|
|
|
t.Run("卡不属于设备时返回错误", func(t *testing.T) {
|
|
req := &dto.DeviceCardOperationReq{Reason: "测试停机"}
|
|
_, err := env.service.SuspendCard(enterpriseCtx, env.devices[0].ID, env.cards[3].ID, req)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("设备未授权时返回错误", func(t *testing.T) {
|
|
req := &dto.DeviceCardOperationReq{Reason: "测试停机"}
|
|
_, err := env.service.SuspendCard(enterpriseCtx, env.devices[1].ID, env.cards[2].ID, req)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("未设置企业ID返回错误", func(t *testing.T) {
|
|
req := &dto.DeviceCardOperationReq{Reason: "测试停机"}
|
|
_, err := env.service.SuspendCard(context.Background(), env.devices[0].ID, env.cards[0].ID, req)
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func TestService_ResumeCard(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
allocateReq := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
}
|
|
_, err := env.service.AllocateDevices(ctx, env.enterprise.ID, allocateReq)
|
|
require.NoError(t, err)
|
|
|
|
enterpriseCtx := createTestContext(1, constants.UserTypeEnterprise, 0, env.enterprise.ID)
|
|
|
|
t.Run("成功复机", func(t *testing.T) {
|
|
req := &dto.DeviceCardOperationReq{Reason: "测试复机"}
|
|
resp, err := env.service.ResumeCard(enterpriseCtx, env.devices[0].ID, env.cards[0].ID, req)
|
|
require.NoError(t, err)
|
|
assert.True(t, resp.Success)
|
|
})
|
|
|
|
t.Run("卡不属于设备时返回错误", func(t *testing.T) {
|
|
req := &dto.DeviceCardOperationReq{Reason: "测试复机"}
|
|
_, err := env.service.ResumeCard(enterpriseCtx, env.devices[0].ID, env.cards[3].ID, req)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("设备未授权时返回错误", func(t *testing.T) {
|
|
req := &dto.DeviceCardOperationReq{Reason: "测试复机"}
|
|
_, err := env.service.ResumeCard(enterpriseCtx, env.devices[1].ID, env.cards[2].ID, req)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("未设置企业ID返回错误", func(t *testing.T) {
|
|
req := &dto.DeviceCardOperationReq{Reason: "测试复机"}
|
|
_, err := env.service.ResumeCard(context.Background(), env.devices[0].ID, env.cards[0].ID, req)
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func TestService_ListDevices_EmptyResult(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
|
|
t.Run("企业无授权设备时返回空列表", func(t *testing.T) {
|
|
req := &dto.EnterpriseDeviceListReq{Page: 1, PageSize: 10}
|
|
resp, err := env.service.ListDevices(ctx, env.enterprise.ID, req)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(0), resp.Total)
|
|
assert.Empty(t, resp.List)
|
|
})
|
|
}
|
|
|
|
func TestService_GetDeviceDetail_WithCarrierInfo(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
allocateReq := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
}
|
|
_, err := env.service.AllocateDevices(ctx, env.enterprise.ID, allocateReq)
|
|
require.NoError(t, err)
|
|
|
|
enterpriseCtx := createTestContext(1, constants.UserTypeEnterprise, 0, env.enterprise.ID)
|
|
|
|
t.Run("获取设备详情包含运营商信息", func(t *testing.T) {
|
|
resp, err := env.service.GetDeviceDetail(enterpriseCtx, env.devices[0].ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, resp.Cards, 2)
|
|
for _, card := range resp.Cards {
|
|
assert.NotEmpty(t, card.CarrierName)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestService_GetDeviceDetail_NetworkStatus(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
allocateReq := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
}
|
|
_, err := env.service.AllocateDevices(ctx, env.enterprise.ID, allocateReq)
|
|
require.NoError(t, err)
|
|
|
|
enterpriseCtx := createTestContext(1, constants.UserTypeEnterprise, 0, env.enterprise.ID)
|
|
|
|
t.Run("网络状态名称正确", func(t *testing.T) {
|
|
resp, err := env.service.GetDeviceDetail(enterpriseCtx, env.devices[0].ID)
|
|
require.NoError(t, err)
|
|
for _, card := range resp.Cards {
|
|
if card.NetworkStatus == 1 {
|
|
assert.Equal(t, "开机", card.NetworkStatusName)
|
|
} else {
|
|
assert.Equal(t, "停机", card.NetworkStatusName)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestService_GetDeviceDetail_DeviceWithoutCards(t *testing.T) {
|
|
tx := testutils.NewTestTransaction(t)
|
|
rdb := testutils.GetTestRedis(t)
|
|
testutils.CleanTestRedisKeys(t, rdb)
|
|
|
|
prefix := uniqueServiceTestPrefix()
|
|
|
|
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
|
|
deviceStore := postgres.NewDeviceStore(tx, rdb)
|
|
deviceSimBindingStore := postgres.NewDeviceSimBindingStore(tx, rdb)
|
|
enterpriseDeviceAuthStore := postgres.NewEnterpriseDeviceAuthorizationStore(tx, rdb)
|
|
enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
|
|
logger := zap.NewNop()
|
|
|
|
svc := New(tx, enterpriseStore, deviceStore, deviceSimBindingStore, enterpriseDeviceAuthStore, enterpriseCardAuthStore, logger)
|
|
|
|
enterprise := &model.Enterprise{
|
|
EnterpriseName: prefix + "_测试企业",
|
|
EnterpriseCode: prefix,
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(enterprise).Error)
|
|
|
|
device := &model.Device{
|
|
DeviceNo: prefix + "_D001",
|
|
DeviceName: "无卡设备",
|
|
Status: 2,
|
|
}
|
|
require.NoError(t, tx.Create(device).Error)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
allocateReq := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{device.DeviceNo},
|
|
}
|
|
_, err := svc.AllocateDevices(ctx, enterprise.ID, allocateReq)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("设备无绑定卡时返回空卡列表", func(t *testing.T) {
|
|
enterpriseCtx := createTestContext(1, constants.UserTypeEnterprise, 0, enterprise.ID)
|
|
resp, err := svc.GetDeviceDetail(enterpriseCtx, device.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, device.ID, resp.Device.DeviceID)
|
|
assert.Empty(t, resp.Cards)
|
|
})
|
|
}
|
|
|
|
func TestService_RecallDevices_CascadeRevoke(t *testing.T) {
|
|
prefix := uniqueServiceTestPrefix()
|
|
env := setupTestEnv(t, prefix)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
|
|
allocateReq := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
}
|
|
resp, err := env.service.AllocateDevices(ctx, env.enterprise.ID, allocateReq)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 2, resp.AuthorizedDevices[0].CardCount)
|
|
|
|
t.Run("撤销设备授权时级联撤销卡授权", func(t *testing.T) {
|
|
recallReq := &dto.RecallDevicesReq{
|
|
DeviceNos: []string{env.devices[0].DeviceNo},
|
|
}
|
|
|
|
recallResp, err := env.service.RecallDevices(ctx, env.enterprise.ID, recallReq)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 1, recallResp.SuccessCount)
|
|
})
|
|
}
|
|
|
|
func TestService_GetDeviceDetail_WithNetworkStatusOn(t *testing.T) {
|
|
tx := testutils.NewTestTransaction(t)
|
|
rdb := testutils.GetTestRedis(t)
|
|
testutils.CleanTestRedisKeys(t, rdb)
|
|
|
|
prefix := uniqueServiceTestPrefix()
|
|
|
|
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
|
|
deviceStore := postgres.NewDeviceStore(tx, rdb)
|
|
deviceSimBindingStore := postgres.NewDeviceSimBindingStore(tx, rdb)
|
|
enterpriseDeviceAuthStore := postgres.NewEnterpriseDeviceAuthorizationStore(tx, rdb)
|
|
enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
|
|
logger := zap.NewNop()
|
|
|
|
svc := New(tx, enterpriseStore, deviceStore, deviceSimBindingStore, enterpriseDeviceAuthStore, enterpriseCardAuthStore, logger)
|
|
|
|
enterprise := &model.Enterprise{
|
|
EnterpriseName: prefix + "_测试企业",
|
|
EnterpriseCode: prefix,
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(enterprise).Error)
|
|
|
|
carrier := &model.Carrier{
|
|
CarrierName: "测试运营商",
|
|
CarrierType: "CMCC",
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(carrier).Error)
|
|
|
|
device := &model.Device{
|
|
DeviceNo: prefix + "_D001",
|
|
DeviceName: "测试设备",
|
|
Status: 2,
|
|
}
|
|
require.NoError(t, tx.Create(device).Error)
|
|
|
|
card := &model.IotCard{
|
|
ICCID: prefix + "0001",
|
|
CarrierID: carrier.ID,
|
|
Status: 2,
|
|
NetworkStatus: 1,
|
|
}
|
|
require.NoError(t, tx.Create(card).Error)
|
|
|
|
now := time.Now()
|
|
binding := &model.DeviceSimBinding{
|
|
DeviceID: device.ID,
|
|
IotCardID: card.ID,
|
|
SlotPosition: 1,
|
|
BindStatus: 1,
|
|
BindTime: &now,
|
|
}
|
|
require.NoError(t, tx.Create(binding).Error)
|
|
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
allocateReq := &dto.AllocateDevicesReq{
|
|
DeviceNos: []string{device.DeviceNo},
|
|
}
|
|
_, err := svc.AllocateDevices(ctx, enterprise.ID, allocateReq)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("开机状态卡显示正确", func(t *testing.T) {
|
|
enterpriseCtx := createTestContext(1, constants.UserTypeEnterprise, 0, enterprise.ID)
|
|
resp, err := svc.GetDeviceDetail(enterpriseCtx, device.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, resp.Cards, 1)
|
|
assert.Equal(t, 1, resp.Cards[0].NetworkStatus)
|
|
assert.Equal(t, "开机", resp.Cards[0].NetworkStatusName)
|
|
})
|
|
}
|
|
|
|
func TestService_EnterpriseNotFound(t *testing.T) {
|
|
tx := testutils.NewTestTransaction(t)
|
|
rdb := testutils.GetTestRedis(t)
|
|
testutils.CleanTestRedisKeys(t, rdb)
|
|
|
|
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
|
|
deviceStore := postgres.NewDeviceStore(tx, rdb)
|
|
deviceSimBindingStore := postgres.NewDeviceSimBindingStore(tx, rdb)
|
|
enterpriseDeviceAuthStore := postgres.NewEnterpriseDeviceAuthorizationStore(tx, rdb)
|
|
enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
|
|
logger := zap.NewNop()
|
|
|
|
svc := New(tx, enterpriseStore, deviceStore, deviceSimBindingStore, enterpriseDeviceAuthStore, enterpriseCardAuthStore, logger)
|
|
ctx := createTestContext(1, constants.UserTypePlatform, 0, 0)
|
|
|
|
t.Run("AllocateDevices企业不存在", func(t *testing.T) {
|
|
req := &dto.AllocateDevicesReq{DeviceNos: []string{"D001"}}
|
|
_, err := svc.AllocateDevices(ctx, 99999, req)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("RecallDevices企业不存在", func(t *testing.T) {
|
|
req := &dto.RecallDevicesReq{DeviceNos: []string{"D001"}}
|
|
_, err := svc.RecallDevices(ctx, 99999, req)
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func TestService_ValidateCardOperation_RevokedDeviceAuth(t *testing.T) {
|
|
tx := testutils.NewTestTransaction(t)
|
|
rdb := testutils.GetTestRedis(t)
|
|
testutils.CleanTestRedisKeys(t, rdb)
|
|
|
|
prefix := uniqueServiceTestPrefix()
|
|
|
|
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
|
|
deviceStore := postgres.NewDeviceStore(tx, rdb)
|
|
deviceSimBindingStore := postgres.NewDeviceSimBindingStore(tx, rdb)
|
|
enterpriseDeviceAuthStore := postgres.NewEnterpriseDeviceAuthorizationStore(tx, rdb)
|
|
enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
|
|
logger := zap.NewNop()
|
|
|
|
svc := New(tx, enterpriseStore, deviceStore, deviceSimBindingStore, enterpriseDeviceAuthStore, enterpriseCardAuthStore, logger)
|
|
|
|
enterprise := &model.Enterprise{
|
|
EnterpriseName: prefix + "_测试企业",
|
|
EnterpriseCode: prefix,
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(enterprise).Error)
|
|
|
|
carrier := &model.Carrier{
|
|
CarrierName: "测试运营商",
|
|
CarrierType: "CMCC",
|
|
Status: 1,
|
|
}
|
|
require.NoError(t, tx.Create(carrier).Error)
|
|
|
|
device := &model.Device{
|
|
DeviceNo: prefix + "_D001",
|
|
DeviceName: "测试设备",
|
|
Status: 2,
|
|
}
|
|
require.NoError(t, tx.Create(device).Error)
|
|
|
|
card := &model.IotCard{
|
|
ICCID: prefix + "0001",
|
|
CarrierID: carrier.ID,
|
|
Status: 2,
|
|
}
|
|
require.NoError(t, tx.Create(card).Error)
|
|
|
|
now := time.Now()
|
|
binding := &model.DeviceSimBinding{
|
|
DeviceID: device.ID,
|
|
IotCardID: card.ID,
|
|
SlotPosition: 1,
|
|
BindStatus: 1,
|
|
BindTime: &now,
|
|
}
|
|
require.NoError(t, tx.Create(binding).Error)
|
|
|
|
deviceAuth := &model.EnterpriseDeviceAuthorization{
|
|
EnterpriseID: enterprise.ID,
|
|
DeviceID: device.ID,
|
|
AuthorizedBy: 1,
|
|
AuthorizedAt: now,
|
|
AuthorizerType: 2,
|
|
RevokedBy: ptrUintED(1),
|
|
RevokedAt: &now,
|
|
}
|
|
require.NoError(t, tx.Create(deviceAuth).Error)
|
|
|
|
t.Run("已撤销的设备授权无法操作卡", func(t *testing.T) {
|
|
enterpriseCtx := createTestContext(1, constants.UserTypeEnterprise, 0, enterprise.ID)
|
|
req := &dto.DeviceCardOperationReq{Reason: "测试"}
|
|
_, err := svc.SuspendCard(enterpriseCtx, device.ID, card.ID, req)
|
|
require.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func ptrUintED(v uint) *uint {
|
|
return &v
|
|
}
|