package unit import ( "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/internal/model/dto" "github.com/break/junhong_cmp_fiber/internal/service/enterprise_card" "github.com/break/junhong_cmp_fiber/internal/store/postgres" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/tests/testutils" ) func createEnterpriseCardTestContext(userID uint, shopID uint) context.Context { ctx := context.Background() ctx = context.WithValue(ctx, constants.ContextKeyUserID, userID) ctx = context.WithValue(ctx, constants.ContextKeyUserType, constants.UserTypePlatform) ctx = context.WithValue(ctx, constants.ContextKeyShopID, shopID) return ctx } func TestEnterpriseCardService_AllocateCardsPreview(t *testing.T) { tx := testutils.NewTestTransaction(t) rdb := testutils.GetTestRedis(t) testutils.CleanTestRedisKeys(t, rdb) enterpriseStore := postgres.NewEnterpriseStore(tx, rdb) enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb) service := enterprise_card.New(tx, enterpriseStore, enterpriseCardAuthStore) t.Run("授权预检-企业不存在应失败", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) req := &dto.AllocateCardsPreviewReq{ ICCIDs: []string{"898600000001"}, } _, err := service.AllocateCardsPreview(ctx, 99999, req) assert.Error(t, err) }) t.Run("授权预检-未授权用户应失败", func(t *testing.T) { ctx := context.Background() req := &dto.AllocateCardsPreviewReq{ ICCIDs: []string{"898600000001"}, } _, err := service.AllocateCardsPreview(ctx, 1, req) assert.Error(t, err) }) t.Run("授权预检-空ICCID列表", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "预检测试企业", EnterpriseCode: "ENT_PREVIEW_001", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) req := &dto.AllocateCardsPreviewReq{ ICCIDs: []string{}, } result, err := service.AllocateCardsPreview(ctx, ent.ID, req) require.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, 0, result.Summary.TotalCardCount) }) t.Run("授权预检-卡不存在", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "预检测试企业2", EnterpriseCode: "ENT_PREVIEW_002", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) req := &dto.AllocateCardsPreviewReq{ ICCIDs: []string{"NON_EXIST_ICCID"}, } result, err := service.AllocateCardsPreview(ctx, ent.ID, req) require.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, 1, result.Summary.FailedCount) assert.Len(t, result.FailedItems, 1) assert.Equal(t, "卡不存在", result.FailedItems[0].Reason) }) t.Run("授权预检-独立卡", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "预检测试企业3", EnterpriseCode: "ENT_PREVIEW_003", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) shopID := uint(1) card := &model.IotCard{ ICCID: "898600001234567890", MSISDN: "13800000001", Status: 1, ShopID: &shopID, } err = tx.Create(card).Error require.NoError(t, err) req := &dto.AllocateCardsPreviewReq{ ICCIDs: []string{"898600001234567890"}, } result, err := service.AllocateCardsPreview(ctx, ent.ID, req) require.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, 1, result.Summary.StandaloneCardCount) assert.Len(t, result.StandaloneCards, 1) }) } func TestEnterpriseCardService_AllocateCards(t *testing.T) { tx := testutils.NewTestTransaction(t) rdb := testutils.GetTestRedis(t) testutils.CleanTestRedisKeys(t, rdb) enterpriseStore := postgres.NewEnterpriseStore(tx, rdb) enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb) service := enterprise_card.New(tx, enterpriseStore, enterpriseCardAuthStore) t.Run("授权卡-企业不存在应失败", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) req := &dto.AllocateCardsReq{ ICCIDs: []string{"898600000001"}, } _, err := service.AllocateCards(ctx, 99999, req) assert.Error(t, err) }) t.Run("授权卡-成功", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "授权测试企业", EnterpriseCode: "ENT_ALLOC_001", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) shopID := uint(1) card := &model.IotCard{ ICCID: "898600002345678901", MSISDN: "13800000002", Status: 1, ShopID: &shopID, } err = tx.Create(card).Error require.NoError(t, err) req := &dto.AllocateCardsReq{ ICCIDs: []string{"898600002345678901"}, } result, err := service.AllocateCards(ctx, ent.ID, req) require.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, 1, result.SuccessCount) }) t.Run("授权卡-重复授权不创建新记录", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "重复授权测试企业", EnterpriseCode: "ENT_ALLOC_002", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) shopID := uint(1) card := &model.IotCard{ ICCID: "898600003456789012", MSISDN: "13800000003", Status: 1, ShopID: &shopID, } err = tx.Create(card).Error require.NoError(t, err) req := &dto.AllocateCardsReq{ ICCIDs: []string{"898600003456789012"}, } _, err = service.AllocateCards(ctx, ent.ID, req) require.NoError(t, err) _, err = service.AllocateCards(ctx, ent.ID, req) require.NoError(t, err) var count int64 tx.Model(&model.EnterpriseCardAuthorization{}). Where("enterprise_id = ? AND iot_card_id = ?", ent.ID, card.ID). Count(&count) assert.Equal(t, int64(1), count) }) } func TestEnterpriseCardService_RecallCards(t *testing.T) { tx := testutils.NewTestTransaction(t) rdb := testutils.GetTestRedis(t) testutils.CleanTestRedisKeys(t, rdb) enterpriseStore := postgres.NewEnterpriseStore(tx, rdb) enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb) service := enterprise_card.New(tx, enterpriseStore, enterpriseCardAuthStore) t.Run("回收授权-企业不存在应失败", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) req := &dto.RecallCardsReq{ ICCIDs: []string{"898600000001"}, } _, err := service.RecallCards(ctx, 99999, req) assert.Error(t, err) }) t.Run("回收授权-卡未授权应失败", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "回收测试企业", EnterpriseCode: "ENT_RECALL_001", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) shopID := uint(1) card := &model.IotCard{ ICCID: "898600004567890123", MSISDN: "13800000004", Status: 1, ShopID: &shopID, } err = tx.Create(card).Error require.NoError(t, err) req := &dto.RecallCardsReq{ ICCIDs: []string{"898600004567890123"}, } result, err := service.RecallCards(ctx, ent.ID, req) require.NoError(t, err) assert.Equal(t, 1, result.FailCount) assert.Equal(t, "该卡未授权给此企业", result.FailedItems[0].Reason) }) t.Run("回收授权-成功", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "回收成功测试企业", EnterpriseCode: "ENT_RECALL_002", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) shopID := uint(1) card := &model.IotCard{ ICCID: "898600005678901234", MSISDN: "13800000005", Status: 1, ShopID: &shopID, } err = tx.Create(card).Error require.NoError(t, err) allocReq := &dto.AllocateCardsReq{ ICCIDs: []string{"898600005678901234"}, } _, err = service.AllocateCards(ctx, ent.ID, allocReq) require.NoError(t, err) recallReq := &dto.RecallCardsReq{ ICCIDs: []string{"898600005678901234"}, } result, err := service.RecallCards(ctx, ent.ID, recallReq) require.NoError(t, err) assert.Equal(t, 1, result.SuccessCount) assert.Equal(t, 0, result.FailCount) }) } func TestEnterpriseCardService_ListCards(t *testing.T) { tx := testutils.NewTestTransaction(t) rdb := testutils.GetTestRedis(t) testutils.CleanTestRedisKeys(t, rdb) enterpriseStore := postgres.NewEnterpriseStore(tx, rdb) enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb) service := enterprise_card.New(tx, enterpriseStore, enterpriseCardAuthStore) t.Run("查询企业卡列表-企业不存在应失败", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) req := &dto.EnterpriseCardListReq{ Page: 1, PageSize: 20, } _, err := service.ListCards(ctx, 99999, req) assert.Error(t, err) }) t.Run("查询企业卡列表-空结果", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "列表测试企业", EnterpriseCode: "ENT_LIST_001", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) req := &dto.EnterpriseCardListReq{ Page: 1, PageSize: 20, } result, err := service.ListCards(ctx, ent.ID, req) require.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, int64(0), result.Total) }) t.Run("查询企业卡列表-有数据", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "列表数据测试企业", EnterpriseCode: "ENT_LIST_002", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) shopID := uint(1) card := &model.IotCard{ ICCID: "898600006789012345", MSISDN: "13800000006", Status: 1, ShopID: &shopID, } err = tx.Create(card).Error require.NoError(t, err) allocReq := &dto.AllocateCardsReq{ ICCIDs: []string{"898600006789012345"}, } _, err = service.AllocateCards(ctx, ent.ID, allocReq) require.NoError(t, err) req := &dto.EnterpriseCardListReq{ Page: 1, PageSize: 20, } result, err := service.ListCards(ctx, ent.ID, req) require.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, int64(1), result.Total) assert.Len(t, result.Items, 1) assert.Equal(t, "898600006789012345", result.Items[0].ICCID) }) t.Run("查询企业卡列表-按ICCID筛选", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "筛选测试企业", EnterpriseCode: "ENT_LIST_003", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) shopID := uint(1) card := &model.IotCard{ ICCID: "898600007890123456", MSISDN: "13800000007", Status: 1, ShopID: &shopID, } err = tx.Create(card).Error require.NoError(t, err) allocReq := &dto.AllocateCardsReq{ ICCIDs: []string{"898600007890123456"}, } _, err = service.AllocateCards(ctx, ent.ID, allocReq) require.NoError(t, err) req := &dto.EnterpriseCardListReq{ Page: 1, PageSize: 20, ICCID: "78901", } result, err := service.ListCards(ctx, ent.ID, req) require.NoError(t, err) assert.NotNil(t, result) assert.GreaterOrEqual(t, result.Total, int64(1)) }) } func TestEnterpriseCardService_SuspendAndResumeCard(t *testing.T) { tx := testutils.NewTestTransaction(t) rdb := testutils.GetTestRedis(t) testutils.CleanTestRedisKeys(t, rdb) enterpriseStore := postgres.NewEnterpriseStore(tx, rdb) enterpriseCardAuthStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb) service := enterprise_card.New(tx, enterpriseStore, enterpriseCardAuthStore) t.Run("停机-未授权的卡应失败", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "停机测试企业", EnterpriseCode: "ENT_SUSPEND_001", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) shopID := uint(1) card := &model.IotCard{ ICCID: "898600008901234567", MSISDN: "13800000008", Status: 1, ShopID: &shopID, } err = tx.Create(card).Error require.NoError(t, err) err = service.SuspendCard(ctx, ent.ID, card.ID) assert.Error(t, err) }) t.Run("停机和复机-成功", func(t *testing.T) { ctx := createEnterpriseCardTestContext(1, 1) ent := &model.Enterprise{ EnterpriseName: "停复机测试企业", EnterpriseCode: "ENT_SUSPEND_002", Status: constants.StatusEnabled, } ent.Creator = 1 ent.Updater = 1 err := tx.Create(ent).Error require.NoError(t, err) shopID := uint(1) card := &model.IotCard{ ICCID: "898600009012345678", MSISDN: "13800000009", Status: 1, NetworkStatus: 1, ShopID: &shopID, } err = tx.Create(card).Error require.NoError(t, err) allocReq := &dto.AllocateCardsReq{ ICCIDs: []string{"898600009012345678"}, } _, err = service.AllocateCards(ctx, ent.ID, allocReq) require.NoError(t, err) err = service.SuspendCard(ctx, ent.ID, card.ID) require.NoError(t, err) var suspendedCard model.IotCard tx.First(&suspendedCard, card.ID) assert.Equal(t, 0, suspendedCard.NetworkStatus) err = service.ResumeCard(ctx, ent.ID, card.ID) require.NoError(t, err) var resumedCard model.IotCard tx.First(&resumedCard, card.ID) assert.Equal(t, 1, resumedCard.NetworkStatus) }) }