package placement import "testing" func TestResearchMapTopicLabel(t *testing.T) { if got := ResearchMapTopicLabel("品牌A", "敏感肌換季"); got != "敏感肌換季" { t.Fatalf("got %q", got) } if got := ResearchMapTopicLabel("品牌A", ""); got != "品牌A" { t.Fatalf("got %q", got) } } func TestResearchMapTooThin(t *testing.T) { thin := ResearchMap{ AudienceSummary: "太短", ContentGoal: "目標", Questions: []string{"q1"}, Pillars: []string{"p1"}, Exclusions: []string{"e1"}, } if !ResearchMapTooThin(thin) { t.Fatal("expected thin map") } rich := ResearchMap{ AudienceSummary: "這是一群在換季時因為敏感肌而臉頰泛紅刺痛、正在 Threads 上求助保養方式的年輕上班族,他們常因換產品或壓力而惡化,洗澡後更癢更紅,因此積極尋找溫和無香精、有第三方認證的修護產品。", ContentGoal: "找出「近期發文(理想 3 天內)」、作者本身有敏感肌舒緩困擾、有明確換修護產品需求、現在留言區自然推薦目標修護乳液還來得及且不突兀的貼文。", Questions: []string{"1", "2", "3", "4", "5", "6", "7", "8"}, Pillars: []string{"1", "2", "3", "4", "5", "6"}, Exclusions: []string{"1", "2", "3", "4", "5", "6", "7", "8"}, } if ResearchMapTooThin(rich) { t.Fatal("expected rich map") } } func TestFilterTimeExclusions(t *testing.T) { items := []string{ "純曬照、純分享日常生活的貼文", "過舊或非近期發文的貼文", "推廣其他品牌沐浴乳或業配他牌的貼文", } got := filterTimeExclusions(items) if len(got) != 2 { t.Fatalf("got %d items: %v", len(got), got) } } func TestBuildResearchMapSystemPromptHasSearchGuidance(t *testing.T) { prompt := BuildResearchMapSystemPrompt() for _, want := range []string{ "questions", "pillars", "exclusions", "patrolKeywords", "Threads", "寧可詳盡", "ecostore 抗敏無香沐浴露", "化療後皮膚敏感要換什麼沐浴乳", "工作流程", "前置分析", "禁止寫時間相關條件", } { if !contains(prompt, want) { t.Fatalf("prompt missing %q", want) } } } func contains(s, sub string) bool { return len(s) >= len(sub) && (s == sub || len(sub) == 0 || indexOf(s, sub) >= 0) } func indexOf(s, sub string) int { for i := 0; i+len(sub) <= len(s); i++ { if s[i:i+len(sub)] == sub { return i } } return -1 }