feat: 实现企业卡授权和授权记录管理功能
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m9s

主要功能:
- 添加企业卡授权/回收接口 (POST /enterprises/:id/allocate-cards, recall-cards)
- 添加授权记录管理接口 (GET/PUT /authorizations)
- 实现代理用户数据权限过滤(只能查看自己店铺下企业的授权记录)
- 添加 GORM callback 支持授权记录表的数据权限过滤

技术改进:
- 原生 SQL 查询手动添加数据权限过滤(ListWithJoin, GetByIDWithJoin)
- 移除卡授权预检接口(allocate-cards/preview),保留内部方法
- 完善单元测试和集成测试覆盖
This commit is contained in:
2026-01-26 15:07:03 +08:00
parent 45aa7deb87
commit fdcff33058
42 changed files with 4782 additions and 298 deletions

View File

@@ -0,0 +1,624 @@
package unit
import (
"context"
"testing"
"time"
pkggorm "github.com/break/junhong_cmp_fiber/pkg/gorm"
"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/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 createAgentContext(userID, shopID uint) context.Context {
ctx := context.Background()
ctx = context.WithValue(ctx, constants.ContextKeyUserID, userID)
ctx = context.WithValue(ctx, constants.ContextKeyUserType, constants.UserTypeAgent)
ctx = context.WithValue(ctx, constants.ContextKeyShopID, shopID)
return ctx
}
func createPlatformContext(userID 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, uint(0))
return ctx
}
func TestAuthorizationPermission_AgentCanOnlyAuthorizeOwnCards(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
iotCardStore := postgres.NewIotCardStore(tx, rdb)
authStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
authService := enterprise_card.NewAuthorizationService(enterpriseStore, iotCardStore, authStore, nil)
shop1ID := uint(100)
shop2ID := uint(200)
ent := &model.Enterprise{
EnterpriseName: "代理1的企业",
EnterpriseCode: "ENT_PERM_001",
OwnerShopID: &shop1ID,
Status: constants.StatusEnabled,
}
ent.Creator = 1
ent.Updater = 1
err := tx.Create(ent).Error
require.NoError(t, err)
card1 := &model.IotCard{ICCID: "PERM_CARD_001", MSISDN: "13800001001", Status: 1, ShopID: &shop1ID}
card2 := &model.IotCard{ICCID: "PERM_CARD_002", MSISDN: "13800001002", Status: 1, ShopID: &shop2ID}
err = tx.Create(card1).Error
require.NoError(t, err)
err = tx.Create(card2).Error
require.NoError(t, err)
t.Run("代理可以授权自己店铺的卡", func(t *testing.T) {
ctx := createAgentContext(1, shop1ID)
err := authService.BatchAuthorize(ctx, enterprise_card.BatchAuthorizeRequest{
EnterpriseID: ent.ID,
CardIDs: []uint{card1.ID},
AuthorizerID: 1,
AuthorizerType: constants.UserTypeAgent,
})
assert.NoError(t, err)
})
t.Run("代理不能授权其他店铺的卡", func(t *testing.T) {
ctx := createAgentContext(1, shop1ID)
err := authService.BatchAuthorize(ctx, enterprise_card.BatchAuthorizeRequest{
EnterpriseID: ent.ID,
CardIDs: []uint{card2.ID},
AuthorizerID: 1,
AuthorizerType: constants.UserTypeAgent,
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "不属于您的店铺")
})
}
func TestAuthorizationPermission_AgentCanOnlyAuthorizeToOwnEnterprise(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
iotCardStore := postgres.NewIotCardStore(tx, rdb)
authStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
authService := enterprise_card.NewAuthorizationService(enterpriseStore, iotCardStore, authStore, nil)
shop1ID := uint(101)
shop2ID := uint(201)
ent1 := &model.Enterprise{
EnterpriseName: "代理1的企业",
EnterpriseCode: "ENT_PERM_101",
OwnerShopID: &shop1ID,
Status: constants.StatusEnabled,
}
ent1.Creator = 1
ent1.Updater = 1
err := tx.Create(ent1).Error
require.NoError(t, err)
ent2 := &model.Enterprise{
EnterpriseName: "代理2的企业",
EnterpriseCode: "ENT_PERM_201",
OwnerShopID: &shop2ID,
Status: constants.StatusEnabled,
}
ent2.Creator = 2
ent2.Updater = 2
err = tx.Create(ent2).Error
require.NoError(t, err)
card := &model.IotCard{ICCID: "PERM_CARD_101", MSISDN: "13800002001", Status: 1, ShopID: &shop1ID}
err = tx.Create(card).Error
require.NoError(t, err)
t.Run("代理可以授权给自己的企业", func(t *testing.T) {
ctx := createAgentContext(1, shop1ID)
err := authService.BatchAuthorize(ctx, enterprise_card.BatchAuthorizeRequest{
EnterpriseID: ent1.ID,
CardIDs: []uint{card.ID},
AuthorizerID: 1,
AuthorizerType: constants.UserTypeAgent,
})
assert.NoError(t, err)
})
card2 := &model.IotCard{ICCID: "PERM_CARD_102", MSISDN: "13800002002", Status: 1, ShopID: &shop1ID}
err = tx.Create(card2).Error
require.NoError(t, err)
t.Run("代理不能授权给其他代理的企业", func(t *testing.T) {
ctx := createAgentContext(1, shop1ID)
err := authService.BatchAuthorize(ctx, enterprise_card.BatchAuthorizeRequest{
EnterpriseID: ent2.ID,
CardIDs: []uint{card2.ID},
AuthorizerID: 1,
AuthorizerType: constants.UserTypeAgent,
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "只能授权给自己的企业")
})
}
func TestAuthorizationPermission_PlatformCanAuthorizeAnyCard(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
iotCardStore := postgres.NewIotCardStore(tx, rdb)
authStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
authService := enterprise_card.NewAuthorizationService(enterpriseStore, iotCardStore, authStore, nil)
shop1ID := uint(301)
shop2ID := uint(302)
ent := &model.Enterprise{
EnterpriseName: "平台测试企业",
EnterpriseCode: "ENT_PLAT_001",
OwnerShopID: &shop1ID,
Status: constants.StatusEnabled,
}
ent.Creator = 1
ent.Updater = 1
err := tx.Create(ent).Error
require.NoError(t, err)
card1 := &model.IotCard{ICCID: "PLAT_CARD_001", MSISDN: "13800003001", Status: 1, ShopID: &shop1ID}
card2 := &model.IotCard{ICCID: "PLAT_CARD_002", MSISDN: "13800003002", Status: 1, ShopID: &shop2ID}
err = tx.Create(card1).Error
require.NoError(t, err)
err = tx.Create(card2).Error
require.NoError(t, err)
ctx := createPlatformContext(1)
t.Run("平台可以授权任意店铺的卡", func(t *testing.T) {
err := authService.BatchAuthorize(ctx, enterprise_card.BatchAuthorizeRequest{
EnterpriseID: ent.ID,
CardIDs: []uint{card1.ID, card2.ID},
AuthorizerID: 1,
AuthorizerType: constants.UserTypePlatform,
})
assert.NoError(t, err)
})
}
func TestAuthorizationPermission_CannotAuthorizeBoundCard(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
iotCardStore := postgres.NewIotCardStore(tx, rdb)
authStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
authService := enterprise_card.NewAuthorizationService(enterpriseStore, iotCardStore, authStore, nil)
shopID := uint(401)
ent := &model.Enterprise{
EnterpriseName: "绑定测试企业",
EnterpriseCode: "ENT_BOUND_001",
OwnerShopID: &shopID,
Status: constants.StatusEnabled,
}
ent.Creator = 1
ent.Updater = 1
err := tx.Create(ent).Error
require.NoError(t, err)
card := &model.IotCard{
ICCID: "BOUND_CARD_001",
MSISDN: "13800004001",
Status: 1,
ShopID: &shopID,
}
err = tx.Create(card).Error
require.NoError(t, err)
bindTime := time.Now()
binding := &model.DeviceSimBinding{
DeviceID: 1,
IotCardID: card.ID,
SlotPosition: 1,
BindStatus: 1,
BindTime: &bindTime,
}
binding.Creator = 1
binding.Updater = 1
err = tx.Create(binding).Error
require.NoError(t, err)
ctx := createPlatformContext(1)
err = authService.BatchAuthorize(ctx, enterprise_card.BatchAuthorizeRequest{
EnterpriseID: ent.ID,
CardIDs: []uint{card.ID},
AuthorizerID: 1,
AuthorizerType: constants.UserTypePlatform,
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "已绑定设备")
}
func TestAuthorizationPermission_CannotAuthorizeUndistributedCard(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
iotCardStore := postgres.NewIotCardStore(tx, rdb)
authStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
authService := enterprise_card.NewAuthorizationService(enterpriseStore, iotCardStore, authStore, nil)
ent := &model.Enterprise{
EnterpriseName: "未分销测试企业",
EnterpriseCode: "ENT_UNDIST_001",
Status: constants.StatusEnabled,
}
ent.Creator = 1
ent.Updater = 1
err := tx.Create(ent).Error
require.NoError(t, err)
card := &model.IotCard{
ICCID: "UNDIST_CARD_001",
MSISDN: "13800005001",
Status: 1,
ShopID: nil,
}
err = tx.Create(card).Error
require.NoError(t, err)
ctx := createPlatformContext(1)
err = authService.BatchAuthorize(ctx, enterprise_card.BatchAuthorizeRequest{
EnterpriseID: ent.ID,
CardIDs: []uint{card.ID},
AuthorizerID: 1,
AuthorizerType: constants.UserTypePlatform,
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "未分销")
}
func TestAuthorizationPermission_AgentCanOnlyRevokeOwnAuthorization(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
iotCardStore := postgres.NewIotCardStore(tx, rdb)
authStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
authService := enterprise_card.NewAuthorizationService(enterpriseStore, iotCardStore, authStore, nil)
shopID := uint(501)
ent := &model.Enterprise{
EnterpriseName: "回收测试企业",
EnterpriseCode: "ENT_REVOKE_001",
OwnerShopID: &shopID,
Status: constants.StatusEnabled,
}
ent.Creator = 1
ent.Updater = 1
err := tx.Create(ent).Error
require.NoError(t, err)
card := &model.IotCard{ICCID: "REVOKE_CARD_001", MSISDN: "13800006001", Status: 1, ShopID: &shopID}
err = tx.Create(card).Error
require.NoError(t, err)
now := time.Now()
auth := &model.EnterpriseCardAuthorization{
EnterpriseID: ent.ID,
CardID: card.ID,
AuthorizedBy: 1,
AuthorizedAt: now,
AuthorizerType: constants.UserTypeAgent,
}
err = authStore.Create(context.Background(), auth)
require.NoError(t, err)
t.Run("代理可以回收自己创建的授权", func(t *testing.T) {
ctx := createAgentContext(1, shopID)
err := authService.RevokeAuthorizations(ctx, enterprise_card.RevokeAuthorizationsRequest{
EnterpriseID: ent.ID,
CardIDs: []uint{card.ID},
RevokedBy: 1,
})
assert.NoError(t, err)
})
card2 := &model.IotCard{ICCID: "REVOKE_CARD_002", MSISDN: "13800006002", Status: 1, ShopID: &shopID}
err = tx.Create(card2).Error
require.NoError(t, err)
auth2 := &model.EnterpriseCardAuthorization{
EnterpriseID: ent.ID,
CardID: card2.ID,
AuthorizedBy: 999,
AuthorizedAt: now,
AuthorizerType: constants.UserTypeAgent,
}
err = authStore.Create(context.Background(), auth2)
require.NoError(t, err)
t.Run("代理不能回收其他人创建的授权", func(t *testing.T) {
ctx := createAgentContext(1, shopID)
err := authService.RevokeAuthorizations(ctx, enterprise_card.RevokeAuthorizationsRequest{
EnterpriseID: ent.ID,
CardIDs: []uint{card2.ID},
RevokedBy: 1,
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "只能回收自己创建的授权")
})
t.Run("平台可以回收任何授权", func(t *testing.T) {
ctx := createPlatformContext(2)
err := authService.RevokeAuthorizations(ctx, enterprise_card.RevokeAuthorizationsRequest{
EnterpriseID: ent.ID,
CardIDs: []uint{card2.ID},
RevokedBy: 2,
})
assert.NoError(t, err)
})
}
func TestAuthorizationService_ListRecords(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
iotCardStore := postgres.NewIotCardStore(tx, rdb)
authStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
authService := enterprise_card.NewAuthorizationService(enterpriseStore, iotCardStore, authStore, nil)
shopID := uint(600)
ent := &model.Enterprise{
EnterpriseName: "列表测试企业",
EnterpriseCode: "ENT_LIST_001",
OwnerShopID: &shopID,
Status: constants.StatusEnabled,
}
ent.Creator = 1
ent.Updater = 1
err := tx.Create(ent).Error
require.NoError(t, err)
card1 := &model.IotCard{ICCID: "LIST_CARD_001", MSISDN: "13800007001", Status: 1, ShopID: &shopID}
card2 := &model.IotCard{ICCID: "LIST_CARD_002", MSISDN: "13800007002", Status: 1, ShopID: &shopID}
err = tx.Create(card1).Error
require.NoError(t, err)
err = tx.Create(card2).Error
require.NoError(t, err)
account := &model.Account{
Username: "test_authorizer",
Phone: "13800008001",
Password: "hashed",
UserType: constants.UserTypePlatform,
Status: constants.StatusEnabled,
}
account.Creator = 1
account.Updater = 1
err = tx.Create(account).Error
require.NoError(t, err)
now := time.Now()
auth1 := &model.EnterpriseCardAuthorization{
EnterpriseID: ent.ID,
CardID: card1.ID,
AuthorizedBy: account.ID,
AuthorizedAt: now,
AuthorizerType: constants.UserTypePlatform,
Remark: "测试备注1",
}
auth2 := &model.EnterpriseCardAuthorization{
EnterpriseID: ent.ID,
CardID: card2.ID,
AuthorizedBy: account.ID,
AuthorizedAt: now,
AuthorizerType: constants.UserTypePlatform,
Remark: "测试备注2",
}
err = authStore.Create(context.Background(), auth1)
require.NoError(t, err)
err = authStore.Create(context.Background(), auth2)
require.NoError(t, err)
ctx := pkggorm.SkipDataPermission(context.Background())
t.Run("分页查询授权记录", func(t *testing.T) {
resp, err := authService.ListRecords(ctx, enterprise_card.ListRecordsRequest{
Page: 1,
PageSize: 10,
})
require.NoError(t, err)
assert.GreaterOrEqual(t, resp.Total, int64(2))
assert.GreaterOrEqual(t, len(resp.Items), 2)
})
t.Run("按企业ID筛选", func(t *testing.T) {
resp, err := authService.ListRecords(ctx, enterprise_card.ListRecordsRequest{
EnterpriseID: &ent.ID,
Page: 1,
PageSize: 10,
})
require.NoError(t, err)
assert.Equal(t, int64(2), resp.Total)
for _, item := range resp.Items {
assert.Equal(t, ent.ID, item.EnterpriseID)
}
})
t.Run("按ICCID筛选", func(t *testing.T) {
resp, err := authService.ListRecords(ctx, enterprise_card.ListRecordsRequest{
ICCID: "LIST_CARD_001",
Page: 1,
PageSize: 10,
})
require.NoError(t, err)
assert.Equal(t, int64(1), resp.Total)
assert.Equal(t, "LIST_CARD_001", resp.Items[0].ICCID)
})
t.Run("按状态筛选-有效授权", func(t *testing.T) {
status := 1
resp, err := authService.ListRecords(ctx, enterprise_card.ListRecordsRequest{
EnterpriseID: &ent.ID,
Status: &status,
Page: 1,
PageSize: 10,
})
require.NoError(t, err)
assert.Equal(t, int64(2), resp.Total)
for _, item := range resp.Items {
assert.Equal(t, 1, item.Status)
}
})
}
func TestAuthorizationService_GetRecordDetail(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
iotCardStore := postgres.NewIotCardStore(tx, rdb)
authStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
authService := enterprise_card.NewAuthorizationService(enterpriseStore, iotCardStore, authStore, nil)
shopID := uint(700)
ent := &model.Enterprise{
EnterpriseName: "详情测试企业",
EnterpriseCode: "ENT_DETAIL_001",
OwnerShopID: &shopID,
Status: constants.StatusEnabled,
}
ent.Creator = 1
ent.Updater = 1
err := tx.Create(ent).Error
require.NoError(t, err)
card := &model.IotCard{ICCID: "DETAIL_CARD_001", MSISDN: "13800009001", Status: 1, ShopID: &shopID}
err = tx.Create(card).Error
require.NoError(t, err)
account := &model.Account{
Username: "detail_authorizer",
Phone: "13800009002",
Password: "hashed",
UserType: constants.UserTypePlatform,
Status: constants.StatusEnabled,
}
account.Creator = 1
account.Updater = 1
err = tx.Create(account).Error
require.NoError(t, err)
auth := &model.EnterpriseCardAuthorization{
EnterpriseID: ent.ID,
CardID: card.ID,
AuthorizedBy: account.ID,
AuthorizedAt: time.Now(),
AuthorizerType: constants.UserTypePlatform,
Remark: "详情测试备注",
}
err = authStore.Create(context.Background(), auth)
require.NoError(t, err)
ctx := pkggorm.SkipDataPermission(context.Background())
t.Run("获取授权记录详情", func(t *testing.T) {
detail, err := authService.GetRecordDetail(ctx, auth.ID)
require.NoError(t, err)
assert.Equal(t, auth.ID, detail.ID)
assert.Equal(t, ent.ID, detail.EnterpriseID)
assert.Equal(t, "详情测试企业", detail.EnterpriseName)
assert.Equal(t, card.ID, detail.CardID)
assert.Equal(t, "DETAIL_CARD_001", detail.ICCID)
assert.Equal(t, "详情测试备注", detail.Remark)
assert.Equal(t, 1, detail.Status)
})
t.Run("获取不存在的记录", func(t *testing.T) {
_, err := authService.GetRecordDetail(ctx, 99999)
assert.Error(t, err)
})
}
func TestAuthorizationService_UpdateRecordRemark(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
enterpriseStore := postgres.NewEnterpriseStore(tx, rdb)
iotCardStore := postgres.NewIotCardStore(tx, rdb)
authStore := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
authService := enterprise_card.NewAuthorizationService(enterpriseStore, iotCardStore, authStore, nil)
shopID := uint(800)
ent := &model.Enterprise{
EnterpriseName: "备注测试企业",
EnterpriseCode: "ENT_REMARK_001",
OwnerShopID: &shopID,
Status: constants.StatusEnabled,
}
ent.Creator = 1
ent.Updater = 1
err := tx.Create(ent).Error
require.NoError(t, err)
card := &model.IotCard{ICCID: "REMARK_CARD_001", MSISDN: "13800010001", Status: 1, ShopID: &shopID}
err = tx.Create(card).Error
require.NoError(t, err)
account := &model.Account{
Username: "remark_authorizer",
Phone: "13800010002",
Password: "hashed",
UserType: constants.UserTypePlatform,
Status: constants.StatusEnabled,
}
account.Creator = 1
account.Updater = 1
err = tx.Create(account).Error
require.NoError(t, err)
auth := &model.EnterpriseCardAuthorization{
EnterpriseID: ent.ID,
CardID: card.ID,
AuthorizedBy: account.ID,
AuthorizedAt: time.Now(),
AuthorizerType: constants.UserTypePlatform,
Remark: "原始备注",
}
err = authStore.Create(context.Background(), auth)
require.NoError(t, err)
ctx := pkggorm.SkipDataPermission(context.Background())
t.Run("更新授权备注", func(t *testing.T) {
updated, err := authService.UpdateRecordRemark(ctx, auth.ID, "更新后的备注")
require.NoError(t, err)
assert.Equal(t, "更新后的备注", updated.Remark)
})
t.Run("更新不存在的记录", func(t *testing.T) {
_, err := authService.UpdateRecordRemark(ctx, 99999, "不会更新")
assert.Error(t, err)
})
}

View File

@@ -0,0 +1,332 @@
package unit
import (
"context"
"testing"
"time"
"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/store/postgres"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/tests/testutils"
)
func TestEnterpriseCardAuthorizationStore_Create(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
store := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
ctx := context.Background()
auth := &model.EnterpriseCardAuthorization{
EnterpriseID: 1,
CardID: 100,
AuthorizedBy: 1,
AuthorizedAt: time.Now(),
AuthorizerType: constants.UserTypePlatform,
}
err := store.Create(ctx, auth)
require.NoError(t, err)
assert.NotZero(t, auth.ID)
}
func TestEnterpriseCardAuthorizationStore_BatchCreate(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
store := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
ctx := context.Background()
now := time.Now()
auths := []*model.EnterpriseCardAuthorization{
{
EnterpriseID: 1,
CardID: 101,
AuthorizedBy: 1,
AuthorizedAt: now,
AuthorizerType: constants.UserTypePlatform,
},
{
EnterpriseID: 1,
CardID: 102,
AuthorizedBy: 1,
AuthorizedAt: now,
AuthorizerType: constants.UserTypePlatform,
},
}
err := store.BatchCreate(ctx, auths)
require.NoError(t, err)
for _, auth := range auths {
assert.NotZero(t, auth.ID)
}
}
func TestEnterpriseCardAuthorizationStore_GetByEnterpriseAndCard(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
store := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
ctx := context.Background()
auth := &model.EnterpriseCardAuthorization{
EnterpriseID: 2,
CardID: 200,
AuthorizedBy: 1,
AuthorizedAt: time.Now(),
AuthorizerType: constants.UserTypePlatform,
}
err := store.Create(ctx, auth)
require.NoError(t, err)
found, err := store.GetByEnterpriseAndCard(ctx, 2, 200)
require.NoError(t, err)
assert.Equal(t, auth.ID, found.ID)
assert.Equal(t, uint(2), found.EnterpriseID)
assert.Equal(t, uint(200), found.CardID)
_, err = store.GetByEnterpriseAndCard(ctx, 999, 999)
assert.Error(t, err)
}
func TestEnterpriseCardAuthorizationStore_ListByEnterprise(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
store := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
ctx := context.Background()
now := time.Now()
revokedAt := time.Now()
auths := []*model.EnterpriseCardAuthorization{
{EnterpriseID: 3, CardID: 301, AuthorizedBy: 1, AuthorizedAt: now, AuthorizerType: constants.UserTypePlatform},
{EnterpriseID: 3, CardID: 302, AuthorizedBy: 1, AuthorizedAt: now, AuthorizerType: constants.UserTypePlatform},
{EnterpriseID: 3, CardID: 303, AuthorizedBy: 1, AuthorizedAt: now, AuthorizerType: constants.UserTypePlatform, RevokedAt: &revokedAt, RevokedBy: ptrUint(1)},
}
err := store.BatchCreate(ctx, auths)
require.NoError(t, err)
activeAuths, err := store.ListByEnterprise(ctx, 3, false)
require.NoError(t, err)
assert.Len(t, activeAuths, 2)
allAuths, err := store.ListByEnterprise(ctx, 3, true)
require.NoError(t, err)
assert.Len(t, allAuths, 3)
}
func TestEnterpriseCardAuthorizationStore_RevokeAuthorizations(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
store := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
ctx := context.Background()
now := time.Now()
auths := []*model.EnterpriseCardAuthorization{
{EnterpriseID: 4, CardID: 401, AuthorizedBy: 1, AuthorizedAt: now, AuthorizerType: constants.UserTypePlatform},
{EnterpriseID: 4, CardID: 402, AuthorizedBy: 1, AuthorizedAt: now, AuthorizerType: constants.UserTypePlatform},
}
err := store.BatchCreate(ctx, auths)
require.NoError(t, err)
err = store.RevokeAuthorizations(ctx, 4, []uint{401}, 2)
require.NoError(t, err)
activeAuths, err := store.ListByEnterprise(ctx, 4, false)
require.NoError(t, err)
assert.Len(t, activeAuths, 1)
assert.Equal(t, uint(402), activeAuths[0].CardID)
allAuths, err := store.ListByEnterprise(ctx, 4, true)
require.NoError(t, err)
assert.Len(t, allAuths, 2)
}
func TestEnterpriseCardAuthorizationStore_GetActiveAuthorizedCardIDs(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
store := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
ctx := context.Background()
now := time.Now()
revokedAt := time.Now()
auths := []*model.EnterpriseCardAuthorization{
{EnterpriseID: 5, CardID: 501, AuthorizedBy: 1, AuthorizedAt: now, AuthorizerType: constants.UserTypePlatform},
{EnterpriseID: 5, CardID: 502, AuthorizedBy: 1, AuthorizedAt: now, AuthorizerType: constants.UserTypePlatform},
{EnterpriseID: 5, CardID: 503, AuthorizedBy: 1, AuthorizedAt: now, AuthorizerType: constants.UserTypePlatform, RevokedAt: &revokedAt, RevokedBy: ptrUint(1)},
}
err := store.BatchCreate(ctx, auths)
require.NoError(t, err)
cardIDs, err := store.GetActiveAuthorizedCardIDs(ctx, 5)
require.NoError(t, err)
assert.Len(t, cardIDs, 2)
assert.Contains(t, cardIDs, uint(501))
assert.Contains(t, cardIDs, uint(502))
assert.NotContains(t, cardIDs, uint(503))
}
func TestEnterpriseCardAuthorizationStore_CheckAuthorizationExists(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
store := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
ctx := context.Background()
auth := &model.EnterpriseCardAuthorization{
EnterpriseID: 6,
CardID: 600,
AuthorizedBy: 1,
AuthorizedAt: time.Now(),
AuthorizerType: constants.UserTypePlatform,
}
err := store.Create(ctx, auth)
require.NoError(t, err)
exists, err := store.CheckAuthorizationExists(ctx, 6, 600)
require.NoError(t, err)
assert.True(t, exists)
exists, err = store.CheckAuthorizationExists(ctx, 6, 999)
require.NoError(t, err)
assert.False(t, exists)
}
func TestEnterpriseCardAuthorizationStore_GetActiveAuthsByCardIDs(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
store := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
ctx := context.Background()
now := time.Now()
auths := []*model.EnterpriseCardAuthorization{
{EnterpriseID: 7, CardID: 701, AuthorizedBy: 1, AuthorizedAt: now, AuthorizerType: constants.UserTypePlatform},
{EnterpriseID: 7, CardID: 702, AuthorizedBy: 1, AuthorizedAt: now, AuthorizerType: constants.UserTypePlatform},
}
err := store.BatchCreate(ctx, auths)
require.NoError(t, err)
result, err := store.GetActiveAuthsByCardIDs(ctx, 7, []uint{701, 702, 703})
require.NoError(t, err)
assert.True(t, result[701])
assert.True(t, result[702])
assert.False(t, result[703])
}
func TestEnterpriseCardAuthorizationStore_ListWithOptions(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
store := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
ctx := context.Background()
now := time.Now()
for i := uint(0); i < 15; i++ {
auth := &model.EnterpriseCardAuthorization{
EnterpriseID: 8,
CardID: 800 + i,
AuthorizedBy: 1,
AuthorizedAt: now,
AuthorizerType: constants.UserTypePlatform,
}
err := store.Create(ctx, auth)
require.NoError(t, err)
}
enterpriseID := uint(8)
opts := postgres.AuthorizationListOptions{
EnterpriseID: &enterpriseID,
Limit: 10,
Offset: 0,
}
auths, total, err := store.ListWithOptions(ctx, opts)
require.NoError(t, err)
assert.Equal(t, int64(15), total)
assert.Len(t, auths, 10)
opts.Offset = 10
auths, total, err = store.ListWithOptions(ctx, opts)
require.NoError(t, err)
assert.Equal(t, int64(15), total)
assert.Len(t, auths, 5)
}
func ptrUint(v uint) *uint {
return &v
}
func TestEnterpriseCardAuthorizationStore_UpdateRemark(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
store := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
ctx := context.Background()
auth := &model.EnterpriseCardAuthorization{
EnterpriseID: 10,
CardID: 1000,
AuthorizedBy: 1,
AuthorizedAt: time.Now(),
AuthorizerType: constants.UserTypePlatform,
Remark: "原始备注",
}
err := store.Create(ctx, auth)
require.NoError(t, err)
err = store.UpdateRemark(ctx, auth.ID, "更新后的备注")
require.NoError(t, err)
updated, err := store.GetByID(ctx, auth.ID)
require.NoError(t, err)
assert.Equal(t, "更新后的备注", updated.Remark)
err = store.UpdateRemark(ctx, 99999, "不存在的记录")
assert.Error(t, err)
}
func TestEnterpriseCardAuthorizationStore_GetByID(t *testing.T) {
tx := testutils.NewTestTransaction(t)
rdb := testutils.GetTestRedis(t)
testutils.CleanTestRedisKeys(t, rdb)
store := postgres.NewEnterpriseCardAuthorizationStore(tx, rdb)
ctx := context.Background()
auth := &model.EnterpriseCardAuthorization{
EnterpriseID: 11,
CardID: 1100,
AuthorizedBy: 1,
AuthorizedAt: time.Now(),
AuthorizerType: constants.UserTypePlatform,
}
err := store.Create(ctx, auth)
require.NoError(t, err)
found, err := store.GetByID(ctx, auth.ID)
require.NoError(t, err)
assert.Equal(t, auth.ID, found.ID)
assert.Equal(t, uint(11), found.EnterpriseID)
assert.Equal(t, uint(1100), found.CardID)
_, err = store.GetByID(ctx, 99999)
assert.Error(t, err)
}

View File

@@ -227,7 +227,7 @@ func TestEnterpriseCardService_AllocateCards(t *testing.T) {
var count int64
tx.Model(&model.EnterpriseCardAuthorization{}).
Where("enterprise_id = ? AND iot_card_id = ?", ent.ID, card.ID).
Where("enterprise_id = ? AND card_id = ?", ent.ID, card.ID).
Count(&count)
assert.Equal(t, int64(1), count)
})