Encapsulate session handling from protocol to new SessionManager (#247)

This commit is contained in:
Christopher Hertel 2026-03-10 18:09:15 +01:00 • committed by GitHub
commit ae320646bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -24,9 +24,8 @@ use Mcp\Schema\Request\CallToolRequest;
use Mcp\Server\Handler\Notification\NotificationHandlerInterface;
use Mcp\Server\Handler\Request\RequestHandlerInterface;
use Mcp\Server\Protocol;
use Mcp\Server\Session\SessionFactoryInterface;
use Mcp\Server\Session\SessionInterface;
use Mcp\Server\Session\SessionStoreInterface;
use Mcp\Server\Session\SessionManagerInterface;
use Mcp\Server\Transport\TransportInterface;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\MockObject\MockObject;
@ -36,15 +35,13 @@ use Symfony\Component\Uid\Uuid;
final class ProtocolTest extends TestCase
{
private MockObject&SessionFactoryInterface $sessionFactory;
private MockObject&SessionStoreInterface $sessionStore;
private MockObject&SessionManagerInterface $sessionManager;
/** @var MockObject&TransportInterface<mixed> */
private MockObject&TransportInterface $transport;
protected function setUp(): void
{
$this->sessionFactory = $this->createMock(SessionFactoryInterface::class);
$this->sessionStore = $this->createMock(SessionStoreInterface::class);
$this->sessionManager = $this->createMock(SessionManagerInterface::class);
$this->transport = $this->createMock(TransportInterface::class);
}
@ -65,15 +62,14 @@ final class ProtocolTest extends TestCase
$session = $this->createMock(SessionInterface::class);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [],
notificationHandlers: [$handlerA, $handlerB, $handlerC],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$sessionId = Uuid::v4();
@ -101,8 +97,8 @@ final class ProtocolTest extends TestCase
$session = $this->createMock(SessionInterface::class);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$session->method('getId')->willReturn(Uuid::v4());
// Configure session mock for queue operations
@ -130,8 +126,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [$handlerA, $handlerB, $handlerC],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$sessionId = Uuid::v4();
@ -168,8 +163,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$sessionId = Uuid::v4();
@ -199,8 +193,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$protocol->processInput(
@ -231,8 +224,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$protocol->processInput(
@ -245,7 +237,7 @@ final class ProtocolTest extends TestCase
#[TestDox('Non-existent session ID returns error')]
public function testNonExistentSessionIdReturnsError(): void
{
$this->sessionStore->method('exists')->willReturn(false);
$this->sessionManager->method('exists')->willReturn(false);
$this->transport->expects($this->once())
->method('send')
@ -265,8 +257,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$sessionId = Uuid::v4();
@ -296,8 +287,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$protocol->processInput(
@ -312,8 +302,8 @@ final class ProtocolTest extends TestCase
{
$session = $this->createMock(SessionInterface::class);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
// Configure session mock for queue operations
$queue = [];
@ -340,8 +330,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$sessionId = Uuid::v4();
@ -365,8 +354,8 @@ final class ProtocolTest extends TestCase
{
$session = $this->createMock(SessionInterface::class);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
// Configure session mock for queue operations
$queue = [];
@ -393,8 +382,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$sessionId = Uuid::v4();
@ -423,8 +411,8 @@ final class ProtocolTest extends TestCase
$session = $this->createMock(SessionInterface::class);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
// Configure session mock for queue operations
$queue = [];
@ -451,8 +439,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [$handler],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$sessionId = Uuid::v4();
@ -481,8 +468,8 @@ final class ProtocolTest extends TestCase
$session = $this->createMock(SessionInterface::class);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
// Configure session mock for queue operations
$queue = [];
@ -509,8 +496,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [$handler],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$sessionId = Uuid::v4();
@ -539,15 +525,14 @@ final class ProtocolTest extends TestCase
$session = $this->createMock(SessionInterface::class);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [],
notificationHandlers: [$handler],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$sessionId = Uuid::v4();
@ -571,8 +556,8 @@ final class ProtocolTest extends TestCase
$session = $this->createMock(SessionInterface::class);
$session->method('getId')->willReturn($sessionId);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
// Configure session mock for queue operations
$queue = [];
@ -599,8 +584,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [$handler],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$protocol->processInput(
@ -650,8 +634,8 @@ final class ProtocolTest extends TestCase
}
});
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
// The protocol now queues responses instead of sending them directly
$session->expects($this->exactly(2))
@ -661,8 +645,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [$handlerA],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$sessionId = Uuid::v4();
@ -687,8 +670,8 @@ final class ProtocolTest extends TestCase
{
$session = $this->createMock(SessionInterface::class);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$session->expects($this->once())->method('save');
@ -696,8 +679,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$sessionId = Uuid::v4();
@ -713,7 +695,7 @@ final class ProtocolTest extends TestCase
{
$sessionId = Uuid::v4();
$this->sessionStore->expects($this->once())
$this->sessionManager->expects($this->once())
->method('destroy')
->with($sessionId);
@ -721,8 +703,7 @@ final class ProtocolTest extends TestCase
requestHandlers: [],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
);
$protocol->destroySession($sessionId);
@ -750,15 +731,14 @@ final class ProtocolTest extends TestCase
$session->method('getId')->willReturn(Uuid::v4());
$session->method('get')->willReturn([]);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [$handler],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: $eventDispatcher,
);
@ -820,15 +800,14 @@ final class ProtocolTest extends TestCase
$session->method('getId')->willReturn(Uuid::v4());
$session->method('get')->willReturn([]);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [$handler],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: $eventDispatcher,
);
@ -857,15 +836,14 @@ final class ProtocolTest extends TestCase
$session->method('getId')->willReturn(Uuid::v4());
$session->method('get')->willReturn([]);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [$handler],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: null,
);
@ -902,15 +880,14 @@ final class ProtocolTest extends TestCase
$session->method('getId')->willReturn(Uuid::v4());
$session->method('get')->willReturn([]);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [$handler],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: $eventDispatcher,
);
@ -969,15 +946,14 @@ final class ProtocolTest extends TestCase
}
});
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [$handler],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: $eventDispatcher,
);
@ -1021,15 +997,14 @@ final class ProtocolTest extends TestCase
$session->method('getId')->willReturn(Uuid::v4());
$session->method('get')->willReturn([]);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [$handler],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: $eventDispatcher,
);
@ -1074,15 +1049,14 @@ final class ProtocolTest extends TestCase
$session->method('getId')->willReturn(Uuid::v4());
$session->method('get')->willReturn([]);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [$handler],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: $eventDispatcher,
);
@ -1126,15 +1100,14 @@ final class ProtocolTest extends TestCase
$session->method('getId')->willReturn(Uuid::v4());
$session->method('get')->willReturn([]);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [$handler],
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: $eventDispatcher,
);
@ -1176,15 +1149,14 @@ final class ProtocolTest extends TestCase
$session->expects($this->once())->method('save');
$session->expects($this->atLeastOnce())->method('set');
$this->sessionFactory->method('create')->willReturn($session); // create() for initialize
$this->sessionStore->method('exists')->willReturn(false); // No existing session
$this->sessionManager->method('create')->willReturn($session); // create() for initialize
$this->sessionManager->method('exists')->willReturn(false); // No existing session
$protocol = new Protocol(
requestHandlers: [], // No handlers
notificationHandlers: [],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: $eventDispatcher,
);
@ -1227,15 +1199,14 @@ final class ProtocolTest extends TestCase
$session = $this->createMock(SessionInterface::class);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [],
notificationHandlers: [$handler],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: $eventDispatcher,
);
@ -1289,15 +1260,14 @@ final class ProtocolTest extends TestCase
$session = $this->createMock(SessionInterface::class);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [],
notificationHandlers: [$handler],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: $eventDispatcher,
);
@ -1324,15 +1294,14 @@ final class ProtocolTest extends TestCase
$session = $this->createMock(SessionInterface::class);
$this->sessionFactory->method('createWithId')->willReturn($session);
$this->sessionStore->method('exists')->willReturn(true);
$this->sessionManager->method('createWithId')->willReturn($session);
$this->sessionManager->method('exists')->willReturn(true);
$protocol = new Protocol(
requestHandlers: [],
notificationHandlers: [$handler],
messageFactory: MessageFactory::make(),
sessionFactory: $this->sessionFactory,
sessionStore: $this->sessionStore,
sessionManager: $this->sessionManager,
eventDispatcher: null,
);