(t *testing.T)
| 812 | } |
| 813 | |
| 814 | func TestUnixSocketClientHostedMCPMethods(t *testing.T) { |
| 815 | t.Parallel() |
| 816 | |
| 817 | t.Run("Should exercise hosted MCP client methods", func(t *testing.T) { |
| 818 | t.Parallel() |
| 819 | |
| 820 | client := &unixSocketClient{ |
| 821 | socketPath: "/tmp/agh.sock", |
| 822 | httpClient: &http.Client{ |
| 823 | Transport: roundTripperFunc(func(req *http.Request) (*http.Response, error) { |
| 824 | switch { |
| 825 | case req.Method == http.MethodPost && req.URL.Path == "/api/internal/hosted-mcp/bind": |
| 826 | var request mcppkg.HostedBindRequest |
| 827 | if err := json.NewDecoder(req.Body).Decode(&request); err != nil { |
| 828 | t.Fatalf("decode bind body: %v", err) |
| 829 | } |
| 830 | if request.SessionID != "sess-1" || request.Nonce != "nonce-test" { |
| 831 | t.Fatalf("bind request = %#v, want session and nonce", request) |
| 832 | } |
| 833 | return newHTTPResponse( |
| 834 | http.StatusOK, |
| 835 | `{"bind_id":"bind-1","scope":{"session_id":"sess-1","workspace_id":"ws-1","agent_name":"coder"},"tools":[],"digest":"digest-1"}`, |
| 836 | ), nil |
| 837 | case req.Method == http.MethodGet && req.URL.Path == "/api/internal/hosted-mcp/projection": |
| 838 | if req.URL.Query().Get("bind_id") != "bind-1" { |
| 839 | t.Fatalf("projection query = %s, want bind_id", req.URL.RawQuery) |
| 840 | } |
| 841 | return newHTTPResponse(http.StatusOK, `{"tools":[],"digest":"digest-2"}`), nil |
| 842 | case req.Method == http.MethodGet && req.URL.Path == "/api/internal/hosted-mcp/projection/stream": |
| 843 | if req.URL.Query().Get("bind_id") != "bind-1" || |
| 844 | req.URL.Query().Get("last_digest") != "digest-1" { |
| 845 | t.Fatalf("projection stream query = %s, want bind_id and last_digest", req.URL.RawQuery) |
| 846 | } |
| 847 | return newHTTPResponse( |
| 848 | http.StatusOK, |
| 849 | "event: ignored\n"+ |
| 850 | "data: {}\n\n"+ |
| 851 | "event: projection\n"+ |
| 852 | "data: {\"tools\":[],\"digest\":\"digest-3\"}\n\n", |
| 853 | ), nil |
| 854 | case req.Method == http.MethodPost && req.URL.Path == "/api/internal/hosted-mcp/tools/call": |
| 855 | var request mcppkg.HostedCallRequest |
| 856 | if err := json.NewDecoder(req.Body).Decode(&request); err != nil { |
| 857 | t.Fatalf("decode hosted call body: %v", err) |
| 858 | } |
| 859 | if request.BindID != "bind-1" || |
| 860 | request.ToolName != "skill_view" || |
| 861 | string(request.Input) != `{"ok":true}` { |
| 862 | t.Fatalf("hosted call request = %#v, want bound tool call", request) |
| 863 | } |
| 864 | return newHTTPResponse( |
| 865 | http.StatusOK, |
| 866 | `{"result":{"structured":{"ok":true},"preview":"ok","bytes":2,"duration_ms":1}}`, |
| 867 | ), nil |
| 868 | case req.Method == http.MethodPost && req.URL.Path == "/api/internal/hosted-mcp/release": |
| 869 | var request mcppkg.HostedReleaseRequest |
| 870 | if err := json.NewDecoder(req.Body).Decode(&request); err != nil { |
| 871 | t.Fatalf("decode release body: %v", err) |
nothing calls this directly
no test coverage detected