feat: centralize send message production gate

This commit is contained in:
zhaoyilun
2026-07-10 20:35:46 +08:00
parent 2a7087218b
commit b08b0e01bd
7 changed files with 187 additions and 22 deletions

View File

@@ -147,6 +147,47 @@ func TestISphereSendMessageProductionIsBlockedWithoutSideEffects(t *testing.T) {
}
}
func TestISphereSendMessageProductionBlockedIncludesGateReason(t *testing.T) {
audit := &fakeSendMessageAuditSink{}
session, cleanup := connectToolsTestSession(t, func(server *mcp.Server) {
RegisterISphereSendMessageToolWithState(server, audit, newFakeSendMessageIdempotencyStore())
})
defer cleanup()
content := "blocked gate reason"
callResult, err := session.CallTool(context.Background(), &mcp.CallToolParams{
Name: ToolNameSendMessage,
Arguments: map[string]any{
"target_type": "direct",
"target_id": "alice@imopenfire1-lanzhou",
"content_text": content,
"content_sha256": sha256HexForSendMessageTest(content),
"idempotency_key": "idem-gate-reason-1",
"execution_mode": "production",
},
})
if err != nil {
t.Fatalf("call production blocked gate reason: %v", err)
}
var decoded struct {
OK bool `json:"ok"`
SendStatus string `json:"send_status"`
GateReasonCode string `json:"gate_reason_code"`
GateReasonMessage string `json:"gate_reason_message"`
}
payload, _ := json.Marshal(callResult.StructuredContent)
if err := json.Unmarshal(payload, &decoded); err != nil {
t.Fatalf("decode payload %s: %v", payload, err)
}
if decoded.OK || decoded.SendStatus != "blocked" || decoded.GateReasonCode != "send_disabled_by_default" || decoded.GateReasonMessage == "" {
t.Fatalf("production blocked response missing gate reason: %s", payload)
}
if len(audit.events) != 1 || audit.events[0].GateReasonCode != "send_disabled_by_default" || audit.events[0].GateReasonMessage == "" {
t.Fatalf("audit event missing gate reason: %+v", audit.events)
}
}
func TestISphereSendMessageFakeConnectorAcceptedAudit(t *testing.T) {
audit := &fakeSendMessageAuditSink{}
idempotency := newFakeSendMessageIdempotencyStore()