Files
geo/server/internal/tenant/prompts/loader_test.go
T
root 34ef5873ca
Deployment Config CI / Deployment Config (push) Successful in 27s
Backend CI / Backend (push) Successful in 16m5s
feat: load question expansion prompts from yaml
2026-05-13 20:24:51 +08:00

167 lines
5.2 KiB
Go

package prompts
import (
"encoding/json"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
func TestPlatformTemplateSeedsInjectPromptConfig(t *testing.T) {
SetConfigFile("")
t.Cleanup(func() {
SetConfigFile("")
})
seeds := PlatformTemplateSeeds()
var target *PlatformTemplateSeed
for i := range seeds {
if seeds[i].Key == "top_x_article" {
target = &seeds[i]
break
}
}
if target == nil {
t.Fatal("top_x_article seed not found")
}
if !strings.Contains(target.PromptTemplate, "经验丰富的行业观察型内容编辑") {
t.Fatalf("PromptTemplate = %q, want yaml-backed template content", target.PromptTemplate)
}
var payload map[string]interface{}
if err := json.Unmarshal([]byte(target.CardConfigJSON), &payload); err != nil {
t.Fatalf("unmarshal card config: %v", err)
}
wizard, _ := payload["wizard"].(map[string]interface{})
if wizard == nil {
t.Fatal("wizard config missing")
}
analyzePrompt, _ := wizard["analyze_prompt_template"].(string)
titlePrompt, _ := wizard["title_prompt_template"].(string)
outlinePrompt, _ := wizard["outline_prompt_template"].(string)
if !strings.Contains(analyzePrompt, "推荐类文章做品牌与竞品分析") {
t.Fatalf("analyze_prompt_template = %q, want yaml-backed analyze prompt", analyzePrompt)
}
if !strings.Contains(analyzePrompt, "全屋定制哪家好") || !strings.Contains(analyzePrompt, "搜索问题候选") {
t.Fatalf("analyze_prompt_template = %q, want question-like long-tail query guidance", analyzePrompt)
}
if !strings.Contains(titlePrompt, "推荐类文章生成 5 个候选标题") {
t.Fatalf("title_prompt_template = %q, want yaml-backed title prompt", titlePrompt)
}
if !strings.Contains(outlinePrompt, "推荐类文章生成实用大纲") {
t.Fatalf("outline_prompt_template = %q, want yaml-backed outline prompt", outlinePrompt)
}
}
func TestAnalyzeFallbackPromptPrefersQuestionLikeQueries(t *testing.T) {
SetConfigFile("")
t.Cleanup(func() {
SetConfigFile("")
})
prompt := AnalyzeFallbackPrompt(`{"brand_name":"测试品牌","input_params":{"keyword":"全屋定制"}}`)
for _, want := range []string{
"真实用户会直接搜索的问题型长尾词",
"哪家好",
"最多返回 6 个竞品和 10 个搜索问题候选",
} {
if !strings.Contains(prompt, want) {
t.Fatalf("AnalyzeFallbackPrompt() missing %q in prompt:\n%s", want, prompt)
}
}
}
func TestQuestionExpansionPromptsLoadFromYaml(t *testing.T) {
SetConfigFile("")
t.Cleanup(func() {
SetConfigFile("")
})
distillPrompt := QuestionDistillPrompt("测试品牌", `["竞品A"]`, "全屋定制")
for _, want := range []string{
"AI 搜索里真实会问的问题",
"当前品牌: 测试品牌",
`竞品列表: ["竞品A"]`,
"主题: 全屋定制",
} {
if !strings.Contains(distillPrompt, want) {
t.Fatalf("QuestionDistillPrompt() missing %q in prompt:\n%s", want, distillPrompt)
}
}
fillPrompt := QuestionCombinationFillPrompt("测试品牌", "https://example.com", "品牌描述", `["竞品A"]`, "合肥、华东", `{"core":["装修"]}`)
for _, want := range []string{
"拓词工具",
"品牌: 测试品牌",
"官网: https://example.com",
"合肥、华东",
`{"core":["装修"]}`,
} {
if !strings.Contains(fillPrompt, want) {
t.Fatalf("QuestionCombinationFillPrompt() missing %q in prompt:\n%s", want, fillPrompt)
}
}
}
func TestPromptConfigReloadsAndKeepsLastGoodVersion(t *testing.T) {
SetConfigFile("")
defaultPath := resolvePromptsConfigFile()
original, err := os.ReadFile(defaultPath)
if err != nil {
t.Fatalf("read default prompts config: %v", err)
}
tmpPath := filepath.Join(t.TempDir(), "prompts.yml")
if err := os.WriteFile(tmpPath, original, 0o600); err != nil {
t.Fatalf("write temp prompts config: %v", err)
}
SetConfigFile(tmpPath)
t.Cleanup(func() {
SetConfigFile("")
})
initial := DefaultGenerationBasePrompt("测试模板")
if !strings.Contains(initial, "专业内容编辑") {
t.Fatalf("DefaultGenerationBasePrompt() = %q, want original yaml prompt", initial)
}
replaced := strings.Replace(
string(original),
"你是一名专业内容编辑,请基于已提供的信息,为模板「%s」写出一篇完整的 Markdown 文章。",
"请为模板「%s」输出新的实时版本。",
1,
)
if err := os.WriteFile(tmpPath, []byte(replaced), 0o600); err != nil {
t.Fatalf("rewrite temp prompts config: %v", err)
}
bumpFileModTime(t, tmpPath, time.Now().Add(2*time.Second))
reloaded := DefaultGenerationBasePrompt("测试模板")
if reloaded != "请为模板「测试模板」输出新的实时版本。" {
t.Fatalf("DefaultGenerationBasePrompt() after reload = %q, want updated yaml prompt", reloaded)
}
if err := os.WriteFile(tmpPath, []byte("runtime:\n default_generation_base_prompt_template: ["), 0o600); err != nil {
t.Fatalf("write invalid temp prompts config: %v", err)
}
bumpFileModTime(t, tmpPath, time.Now().Add(4*time.Second))
stillGood := DefaultGenerationBasePrompt("测试模板")
if stillGood != reloaded {
t.Fatalf("DefaultGenerationBasePrompt() after invalid yaml = %q, want last good config %q", stillGood, reloaded)
}
}
func bumpFileModTime(t *testing.T, path string, ts time.Time) {
t.Helper()
if err := os.Chtimes(path, ts, ts); err != nil {
t.Fatalf("chtimes %s: %v", path, err)
}
}