diff --git a/service/model_resolve_test.go b/service/model_resolve_test.go deleted file mode 100644 index 2bbc5d8..0000000 --- a/service/model_resolve_test.go +++ /dev/null @@ -1,170 +0,0 @@ -package service - -import ( - "testing" - - "model-gateway/model/entity" - - "gitea.redpowerfuture.com/red-future/common/beans" - "github.com/gogf/gf/v2/util/gconv" -) - -func TestReplacePlaceholder(t *testing.T) { - if got := replacePlaceholder("Bearer {apiKey}", "{apiKey}", "sk-1"); got != "Bearer sk-1" { - t.Fatalf("string: %v", got) - } - got := replacePlaceholder(map[string]any{ - "url": "https://x.com?key={apiKey}", - "n": 1, - "sub": map[string]any{"k": "v-{apiKey}"}, - "list": []any{"a-{apiKey}", 2}, - }, "{apiKey}", "sk-9") - m, ok := got.(map[string]any) - if !ok { - t.Fatalf("not map: %T", got) - } - if m["url"] != "https://x.com?key=sk-9" { - t.Fatalf("url: %v", m["url"]) - } - if m["n"] != 1 { - t.Fatalf("n: %v", m["n"]) - } - if m["sub"].(map[string]any)["k"] != "v-sk-9" { - t.Fatalf("sub: %v", m["sub"]) - } - if m["list"].([]any)[0] != "a-sk-9" { - t.Fatalf("list[0]: %v", m["list"]) - } -} - -func TestSubstituteAPIPlaceholder(t *testing.T) { - m := &entity.ModelManage{ - BaseURL: "https://api.xx.com?key={apiKey}", - RequestHeadMapping: map[string]string{"Authorization": "Bearer {apiKey}"}, - RequestBodyMapping: map[string]any{"model": "{apiKey}"}, - RequestBusinessFieldMapping: map[string]string{"key": "{apiKey}"}, - AsyncTaskMapping: &entity.AsyncTaskMapping{ - Url: "https://api.xx.com/task/{taskId}?key={apiKey}", - RequestBodyMapping: map[string]any{"auth": "{apiKey}"}, - }, - } - substituteAPIPlaceholder(m, "sk-user") - if m.BaseURL != "https://api.xx.com?key=sk-user" { - t.Fatalf("baseURL: %s", m.BaseURL) - } - if m.RequestHeadMapping["Authorization"] != "Bearer sk-user" { - t.Fatalf("head: %s", m.RequestHeadMapping["Authorization"]) - } - if m.RequestBodyMapping["model"] != "sk-user" { - t.Fatalf("body: %v", m.RequestBodyMapping["model"]) - } - if m.RequestBusinessFieldMapping["key"] != "sk-user" { - t.Fatalf("biz: %v", m.RequestBusinessFieldMapping["key"]) - } - if m.AsyncTaskMapping.Url != "https://api.xx.com/task/{taskId}?key=sk-user" { - t.Fatalf("async url: %s", m.AsyncTaskMapping.Url) - } - if m.AsyncTaskMapping.RequestBodyMapping["auth"] != "sk-user" { - t.Fatalf("async body: %v", m.AsyncTaskMapping.RequestBodyMapping["auth"]) - } -} - -func TestMergeReferenceConfig(t *testing.T) { - sys := &entity.ModelManage{ - SQLBaseDO: beans.SQLBaseDO{Id: 100}, BaseURL: "https://sys", SystemModel: gconv.PtrBool(true), - Enabled: gconv.PtrBool(true), RequestHeadMapping: map[string]string{"Authorization": "Bearer {apiKey}"}, - } - stub := &entity.ModelManage{RefSystemModelId: 100, ApiKey: "sk-user", Enabled: gconv.PtrBool(true), ChatModel: gconv.PtrBool(true)} - - out := mergeReferenceConfig(stub, sys) - if out.Id != 100 { - t.Fatalf("id: %d", out.Id) - } - if out.ApiKey != "sk-user" { - t.Fatalf("apiKey: %s", out.ApiKey) - } - if out.ChatModel == nil || !*out.ChatModel { - t.Fatalf("chatModel should follow stub") - } - if out.BaseURL != "https://sys" { - t.Fatalf("baseURL should follow sys: %s", out.BaseURL) - } - - // 系统停用 → 引用失效 - sysOff := &entity.ModelManage{Enabled: gconv.PtrBool(false)} - if out := mergeReferenceConfig(stub, sysOff); out.Enabled == nil || *out.Enabled { - t.Fatalf("system disabled should gate reference") - } - // 引用行停用 → 停用 - stubOff := &entity.ModelManage{Enabled: gconv.PtrBool(false)} - if out := mergeReferenceConfig(stubOff, sys); out.Enabled == nil || *out.Enabled { - t.Fatalf("stub disabled should gate") - } - // 引用行未设 enabled → 用系统行 - stubNil := &entity.ModelManage{ApiKey: "sk-user"} - if out := mergeReferenceConfig(stubNil, sys); out.Enabled == nil || !*out.Enabled { - t.Fatalf("stub nil enabled should follow sys") - } -} - -func TestMergeReferenceConfigForQuery(t *testing.T) { - sys := &entity.ModelManage{ - SQLBaseDO: beans.SQLBaseDO{Id: 100, Creator: "admin"}, BaseURL: "https://sys", - SystemModel: gconv.PtrBool(true), Enabled: gconv.PtrBool(false), - RequestHeadMapping: map[string]string{"Authorization": "Bearer {apiKey}"}, - TokenMapping: &entity.TokenMapping{PromptTokens: "a"}, - } - stub := &entity.ModelManage{ - SQLBaseDO: beans.SQLBaseDO{Id: 200, Creator: "user"}, RefSystemModelId: 100, - SystemModel: gconv.PtrBool(false), Enabled: gconv.PtrBool(true), ApiKey: "sk-user", - } - - out := mergeReferenceConfigForQuery(stub, sys) - // 保留引用行自身身份字段 - if out.Id != 200 { - t.Fatalf("id should keep stub: %d", out.Id) - } - if out.RefSystemModelId != 100 { - t.Fatalf("refSystemModelId should keep stub: %d", out.RefSystemModelId) - } - if out.Creator != "user" { - t.Fatalf("creator should keep stub: %s", out.Creator) - } - if out.SystemModel == nil || *out.SystemModel { - t.Fatalf("systemModel should keep stub (false)") - } - // 配置列合入系统行 - if out.BaseURL != "https://sys" { - t.Fatalf("baseURL should follow sys: %s", out.BaseURL) - } - if out.RequestHeadMapping["Authorization"] != "Bearer {apiKey}" { - t.Fatalf("head mapping should follow sys template (不替换占位): %v", out.RequestHeadMapping) - } - if out.TokenMapping == nil || out.TokenMapping.PromptTokens != "a" { - t.Fatalf("tokenMapping should follow sys") - } - // 个人字段保留引用行(不做系统 enabled 的 AND 门禁) - if out.ApiKey != "sk-user" { - t.Fatalf("apiKey should keep stub: %s", out.ApiKey) - } - if out.Enabled == nil || !*out.Enabled { - t.Fatalf("enabled should keep stub (系统停用不在此门禁)") - } -} - -func TestResolveModelConfigNonReference(t *testing.T) { - m := &entity.ModelManage{SQLBaseDO: beans.SQLBaseDO{Id: 5}, BaseURL: "https://x?key={apiKey}", ApiKey: "sk-sys"} - out, err := resolveModelConfig(nil, m) // 非引用路径不触 DB,ctx 可为 nil - if err != nil { - t.Fatalf("err: %v", err) - } - if out.BaseURL != "https://x?key=sk-sys" { - t.Fatalf("baseURL: %s", out.BaseURL) - } - if out.Id != 5 { - t.Fatalf("id: %d", out.Id) - } - if out == m { - t.Fatalf("should return a copy, not mutate input") - } -}