22#![ allow( clippy:: unwrap_used) ]
33
44use mcp_proxy:: internal:: { decode_content_texts, extract_sse_json_line, unwrap_json_rpc_inner_result} ;
5- use mcp_proxy:: { Config , JsonRpcRequest , McpProxy } ;
5+ use mcp_proxy:: { Config , JsonRpcRequest , JsonRpcResponse , McpProxy } ;
66
77use std:: collections:: HashMap ;
88
@@ -50,18 +50,18 @@ fn sse_no_data_is_none() {
5050fn decode_escaped_texts_works ( ) {
5151 let mut text_obj = HashMap :: new ( ) ;
5252 text_obj. insert (
53- "text" . to_string ( ) ,
54- tinyjson:: JsonValue :: String ( "hello\\ u0027world\\ ncode:\\ u003Ctag\\ u003E" . to_string ( ) ) ,
53+ "text" . to_owned ( ) ,
54+ tinyjson:: JsonValue :: String ( "hello\\ u0027world\\ ncode:\\ u003Ctag\\ u003E" . to_owned ( ) ) ,
5555 ) ;
5656
5757 let mut content_obj = HashMap :: new ( ) ;
5858 content_obj. insert (
59- "content" . to_string ( ) ,
59+ "content" . to_owned ( ) ,
6060 tinyjson:: JsonValue :: Array ( vec ! [ tinyjson:: JsonValue :: Object ( text_obj) ] ) ,
6161 ) ;
6262
6363 let mut result_obj = HashMap :: new ( ) ;
64- result_obj. insert ( "result" . to_string ( ) , tinyjson:: JsonValue :: Object ( content_obj) ) ;
64+ result_obj. insert ( "result" . to_owned ( ) , tinyjson:: JsonValue :: Object ( content_obj) ) ;
6565
6666 let mut v = tinyjson:: JsonValue :: Object ( result_obj) ;
6767 decode_content_texts ( & mut v) ;
@@ -75,10 +75,10 @@ fn decode_escaped_texts_works() {
7575#[ test]
7676fn unwrap_json_rpc_inner_result_prefers_result ( ) {
7777 let mut tools_obj = HashMap :: new ( ) ;
78- tools_obj. insert ( "tools" . to_string ( ) , tinyjson:: JsonValue :: Array ( vec ! [ ] ) ) ;
78+ tools_obj. insert ( "tools" . to_owned ( ) , tinyjson:: JsonValue :: Array ( vec ! [ ] ) ) ;
7979
8080 let mut v_obj = HashMap :: new ( ) ;
81- v_obj. insert ( "result" . to_string ( ) , tinyjson:: JsonValue :: Object ( tools_obj. clone ( ) ) ) ;
81+ v_obj. insert ( "result" . to_owned ( ) , tinyjson:: JsonValue :: Object ( tools_obj. clone ( ) ) ) ;
8282
8383 let v = tinyjson:: JsonValue :: Object ( v_obj) ;
8484 let got = unwrap_json_rpc_inner_result ( v) ;
@@ -90,7 +90,7 @@ fn unwrap_json_rpc_inner_result_prefers_result() {
9090#[ test]
9191fn unwrap_json_rpc_inner_result_passthrough ( ) {
9292 let mut v_obj = HashMap :: new ( ) ;
93- v_obj. insert ( "tools" . to_string ( ) , tinyjson:: JsonValue :: Array ( vec ! [ ] ) ) ;
93+ v_obj. insert ( "tools" . to_owned ( ) , tinyjson:: JsonValue :: Array ( vec ! [ ] ) ) ;
9494
9595 let v = tinyjson:: JsonValue :: Object ( v_obj) ;
9696 let got = unwrap_json_rpc_inner_result ( v. clone ( ) ) ;
@@ -137,3 +137,40 @@ async fn unknown_method_is_32601() {
137137 . unwrap ( ) ;
138138 assert_eq ! ( get_number_path( resp. error. as_ref( ) . unwrap( ) , & [ "code" ] ) , -32601.0 ) ;
139139}
140+
141+ #[ test]
142+ fn response_omits_null_id ( ) {
143+ let response = JsonRpcResponse {
144+ jsonrpc : "2.0" . to_owned ( ) ,
145+ id : None ,
146+ result : Some ( tinyjson:: JsonValue :: String ( "test" . to_owned ( ) ) ) ,
147+ error : None ,
148+ } ;
149+
150+ let json_str = response. to_string ( ) . unwrap ( ) ;
151+ let parsed: tinyjson:: JsonValue = json_str. parse ( ) . unwrap ( ) ;
152+ let obj = parsed. get :: < HashMap < String , tinyjson:: JsonValue > > ( ) . unwrap ( ) ;
153+
154+ // The id field should not be present when None
155+ assert ! ( !obj. contains_key( "id" ) ) ;
156+ assert ! ( obj. contains_key( "jsonrpc" ) ) ;
157+ assert ! ( obj. contains_key( "result" ) ) ;
158+ }
159+
160+ #[ test]
161+ fn response_includes_id_when_present ( ) {
162+ let response = JsonRpcResponse {
163+ jsonrpc : "2.0" . to_owned ( ) ,
164+ id : Some ( 42 ) ,
165+ result : Some ( tinyjson:: JsonValue :: String ( "test" . to_owned ( ) ) ) ,
166+ error : None ,
167+ } ;
168+
169+ let json_str = response. to_string ( ) . unwrap ( ) ;
170+ let parsed: tinyjson:: JsonValue = json_str. parse ( ) . unwrap ( ) ;
171+ let obj = parsed. get :: < HashMap < String , tinyjson:: JsonValue > > ( ) . unwrap ( ) ;
172+
173+ // The id field should be present when Some
174+ assert ! ( obj. contains_key( "id" ) ) ;
175+ assert_eq ! ( obj. get( "id" ) . unwrap( ) . get:: <f64 >( ) . unwrap( ) , & 42.0 ) ;
176+ }
0 commit comments