Skip to content

Commit 7a0d778

Browse files
committed
Create failing tests for stateless mode
1 parent 4ba1e2b commit 7a0d778

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

test/mcp/server/transports/streamable_http_transport_test.rb

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,111 @@ class StreamableHTTPTransportTest < ActiveSupport::TestCase
578578
assert_equal "Method not allowed", body["error"]
579579
end
580580

581+
test "stateless mode allows requests without session IDs, responding with a new session ID" do
582+
stateless_transport = StreamableHTTPTransport.new(@server, stateless: true)
583+
584+
init_request = create_rack_request(
585+
"POST",
586+
"/",
587+
{ "CONTENT_TYPE" => "application/json" },
588+
{ jsonrpc: "2.0", method: "initialize", id: "init" }.to_json,
589+
)
590+
init_response = stateless_transport.handle_request(init_request)
591+
session_id = init_response[1]["Mcp-Session-Id"]
592+
593+
assert_not_nil session_id
594+
end
595+
596+
test "stateless mode responds without any session ID when session ID is present" do
597+
stateless_transport = StreamableHTTPTransport.new(@server, stateless: true)
598+
599+
request = create_rack_request(
600+
"POST",
601+
"/",
602+
{
603+
"CONTENT_TYPE" => "application/json",
604+
"HTTP_MCP_SESSION_ID" => "unseen_session_id",
605+
},
606+
{ jsonrpc: "2.0", method: "ping", id: "123" }.to_json,
607+
)
608+
609+
response = stateless_transport.handle_request(request)
610+
assert_equal 200, response[0]
611+
assert_equal(
612+
{
613+
"Content-Type" => "application/json",
614+
},
615+
response[1],
616+
)
617+
618+
body = JSON.parse(response[2][0])
619+
assert_equal "2.0", body["jsonrpc"]
620+
assert_equal "123", body["id"]
621+
end
622+
623+
test "stateless mode responds with 405 when SSE is requested" do
624+
stateless_transport = StreamableHTTPTransport.new(@server, stateless: true)
625+
626+
get_request = create_rack_request(
627+
"GET",
628+
"/",
629+
{
630+
"CONTENT_TYPE" => "application/json,text/event-stream",
631+
},
632+
)
633+
response = stateless_transport.handle_request(get_request)
634+
assert_equal 405, response[0]
635+
assert_equal({ "Content-Type" => "application/json" }, response[1])
636+
637+
body = JSON.parse(response[2][0])
638+
assert_equal "Method not allowed", body["error"]
639+
end
640+
641+
test "stateless mode silently responds with success to session DELETE when session ID is not present" do
642+
stateless_transport = StreamableHTTPTransport.new(@server, stateless: true)
643+
644+
delete_request = create_rack_request(
645+
"DELETE",
646+
"/",
647+
{},
648+
)
649+
response = stateless_transport.handle_request(delete_request)
650+
assert_equal 200, response[0]
651+
assert_equal({ "Content-Type" => "application/json" }, response[1])
652+
653+
body = JSON.parse(response[2][0])
654+
assert body["success"]
655+
end
656+
657+
test "stateless mode silently responds with success to session DELETE when session ID is provided" do
658+
stateless_transport = StreamableHTTPTransport.new(@server, stateless: true)
659+
660+
delete_request = create_rack_request(
661+
"DELETE",
662+
"/",
663+
{ "HTTP_MCP_SESSION_ID" => "session_id" },
664+
)
665+
response = stateless_transport.handle_request(delete_request)
666+
assert_equal 200, response[0]
667+
assert_equal({ "Content-Type" => "application/json" }, response[1])
668+
669+
body = JSON.parse(response[2][0])
670+
assert body["success"]
671+
end
672+
673+
test "stateless mode does not support notifications" do
674+
stateless_transport = StreamableHTTPTransport.new(@server, stateless: true)
675+
676+
# There are no sessions, so this should fail
677+
assert_raises(RuntimeError, "Stateless mode does not support notifications") do
678+
stateless_transport.send_notification(
679+
"test_notification",
680+
{ message: "Hello" },
681+
session_id: "some_session_id",
682+
)
683+
end
684+
end
685+
581686
test "handle post request with a standard error" do
582687
request = create_rack_request(
583688
"POST",

0 commit comments

Comments
 (0)