All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m30s
新增功能: - 门店套餐分配管理(shop_package_allocation):支持门店套餐库存管理 - 门店套餐系列分配管理(shop_series_allocation):支持套餐系列分配和佣金层级设置 - 我的套餐查询(my_package):支持门店查询自己的套餐分配情况 测试改进: - 统一集成测试基础设施,新增 testutils.NewIntegrationTestEnv - 重构所有集成测试使用新的测试环境设置 - 移除旧的测试辅助函数和冗余测试文件 - 新增 test_helpers_test.go 统一任务测试辅助 技术细节: - 新增数据库迁移 000025_create_shop_allocation_tables - 新增 3 个 Handler、Service、Store 和对应的单元测试 - 更新 OpenAPI 文档和文档生成器 - 测试覆盖率:Service 层 > 90% Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
369 lines
13 KiB
Go
369 lines
13 KiB
Go
package integration
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"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/pkg/constants"
|
|
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
|
"github.com/break/junhong_cmp_fiber/pkg/response"
|
|
"github.com/break/junhong_cmp_fiber/tests/testutils/integ"
|
|
)
|
|
|
|
func TestPermissionAPI_Create(t *testing.T) {
|
|
env := integ.NewIntegrationTestEnv(t)
|
|
|
|
t.Run("成功创建权限", func(t *testing.T) {
|
|
// 权限编码必须符合 module:action 格式(两边都以小写字母开头)
|
|
permCode := fmt.Sprintf("test:action%d", time.Now().UnixNano())
|
|
reqBody := dto.CreatePermissionRequest{
|
|
PermName: fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
PermCode: permCode,
|
|
PermType: constants.PermissionTypeMenu,
|
|
URL: "/admin/users",
|
|
}
|
|
|
|
jsonBody, _ := json.Marshal(reqBody)
|
|
resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/permissions", jsonBody)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var result response.Response
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, result.Code)
|
|
|
|
var count int64
|
|
env.RawDB().Model(&model.Permission{}).Where("perm_code = ?", permCode).Count(&count)
|
|
assert.Equal(t, int64(1), count)
|
|
})
|
|
|
|
t.Run("权限编码重复时返回错误", func(t *testing.T) {
|
|
existingPerm := env.CreateTestPermission(
|
|
fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
fmt.Sprintf("test:dup%d", time.Now().UnixNano()),
|
|
constants.PermissionTypeMenu,
|
|
)
|
|
|
|
reqBody := dto.CreatePermissionRequest{
|
|
PermName: fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
PermCode: existingPerm.PermCode,
|
|
PermType: constants.PermissionTypeMenu,
|
|
}
|
|
|
|
jsonBody, _ := json.Marshal(reqBody)
|
|
resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/permissions", jsonBody)
|
|
require.NoError(t, err)
|
|
|
|
var result response.Response
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, errors.CodePermCodeExists, result.Code)
|
|
})
|
|
|
|
t.Run("创建子权限", func(t *testing.T) {
|
|
parentPermCode := fmt.Sprintf("test:parent%d", time.Now().UnixNano())
|
|
parentPerm := env.CreateTestPermission(
|
|
fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
parentPermCode,
|
|
constants.PermissionTypeMenu,
|
|
)
|
|
|
|
childPermCode := fmt.Sprintf("test:child%d", time.Now().UnixNano())
|
|
reqBody := dto.CreatePermissionRequest{
|
|
PermName: fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
PermCode: childPermCode,
|
|
PermType: constants.PermissionTypeButton,
|
|
ParentID: &parentPerm.ID,
|
|
}
|
|
|
|
jsonBody, _ := json.Marshal(reqBody)
|
|
resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/permissions", jsonBody)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var child model.Permission
|
|
err = env.RawDB().Where("perm_code = ?", childPermCode).First(&child).Error
|
|
require.NoError(t, err, "子权限应该已创建")
|
|
require.NotNil(t, child.ParentID, "子权限的 ParentID 应该已设置")
|
|
assert.Equal(t, parentPerm.ID, *child.ParentID)
|
|
})
|
|
}
|
|
|
|
func TestPermissionAPI_Get(t *testing.T) {
|
|
env := integ.NewIntegrationTestEnv(t)
|
|
|
|
testPerm := env.CreateTestPermission(
|
|
fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
fmt.Sprintf("test:get%d", time.Now().UnixNano()),
|
|
constants.PermissionTypeMenu,
|
|
)
|
|
|
|
t.Run("成功获取权限详情", func(t *testing.T) {
|
|
resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/permissions/%d", testPerm.ID), nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var result response.Response
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, result.Code)
|
|
})
|
|
|
|
t.Run("权限不存在时返回错误", func(t *testing.T) {
|
|
resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/permissions/99999", nil)
|
|
require.NoError(t, err)
|
|
|
|
var result response.Response
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, errors.CodePermissionNotFound, result.Code)
|
|
})
|
|
}
|
|
|
|
func TestPermissionAPI_Update(t *testing.T) {
|
|
env := integ.NewIntegrationTestEnv(t)
|
|
|
|
testPerm := env.CreateTestPermission(
|
|
fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
fmt.Sprintf("test:upd%d", time.Now().UnixNano()),
|
|
constants.PermissionTypeMenu,
|
|
)
|
|
|
|
t.Run("成功更新权限", func(t *testing.T) {
|
|
newName := "更新后权限"
|
|
reqBody := dto.UpdatePermissionRequest{
|
|
PermName: &newName,
|
|
}
|
|
|
|
jsonBody, _ := json.Marshal(reqBody)
|
|
resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/permissions/%d", testPerm.ID), jsonBody)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var updated model.Permission
|
|
env.RawDB().First(&updated, testPerm.ID)
|
|
assert.Equal(t, newName, updated.PermName)
|
|
})
|
|
}
|
|
|
|
func TestPermissionAPI_Delete(t *testing.T) {
|
|
env := integ.NewIntegrationTestEnv(t)
|
|
|
|
t.Run("成功软删除权限", func(t *testing.T) {
|
|
testPerm := env.CreateTestPermission(
|
|
fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
fmt.Sprintf("test:del%d", time.Now().UnixNano()),
|
|
constants.PermissionTypeMenu,
|
|
)
|
|
|
|
resp, err := env.AsSuperAdmin().Request("DELETE", fmt.Sprintf("/api/admin/permissions/%d", testPerm.ID), nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var deleted model.Permission
|
|
err = env.RawDB().Unscoped().First(&deleted, testPerm.ID).Error
|
|
require.NoError(t, err)
|
|
assert.NotNil(t, deleted.DeletedAt)
|
|
})
|
|
}
|
|
|
|
func TestPermissionAPI_List(t *testing.T) {
|
|
env := integ.NewIntegrationTestEnv(t)
|
|
|
|
for i := 1; i <= 5; i++ {
|
|
env.CreateTestPermission(fmt.Sprintf("列表测试权限_%d", i), fmt.Sprintf("list:perm%d", i), constants.PermissionTypeMenu)
|
|
}
|
|
|
|
t.Run("成功获取权限列表", func(t *testing.T) {
|
|
resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/permissions?page=1&page_size=10", nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var result response.Response
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, result.Code)
|
|
})
|
|
|
|
t.Run("按类型过滤权限", func(t *testing.T) {
|
|
resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/permissions?perm_type=%d", constants.PermissionTypeMenu), nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
})
|
|
}
|
|
|
|
func TestPermissionAPI_GetTree(t *testing.T) {
|
|
env := integ.NewIntegrationTestEnv(t)
|
|
|
|
rootPerm := env.CreateTestPermission(
|
|
fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
fmt.Sprintf("test:root%d", time.Now().UnixNano()),
|
|
constants.PermissionTypeMenu,
|
|
)
|
|
|
|
childPermCode := fmt.Sprintf("test:child%d", time.Now().UnixNano())
|
|
childPerm := &model.Permission{
|
|
BaseModel: model.BaseModel{Creator: 1, Updater: 1},
|
|
PermName: fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
PermCode: childPermCode,
|
|
PermType: constants.PermissionTypeMenu,
|
|
ParentID: &rootPerm.ID,
|
|
Status: constants.StatusEnabled,
|
|
}
|
|
env.TX.Create(childPerm)
|
|
|
|
grandchildPermCode := fmt.Sprintf("test:grand%d", time.Now().UnixNano())
|
|
grandchildPerm := &model.Permission{
|
|
BaseModel: model.BaseModel{Creator: 1, Updater: 1},
|
|
PermName: fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
PermCode: grandchildPermCode,
|
|
PermType: constants.PermissionTypeButton,
|
|
ParentID: &childPerm.ID,
|
|
Status: constants.StatusEnabled,
|
|
}
|
|
env.TX.Create(grandchildPerm)
|
|
|
|
t.Run("成功获取权限树", func(t *testing.T) {
|
|
resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/permissions/tree", nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var result response.Response
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, result.Code)
|
|
})
|
|
}
|
|
|
|
func TestPermissionAPI_GetTreeByRoleType(t *testing.T) {
|
|
env := integ.NewIntegrationTestEnv(t)
|
|
|
|
platformPerm := &model.Permission{
|
|
BaseModel: model.BaseModel{Creator: 1, Updater: 1},
|
|
PermName: fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
PermCode: fmt.Sprintf("test:plat%d", time.Now().UnixNano()),
|
|
PermType: constants.PermissionTypeMenu,
|
|
AvailableForRoleTypes: "1",
|
|
Status: constants.StatusEnabled,
|
|
}
|
|
env.TX.Create(platformPerm)
|
|
|
|
customerPerm := &model.Permission{
|
|
BaseModel: model.BaseModel{Creator: 1, Updater: 1},
|
|
PermName: fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
PermCode: fmt.Sprintf("test:cust%d", time.Now().UnixNano()),
|
|
PermType: constants.PermissionTypeMenu,
|
|
AvailableForRoleTypes: "2",
|
|
Status: constants.StatusEnabled,
|
|
}
|
|
env.TX.Create(customerPerm)
|
|
|
|
commonPerm := &model.Permission{
|
|
BaseModel: model.BaseModel{Creator: 1, Updater: 1},
|
|
PermName: fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
PermCode: fmt.Sprintf("test:comm%d", time.Now().UnixNano()),
|
|
PermType: constants.PermissionTypeMenu,
|
|
AvailableForRoleTypes: "1,2",
|
|
Status: constants.StatusEnabled,
|
|
}
|
|
env.TX.Create(commonPerm)
|
|
|
|
t.Run("按角色类型过滤权限树-平台角色", func(t *testing.T) {
|
|
resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/permissions/tree?available_for_role_type=%d", constants.RoleTypePlatform), nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var result response.Response
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, result.Code)
|
|
})
|
|
|
|
t.Run("按角色类型过滤权限树-客户角色", func(t *testing.T) {
|
|
resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/permissions/tree?available_for_role_type=2", nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var result response.Response
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, result.Code)
|
|
})
|
|
|
|
t.Run("按平台和角色类型过滤", func(t *testing.T) {
|
|
resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/permissions/tree?platform=all&available_for_role_type=1", nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var result response.Response
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, result.Code)
|
|
})
|
|
}
|
|
|
|
func TestPermissionAPI_FilterByAvailableForRoleTypes(t *testing.T) {
|
|
env := integ.NewIntegrationTestEnv(t)
|
|
|
|
platformPerm := &model.Permission{
|
|
BaseModel: model.BaseModel{Creator: 1, Updater: 1},
|
|
PermName: fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
PermCode: fmt.Sprintf("test:fplat%d", time.Now().UnixNano()),
|
|
PermType: constants.PermissionTypeMenu,
|
|
AvailableForRoleTypes: "1",
|
|
Status: constants.StatusEnabled,
|
|
}
|
|
env.TX.Create(platformPerm)
|
|
|
|
customerPerm := &model.Permission{
|
|
BaseModel: model.BaseModel{Creator: 1, Updater: 1},
|
|
PermName: fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
PermCode: fmt.Sprintf("test:fcust%d", time.Now().UnixNano()),
|
|
PermType: constants.PermissionTypeMenu,
|
|
AvailableForRoleTypes: "2",
|
|
Status: constants.StatusEnabled,
|
|
}
|
|
env.TX.Create(customerPerm)
|
|
|
|
commonPerm := &model.Permission{
|
|
BaseModel: model.BaseModel{Creator: 1, Updater: 1},
|
|
PermName: fmt.Sprintf("test_permission_%d", time.Now().UnixNano()),
|
|
PermCode: fmt.Sprintf("test:fcomm%d", time.Now().UnixNano()),
|
|
PermType: constants.PermissionTypeMenu,
|
|
AvailableForRoleTypes: "1,2",
|
|
Status: constants.StatusEnabled,
|
|
}
|
|
env.TX.Create(commonPerm)
|
|
|
|
t.Run("过滤平台角色可用权限", func(t *testing.T) {
|
|
resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/permissions?available_for_role_type=1", nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var result response.Response
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, result.Code)
|
|
})
|
|
|
|
t.Run("按角色类型过滤权限树", func(t *testing.T) {
|
|
resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/permissions/tree?available_for_role_type=%d", constants.RoleTypePlatform), nil)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, fiber.StatusOK, resp.StatusCode)
|
|
|
|
var result response.Response
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 0, result.Code)
|
|
})
|
|
}
|