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/dto" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/response" "github.com/break/junhong_cmp_fiber/tests/testutils/integ" ) // TestAccountPermission_12_2 企业账号访问账号管理接口被路由层拦截 func TestAccountPermission_12_2(t *testing.T) { env := integ.NewIntegrationTestEnv(t) shop := env.CreateTestShop("测试店铺", 1, nil) enterprise := env.CreateTestEnterprise("测试企业", &shop.ID) enterpriseAccount := env.CreateTestAccount( "enterprise_user", "password123", constants.UserTypeEnterprise, nil, &enterprise.ID, ) reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("test_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypeEnterprise, EnterpriseID: &enterprise.ID, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsUser(enterpriseAccount).Request("POST", "/api/admin/accounts", jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusForbidden, resp.StatusCode, "企业账号应被路由层拦截") var result response.Response err = json.NewDecoder(resp.Body).Decode(&result) require.NoError(t, err) assert.Contains(t, result.Message, "权限", "错误消息应包含权限相关信息") } // TestAccountPermission_12_3 代理账号创建自己店铺的账号成功 func TestAccountPermission_12_3(t *testing.T) { env := integ.NewIntegrationTestEnv(t) shop := env.CreateTestShop("代理店铺1", 1, nil) agentAccount := env.CreateTestAccount( "agent_user", "password123", constants.UserTypeAgent, &shop.ID, nil, ) reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("agent_same_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypeAgent, ShopID: &shop.ID, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsUser(agentAccount).Request("POST", "/api/admin/accounts", 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, "业务码应为0") } // TestAccountPermission_12_4 代理账号创建下级店铺的账号成功 func TestAccountPermission_12_4(t *testing.T) { env := integ.NewIntegrationTestEnv(t) parentShop := env.CreateTestShop("父店铺", 1, nil) childShop := env.CreateTestShop("子店铺", 2, &parentShop.ID) agentAccount := env.CreateTestAccount( "agent_parent", "password123", constants.UserTypeAgent, &parentShop.ID, nil, ) reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("agent_child_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypeAgent, ShopID: &childShop.ID, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsUser(agentAccount).Request("POST", "/api/admin/accounts", 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, "业务码应为0") } // TestAccountPermission_12_5 代理账号创建其他店铺的账号失败 func TestAccountPermission_12_5(t *testing.T) { env := integ.NewIntegrationTestEnv(t) shop1 := env.CreateTestShop("独立店铺1", 1, nil) shop2 := env.CreateTestShop("独立店铺2", 1, nil) agentAccount := env.CreateTestAccount( "agent_shop1", "password123", constants.UserTypeAgent, &shop1.ID, nil, ) reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("agent_other_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypeAgent, ShopID: &shop2.ID, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsUser(agentAccount).Request("POST", "/api/admin/accounts", jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusForbidden, resp.StatusCode, "代理账号不应能创建其他店铺的账号") var result response.Response err = json.NewDecoder(resp.Body).Decode(&result) require.NoError(t, err) assert.Contains(t, result.Message, "权限", "错误消息应包含权限相关信息") } // TestAccountPermission_12_6 代理账号创建平台账号失败 func TestAccountPermission_12_6(t *testing.T) { env := integ.NewIntegrationTestEnv(t) shop := env.CreateTestShop("代理店铺", 1, nil) agentAccount := env.CreateTestAccount( "agent_try_platform", "password123", constants.UserTypeAgent, &shop.ID, nil, ) reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("platform_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypePlatform, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsUser(agentAccount).Request("POST", "/api/admin/accounts", jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusForbidden, resp.StatusCode, "代理账号不应能创建平台账号") var result response.Response err = json.NewDecoder(resp.Body).Decode(&result) require.NoError(t, err) assert.Contains(t, result.Message, "权限", "错误消息应包含权限相关信息") } // TestAccountPermission_12_7 平台账号创建任意类型账号成功 func TestAccountPermission_12_7(t *testing.T) { env := integ.NewIntegrationTestEnv(t) shop := env.CreateTestShop("平台测试店铺", 1, nil) platformAccount := env.CreateTestAccount( "platform_user", "password123", constants.UserTypePlatform, nil, nil, ) t.Run("创建平台账号", func(t *testing.T) { reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("platform_new_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypePlatform, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsUser(platformAccount).Request("POST", "/api/admin/accounts", jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusOK, resp.StatusCode, "平台账号应能创建平台账号") }) t.Run("创建代理账号", func(t *testing.T) { time.Sleep(time.Millisecond) reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("agent_new_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypeAgent, ShopID: &shop.ID, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsUser(platformAccount).Request("POST", "/api/admin/accounts", jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusOK, resp.StatusCode, "平台账号应能创建代理账号") }) } // TestAccountPermission_12_8 超级管理员创建任意类型账号成功 func TestAccountPermission_12_8(t *testing.T) { env := integ.NewIntegrationTestEnv(t) shop := env.CreateTestShop("超管测试店铺", 1, nil) enterprise := env.CreateTestEnterprise("超管测试企业", &shop.ID) t.Run("创建平台账号", func(t *testing.T) { reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("superadmin_platform_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypePlatform, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusOK, resp.StatusCode, "超级管理员应能创建平台账号") }) t.Run("创建代理账号", func(t *testing.T) { time.Sleep(time.Millisecond) reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("superadmin_agent_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypeAgent, ShopID: &shop.ID, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusOK, resp.StatusCode, "超级管理员应能创建代理账号") }) t.Run("创建企业账号", func(t *testing.T) { time.Sleep(time.Millisecond) reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("superadmin_ent_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypeEnterprise, EnterpriseID: &enterprise.ID, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/accounts", jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusOK, resp.StatusCode, "超级管理员应能创建企业账号") }) } // TestAccountPermission_12_9 查询不存在的账号返回统一错误 func TestAccountPermission_12_9(t *testing.T) { env := integ.NewIntegrationTestEnv(t) shop := env.CreateTestShop("查询测试店铺", 1, nil) agentAccount := env.CreateTestAccount( "agent_query", "password123", constants.UserTypeAgent, &shop.ID, nil, ) resp, err := env.AsUser(agentAccount).Request("GET", "/api/admin/accounts/99999", nil) require.NoError(t, err) // GORM 自动过滤后,查询不存在的账号返回 "账号不存在" (400) // 或 "无权限操作该资源或资源不存在" (403) assert.True(t, resp.StatusCode == fiber.StatusBadRequest || resp.StatusCode == fiber.StatusForbidden || resp.StatusCode == fiber.StatusNotFound, "查询不存在的账号应返回错误状态码") var result response.Response err = json.NewDecoder(resp.Body).Decode(&result) require.NoError(t, err) assert.NotEqual(t, 0, result.Code, "业务码应不为0") } // TestAccountPermission_12_10 查询越权的账号返回相同错误消息 func TestAccountPermission_12_10(t *testing.T) { env := integ.NewIntegrationTestEnv(t) shop1 := env.CreateTestShop("越权测试店铺1", 1, nil) shop2 := env.CreateTestShop("越权测试店铺2", 1, nil) agentAccount1 := env.CreateTestAccount( "agent_auth1", "password123", constants.UserTypeAgent, &shop1.ID, nil, ) agentAccount2 := env.CreateTestAccount( "agent_auth2", "password123", constants.UserTypeAgent, &shop2.ID, nil, ) resp, err := env.AsUser(agentAccount1).Request( "GET", fmt.Sprintf("/api/admin/accounts/%d", agentAccount2.ID), nil, ) require.NoError(t, err) // GORM 自动过滤使越权查询返回与不存在相同的错误,防止信息泄露 assert.True(t, resp.StatusCode == fiber.StatusBadRequest || resp.StatusCode == fiber.StatusForbidden || resp.StatusCode == fiber.StatusNotFound, "查询越权账号应返回错误状态码") var result response.Response err = json.NewDecoder(resp.Body).Decode(&result) require.NoError(t, err) assert.NotEqual(t, 0, result.Code, "业务码应不为0") } // TestAccountPermission_12_11 代理账号更新其他店铺的账号失败 func TestAccountPermission_12_11(t *testing.T) { env := integ.NewIntegrationTestEnv(t) shop1 := env.CreateTestShop("更新测试店铺1", 1, nil) shop2 := env.CreateTestShop("更新测试店铺2", 1, nil) agentAccount1 := env.CreateTestAccount( "agent_update1", "password123", constants.UserTypeAgent, &shop1.ID, nil, ) agentAccount2 := env.CreateTestAccount( "agent_update2", "password123", constants.UserTypeAgent, &shop2.ID, nil, ) newUsername := "updated_username" reqBody := dto.UpdateAccountRequest{ Username: &newUsername, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsUser(agentAccount1).Request( "PUT", fmt.Sprintf("/api/admin/accounts/%d", agentAccount2.ID), jsonBody, ) require.NoError(t, err) assert.Equal(t, fiber.StatusForbidden, resp.StatusCode, "代理账号不应能更新其他店铺的账号") var result response.Response err = json.NewDecoder(resp.Body).Decode(&result) require.NoError(t, err) assert.Contains(t, result.Message, "权限", "错误消息应包含权限相关信息") } // TestEnterpriseAccountRouteBlocking 测试企业账号访问各类型账号管理接口的路由层拦截 func TestEnterpriseAccountRouteBlocking(t *testing.T) { env := integ.NewIntegrationTestEnv(t) shop := env.CreateTestShop("路由拦截测试店铺", 1, nil) enterprise := env.CreateTestEnterprise("路由拦截测试企业", &shop.ID) enterpriseAccount := env.CreateTestAccount( "enterprise_route_test", "password123", constants.UserTypeEnterprise, nil, &enterprise.ID, ) t.Run("企业账号访问企业账号列表接口被拦截", func(t *testing.T) { resp, err := env.AsUser(enterpriseAccount).Request("GET", "/api/admin/accounts", nil) require.NoError(t, err) assert.Equal(t, fiber.StatusForbidden, resp.StatusCode) }) t.Run("企业账号访问企业账号详情接口被拦截", func(t *testing.T) { resp, err := env.AsUser(enterpriseAccount).Request("GET", "/api/admin/accounts/1", nil) require.NoError(t, err) assert.Equal(t, fiber.StatusForbidden, resp.StatusCode) }) t.Run("企业账号访问创建企业账号接口被拦截", func(t *testing.T) { reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("test_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypeEnterprise, EnterpriseID: &enterprise.ID, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsUser(enterpriseAccount).Request("POST", "/api/admin/accounts", jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusForbidden, resp.StatusCode) }) } // TestAgentAccountHierarchyPermission 测试代理账号的层级权限 func TestAgentAccountHierarchyPermission(t *testing.T) { env := integ.NewIntegrationTestEnv(t) level1Shop := env.CreateTestShop("一级店铺", 1, nil) level2Shop := env.CreateTestShop("二级店铺", 2, &level1Shop.ID) level3Shop := env.CreateTestShop("三级店铺", 3, &level2Shop.ID) level2Agent := env.CreateTestAccount( "level2_agent", "password123", constants.UserTypeAgent, &level2Shop.ID, nil, ) t.Run("二级代理可以管理三级店铺账号", func(t *testing.T) { reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("level3_new_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypeAgent, ShopID: &level3Shop.ID, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsUser(level2Agent).Request("POST", "/api/admin/accounts", jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusOK, resp.StatusCode, "二级代理应能管理三级店铺账号") }) t.Run("二级代理不能管理一级店铺账号", func(t *testing.T) { reqBody := dto.CreateAccountRequest{ Username: fmt.Sprintf("level1_new_%d", time.Now().UnixNano()), Phone: fmt.Sprintf("138%08d", time.Now().UnixNano()%100000000), Password: "Password123", UserType: constants.UserTypeAgent, ShopID: &level1Shop.ID, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsUser(level2Agent).Request("POST", "/api/admin/accounts", jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusForbidden, resp.StatusCode, "二级代理不应能管理一级店铺账号") }) }