Files
junhong_cmp_fiber/tests/integration/account_test.go
huang fba8e9e76b
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m18s
refactor(account): 移除卡类型字段、优化账号列表查询和权限检查
- 移除 IoT 卡和号卡的 card_type 字段(数据库迁移)
- 优化账号列表查询,支持按店铺和企业筛选
- 账号响应增加店铺名称和企业名称字段
- 实现批量加载店铺和企业名称,避免 N+1 查询
- 更新权限检查中间件,完善权限验证逻辑
- 更新相关测试用例,确保功能正确性
2026-02-03 10:59:44 +08:00

937 lines
32 KiB
Go

package integration
import (
"encoding/json"
"fmt"
"net/http"
"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 TestPlatformAccount_Create(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
username := fmt.Sprintf("platform_user_%d", time.Now().UnixNano())
phone := fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000)
reqBody := dto.CreateAccountRequest{
Username: username,
Phone: phone,
Password: "Password123",
UserType: constants.UserTypePlatform,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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.Account{}).Where("username = ?", username).Count(&count)
assert.Equal(t, int64(1), count)
}
func TestPlatformAccount_Create_DuplicateUsername(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
existingAccount := env.CreateTestAccount("existing_platform", "password123", constants.UserTypePlatform, nil, nil)
phone := fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000)
reqBody := dto.CreateAccountRequest{
Username: existingAccount.Username,
Phone: phone,
Password: "Password123",
UserType: constants.UserTypePlatform,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
var result response.Response
err = json.NewDecoder(resp.Body).Decode(&result)
require.NoError(t, err)
assert.Equal(t, errors.CodeUsernameExists, result.Code)
}
func TestPlatformAccount_List(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
for i := 1; i <= 3; i++ {
env.CreateTestAccount(fmt.Sprintf("platform_list_%d", i), "password123", constants.UserTypePlatform, nil, nil)
}
resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/accounts?page=1&page_size=10", nil)
require.NoError(t, err)
defer resp.Body.Close()
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)
data := result.Data.(map[string]interface{})
items := data["items"].([]interface{})
assert.GreaterOrEqual(t, len(items), 3)
}
func TestPlatformAccount_Get(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testAccount := env.CreateTestAccount("platform_detail", "password123", constants.UserTypePlatform, nil, nil)
resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
require.NoError(t, err)
defer resp.Body.Close()
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 TestPlatformAccount_Get_NotFound(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/accounts/99999", nil)
require.NoError(t, err)
defer resp.Body.Close()
var result response.Response
err = json.NewDecoder(resp.Body).Decode(&result)
require.NoError(t, err)
assert.Equal(t, errors.CodeAccountNotFound, result.Code)
}
func TestPlatformAccount_Update(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testAccount := env.CreateTestAccount("platform_update", "password123", constants.UserTypePlatform, nil, nil)
newUsername := fmt.Sprintf("updated_%d", time.Now().UnixNano())
reqBody := dto.UpdateAccountRequest{
Username: &newUsername,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestPlatformAccount_UpdatePassword(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testAccount := env.CreateTestAccount("platform_pwd", "password123", constants.UserTypePlatform, nil, nil)
reqBody := dto.UpdatePasswordRequest{
NewPassword: "NewPassword@123",
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/password", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestPlatformAccount_UpdateStatus(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testAccount := env.CreateTestAccount("platform_status", "password123", constants.UserTypePlatform, nil, nil)
reqBody := dto.UpdateStatusRequest{
Status: constants.StatusDisabled,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/status", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestPlatformAccount_Delete(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testAccount := env.CreateTestAccount("platform_delete", "password123", constants.UserTypePlatform, nil, nil)
resp, err := env.AsSuperAdmin().Request("DELETE", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
require.NoError(t, err)
defer resp.Body.Close()
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 TestShopAccount_Create(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("代理账号测试店铺", 1, nil)
username := fmt.Sprintf("agent_user_%d", time.Now().UnixNano())
phone := fmt.Sprintf("139%08d", time.Now().UnixNano()%100000000)
reqBody := dto.CreateAccountRequest{
Username: username,
Phone: phone,
Password: "Password123",
UserType: constants.UserTypeAgent,
ShopID: &testShop.ID,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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)
assert.NotNil(t, result.Data)
}
func TestShopAccount_Create_MissingShopID(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
username := fmt.Sprintf("agent_no_shop_%d", time.Now().UnixNano())
phone := fmt.Sprintf("139%08d", time.Now().UnixNano()%100000000)
reqBody := dto.CreateAccountRequest{
Username: username,
Phone: phone,
Password: "Password123",
UserType: constants.UserTypeAgent,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
var result response.Response
err = json.NewDecoder(resp.Body).Decode(&result)
require.NoError(t, err)
assert.NotEqual(t, 0, result.Code, "创建代理账号缺少店铺ID应返回错误")
}
func TestShopAccount_List(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("代理列表测试店铺", 1, nil)
for i := 1; i <= 3; i++ {
env.CreateTestAccount(fmt.Sprintf("agent_list_%d", i), "password123", constants.UserTypeAgent, &testShop.ID, nil)
}
resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/accounts?page=1&page_size=10", nil)
require.NoError(t, err)
defer resp.Body.Close()
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)
data := result.Data.(map[string]interface{})
items := data["items"].([]interface{})
assert.GreaterOrEqual(t, len(items), 3)
}
func TestShopAccount_Get(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("代理详情测试店铺", 1, nil)
testAccount := env.CreateTestAccount("agent_detail", "password123", constants.UserTypeAgent, &testShop.ID, nil)
resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
require.NoError(t, err)
defer resp.Body.Close()
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 TestShopAccount_Update(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("代理更新测试店铺", 1, nil)
testAccount := env.CreateTestAccount("agent_update", "password123", constants.UserTypeAgent, &testShop.ID, nil)
newUsername := fmt.Sprintf("updated_agent_%d", time.Now().UnixNano())
reqBody := dto.UpdateAccountRequest{
Username: &newUsername,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestShopAccount_UpdatePassword(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("代理密码测试店铺", 1, nil)
testAccount := env.CreateTestAccount("agent_pwd", "password123", constants.UserTypeAgent, &testShop.ID, nil)
reqBody := dto.UpdatePasswordRequest{
NewPassword: "NewPassword@456",
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/password", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestShopAccount_UpdateStatus(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("代理状态测试店铺", 1, nil)
testAccount := env.CreateTestAccount("agent_status", "password123", constants.UserTypeAgent, &testShop.ID, nil)
reqBody := dto.UpdateStatusRequest{
Status: constants.StatusDisabled,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/status", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestShopAccount_Delete(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("代理删除测试店铺", 1, nil)
testAccount := env.CreateTestAccount("agent_delete", "password123", constants.UserTypeAgent, &testShop.ID, nil)
resp, err := env.AsSuperAdmin().Request("DELETE", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
require.NoError(t, err)
defer resp.Body.Close()
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 TestEnterpriseAccount_Create(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("企业账号测试店铺", 1, nil)
testEnterprise := env.CreateTestEnterprise("测试企业", &testShop.ID)
username := fmt.Sprintf("enterprise_user_%d", time.Now().UnixNano())
phone := fmt.Sprintf("137%08d", time.Now().UnixNano()%100000000)
reqBody := dto.CreateAccountRequest{
Username: username,
Phone: phone,
Password: "Password123",
UserType: constants.UserTypeEnterprise,
EnterpriseID: &testEnterprise.ID,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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)
assert.NotNil(t, result.Data)
}
func TestEnterpriseAccount_Create_MissingEnterpriseID(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
username := fmt.Sprintf("enterprise_no_ent_%d", time.Now().UnixNano())
phone := fmt.Sprintf("137%08d", time.Now().UnixNano()%100000000)
reqBody := dto.CreateAccountRequest{
Username: username,
Phone: phone,
Password: "Password123",
UserType: constants.UserTypeEnterprise,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
var result response.Response
err = json.NewDecoder(resp.Body).Decode(&result)
require.NoError(t, err)
assert.NotEqual(t, 0, result.Code, "创建企业账号缺少企业ID应返回错误")
}
func TestEnterpriseAccount_List(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("企业列表测试店铺", 1, nil)
testEnterprise := env.CreateTestEnterprise("列表测试企业", &testShop.ID)
for i := 1; i <= 3; i++ {
env.CreateTestAccount(fmt.Sprintf("ent_list_%d", i), "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)
}
resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/accounts?page=1&page_size=10", nil)
require.NoError(t, err)
defer resp.Body.Close()
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)
data := result.Data.(map[string]interface{})
items := data["items"].([]interface{})
assert.GreaterOrEqual(t, len(items), 3)
}
func TestEnterpriseAccount_Get(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("企业详情测试店铺", 1, nil)
testEnterprise := env.CreateTestEnterprise("详情测试企业", &testShop.ID)
testAccount := env.CreateTestAccount("ent_detail", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)
resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
require.NoError(t, err)
defer resp.Body.Close()
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 TestEnterpriseAccount_Update(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("企业更新测试店铺", 1, nil)
testEnterprise := env.CreateTestEnterprise("更新测试企业", &testShop.ID)
testAccount := env.CreateTestAccount("ent_update", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)
newUsername := fmt.Sprintf("updated_ent_%d", time.Now().UnixNano())
reqBody := dto.UpdateAccountRequest{
Username: &newUsername,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestEnterpriseAccount_UpdatePassword(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("企业密码测试店铺", 1, nil)
testEnterprise := env.CreateTestEnterprise("密码测试企业", &testShop.ID)
testAccount := env.CreateTestAccount("ent_pwd", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)
reqBody := dto.UpdatePasswordRequest{
NewPassword: "NewPassword@789",
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/password", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestEnterpriseAccount_UpdateStatus(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("企业状态测试店铺", 1, nil)
testEnterprise := env.CreateTestEnterprise("状态测试企业", &testShop.ID)
testAccount := env.CreateTestAccount("ent_status", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)
reqBody := dto.UpdateStatusRequest{
Status: constants.StatusDisabled,
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/accounts/%d/status", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestEnterpriseAccount_Delete(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("企业删除测试店铺", 1, nil)
testEnterprise := env.CreateTestEnterprise("删除测试企业", &testShop.ID)
testAccount := env.CreateTestAccount("ent_delete", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)
resp, err := env.AsSuperAdmin().Request("DELETE", fmt.Sprintf("/api/admin/accounts/%d", testAccount.ID), nil)
require.NoError(t, err)
defer resp.Body.Close()
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 TestEnterpriseAccount_Forbidden(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("企业禁止测试店铺", 1, nil)
testEnterprise := env.CreateTestEnterprise("禁止测试企业", &testShop.ID)
entAccount := env.CreateTestAccount("ent_forbidden", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)
resp, err := env.AsUser(entAccount).Request("GET", "/api/admin/accounts", nil)
require.NoError(t, err)
defer resp.Body.Close()
var result response.Response
err = json.NewDecoder(resp.Body).Decode(&result)
require.NoError(t, err)
assert.Equal(t, errors.CodeForbidden, result.Code, "企业用户应禁止访问账号管理功能")
}
// =============================================================================
// 角色管理测试(所有账号类型)
// =============================================================================
func TestAccount_AssignRoles_Platform(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
platformRole := env.CreateTestRole("平台角色", constants.RoleTypePlatform)
testAccount := env.CreateTestAccount("role_platform", "password123", constants.UserTypePlatform, nil, nil)
reqBody := dto.AssignRolesRequest{
RoleIDs: []uint{platformRole.ID},
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestAccount_GetRoles_Platform(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
platformRole := env.CreateTestRole("平台角色获取", constants.RoleTypePlatform)
testAccount := env.CreateTestAccount("role_platform_get", "password123", constants.UserTypePlatform, nil, nil)
accountRole := &model.AccountRole{
AccountID: testAccount.ID,
RoleID: platformRole.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}
env.TX.Create(accountRole)
resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), nil)
require.NoError(t, err)
defer resp.Body.Close()
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 TestAccount_ClearRoles_Platform(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
platformRole := env.CreateTestRole("平台角色清空", constants.RoleTypePlatform)
testAccount := env.CreateTestAccount("role_platform_clr", "password123", constants.UserTypePlatform, nil, nil)
accountRole := &model.AccountRole{
AccountID: testAccount.ID,
RoleID: platformRole.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}
env.TX.Create(accountRole)
reqBody := dto.AssignRolesRequest{
RoleIDs: []uint{},
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestAccount_SuperAdminCannotAssignRoles(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
platformRole := env.CreateTestRole("禁止分配角色", constants.RoleTypePlatform)
superAdmin := env.CreateTestAccount("superadmin_role", "password123", constants.UserTypeSuperAdmin, nil, nil)
reqBody := dto.AssignRolesRequest{
RoleIDs: []uint{platformRole.ID},
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/accounts/%d/roles", superAdmin.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
var result response.Response
err = json.NewDecoder(resp.Body).Decode(&result)
require.NoError(t, err)
assert.Equal(t, errors.CodeInvalidParam, result.Code)
assert.Contains(t, result.Message, "超级管理员不允许分配角色")
}
func TestAccount_AssignRoles_Shop(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("代理角色测试店铺", 1, nil)
agentRole := env.CreateTestRole("代理角色", constants.RoleTypeCustomer)
testAccount := env.CreateTestAccount("role_agent", "password123", constants.UserTypeAgent, &testShop.ID, nil)
reqBody := dto.AssignRolesRequest{
RoleIDs: []uint{agentRole.ID},
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestAccount_GetRoles_Shop(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("代理获取角色测试店铺", 1, nil)
agentRole := env.CreateTestRole("代理获取角色", constants.RoleTypeCustomer)
testAccount := env.CreateTestAccount("role_agent_get", "password123", constants.UserTypeAgent, &testShop.ID, nil)
accountRole := &model.AccountRole{
AccountID: testAccount.ID,
RoleID: agentRole.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}
env.TX.Create(accountRole)
resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), nil)
require.NoError(t, err)
defer resp.Body.Close()
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 TestAccount_AssignRoles_Enterprise(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("企业角色测试店铺", 1, nil)
testEnterprise := env.CreateTestEnterprise("角色测试企业", &testShop.ID)
entRole := env.CreateTestRole("企业角色", constants.RoleTypeCustomer)
testAccount := env.CreateTestAccount("role_ent", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)
reqBody := dto.AssignRolesRequest{
RoleIDs: []uint{entRole.ID},
}
jsonBody, _ := json.Marshal(reqBody)
resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), jsonBody)
require.NoError(t, err)
defer resp.Body.Close()
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 TestAccount_GetRoles_Enterprise(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
testShop := env.CreateTestShop("企业获取角色测试店铺", 1, nil)
testEnterprise := env.CreateTestEnterprise("获取角色测试企业", &testShop.ID)
entRole := env.CreateTestRole("企业获取角色", constants.RoleTypeCustomer)
testAccount := env.CreateTestAccount("role_ent_get", "password123", constants.UserTypeEnterprise, nil, &testEnterprise.ID)
accountRole := &model.AccountRole{
AccountID: testAccount.ID,
RoleID: entRole.ID,
Status: constants.StatusEnabled,
Creator: 1,
Updater: 1,
}
env.TX.Create(accountRole)
resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/accounts/%d/roles", testAccount.ID), nil)
require.NoError(t, err)
defer resp.Body.Close()
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 TestAccount_Unauthorized_Platform(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
resp, err := env.ClearAuth().Request("GET", "/api/admin/accounts", nil)
require.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
}
func TestAccount_Unauthorized_Shop(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
resp, err := env.ClearAuth().Request("GET", "/api/admin/accounts", nil)
require.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
}
func TestAccount_Unauthorized_Enterprise(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
resp, err := env.ClearAuth().Request("GET", "/api/admin/accounts", nil)
require.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
}
func TestAccount_InvalidID(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/accounts/invalid", nil)
require.NoError(t, err)
defer resp.Body.Close()
var result response.Response
err = json.NewDecoder(resp.Body).Decode(&result)
require.NoError(t, err)
assert.Equal(t, errors.CodeInvalidParam, result.Code)
}
// =============================================================================
// 关联查询测试
// =============================================================================
func TestAccountList_FilterByShopID_WithShopName(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
shop1 := env.CreateTestShop("测试店铺A", 1, nil)
shop2 := env.CreateTestShop("测试店铺B", 1, nil)
account1 := env.CreateTestAccount("shop_account_1", "password123", constants.UserTypeAgent, &shop1.ID, nil)
account2 := env.CreateTestAccount("shop_account_2", "password123", constants.UserTypeAgent, &shop1.ID, nil)
account3 := env.CreateTestAccount("shop_account_3", "password123", constants.UserTypeAgent, &shop2.ID, nil)
url := fmt.Sprintf("/api/admin/accounts?shop_id=%d&page=1&page_size=10", shop1.ID)
resp, err := env.AsSuperAdmin().Request("GET", url, nil)
require.NoError(t, err)
defer resp.Body.Close()
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)
data := result.Data.(map[string]interface{})
items := data["items"].([]interface{})
assert.GreaterOrEqual(t, len(items), 2)
foundAccount1 := false
foundAccount2 := false
for _, item := range items {
accountData := item.(map[string]interface{})
accountID := uint(accountData["id"].(float64))
if accountID == account1.ID || accountID == account2.ID {
assert.Equal(t, float64(shop1.ID), accountData["shop_id"])
assert.Equal(t, shop1.ShopName, accountData["shop_name"])
if accountID == account1.ID {
foundAccount1 = true
}
if accountID == account2.ID {
foundAccount2 = true
}
}
if accountID == account3.ID {
t.Errorf("不应该返回 shop2 的账号,但返回了账号 %d", account3.ID)
}
}
assert.True(t, foundAccount1, "应该返回 account1")
assert.True(t, foundAccount2, "应该返回 account2")
}
func TestAccountList_FilterByEnterpriseID_WithEnterpriseName(t *testing.T) {
env := integ.NewIntegrationTestEnv(t)
shop := env.CreateTestShop("归属店铺", 1, nil)
enterprise1 := env.CreateTestEnterprise("测试企业A", &shop.ID)
enterprise2 := env.CreateTestEnterprise("测试企业B", &shop.ID)
account1 := env.CreateTestAccount("enterprise_account_1", "password123", constants.UserTypeEnterprise, nil, &enterprise1.ID)
account2 := env.CreateTestAccount("enterprise_account_2", "password123", constants.UserTypeEnterprise, nil, &enterprise2.ID)
url := fmt.Sprintf("/api/admin/accounts?enterprise_id=%d&page=1&page_size=10", enterprise1.ID)
resp, err := env.AsSuperAdmin().Request("GET", url, nil)
require.NoError(t, err)
defer resp.Body.Close()
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)
data := result.Data.(map[string]interface{})
items := data["items"].([]interface{})
assert.GreaterOrEqual(t, len(items), 1)
foundAccount1 := false
for _, item := range items {
accountData := item.(map[string]interface{})
accountID := uint(accountData["id"].(float64))
if accountID == account1.ID {
foundAccount1 = true
assert.Equal(t, float64(enterprise1.ID), accountData["enterprise_id"])
assert.Equal(t, enterprise1.EnterpriseName, accountData["enterprise_name"])
}
if accountID == account2.ID {
t.Errorf("不应该返回 enterprise2 的账号,但返回了账号 %d", account2.ID)
}
}
assert.True(t, foundAccount1, "应该返回 account1")
}