From f699746d65f8f3346d6d2816c74c2b9c2625f551 Mon Sep 17 00:00:00 2001 From: matevip Date: Tue, 9 Jun 2026 10:15:22 +0800 Subject: [PATCH] test(memory,wecom): align two stale tests with current production behavior Both failed on dev independently of the recent merges (confirmed against a pre-merge baseline): - MemorySummarizationStructuredRoutingTest reflected applyStructuredEntries by its old (Long, JsonNode) signature; owner-isolation added a trailing ownerKey param. Update the reflective lookup to (Long, JsonNode, String) and the remember() verifications to the 6-arg overload. - ToolGuardCardHandlerTest still asserted the old 'system-owned pending accepts any clicker' behavior, but the handler now rejects a group click on a system/cron-owned approval fail-closed (no human requester to match), routing it to the admin console. Assert no synthetic injection + the unauthorized card render instead. --- .../tool_guard/ToolGuardCardHandlerTest.java | 10 +++++--- ...orySummarizationStructuredRoutingTest.java | 23 ++++++++++--------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/mateclaw-server/src/test/java/vip/mate/channel/wecom/cards/tool_guard/ToolGuardCardHandlerTest.java b/mateclaw-server/src/test/java/vip/mate/channel/wecom/cards/tool_guard/ToolGuardCardHandlerTest.java index d1873f62..77c8b6eb 100644 --- a/mateclaw-server/src/test/java/vip/mate/channel/wecom/cards/tool_guard/ToolGuardCardHandlerTest.java +++ b/mateclaw-server/src/test/java/vip/mate/channel/wecom/cards/tool_guard/ToolGuardCardHandlerTest.java @@ -130,8 +130,8 @@ class ToolGuardCardHandlerTest { } @Test - @DisplayName("system-owned pending allows ANY clicker (no original requester)") - void systemPendingAcceptsAnyClicker() { + @DisplayName("system-owned pending rejects a group clicker (fail-closed → admin console)") + void systemPendingRejectsGroupClicker() { PendingApproval pending = pendingFor("pid_sys", "system", "shell_exec"); when(approvalService.getPending("pid_sys")).thenReturn(Optional.of(pending)); @@ -139,7 +139,11 @@ class ToolGuardCardHandlerTest { ToolGuardButtonKey.Action.APPROVE, "pid_sys", "shell_exec", "MEDIUM")); handler.handle(adapter, frame, tce(frame), fromBlock("anyone")); - verify(adapter).injectSyntheticMessage(any(ChannelMessage.class)); + // A "system"/cron-owned approval has no human requester to match the + // clicker against, so a group button click is rejected (fail-closed) and + // never injected for execution — these resolve through the admin console. + verify(adapter, never()).injectSyntheticMessage(any(ChannelMessage.class)); + verify(adapter).updateTemplateCard(eq("evt_req_5"), any()); } @Test diff --git a/mateclaw-server/src/test/java/vip/mate/memory/service/MemorySummarizationStructuredRoutingTest.java b/mateclaw-server/src/test/java/vip/mate/memory/service/MemorySummarizationStructuredRoutingTest.java index 92714ce5..b8720274 100644 --- a/mateclaw-server/src/test/java/vip/mate/memory/service/MemorySummarizationStructuredRoutingTest.java +++ b/mateclaw-server/src/test/java/vip/mate/memory/service/MemorySummarizationStructuredRoutingTest.java @@ -36,12 +36,13 @@ class MemorySummarizationStructuredRoutingTest { structured); } - private void invokeApply(MemorySummarizationService svc, long agentId, String entriesJson) throws Exception { + private void invokeApply(MemorySummarizationService svc, long agentId, String ownerKey, String entriesJson) + throws Exception { JsonNode node = mapper.readTree(entriesJson); Method m = MemorySummarizationService.class - .getDeclaredMethod("applyStructuredEntries", Long.class, JsonNode.class); + .getDeclaredMethod("applyStructuredEntries", Long.class, JsonNode.class, String.class); m.setAccessible(true); - m.invoke(svc, agentId, node); + m.invoke(svc, agentId, node, ownerKey); } @Test @@ -50,15 +51,15 @@ class MemorySummarizationStructuredRoutingTest { StructuredMemoryService structured = mock(StructuredMemoryService.class); MemorySummarizationService svc = newService(structured); - invokeApply(svc, 1000000001L, """ + invokeApply(svc, 1000000001L, "owner-1", """ [ {"type": "project", "key": "project_codename", "content": "项目代号:云梯计划"}, {"type": "user", "key": "preferred_output_format", "content": "偏好表格输出"} ] """); - verify(structured).remember(1000000001L, "project", "project_codename", "项目代号:云梯计划", "auto-summary"); - verify(structured).remember(1000000001L, "user", "preferred_output_format", "偏好表格输出", "auto-summary"); + verify(structured).remember(1000000001L, "project", "project_codename", "项目代号:云梯计划", "auto-summary", "owner-1"); + verify(structured).remember(1000000001L, "user", "preferred_output_format", "偏好表格输出", "auto-summary", "owner-1"); verifyNoMoreInteractions(structured); } @@ -68,7 +69,7 @@ class MemorySummarizationStructuredRoutingTest { StructuredMemoryService structured = mock(StructuredMemoryService.class); MemorySummarizationService svc = newService(structured); - invokeApply(svc, 1000000001L, """ + invokeApply(svc, 1000000001L, "owner-1", """ [ {"type": "secret", "key": "k", "content": "bad type"}, {"type": "project", "key": "", "content": "missing key"}, @@ -78,7 +79,7 @@ class MemorySummarizationStructuredRoutingTest { """); // Only the last, fully-valid entry is written. - verify(structured).remember(1000000001L, "project", "good", "kept", "auto-summary"); + verify(structured).remember(1000000001L, "project", "good", "kept", "auto-summary", "owner-1"); verifyNoMoreInteractions(structured); } @@ -88,9 +89,9 @@ class MemorySummarizationStructuredRoutingTest { StructuredMemoryService structured = mock(StructuredMemoryService.class); MemorySummarizationService svc = newService(structured); - invokeApply(svc, 1000000001L, "null"); - invokeApply(svc, 1000000001L, "\"not-an-array\""); - invokeApply(svc, 1000000001L, "[]"); + invokeApply(svc, 1000000001L, "owner-1", "null"); + invokeApply(svc, 1000000001L, "owner-1", "\"not-an-array\""); + invokeApply(svc, 1000000001L, "owner-1", "[]"); verifyNoInteractions(structured); }