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 TestRoleAPI_Create(t *testing.T) { env := integ.NewIntegrationTestEnv(t) t.Run("成功创建角色", func(t *testing.T) { roleName := fmt.Sprintf("test_role_%d", time.Now().UnixNano()) reqBody := dto.CreateRoleRequest{ RoleName: roleName, RoleDesc: "这是一个测试角色", RoleType: constants.RoleTypePlatform, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/roles", jsonBody) require.NoError(t, err) var result response.Response err = json.NewDecoder(resp.Body).Decode(&result) require.NoError(t, err) t.Logf("响应状态码: %d, 业务码: %d, 消息: %s", resp.StatusCode, result.Code, result.Message) assert.Equal(t, fiber.StatusOK, resp.StatusCode) assert.Equal(t, 0, result.Code, "业务码应为0,实际消息: %s", result.Message) var count int64 env.RawDB().Model(&model.Role{}).Where("role_name = ?", roleName).Count(&count) t.Logf("查询角色 '%s' 数量: %d", roleName, count) assert.Equal(t, int64(1), count) }) t.Run("缺少必填字段返回错误", func(t *testing.T) { reqBody := map[string]interface{}{ "role_desc": "缺少名称", } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsSuperAdmin().Request("POST", "/api/admin/roles", jsonBody) require.NoError(t, err) var result response.Response json.NewDecoder(resp.Body).Decode(&result) assert.NotEqual(t, 0, result.Code) }) } func TestRoleAPI_Get(t *testing.T) { env := integ.NewIntegrationTestEnv(t) testRole := env.CreateTestRole("获取测试角色", constants.RoleTypePlatform) t.Run("成功获取角色详情", func(t *testing.T) { resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/roles/%d", testRole.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/roles/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.CodeRoleNotFound, result.Code) }) } func TestRoleAPI_Update(t *testing.T) { env := integ.NewIntegrationTestEnv(t) testRole := env.CreateTestRole("更新测试角色", constants.RoleTypePlatform) t.Run("成功更新角色", func(t *testing.T) { newName := "更新后角色" reqBody := dto.UpdateRoleRequest{ RoleName: &newName, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/roles/%d", testRole.ID), jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusOK, resp.StatusCode) var updated model.Role env.RawDB().First(&updated, testRole.ID) assert.Equal(t, newName, updated.RoleName) }) } func TestRoleAPI_Delete(t *testing.T) { env := integ.NewIntegrationTestEnv(t) t.Run("成功软删除角色", func(t *testing.T) { testRole := env.CreateTestRole("删除测试角色", constants.RoleTypePlatform) resp, err := env.AsSuperAdmin().Request("DELETE", fmt.Sprintf("/api/admin/roles/%d", testRole.ID), nil) require.NoError(t, err) assert.Equal(t, fiber.StatusOK, resp.StatusCode) var deleted model.Role err = env.RawDB().Unscoped().First(&deleted, testRole.ID).Error require.NoError(t, err) assert.NotNil(t, deleted.DeletedAt) }) } func TestRoleAPI_List(t *testing.T) { env := integ.NewIntegrationTestEnv(t) for i := 1; i <= 5; i++ { env.CreateTestRole(fmt.Sprintf("test_role_%d_%d", time.Now().UnixNano(), i), constants.RoleTypePlatform) } t.Run("成功获取角色列表", func(t *testing.T) { resp, err := env.AsSuperAdmin().Request("GET", "/api/admin/roles?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) }) } func TestRoleAPI_AssignPermissions(t *testing.T) { env := integ.NewIntegrationTestEnv(t) testRole := env.CreateTestRole("权限分配测试角色", constants.RoleTypePlatform) testPerm := env.CreateTestPermission("测试权限", "test:permission", constants.PermissionTypeMenu) t.Run("成功分配权限", func(t *testing.T) { reqBody := dto.AssignPermissionsRequest{ PermIDs: []uint{testPerm.ID}, } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsSuperAdmin().Request("POST", fmt.Sprintf("/api/admin/roles/%d/permissions", testRole.ID), jsonBody) require.NoError(t, err) assert.Equal(t, fiber.StatusOK, resp.StatusCode) var count int64 env.RawDB().Model(&model.RolePermission{}).Where("role_id = ? AND perm_id = ?", testRole.ID, testPerm.ID).Count(&count) assert.Equal(t, int64(1), count) }) } func TestRoleAPI_GetPermissions(t *testing.T) { env := integ.NewIntegrationTestEnv(t) testRole := env.CreateTestRole("获取权限测试角色", constants.RoleTypePlatform) testPerm := env.CreateTestPermission("获取权限测试", "get:permission:test", constants.PermissionTypeMenu) rolePerm := &model.RolePermission{ RoleID: testRole.ID, PermID: testPerm.ID, Status: constants.StatusEnabled, } env.TX.Create(rolePerm) t.Run("成功获取角色权限", func(t *testing.T) { resp, err := env.AsSuperAdmin().Request("GET", fmt.Sprintf("/api/admin/roles/%d/permissions", testRole.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) }) } func TestRoleAPI_RemovePermission(t *testing.T) { env := integ.NewIntegrationTestEnv(t) testRole := env.CreateTestRole("移除权限测试角色", constants.RoleTypePlatform) testPerm := env.CreateTestPermission("移除权限测试", "remove:permission:test", constants.PermissionTypeMenu) rolePerm := &model.RolePermission{ RoleID: testRole.ID, PermID: testPerm.ID, Status: constants.StatusEnabled, } env.TX.Create(rolePerm) t.Run("成功移除权限", func(t *testing.T) { resp, err := env.AsSuperAdmin().Request("DELETE", fmt.Sprintf("/api/admin/roles/%d/permissions/%d", testRole.ID, testPerm.ID), nil) require.NoError(t, err) assert.Equal(t, fiber.StatusOK, resp.StatusCode) var rp model.RolePermission err = env.RawDB().Unscoped().Where("role_id = ? AND perm_id = ?", testRole.ID, testPerm.ID).First(&rp).Error require.NoError(t, err) assert.NotNil(t, rp.DeletedAt) }) } func TestRoleAPI_UpdateStatus(t *testing.T) { env := integ.NewIntegrationTestEnv(t) testRole := env.CreateTestRole("状态切换测试角色", constants.RoleTypePlatform) t.Run("成功禁用角色", func(t *testing.T) { reqBody := dto.UpdateRoleStatusRequest{ Status: intPtr(constants.StatusDisabled), } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/roles/%d/status", testRole.ID), 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 updated model.Role env.RawDB().First(&updated, testRole.ID) assert.Equal(t, constants.StatusDisabled, updated.Status) }) t.Run("成功启用角色", func(t *testing.T) { reqBody := dto.UpdateRoleStatusRequest{ Status: intPtr(constants.StatusEnabled), } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsSuperAdmin().Request("PUT", fmt.Sprintf("/api/admin/roles/%d/status", testRole.ID), 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 updated model.Role env.RawDB().First(&updated, testRole.ID) assert.Equal(t, constants.StatusEnabled, updated.Status) }) t.Run("角色不存在返回错误", func(t *testing.T) { reqBody := dto.UpdateRoleStatusRequest{ Status: intPtr(constants.StatusEnabled), } jsonBody, _ := json.Marshal(reqBody) resp, err := env.AsSuperAdmin().Request("PUT", "/api/admin/roles/99999/status", jsonBody) require.NoError(t, err) var result response.Response err = json.NewDecoder(resp.Body).Decode(&result) require.NoError(t, err) assert.Equal(t, errors.CodeRoleNotFound, result.Code) }) } // intPtr 返回 int 的指针 func intPtr(v int) *int { return &v }