feat: centralize send message production gate
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user