PR #5666 引入 CN 平台后,路由/调度/前端类型均已支持 CN 平台分组,但分组 创建入口两头缺失:后端 Create/UpdateGroupRequest 的 platform oneof 白名单 与前端 GroupsView 平台选项都没有三平台,导致 CN 账号「无可用分组」、整条 流量链路不通(composite 不能作为替代:CN 不可为 composite 路由目标)。 - group_handler.go: 两处 oneof 加 kimi/zhipu/deepseek;composite 路由目标 白名单有意不动(DetectModelPlatform/isConcreteRequestPlatform 均无 CN 分支) - GroupsView: platformOptions/platformFilterOptions 补三项;两处徽章配色链 按 platformColors.ts 色系补 CN 分支 - i18n: admin.groups.platforms 补 kimi/zhipu/deepseek 键(zh/en),缺键时 分组徽章/GroupRPM/RateMultipliers 弹窗/ChannelsView 会渲染原始 key - GroupBadge: badgeClass/labelClass 补 CN 配色 - 新增表驱动测试:9 平台 Create/Update 全放行、非法值(别名/大小写/空格) 全拒绝、composite target 对 CN 保持拒绝的守卫
84 lines
2.9 KiB
Go
84 lines
2.9 KiB
Go
//go:build unit
|
||
|
||
package admin
|
||
|
||
import (
|
||
"bytes"
|
||
"fmt"
|
||
"net/http/httptest"
|
||
"testing"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/stretchr/testify/require"
|
||
)
|
||
|
||
// 回归分组平台枚举:kimi/zhipu/deepseek 必须能通过 Create/Update 的 binding 校验
|
||
// (历史 bug:调度/路由链路已支持 CN 平台分组,但 oneof 白名单漏加三平台,导致
|
||
// 平台分组无法创建、CN 账号"无可用分组");非法值仍须被拒。
|
||
func bindGroupPlatformJSON(t *testing.T, target any, body string) error {
|
||
t.Helper()
|
||
gin.SetMode(gin.TestMode)
|
||
c, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||
c.Request = httptest.NewRequest("POST", "/", bytes.NewBufferString(body))
|
||
c.Request.Header.Set("Content-Type", "application/json")
|
||
return c.ShouldBindJSON(target)
|
||
}
|
||
|
||
func TestGroupPlatformBinding_AllowedPlatforms(t *testing.T) {
|
||
allowed := []string{
|
||
"anthropic", "openai", "gemini", "antigravity", "grok",
|
||
"kimi", "zhipu", "deepseek", "composite",
|
||
}
|
||
for _, platform := range allowed {
|
||
t.Run("create_"+platform, func(t *testing.T) {
|
||
var req CreateGroupRequest
|
||
body := fmt.Sprintf(`{"name":"g","platform":%q}`, platform)
|
||
require.NoError(t, bindGroupPlatformJSON(t, &req, body),
|
||
"platform %q 应通过 CreateGroupRequest 校验", platform)
|
||
require.Equal(t, platform, req.Platform)
|
||
})
|
||
t.Run("update_"+platform, func(t *testing.T) {
|
||
var req UpdateGroupRequest
|
||
body := fmt.Sprintf(`{"platform":%q}`, platform)
|
||
require.NoError(t, bindGroupPlatformJSON(t, &req, body),
|
||
"platform %q 应通过 UpdateGroupRequest 校验", platform)
|
||
require.Equal(t, platform, req.Platform)
|
||
})
|
||
}
|
||
}
|
||
|
||
func TestGroupPlatformBinding_RejectsInvalidPlatforms(t *testing.T) {
|
||
invalid := []string{
|
||
"moonshot", // 厂商别名,不是平台标识
|
||
"Kimi", // 大小写敏感
|
||
"openai ", // 尾随空格
|
||
"glm",
|
||
"bogus",
|
||
}
|
||
for _, platform := range invalid {
|
||
t.Run("create_"+platform, func(t *testing.T) {
|
||
var req CreateGroupRequest
|
||
body := fmt.Sprintf(`{"name":"g","platform":%q}`, platform)
|
||
require.Error(t, bindGroupPlatformJSON(t, &req, body),
|
||
"platform %q 应被 CreateGroupRequest 拒绝", platform)
|
||
})
|
||
t.Run("update_"+platform, func(t *testing.T) {
|
||
var req UpdateGroupRequest
|
||
body := fmt.Sprintf(`{"platform":%q}`, platform)
|
||
require.Error(t, bindGroupPlatformJSON(t, &req, body),
|
||
"platform %q 应被 UpdateGroupRequest 拒绝", platform)
|
||
})
|
||
}
|
||
}
|
||
|
||
// 守住 composite 路由目标不放行 CN:CN 平台不可作为 composite 路由目标
|
||
// (DetectModelPlatform/isConcreteRequestPlatform 均无 CN 分支,放行即打开半实现路径)。
|
||
func TestCompositeRouteTargetPlatform_StillExcludesCNProviders(t *testing.T) {
|
||
for _, platform := range []string{"kimi", "zhipu", "deepseek"} {
|
||
var req CompositeRouteRequest
|
||
body := fmt.Sprintf(`{"public_model":"m","target_platform":%q}`, platform)
|
||
require.Error(t, bindGroupPlatformJSON(t, &req, body),
|
||
"composite target_platform %q 应保持被拒", platform)
|
||
}
|
||
}
|