2026-04-23 09:11:53 +08:00
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-23 22:54:56 +08:00
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-23 09:11:53 +08:00
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-23 22:54:56 +08:00
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|