11package main
22
33import (
4+ "encoding/json"
45 "testing"
6+
7+ "github.com/higress-group/proxy-wasm-go-sdk/proxywasm/types"
8+ "github.com/higress-group/wasm-go/pkg/test"
9+ "github.com/stretchr/testify/require"
510)
611
12+ // TestTruncateString tests the truncateString function
713func TestTruncateString (t * testing.T ) {
814 tests := []struct {
915 name string
@@ -14,6 +20,8 @@ func TestTruncateString(t *testing.T) {
1420 {"Short String" , "Higress Is an AI-Native API Gateway" , 1000 , "Higress Is an AI-Native API Gateway" },
1521 {"Exact Length" , "Higress Is an AI-Native API Gateway" , 35 , "Higress Is an AI-Native API Gateway" },
1622 {"Truncated String" , "Higress Is an AI-Native API Gateway" , 20 , "Higress Is...(truncated)...PI Gateway" },
23+ {"Empty String" , "" , 10 , "" },
24+ {"Single Char" , "A" , 10 , "A" },
1725 }
1826
1927 for _ , tt := range tests {
@@ -26,3 +34,248 @@ func TestTruncateString(t *testing.T) {
2634 })
2735 }
2836}
37+
38+ // TestIsPreRequestStage tests the isPreRequestStage function
39+ func TestIsPreRequestStage (t * testing.T ) {
40+ config := McpConverterConfig {Stage : ProcessRequest }
41+ require .True (t , isPreRequestStage (config ))
42+
43+ config = McpConverterConfig {Stage : ProcessResponse }
44+ require .False (t , isPreRequestStage (config ))
45+ }
46+
47+ // TestIsPreResponseStage tests the isPreResponseStage function
48+ func TestIsPreResponseStage (t * testing.T ) {
49+ config := McpConverterConfig {Stage : ProcessResponse }
50+ require .True (t , isPreResponseStage (config ))
51+
52+ config = McpConverterConfig {Stage : ProcessRequest }
53+ require .False (t , isPreResponseStage (config ))
54+ }
55+
56+ // TestIsMethodAllowed tests the isMethodAllowed function
57+ func TestIsMethodAllowed (t * testing.T ) {
58+ config := McpConverterConfig {AllowedMethods : []string {MethodToolList , MethodToolCall }}
59+
60+ require .True (t , isMethodAllowed (config , MethodToolList ))
61+ require .True (t , isMethodAllowed (config , MethodToolCall ))
62+ require .False (t , isMethodAllowed (config , "invalid/method" ))
63+ }
64+
65+ // TestConstants tests the constant values
66+ func TestConstants (t * testing.T ) {
67+ require .Equal (t , "x-envoy-jsonrpc-id" , JsonRpcId )
68+ require .Equal (t , "x-envoy-jsonrpc-method" , JsonRpcMethod )
69+ require .Equal (t , "x-envoy-jsonrpc-params" , JsonRpcParams )
70+ require .Equal (t , "x-envoy-jsonrpc-result" , JsonRpcResult )
71+ require .Equal (t , "x-envoy-jsonrpc-error" , JsonRpcError )
72+ require .Equal (t , "x-envoy-mcp-tool-name" , McpToolName )
73+ require .Equal (t , "x-envoy-mcp-tool-arguments" , McpToolArguments )
74+ require .Equal (t , "x-envoy-mcp-tool-response" , McpToolResponse )
75+ require .Equal (t , "x-envoy-mcp-tool-error" , McpToolError )
76+ require .Equal (t , 4000 , DefaultMaxHeaderLength )
77+ require .Equal (t , "tools/list" , MethodToolList )
78+ require .Equal (t , "tools/call" , MethodToolCall )
79+ require .Equal (t , ProcessStage ("request" ), ProcessRequest )
80+ require .Equal (t , ProcessStage ("response" ), ProcessResponse )
81+ }
82+
83+ // TestMcpConverterConfigDefaults tests config default values
84+ func TestMcpConverterConfigDefaults (t * testing.T ) {
85+ config := McpConverterConfig {}
86+ require .Equal (t , 0 , config .MaxHeaderLength )
87+ require .Equal (t , ProcessStage ("" ), config .Stage )
88+ require .Nil (t , config .AllowedMethods )
89+ }
90+
91+ // TestProcessStage tests ProcessStage type
92+ func TestProcessStage (t * testing.T ) {
93+ require .Equal (t , ProcessStage ("request" ), ProcessRequest )
94+ require .Equal (t , ProcessStage ("response" ), ProcessResponse )
95+ }
96+
97+ // TestRemoveJsonRpcHeadersFunction tests removeJsonRpcHeaders function logic
98+ func TestRemoveJsonRpcHeadersFunction (t * testing.T ) {
99+ headersToRemove := []string {
100+ JsonRpcId ,
101+ JsonRpcMethod ,
102+ JsonRpcParams ,
103+ JsonRpcResult ,
104+ McpToolName ,
105+ McpToolArguments ,
106+ McpToolResponse ,
107+ McpToolError ,
108+ }
109+ require .Len (t , headersToRemove , 8 )
110+ }
111+
112+ // TestTruncateStringLong tests truncation of very long strings
113+ func TestTruncateStringLong (t * testing.T ) {
114+ longString := ""
115+ for i := 0 ; i < 5000 ; i ++ {
116+ longString += "a"
117+ }
118+ config := McpConverterConfig {MaxHeaderLength : 1000 }
119+ result := truncateString (longString , config )
120+ require .Contains (t , result , "...(truncated)..." )
121+ require .LessOrEqual (t , len (result ), 1020 )
122+ }
123+
124+ // TestTruncateStringWithSmallMaxLength tests truncation with small max length
125+ func TestTruncateStringWithSmallMaxLength (t * testing.T ) {
126+ config := McpConverterConfig {MaxHeaderLength : 10 }
127+ result := truncateString ("This is a very long string" , config )
128+ require .Contains (t , result , "...(truncated)..." )
129+ }
130+
131+ // TestPluginInit tests plugin initialization
132+ func TestPluginInit (t * testing.T ) {
133+ configBytes , _ := json .Marshal (McpConverterConfig {
134+ Stage : ProcessRequest ,
135+ MaxHeaderLength : DefaultMaxHeaderLength ,
136+ AllowedMethods : []string {MethodToolList , MethodToolCall },
137+ })
138+
139+ host , status := test .NewTestHost (configBytes )
140+ defer host .Reset ()
141+ require .Equal (t , types .OnPluginStartStatusOK , status )
142+ }
143+
144+ // TestProcessJsonRpcRequest tests processJsonRpcRequest function
145+ func TestProcessJsonRpcRequest (t * testing.T ) {
146+ configBytes , _ := json .Marshal (McpConverterConfig {
147+ Stage : ProcessRequest ,
148+ MaxHeaderLength : DefaultMaxHeaderLength ,
149+ AllowedMethods : []string {MethodToolList , MethodToolCall },
150+ })
151+
152+ host , status := test .NewTestHost (configBytes )
153+ defer host .Reset ()
154+ require .Equal (t , types .OnPluginStartStatusOK , status )
155+
156+ host .InitHttp ()
157+ host .CallOnHttpRequestHeaders ([][2 ]string {
158+ {":authority" , "mcp-server.example.com" },
159+ {":method" , "POST" },
160+ {":path" , "/mcp" },
161+ {"content-type" , "application/json" },
162+ })
163+
164+ toolsListRequest := `{
165+ "jsonrpc": "2.0",
166+ "id": 1,
167+ "method": "tools/list",
168+ "params": {}
169+ }`
170+ action := host .CallOnHttpRequestBody ([]byte (toolsListRequest ))
171+ require .Equal (t , types .ActionContinue , action )
172+
173+ host .CompleteHttp ()
174+ }
175+
176+ // TestProcessToolCallRequest tests processToolCallRequest function
177+ func TestProcessToolCallRequest (t * testing.T ) {
178+ configBytes , _ := json .Marshal (McpConverterConfig {
179+ Stage : ProcessRequest ,
180+ MaxHeaderLength : DefaultMaxHeaderLength ,
181+ AllowedMethods : []string {MethodToolCall },
182+ })
183+
184+ host , status := test .NewTestHost (configBytes )
185+ defer host .Reset ()
186+ require .Equal (t , types .OnPluginStartStatusOK , status )
187+
188+ host .InitHttp ()
189+ host .CallOnHttpRequestHeaders ([][2 ]string {
190+ {":authority" , "mcp-server.example.com" },
191+ {":method" , "POST" },
192+ {":path" , "/mcp" },
193+ {"content-type" , "application/json" },
194+ })
195+
196+ toolCallRequest := `{
197+ "jsonrpc": "2.0",
198+ "id": 1,
199+ "method": "tools/call",
200+ "params": {
201+ "name": "test_tool",
202+ "arguments": {"arg1": "value1"}
203+ }
204+ }`
205+ action := host .CallOnHttpRequestBody ([]byte (toolCallRequest ))
206+ require .Equal (t , types .ActionContinue , action )
207+
208+ host .CompleteHttp ()
209+ }
210+
211+ // TestProcessJsonRpcResponse tests processJsonRpcResponse function
212+ func TestProcessJsonRpcResponse (t * testing.T ) {
213+ configBytes , _ := json .Marshal (McpConverterConfig {
214+ Stage : ProcessResponse ,
215+ MaxHeaderLength : DefaultMaxHeaderLength ,
216+ AllowedMethods : []string {MethodToolList , MethodToolCall },
217+ })
218+
219+ host , status := test .NewTestHost (configBytes )
220+ defer host .Reset ()
221+ require .Equal (t , types .OnPluginStartStatusOK , status )
222+
223+ host .InitHttp ()
224+ host .CallOnHttpRequestHeaders ([][2 ]string {
225+ {":authority" , "mcp-server.example.com" },
226+ {":method" , "POST" },
227+ {":path" , "/mcp" },
228+ {"content-type" , "application/json" },
229+ })
230+
231+ responseBody := `{
232+ "jsonrpc": "2.0",
233+ "id": 1,
234+ "result": {
235+ "tools": [{"name": "test_tool"}]
236+ }
237+ }`
238+ host .CallOnHttpResponseHeaders ([][2 ]string {
239+ {":status" , "200" },
240+ {"content-type" , "application/json" },
241+ })
242+ host .CallOnHttpResponseBody ([]byte (responseBody ))
243+
244+ host .CompleteHttp ()
245+ }
246+
247+ // TestProcessToolListResponse tests processToolListResponse function
248+ func TestProcessToolListResponse (t * testing.T ) {
249+ configBytes , _ := json .Marshal (McpConverterConfig {
250+ Stage : ProcessResponse ,
251+ MaxHeaderLength : DefaultMaxHeaderLength ,
252+ AllowedMethods : []string {MethodToolList },
253+ })
254+
255+ host , status := test .NewTestHost (configBytes )
256+ defer host .Reset ()
257+ require .Equal (t , types .OnPluginStartStatusOK , status )
258+
259+ host .InitHttp ()
260+ host .CallOnHttpRequestHeaders ([][2 ]string {
261+ {":authority" , "mcp-server.example.com" },
262+ {":method" , "POST" },
263+ {":path" , "/mcp" },
264+ {"content-type" , "application/json" },
265+ })
266+
267+ responseBody := `{
268+ "jsonrpc": "2.0",
269+ "id": 1,
270+ "result": {
271+ "tools": [{"name": "test_tool"}]
272+ }
273+ }`
274+ host .CallOnHttpResponseHeaders ([][2 ]string {
275+ {":status" , "200" },
276+ {"content-type" , "application/json" },
277+ })
278+ host .CallOnHttpResponseBody ([]byte (responseBody ))
279+
280+ host .CompleteHttp ()
281+ }
0 commit comments