package app import ( "encoding/json" "testing" ) func TestBuildMonitoringRawPayloadKimiExcludesSearchResultsFromCitationInputs(t *testing.T) { citationTitle := "真实引用文章" searchTitle := "搜索网页结果" req := MonitoringTaskResultRequest{ Status: "succeeded", Citations: []MonitoringSourceItem{ { URL: "https://example.com/citation", Title: &citationTitle, }, }, SearchResults: []MonitoringSourceItem{ { URL: "https://example.com/search", Title: &searchTitle, }, }, } rawPayload, sourceInputs := buildMonitoringRawPayload("kimi", req) if len(sourceInputs) != 1 { t.Fatalf("buildMonitoringRawPayload() sourceInputs len = %d, want 1", len(sourceInputs)) } for _, item := range sourceInputs { if item.URL != "https://example.com/citation" { t.Fatalf("buildMonitoringRawPayload() source url = %q, want citation url", item.URL) } } var payload map[string]interface{} if err := json.Unmarshal(rawPayload, &payload); err != nil { t.Fatalf("json.Unmarshal(rawPayload) error = %v", err) } if got := len(extractMonitoringSourceItems(payload["search_results"])); got != 1 { t.Fatalf("stored search_results len = %d, want 1", got) } } func TestBuildMonitoringRawPayloadQwenIncludesSearchResultsInCitationInputs(t *testing.T) { searchTitle := "搜索网页结果" req := MonitoringTaskResultRequest{ Status: "succeeded", SearchResults: []MonitoringSourceItem{ { URL: "https://example.com/search", Title: &searchTitle, }, }, } _, sourceInputs := buildMonitoringRawPayload("qwen", req) if len(sourceInputs) != 1 { t.Fatalf("buildMonitoringRawPayload() sourceInputs len = %d, want 1", len(sourceInputs)) } for _, item := range sourceInputs { if item.URL != "https://example.com/search" { t.Fatalf("buildMonitoringRawPayload() source url = %q, want search url", item.URL) } } } func TestBuildMonitoringRawPayloadDeepSeekIncludesSearchResultsInCitationInputs(t *testing.T) { searchTitle := "搜索网页结果" req := MonitoringTaskResultRequest{ Status: "succeeded", SearchResults: []MonitoringSourceItem{ { URL: "https://example.com/search", Title: &searchTitle, }, }, } _, sourceInputs := buildMonitoringRawPayload("deepseek", req) if len(sourceInputs) != 1 { t.Fatalf("buildMonitoringRawPayload() sourceInputs len = %d, want 1", len(sourceInputs)) } for _, item := range sourceInputs { if item.URL != "https://example.com/search" { t.Fatalf("buildMonitoringRawPayload() source url = %q, want search url", item.URL) } } } func TestExtractMonitoringInlineCitationsFromRawResponseKimi(t *testing.T) { raw := []byte(`{ "inline_citation_candidates": [ { "url": "https://example.com/a#ref", "title": "文章 A", "site_name": "示例站点" }, { "url": "https://example.com/a#other", "title": "文章 A", "site_name": "示例站点" }, { "url": "https://example.com/b", "title": "文章 B", "site_name": "另一个站点" } ] }`) items := extractMonitoringInlineCitationsFromRawResponse(raw, "kimi") if len(items) != 2 { t.Fatalf("extractMonitoringInlineCitationsFromRawResponse() len = %d, want 2", len(items)) } if items[0].URL != "https://example.com/a" { t.Fatalf("extractMonitoringInlineCitationsFromRawResponse() first url = %q, want https://example.com/a", items[0].URL) } if items[1].URL != "https://example.com/b" { t.Fatalf("extractMonitoringInlineCitationsFromRawResponse() second url = %q, want https://example.com/b", items[1].URL) } } func TestExtractMonitoringInlineCitationsFromRawResponseDeepSeekFallsBackToInlineLinks(t *testing.T) { raw := []byte(`{ "inline_links": [ { "url": "https://example.com/a#cite-1", "text": "-1", "siteName": "示例站点" }, { "url": "https://example.com/b", "title": "文章 B", "siteName": "另一个站点" } ] }`) items := extractMonitoringInlineCitationsFromRawResponse(raw, "deepseek") if len(items) != 2 { t.Fatalf("extractMonitoringInlineCitationsFromRawResponse() len = %d, want 2", len(items)) } if items[0].URL != "https://example.com/a" { t.Fatalf("extractMonitoringInlineCitationsFromRawResponse() first url = %q, want https://example.com/a", items[0].URL) } if items[0].SiteName == nil || *items[0].SiteName != "示例站点" { t.Fatalf("extractMonitoringInlineCitationsFromRawResponse() first site = %v, want 示例站点", items[0].SiteName) } if items[1].Title == nil || *items[1].Title != "文章 B" { t.Fatalf("extractMonitoringInlineCitationsFromRawResponse() second title = %v, want 文章 B", items[1].Title) } }