package echomeet import ( "testing" "yunyan/comm" ) // 编排选路的语言过滤(svcSupportsLanguage)回归: // 铁律沿袭「未知语言绝不 fallback」——languages 配置了就必须命中(精确或主语言段), // 防止重蹈「西语送进 paraformer-v2 静默返回空转写」的线上事故(该白名单现由后台 // 服务池 languages 字段承担,本测试钉住过滤语义)。 func TestSvcSupportsLanguage(t *testing.T) { aliLangs := []string{"zh-CN", "yue-CN", "en-US", "ja-JP", "ko-KR", "de-DE", "fr-FR", "ru-RU"} cases := []struct { langs []string want string ok bool }{ {aliLangs, "es-ES", false}, // 西语:阿里 paraformer-v2 不支持,必须被过滤 {aliLangs, "zh-CN", true}, {aliLangs, "zh", true}, // 主语言段命中 {aliLangs, "en-GB", true}, // en 主段命中 {aliLangs, "pt-BR", false}, {nil, "es-ES", true}, // 未配置 languages = 不限 {aliLangs, "", true}, // 空语言 = 不过滤(交给引擎自动检测) } for _, c := range cases { if got := svcSupportsLanguage(c.langs, c.want); got != c.ok { t.Errorf("svcSupportsLanguage(%v, %q) = %v, want %v", c.langs, c.want, got, c.ok) } } } // 作用域具体度(scopeRank)回归:(app,region) > (app,0) > ('',region) > ('',0), // 非本部署作用域链上的行必须是 0。 func TestScopeRank(t *testing.T) { const app, reg = "voitrans", int32(1) cases := []struct { appName string region int32 want int }{ {"voitrans", 1, 4}, {"voitrans", 0, 3}, {"", 1, 2}, {"", 0, 1}, {"otherapp", 1, 0}, // 别的应用 {"voitrans", 2, 0}, // 别的区域 } for _, c := range cases { if got := scopeRank(c.appName, c.region, app, reg); got != c.want { t.Errorf("scopeRank(%q,%d) = %d, want %d", c.appName, c.region, got, c.want) } } } // 区域覆盖合并 + 解密(resolveSvcFields)回归: // Overrides 覆盖默认值、ExtraFields 追加、DisabledKeys 剔除;加密字段解不开必须整体报错(fail-closed)。 func TestResolveSvcFields(t *testing.T) { const key = "test-field-encrypt-key" enc, err := comm.Encrypt(key, "sk-plain") if err != nil { t.Fatalf("encrypt: %v", err) } svc := &comm.ThirdSvcConfig{ Id: "asr1", Name: "阿里识别", Provider: "alibaba", Fields: []comm.SvcField{ {Key: "api_key", Encrypted: true, DefValue: enc}, {Key: "languages", DefValue: "zh-CN,en-US"}, {Key: "callback_path", DefValue: "/api/home/echomeet_alibackcall"}, {Key: "obsolete", DefValue: "x"}, }, } ovr := &comm.SvcRegionOverride{ SvcId: "asr1", Overrides: map[string]string{"languages": "ja-JP"}, ExtraFields: []comm.SvcField{{Key: "extra", DefValue: "y"}}, DisabledKeys: []string{"obsolete"}, } rs, err := resolveSvcFields(svc, ovr, key) if err != nil { t.Fatalf("resolve: %v", err) } if rs.Fields["api_key"] != "sk-plain" { t.Errorf("加密字段应解出明文, got %q", rs.Fields["api_key"]) } if len(rs.Languages) != 1 || rs.Languages[0] != "ja-JP" { t.Errorf("languages 应被区域覆盖为 ja-JP, got %v", rs.Languages) } if rs.Fields["extra"] != "y" { t.Errorf("ExtraFields 应追加") } if _, ok := rs.Fields["obsolete"]; ok { t.Errorf("DisabledKeys 应剔除 obsolete") } // fail-closed:错的 key 解不开必须报错,绝不把密文当明文用 if _, err := resolveSvcFields(svc, nil, "wrong-key"); err == nil { t.Errorf("错误密钥应整体报错(fail-closed),不能静默把密文当明文") } }