feat: register isphere file receive list tool
This commit is contained in:
@@ -9,7 +9,8 @@ $expectedTools = @(
|
||||
"win_helper_dump_uia",
|
||||
"isphere_receive_messages",
|
||||
"isphere_search_contacts",
|
||||
"isphere_search_groups"
|
||||
"isphere_search_groups",
|
||||
"isphere_receive_files"
|
||||
)
|
||||
|
||||
$tempRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("isphere-go-mcp-verify-" + [guid]::NewGuid().ToString("N"))
|
||||
@@ -83,9 +84,10 @@ var expectedTools = []string{
|
||||
"isphere_receive_messages",
|
||||
"isphere_search_contacts",
|
||||
"isphere_search_groups",
|
||||
"isphere_receive_files",
|
||||
}
|
||||
|
||||
var forbiddenTerms = []string{"send", "file", "login", "conversation", "upload", "download", "autologin"}
|
||||
var forbiddenTerms = []string{"send", "login", "conversation", "upload", "download", "autologin"}
|
||||
|
||||
func main() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
@@ -138,7 +140,7 @@ func main() {
|
||||
sort.Strings(toolNames)
|
||||
want := append([]string(nil), expectedTools...)
|
||||
sort.Strings(want)
|
||||
if len(toolNames) != 7 || !reflect.DeepEqual(toolNames, want) {
|
||||
if len(toolNames) != 8 || !reflect.DeepEqual(toolNames, want) {
|
||||
fail("tools/list", fmt.Errorf("tool names = %#v, want %#v", toolNames, want))
|
||||
}
|
||||
|
||||
@@ -190,7 +192,8 @@ func main() {
|
||||
}
|
||||
defaultContactCount := verifySearchContacts(ctx, session, "sender", "tools/call isphere_search_contacts default", 0)
|
||||
defaultGroupCount := verifySearchGroups(ctx, session, "project", "tools/call isphere_search_groups default", 0)
|
||||
configuredReceiveCount, configuredContactCount, configuredGroupCount := verifyConfiguredReceiveSource(ctx)
|
||||
defaultFileCount := verifyReceiveFiles(ctx, session, "report", "tools/call isphere_receive_files default", 0)
|
||||
configuredReceiveCount, configuredContactCount, configuredGroupCount, configuredFileCount := verifyConfiguredReceiveSource(ctx)
|
||||
|
||||
result := map[string]any{
|
||||
"ok": true,
|
||||
@@ -202,9 +205,11 @@ func main() {
|
||||
"receive_message_count": len(messagesValue),
|
||||
"contact_count": defaultContactCount,
|
||||
"group_count": defaultGroupCount,
|
||||
"file_count": defaultFileCount,
|
||||
"configured_receive_message_count": configuredReceiveCount,
|
||||
"configured_contact_count": configuredContactCount,
|
||||
"configured_group_count": configuredGroupCount,
|
||||
"configured_file_count": configuredFileCount,
|
||||
"packet_log_file_configured": os.Getenv("ISPHERE_PACKET_LOG_FILE") != "",
|
||||
"real_isphere_login_required": false,
|
||||
"python_runtime_required": false,
|
||||
@@ -215,13 +220,13 @@ func main() {
|
||||
}
|
||||
|
||||
|
||||
func verifyConfiguredReceiveSource(ctx context.Context) (int, int, int) {
|
||||
func verifyConfiguredReceiveSource(ctx context.Context) (int, int, int, int) {
|
||||
plaintext := "--------------------------------------------------------------------------------------------------------------------------------------------\n" +
|
||||
"2026/7/7 15:30:07\n" +
|
||||
"<message id=\"msg-fixture-1\" from=\"project-room@conference.imopenfire1-lanzhou/imp_pc_4.1.2.6842\" to=\"sender@imopenfire1-lanzhou\" type=\"groupchat\">\n" +
|
||||
" <body>redacted fixture</body>\n" +
|
||||
" <body>redacted-report.docx</body>\n" +
|
||||
" <received xmlns=\"urn:xmpp:receipts\" id=\"receipt-fixture-1\" type=\"1\" stamp=\"\" />\n" +
|
||||
" <subject>VERIFY_FIXTURE</subject>\n" +
|
||||
" <subject>FILE_TRANSFER_CANCEL</subject>\n" +
|
||||
" <isphere xmlns=\"isphere.im\" type=\"1001\" sendtime=\"1783423807000\" version=\"1\" />\n" +
|
||||
" <readed />\n" +
|
||||
"</message>"
|
||||
@@ -306,7 +311,7 @@ func verifyConfiguredReceiveSource(ctx context.Context) (int, int, int) {
|
||||
if !ok {
|
||||
fail("fixture/assert", fmt.Errorf("message was not object: %#v", messagesValue[0]))
|
||||
}
|
||||
if message["id"] != "msg-fixture-1" || message["text"] != "redacted fixture" || message["subject"] != "VERIFY_FIXTURE" {
|
||||
if message["id"] != "msg-fixture-1" || message["text"] != "redacted-report.docx" || message["subject"] != "FILE_TRANSFER_CANCEL" {
|
||||
fail("fixture/assert", fmt.Errorf("unexpected message: %#v", message))
|
||||
}
|
||||
if message["conversation_id"] != "project-room@conference.imopenfire1-lanzhou|sender@imopenfire1-lanzhou" {
|
||||
@@ -314,7 +319,8 @@ func verifyConfiguredReceiveSource(ctx context.Context) (int, int, int) {
|
||||
}
|
||||
contactCount := verifySearchContacts(ctx, session, "sender", "fixture/call isphere_search_contacts", 1)
|
||||
groupCount := verifySearchGroups(ctx, session, "project", "fixture/call isphere_search_groups", 1)
|
||||
return len(messagesValue), contactCount, groupCount
|
||||
fileCount := verifyReceiveFiles(ctx, session, "report", "fixture/call isphere_receive_files", 1)
|
||||
return len(messagesValue), contactCount, groupCount, fileCount
|
||||
}
|
||||
|
||||
func verifySearchContacts(ctx context.Context, session *mcp.ClientSession, query string, step string, wantCount int) int {
|
||||
@@ -388,6 +394,45 @@ func verifySearchGroups(ctx context.Context, session *mcp.ClientSession, query s
|
||||
return len(groupsValue)
|
||||
}
|
||||
|
||||
|
||||
func verifyReceiveFiles(ctx context.Context, session *mcp.ClientSession, nameContains string, step string, wantCount int) int {
|
||||
callResult, err := session.CallTool(ctx, &mcp.CallToolParams{Name: "isphere_receive_files", Arguments: map[string]any{"mode": "list", "name_contains": nameContains, "limit": 5}})
|
||||
if err != nil {
|
||||
fail(step, err)
|
||||
}
|
||||
if callResult.IsError {
|
||||
fail(step, fmt.Errorf("tool returned isError=true: %#v", callResult.Content))
|
||||
}
|
||||
var filesPayload map[string]any
|
||||
encoded, _ := json.Marshal(callResult.StructuredContent)
|
||||
if err := json.Unmarshal(encoded, &filesPayload); err != nil {
|
||||
fail(step, fmt.Errorf("decode structuredContent %s: %w", encoded, err))
|
||||
}
|
||||
if filesPayload["ok"] != true || filesPayload["mode"] != "list" {
|
||||
fail(step, fmt.Errorf("ok/mode mismatch: %s", encoded))
|
||||
}
|
||||
filesValue, ok := filesPayload["files"].([]any)
|
||||
if !ok {
|
||||
fail(step, fmt.Errorf("files missing or not array: %s", encoded))
|
||||
}
|
||||
if len(filesValue) != wantCount {
|
||||
fail(step, fmt.Errorf("files count = %d, want %d: %s", len(filesValue), wantCount, encoded))
|
||||
}
|
||||
if wantCount > 0 {
|
||||
file, ok := filesValue[0].(map[string]any)
|
||||
if !ok {
|
||||
fail(step, fmt.Errorf("file was not object: %#v", filesValue[0]))
|
||||
}
|
||||
if file["file_id"] != "msg-fixture-1:redacted-report.docx" || file["file_name"] != "redacted-report.docx" || file["source"] != "local_readonly" {
|
||||
fail(step, fmt.Errorf("unexpected file: %#v", file))
|
||||
}
|
||||
if file["download_ref"] != nil || file["saved_path"] != nil || file["sha256"] != nil {
|
||||
fail(step, fmt.Errorf("download/cache fields should be nil: %#v", file))
|
||||
}
|
||||
}
|
||||
return len(filesValue)
|
||||
}
|
||||
|
||||
func encryptPacketLogLineForHarness(plaintext string) (string, error) {
|
||||
block, err := des.NewCipher([]byte("hyhccdtm"))
|
||||
if err != nil {
|
||||
@@ -436,13 +481,15 @@ func fail(step string, err error) {
|
||||
|
||||
Assert-True ($script:harnessJson.ok -eq $true) "SDK harness did not return ok=true"
|
||||
Assert-True ($script:harnessJson.helper_name -eq "ISphereWinHelper") "SDK harness helper_name mismatch: $($script:harnessJson.helper_name)"
|
||||
Assert-True ($script:harnessJson.tool_count -eq 7) "SDK harness tool_count mismatch: $($script:harnessJson.tool_count)"
|
||||
Assert-True ($script:harnessJson.tool_count -eq 8) "SDK harness tool_count mismatch: $($script:harnessJson.tool_count)"
|
||||
Assert-True ($script:harnessJson.receive_message_count -eq 0) "SDK harness receive_message_count mismatch: $($script:harnessJson.receive_message_count)"
|
||||
Assert-True ($script:harnessJson.contact_count -eq 0) "SDK harness contact_count mismatch: $($script:harnessJson.contact_count)"
|
||||
Assert-True ($script:harnessJson.group_count -eq 0) "SDK harness group_count mismatch: $($script:harnessJson.group_count)"
|
||||
Assert-True ($script:harnessJson.file_count -eq 0) "SDK harness file_count mismatch: $($script:harnessJson.file_count)"
|
||||
Assert-True ($script:harnessJson.configured_receive_message_count -eq 1) "SDK harness configured_receive_message_count mismatch: $($script:harnessJson.configured_receive_message_count)"
|
||||
Assert-True ($script:harnessJson.configured_contact_count -eq 1) "SDK harness configured_contact_count mismatch: $($script:harnessJson.configured_contact_count)"
|
||||
Assert-True ($script:harnessJson.configured_group_count -eq 1) "SDK harness configured_group_count mismatch: $($script:harnessJson.configured_group_count)"
|
||||
Assert-True ($script:harnessJson.configured_file_count -eq 1) "SDK harness configured_file_count mismatch: $($script:harnessJson.configured_file_count)"
|
||||
|
||||
[ordered]@{
|
||||
ok = $true
|
||||
@@ -454,9 +501,11 @@ func fail(step string, err error) {
|
||||
receive_message_count = $script:harnessJson.receive_message_count
|
||||
contact_count = $script:harnessJson.contact_count
|
||||
group_count = $script:harnessJson.group_count
|
||||
file_count = $script:harnessJson.file_count
|
||||
configured_receive_message_count = $script:harnessJson.configured_receive_message_count
|
||||
configured_contact_count = $script:harnessJson.configured_contact_count
|
||||
configured_group_count = $script:harnessJson.configured_group_count
|
||||
configured_file_count = $script:harnessJson.configured_file_count
|
||||
packet_log_file_configured = $script:harnessJson.packet_log_file_configured
|
||||
python_runtime_required = $false
|
||||
real_isphere_login_required = $false
|
||||
|
||||
Reference in New Issue
Block a user