From 5fefe9d0cb96b513ddc6758e9f762c2d472b168a Mon Sep 17 00:00:00 2001 From: huang Date: Tue, 27 Jan 2026 22:44:21 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84:=20=E4=BD=BF=E7=94=A8=20test?= =?UTF-8?q?utils.NewIntegrationTestEnv=20=E6=9B=BF=E6=8D=A2=E6=97=A7?= =?UTF-8?q?=E7=9A=84=E6=B5=8B=E8=AF=95=E7=8E=AF=E5=A2=83=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除 setupAuthorizationTestEnv 和 teardown 函数 - 移除所有 DELETE 清理代码,改用事务隔离 - 每个测试函数改用 env := testutils.NewIntegrationTestEnv(t) - 使用 env.TX 替代 env.db - 使用 env.AsSuperAdmin().Request() 和 env.AsUser() 发送请求 - 使用 env.CreateTestShop/Enterprise/Account 创建测试数据 - 移除未使用的导入(bytes, net/http/httptest) - 保持所有测试业务逻辑不变 --- tests/integration/authorization_test.go | 395 +++++++----------------- 1 file changed, 118 insertions(+), 277 deletions(-) diff --git a/tests/integration/authorization_test.go b/tests/integration/authorization_test.go index 014822c..906d810 100644 --- a/tests/integration/authorization_test.go +++ b/tests/integration/authorization_test.go @@ -1,150 +1,26 @@ package integration import ( - "bytes" - "context" "encoding/json" "fmt" - "net/http/httptest" "testing" "time" - "github.com/break/junhong_cmp_fiber/internal/bootstrap" - internalMiddleware "github.com/break/junhong_cmp_fiber/internal/middleware" "github.com/break/junhong_cmp_fiber/internal/model" - "github.com/break/junhong_cmp_fiber/internal/routes" - "github.com/break/junhong_cmp_fiber/pkg/auth" - "github.com/break/junhong_cmp_fiber/pkg/config" "github.com/break/junhong_cmp_fiber/pkg/constants" - "github.com/break/junhong_cmp_fiber/pkg/queue" "github.com/break/junhong_cmp_fiber/pkg/response" - "github.com/break/junhong_cmp_fiber/tests/testutil" - "github.com/gofiber/fiber/v2" - "github.com/redis/go-redis/v9" + "github.com/break/junhong_cmp_fiber/tests/testutils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.uber.org/zap" - "gorm.io/driver/postgres" - "gorm.io/gorm" - "gorm.io/gorm/logger" ) -const ( - testDBDSN = "host=cxd.whcxd.cn port=16159 user=erp_pgsql password=erp_2025 dbname=junhong_cmp_test sslmode=disable TimeZone=Asia/Shanghai" - testRedisAddr = "cxd.whcxd.cn:16299" - testRedisPasswd = "cpNbWtAaqgo1YJmbMp3h" - testRedisDB = 6 -) - -type authorizationTestEnv struct { - db *gorm.DB - rdb *redis.Client - tokenManager *auth.TokenManager - app *fiber.App - adminToken string - agentToken string - enterprise *model.Enterprise - card1 *model.IotCard - card2 *model.IotCard - auth1 *model.EnterpriseCardAuthorization - shop *model.Shop - agentAccount *model.Account - t *testing.T -} - -func setupTestEnvVars(t *testing.T) { - t.Helper() - t.Setenv("JUNHONG_DATABASE_HOST", "cxd.whcxd.cn") - t.Setenv("JUNHONG_DATABASE_PORT", "16159") - t.Setenv("JUNHONG_DATABASE_USER", "erp_pgsql") - t.Setenv("JUNHONG_DATABASE_PASSWORD", "erp_2025") - t.Setenv("JUNHONG_DATABASE_DBNAME", "junhong_cmp_test") - t.Setenv("JUNHONG_DATABASE_SSLMODE", "disable") - t.Setenv("JUNHONG_REDIS_ADDRESS", "cxd.whcxd.cn") - t.Setenv("JUNHONG_REDIS_PORT", "16299") - t.Setenv("JUNHONG_REDIS_PASSWORD", "cpNbWtAaqgo1YJmbMp3h") - t.Setenv("JUNHONG_REDIS_DB", "6") - t.Setenv("JUNHONG_JWT_SECRET_KEY", "dev-secret-key-for-testing-only-32chars!") - t.Setenv("JUNHONG_SERVER_ADDRESS", ":3000") - t.Setenv("JUNHONG_LOGGING_LEVEL", "debug") - t.Setenv("JUNHONG_LOGGING_DEVELOPMENT", "true") -} - -func setupAuthorizationTestEnv(t *testing.T) *authorizationTestEnv { - t.Helper() - - setupTestEnvVars(t) - cfg, err := config.Load() - require.NoError(t, err) - err = config.Set(cfg) - require.NoError(t, err) - - zapLogger, _ := zap.NewDevelopment() - - db, err := gorm.Open(postgres.Open(testDBDSN), &gorm.Config{ - Logger: logger.Default.LogMode(logger.Silent), - }) - require.NoError(t, err) - - rdb := redis.NewClient(&redis.Options{ - Addr: testRedisAddr, - Password: testRedisPasswd, - DB: testRedisDB, - }) - - ctx := context.Background() - err = rdb.Ping(ctx).Err() - require.NoError(t, err) - - testPrefix := fmt.Sprintf("test:%s:", t.Name()) - keys, _ := rdb.Keys(ctx, testPrefix+"*").Result() - if len(keys) > 0 { - rdb.Del(ctx, keys...) - } - - tokenManager := auth.NewTokenManager(rdb, 24*time.Hour, 7*24*time.Hour) - superAdmin := testutil.CreateSuperAdmin(t, db) - adminToken, _ := testutil.GenerateTestToken(t, rdb, superAdmin, "web") - - queueClient := queue.NewClient(rdb, zapLogger) - - deps := &bootstrap.Dependencies{ - DB: db, - Redis: rdb, - Logger: zapLogger, - TokenManager: tokenManager, - QueueClient: queueClient, - } - - result, err := bootstrap.Bootstrap(deps) - require.NoError(t, err) - - app := fiber.New(fiber.Config{ - ErrorHandler: internalMiddleware.ErrorHandler(zapLogger), - }) - - routes.RegisterRoutes(app, result.Handlers, result.Middlewares) +func TestAuthorization_List(t *testing.T) { + env := testutils.NewIntegrationTestEnv(t) ts := time.Now().Unix() % 100000 - shop := &model.Shop{ - ShopName: "AUTH_TEST_SHOP", - ShopCode: fmt.Sprintf("AS%d", ts), - Level: 1, - Status: constants.StatusEnabled, - } - shop.Creator = superAdmin.ID - shop.Updater = superAdmin.ID - require.NoError(t, db.Create(shop).Error) + shop := env.CreateTestShop("AUTH_TEST_SHOP", 1, nil) - enterprise := &model.Enterprise{ - EnterpriseName: "AUTH_TEST_ENTERPRISE", - EnterpriseCode: fmt.Sprintf("AE%d", ts), - OwnerShopID: &shop.ID, - Status: constants.StatusEnabled, - } - enterprise.Creator = superAdmin.ID - enterprise.Updater = superAdmin.ID - require.NoError(t, db.Create(enterprise).Error) + enterprise := env.CreateTestEnterprise("AUTH_TEST_ENTERPRISE", &shop.ID) card1 := &model.IotCard{ ICCID: fmt.Sprintf("AC1%d", ts), @@ -160,77 +36,22 @@ func setupAuthorizationTestEnv(t *testing.T) *authorizationTestEnv { Status: 1, ShopID: &shop.ID, } - require.NoError(t, db.Create(card1).Error) - require.NoError(t, db.Create(card2).Error) + require.NoError(t, env.TX.Create(card1).Error) + require.NoError(t, env.TX.Create(card2).Error) now := time.Now() auth1 := &model.EnterpriseCardAuthorization{ EnterpriseID: enterprise.ID, CardID: card1.ID, - AuthorizedBy: superAdmin.ID, + AuthorizedBy: 1, AuthorizedAt: now, AuthorizerType: constants.UserTypePlatform, Remark: "集成测试授权记录", } - require.NoError(t, db.Create(auth1).Error) - - agentAccount := &model.Account{ - Username: fmt.Sprintf("aa%d", ts), - Phone: fmt.Sprintf("138%05d", ts), - Password: "hashed_password", - UserType: constants.UserTypeAgent, - ShopID: &shop.ID, - Status: constants.StatusEnabled, - } - agentAccount.Creator = superAdmin.ID - agentAccount.Updater = superAdmin.ID - require.NoError(t, db.Create(agentAccount).Error) - - agentToken, _ := testutil.GenerateTestToken(t, rdb, agentAccount, "web") - - return &authorizationTestEnv{ - db: db, - rdb: rdb, - tokenManager: tokenManager, - app: app, - adminToken: adminToken, - agentToken: agentToken, - enterprise: enterprise, - card1: card1, - card2: card2, - auth1: auth1, - shop: shop, - agentAccount: agentAccount, - t: t, - } -} - -func (e *authorizationTestEnv) teardown() { - e.db.Exec("DELETE FROM tb_enterprise_card_authorization WHERE enterprise_id = ?", e.enterprise.ID) - e.db.Exec("DELETE FROM tb_iot_card WHERE iccid LIKE 'AC%'") - e.db.Exec("DELETE FROM tb_enterprise WHERE enterprise_code LIKE 'AE%'") - e.db.Exec("DELETE FROM tb_account WHERE username LIKE 'aa%'") - e.db.Exec("DELETE FROM tb_shop WHERE shop_code LIKE 'AS%'") - - ctx := context.Background() - testPrefix := fmt.Sprintf("test:%s:", e.t.Name()) - keys, _ := e.rdb.Keys(ctx, testPrefix+"*").Result() - if len(keys) > 0 { - e.rdb.Del(ctx, keys...) - } - - e.rdb.Close() -} - -func TestAuthorization_List(t *testing.T) { - env := setupAuthorizationTestEnv(t) - defer env.teardown() + require.NoError(t, env.TX.Create(auth1).Error) t.Run("平台用户获取授权记录列表", func(t *testing.T) { - req := httptest.NewRequest("GET", "/api/admin/authorizations?page=1&page_size=20", nil) - req.Header.Set("Authorization", "Bearer "+env.adminToken) - - resp, err := env.app.Test(req, -1) + resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/authorizations?page=1&page_size=20", nil) require.NoError(t, err) defer resp.Body.Close() @@ -249,11 +70,8 @@ func TestAuthorization_List(t *testing.T) { }) t.Run("按企业ID筛选授权记录", func(t *testing.T) { - url := fmt.Sprintf("/api/admin/authorizations?enterprise_id=%d&page=1&page_size=20", env.enterprise.ID) - req := httptest.NewRequest("GET", url, nil) - req.Header.Set("Authorization", "Bearer "+env.adminToken) - - resp, err := env.app.Test(req, -1) + url := fmt.Sprintf("/api/admin/authorizations?enterprise_id=%d&page=1&page_size=20", enterprise.ID) + resp, err := env.AsSuperAdmin().Request("GET", url, nil) require.NoError(t, err) defer resp.Body.Close() @@ -270,11 +88,8 @@ func TestAuthorization_List(t *testing.T) { }) t.Run("按ICCID筛选授权记录", func(t *testing.T) { - url := fmt.Sprintf("/api/admin/authorizations?iccid=%s&page=1&page_size=20", env.card1.ICCID) - req := httptest.NewRequest("GET", url, nil) - req.Header.Set("Authorization", "Bearer "+env.adminToken) - - resp, err := env.app.Test(req, -1) + url := fmt.Sprintf("/api/admin/authorizations?iccid=%s&page=1&page_size=20", card1.ICCID) + resp, err := env.AsSuperAdmin().Request("GET", url, nil) require.NoError(t, err) defer resp.Body.Close() @@ -291,11 +106,8 @@ func TestAuthorization_List(t *testing.T) { }) t.Run("按状态筛选-有效授权", func(t *testing.T) { - url := fmt.Sprintf("/api/admin/authorizations?enterprise_id=%d&status=1&page=1&page_size=20", env.enterprise.ID) - req := httptest.NewRequest("GET", url, nil) - req.Header.Set("Authorization", "Bearer "+env.adminToken) - - resp, err := env.app.Test(req, -1) + url := fmt.Sprintf("/api/admin/authorizations?enterprise_id=%d&status=1&page=1&page_size=20", enterprise.ID) + resp, err := env.AsSuperAdmin().Request("GET", url, nil) require.NoError(t, err) defer resp.Body.Close() @@ -309,15 +121,36 @@ func TestAuthorization_List(t *testing.T) { } func TestAuthorization_GetDetail(t *testing.T) { - env := setupAuthorizationTestEnv(t) - defer env.teardown() + env := testutils.NewIntegrationTestEnv(t) + + ts := time.Now().Unix() % 100000 + shop := env.CreateTestShop("AUTH_TEST_SHOP", 1, nil) + + enterprise := env.CreateTestEnterprise("AUTH_TEST_ENTERPRISE", &shop.ID) + + card1 := &model.IotCard{ + ICCID: fmt.Sprintf("AC1%d", ts), + MSISDN: "13800001001", + CardType: "data_card", + Status: 1, + ShopID: &shop.ID, + } + require.NoError(t, env.TX.Create(card1).Error) + + now := time.Now() + auth1 := &model.EnterpriseCardAuthorization{ + EnterpriseID: enterprise.ID, + CardID: card1.ID, + AuthorizedBy: 1, + AuthorizedAt: now, + AuthorizerType: constants.UserTypePlatform, + Remark: "集成测试授权记录", + } + require.NoError(t, env.TX.Create(auth1).Error) t.Run("获取授权记录详情", func(t *testing.T) { - url := fmt.Sprintf("/api/admin/authorizations/%d", env.auth1.ID) - req := httptest.NewRequest("GET", url, nil) - req.Header.Set("Authorization", "Bearer "+env.adminToken) - - resp, err := env.app.Test(req, -1) + url := fmt.Sprintf("/api/admin/authorizations/%d", auth1.ID) + resp, err := env.AsSuperAdmin().Request("GET", url, nil) require.NoError(t, err) defer resp.Body.Close() @@ -329,19 +162,16 @@ func TestAuthorization_GetDetail(t *testing.T) { assert.Equal(t, 0, result.Code) data := result.Data.(map[string]interface{}) - assert.Equal(t, float64(env.auth1.ID), data["id"]) - assert.Equal(t, float64(env.enterprise.ID), data["enterprise_id"]) + assert.Equal(t, float64(auth1.ID), data["id"]) + assert.Equal(t, float64(enterprise.ID), data["enterprise_id"]) assert.Equal(t, "AUTH_TEST_ENTERPRISE", data["enterprise_name"]) - assert.Equal(t, env.card1.ICCID, data["iccid"]) + assert.Equal(t, card1.ICCID, data["iccid"]) assert.Equal(t, "集成测试授权记录", data["remark"]) assert.Equal(t, float64(1), data["status"]) }) t.Run("获取不存在的授权记录", func(t *testing.T) { - req := httptest.NewRequest("GET", "/api/admin/authorizations/999999", nil) - req.Header.Set("Authorization", "Bearer "+env.adminToken) - - resp, err := env.app.Test(req, -1) + resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/authorizations/999999", nil) require.NoError(t, err) defer resp.Body.Close() @@ -355,19 +185,39 @@ func TestAuthorization_GetDetail(t *testing.T) { } func TestAuthorization_UpdateRemark(t *testing.T) { - env := setupAuthorizationTestEnv(t) - defer env.teardown() + env := testutils.NewIntegrationTestEnv(t) + + ts := time.Now().Unix() % 100000 + shop := env.CreateTestShop("AUTH_TEST_SHOP", 1, nil) + + enterprise := env.CreateTestEnterprise("AUTH_TEST_ENTERPRISE", &shop.ID) + + card1 := &model.IotCard{ + ICCID: fmt.Sprintf("AC1%d", ts), + MSISDN: "13800001001", + CardType: "data_card", + Status: 1, + ShopID: &shop.ID, + } + require.NoError(t, env.TX.Create(card1).Error) + + now := time.Now() + auth1 := &model.EnterpriseCardAuthorization{ + EnterpriseID: enterprise.ID, + CardID: card1.ID, + AuthorizedBy: 1, + AuthorizedAt: now, + AuthorizerType: constants.UserTypePlatform, + Remark: "集成测试授权记录", + } + require.NoError(t, env.TX.Create(auth1).Error) t.Run("更新授权记录备注", func(t *testing.T) { - url := fmt.Sprintf("/api/admin/authorizations/%d/remark", env.auth1.ID) + url := fmt.Sprintf("/api/admin/authorizations/%d/remark", auth1.ID) body := map[string]string{"remark": "更新后的备注内容"} bodyBytes, _ := json.Marshal(body) - req := httptest.NewRequest("PUT", url, bytes.NewReader(bodyBytes)) - req.Header.Set("Authorization", "Bearer "+env.adminToken) - req.Header.Set("Content-Type", "application/json") - - resp, err := env.app.Test(req, -1) + resp, err := env.AsSuperAdmin().Request("PUT", url, bodyBytes) require.NoError(t, err) defer resp.Body.Close() @@ -386,11 +236,7 @@ func TestAuthorization_UpdateRemark(t *testing.T) { body := map[string]string{"remark": "不会更新"} bodyBytes, _ := json.Marshal(body) - req := httptest.NewRequest("PUT", "/api/admin/authorizations/999999/remark", bytes.NewReader(bodyBytes)) - req.Header.Set("Authorization", "Bearer "+env.adminToken) - req.Header.Set("Content-Type", "application/json") - - resp, err := env.app.Test(req, -1) + resp, err := env.AsSuperAdmin().Request("PUT", "/api/admin/authorizations/999999/remark", bodyBytes) require.NoError(t, err) defer resp.Body.Close() @@ -399,31 +245,39 @@ func TestAuthorization_UpdateRemark(t *testing.T) { } func TestAuthorization_DataPermission(t *testing.T) { - env := setupAuthorizationTestEnv(t) - defer env.teardown() + env := testutils.NewIntegrationTestEnv(t) + + ts := time.Now().Unix() % 100000 + shop := env.CreateTestShop("AUTH_TEST_SHOP", 1, nil) + + enterprise := env.CreateTestEnterprise("AUTH_TEST_ENTERPRISE", &shop.ID) + + card1 := &model.IotCard{ + ICCID: fmt.Sprintf("AC1%d", ts), + MSISDN: "13800001001", + CardType: "data_card", + Status: 1, + ShopID: &shop.ID, + } + require.NoError(t, env.TX.Create(card1).Error) + + now := time.Now() + auth1 := &model.EnterpriseCardAuthorization{ + EnterpriseID: enterprise.ID, + CardID: card1.ID, + AuthorizedBy: 1, + AuthorizedAt: now, + AuthorizerType: constants.UserTypePlatform, + Remark: "集成测试授权记录", + } + require.NoError(t, env.TX.Create(auth1).Error) + + agentAccount := env.CreateTestAccount("agent", "password123", constants.UserTypeAgent, &shop.ID, nil) ts2 := time.Now().Unix() % 100000 - otherShop := &model.Shop{ - ShopName: "OTHER_TEST_SHOP", - ShopCode: fmt.Sprintf("OS%d", ts2), - Level: 1, - Status: constants.StatusEnabled, - } - otherShop.Creator = 1 - otherShop.Updater = 1 - require.NoError(t, env.db.Create(otherShop).Error) - defer env.db.Exec("DELETE FROM tb_shop WHERE id = ?", otherShop.ID) + otherShop := env.CreateTestShop("OTHER_TEST_SHOP", 1, nil) - otherEnterprise := &model.Enterprise{ - EnterpriseName: "OTHER_TEST_ENTERPRISE", - EnterpriseCode: fmt.Sprintf("OE%d", ts2), - OwnerShopID: &otherShop.ID, - Status: constants.StatusEnabled, - } - otherEnterprise.Creator = 1 - otherEnterprise.Updater = 1 - require.NoError(t, env.db.Create(otherEnterprise).Error) - defer env.db.Exec("DELETE FROM tb_enterprise WHERE id = ?", otherEnterprise.ID) + otherEnterprise := env.CreateTestEnterprise("OTHER_TEST_ENTERPRISE", &otherShop.ID) otherCard := &model.IotCard{ ICCID: fmt.Sprintf("OC%d", ts2), @@ -432,10 +286,8 @@ func TestAuthorization_DataPermission(t *testing.T) { Status: 1, ShopID: &otherShop.ID, } - require.NoError(t, env.db.Create(otherCard).Error) - defer env.db.Exec("DELETE FROM tb_iot_card WHERE id = ?", otherCard.ID) + require.NoError(t, env.TX.Create(otherCard).Error) - now := time.Now() otherAuth := &model.EnterpriseCardAuthorization{ EnterpriseID: otherEnterprise.ID, CardID: otherCard.ID, @@ -444,14 +296,10 @@ func TestAuthorization_DataPermission(t *testing.T) { AuthorizerType: constants.UserTypePlatform, Remark: "其他店铺的授权记录", } - require.NoError(t, env.db.Create(otherAuth).Error) - defer env.db.Exec("DELETE FROM tb_enterprise_card_authorization WHERE id = ?", otherAuth.ID) + require.NoError(t, env.TX.Create(otherAuth).Error) t.Run("代理用户只能看到自己店铺的授权记录", func(t *testing.T) { - req := httptest.NewRequest("GET", "/api/admin/authorizations?page=1&page_size=100", nil) - req.Header.Set("Authorization", "Bearer "+env.agentToken) - - resp, err := env.app.Test(req, -1) + resp, err := env.AsUser(agentAccount).Request("GET", "/api/admin/authorizations?page=1&page_size=100", nil) require.NoError(t, err) defer resp.Body.Close() @@ -473,19 +321,16 @@ func TestAuthorization_DataPermission(t *testing.T) { if authID == otherAuth.ID { sawOtherAuth = true } - if authID == env.auth1.ID { + if authID == auth1.ID { sawOwnAuth = true } } assert.False(t, sawOtherAuth, "代理用户不应该看到其他店铺的授权记录 (otherAuth.ID=%d)", otherAuth.ID) - assert.True(t, sawOwnAuth, "代理用户应该能看到自己店铺的授权记录 (auth1.ID=%d)", env.auth1.ID) + assert.True(t, sawOwnAuth, "代理用户应该能看到自己店铺的授权记录 (auth1.ID=%d)", auth1.ID) }) t.Run("平台用户可以看到所有授权记录", func(t *testing.T) { - req := httptest.NewRequest("GET", "/api/admin/authorizations?page=1&page_size=100", nil) - req.Header.Set("Authorization", "Bearer "+env.adminToken) - - resp, err := env.app.Test(req, -1) + resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/authorizations?page=1&page_size=100", nil) require.NoError(t, err) defer resp.Body.Close() @@ -503,13 +348,10 @@ func TestAuthorization_DataPermission(t *testing.T) { } func TestAuthorization_Unauthorized(t *testing.T) { - env := setupAuthorizationTestEnv(t) - defer env.teardown() + env := testutils.NewIntegrationTestEnv(t) t.Run("无Token访问被拒绝", func(t *testing.T) { - req := httptest.NewRequest("GET", "/api/admin/authorizations", nil) - - resp, err := env.app.Test(req, -1) + resp, err := env.ClearAuth().Request("GET", "/api/admin/authorizations", nil) require.NoError(t, err) defer resp.Body.Close() @@ -517,10 +359,9 @@ func TestAuthorization_Unauthorized(t *testing.T) { }) t.Run("无效Token访问被拒绝", func(t *testing.T) { - req := httptest.NewRequest("GET", "/api/admin/authorizations", nil) - req.Header.Set("Authorization", "Bearer invalid_token") - - resp, err := env.app.Test(req, -1) + resp, err := env.RequestWithHeaders("GET", "/api/admin/authorizations", nil, map[string]string{ + "Authorization": "Bearer invalid_token", + }) require.NoError(t, err) defer resp.Body.Close()