Files
sub2api/backend/internal/service/content_moderation_input_test.go
T

180 lines
5.4 KiB
Go
Raw Normal View History

package service
import (
"testing"
"github.com/stretchr/testify/require"
)
// 当数组末尾不是用户消息时(典型场景:Agent 工具循环结束于 tool/assistant),
// 应直接跳过审计——不再回溯查找历史中的某条用户消息。
func TestExtractContentModerationInput_AnthropicAgentToolLoopSkipsAudit(t *testing.T) {
body := []byte(`{
"messages": [
{"role":"user","content":"调用一下天气工具"},
{"role":"assistant","content":[{"type":"tool_use","id":"tool_1","name":"weather","input":{}}]},
{"role":"user","content":[{"type":"tool_result","tool_use_id":"tool_1","content":"晴 25 度"}]}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolAnthropicMessages, body)
require.Empty(t, input.Text)
require.Empty(t, input.Images)
}
func TestExtractContentModerationInput_AnthropicFirstTurnExtractsUser(t *testing.T) {
body := []byte(`{
"messages": [
{"role":"user","content":"Q1"}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolAnthropicMessages, body)
require.Equal(t, "Q1", input.Text)
}
func TestExtractContentModerationInput_AnthropicMultiTurnExtractsLatestUser(t *testing.T) {
body := []byte(`{
"messages": [
{"role":"user","content":"Q1"},
{"role":"assistant","content":"A1"},
{"role":"user","content":"Q2"}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolAnthropicMessages, body)
require.Equal(t, "Q2", input.Text)
}
func TestExtractContentModerationInput_AnthropicStreamResendExtractsResend(t *testing.T) {
body := []byte(`{
"messages": [
{"role":"user","content":"原问题"},
{"role":"assistant","content":"部分回答……"},
{"role":"user","content":"重发"}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolAnthropicMessages, body)
require.Equal(t, "重发", input.Text)
}
func TestExtractContentModerationInput_OpenAIChatAgentToolLoopSkipsAudit(t *testing.T) {
body := []byte(`{
"messages": [
{"role":"system","content":"sys"},
{"role":"user","content":"列出我的订单"},
{"role":"assistant","content":null,"tool_calls":[{"id":"call_1","type":"function","function":{"name":"orders","arguments":"{}"}}]},
{"role":"tool","tool_call_id":"call_1","content":"[]"}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolOpenAIChat, body)
require.Empty(t, input.Text)
require.Empty(t, input.Images)
}
func TestExtractContentModerationInput_OpenAIChatMultiTurnExtractsLatestUser(t *testing.T) {
body := []byte(`{
"messages": [
{"role":"user","content":"Q1"},
{"role":"assistant","content":"A1"},
{"role":"user","content":"Q2"}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolOpenAIChat, body)
require.Equal(t, "Q2", input.Text)
}
func TestExtractContentModerationInput_GeminiAgentToolLoopSkipsAudit(t *testing.T) {
body := []byte(`{
"contents": [
{"role":"user","parts":[{"text":"查询天气"}]},
{"role":"model","parts":[{"functionCall":{"name":"weather","args":{}}}]},
{"role":"user","parts":[{"functionResponse":{"name":"weather","response":{"temp":25}}}]}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolGemini, body)
require.Empty(t, input.Text)
require.Empty(t, input.Images)
}
func TestExtractContentModerationInput_GeminiFirstTurnExtractsUser(t *testing.T) {
body := []byte(`{
"contents": [
{"role":"user","parts":[{"text":"你好"}]}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolGemini, body)
require.Equal(t, "你好", input.Text)
}
func TestExtractContentModerationInput_GeminiMultiTurnExtractsLatestUser(t *testing.T) {
body := []byte(`{
"contents": [
{"role":"user","parts":[{"text":"Q1"}]},
{"role":"model","parts":[{"text":"A1"}]},
{"role":"user","parts":[{"text":"Q2"}]}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolGemini, body)
require.Equal(t, "Q2", input.Text)
}
func TestExtractContentModerationInput_ResponsesAgentToolLoopSkipsAudit(t *testing.T) {
body := []byte(`{
"input":[
{"type":"message","role":"user","content":[{"type":"input_text","text":"运行测试"}]},
{"type":"function_call","call_id":"call_1","name":"run_tests","arguments":"{}"},
{"type":"function_call_output","call_id":"call_1","output":"all passed"}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolOpenAIResponses, body)
require.Empty(t, input.Text)
require.Empty(t, input.Images)
}
func TestExtractContentModerationInput_ResponsesLastUserMessageExtracted(t *testing.T) {
body := []byte(`{
"input":[
{"type":"message","role":"user","content":[{"type":"input_text","text":"first"}]},
{"type":"message","role":"assistant","content":[{"type":"output_text","text":"answer"}]},
{"type":"message","role":"user","content":[{"type":"input_text","text":"latest"}]}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolOpenAIResponses, body)
require.Equal(t, "latest", input.Text)
}
func TestExtractContentModerationInput_ResponsesLastIsAssistantSkipped(t *testing.T) {
body := []byte(`{
"input":[
{"type":"message","role":"user","content":[{"type":"input_text","text":"q1"}]},
{"type":"message","role":"assistant","content":[{"type":"output_text","text":"a1"}]}
]
}`)
input := ExtractContentModerationInput(ContentModerationProtocolOpenAIResponses, body)
require.Empty(t, input.Text)
require.Empty(t, input.Images)
}