Files
higress/plugins/wasm-go/pkg/mcp/utils/json_rpc_test.go

161 lines
3.7 KiB
Go

// Copyright (c) 2022 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package utils
import (
"encoding/json"
"strings"
"testing"
"github.com/tidwall/gjson"
)
func TestJsonRpcIDFromGjson(t *testing.T) {
tests := []struct {
name string
jsonData string
expected JsonRpcID
}{
{
name: "integer id",
jsonData: `{"id": 123}`,
expected: JsonRpcID{
IntValue: 123,
IsString: false,
},
},
{
name: "string id",
jsonData: `{"id": "abc-123"}`,
expected: JsonRpcID{
StringValue: "abc-123",
IsString: true,
},
},
{
name: "float id treated as int",
jsonData: `{"id": 123.45}`,
expected: JsonRpcID{
IntValue: 123,
IsString: false,
},
},
{
name: "boolean id treated as int",
jsonData: `{"id": true}`,
expected: JsonRpcID{
IntValue: 1,
IsString: false,
},
},
{
name: "null id treated as int zero",
jsonData: `{"id": null}`,
expected: JsonRpcID{
IntValue: 0,
IsString: false,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
idResult := gjson.Get(tt.jsonData, "id")
result := NewJsonRpcIDFromGjson(idResult)
if result.IsString != tt.expected.IsString {
t.Errorf("IsString = %v, want %v", result.IsString, tt.expected.IsString)
}
if result.IsString {
if result.StringValue != tt.expected.StringValue {
t.Errorf("StringValue = %v, want %v", result.StringValue, tt.expected.StringValue)
}
} else {
if result.IntValue != tt.expected.IntValue {
t.Errorf("IntValue = %v, want %v", result.IntValue, tt.expected.IntValue)
}
}
})
}
}
// Skip TestSendJsonRpcResponse because it requires proxywasm which is not available in the test environment
// This function would normally test that sendJsonRpcResponse correctly handles different ID types
func TestSendJsonRpcResponse(t *testing.T) {
t.Skip("Skipping test that requires proxywasm")
}
func TestJsonRpcIDMarshaling(t *testing.T) {
// Test that JsonRpcID is correctly marshaled in a JSON response
tests := []struct {
name string
id JsonRpcID
expected string
}{
{
name: "integer id",
id: JsonRpcID{
IntValue: 123,
IsString: false,
},
expected: `"id":123`,
},
{
name: "string id",
id: JsonRpcID{
StringValue: "abc-123",
IsString: true,
},
expected: `"id":"abc-123"`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create a JSON object with the ID
var jsonObj map[string]interface{}
if tt.id.IsString {
jsonObj = map[string]interface{}{
"jsonrpc": "2.0",
"id": tt.id.StringValue,
}
} else {
jsonObj = map[string]interface{}{
"jsonrpc": "2.0",
"id": tt.id.IntValue,
}
}
// Marshal to JSON
body, err := json.Marshal(jsonObj)
if err != nil {
t.Errorf("Failed to marshal JSON: %v", err)
}
// Check that the ID is correctly marshaled
if !json.Valid(body) {
t.Errorf("Invalid JSON: %s", string(body))
}
// Check that the ID is correctly formatted
if !strings.Contains(string(body), tt.expected) {
t.Errorf("ID not correctly formatted. Expected to contain %s, got %s", tt.expected, string(body))
}
})
}
}