Skip to content

Commit 6ec4c09

Browse files
committed
Add tests for issuing cancellation notifications
1 parent 1451d0e commit 6ec4c09

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

src/client/index.test.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,3 +436,58 @@ test("should typecheck", () => {
436436
},
437437
});
438438
});
439+
440+
test("should handle client cancelling a request", async () => {
441+
const server = new Server(
442+
{
443+
name: "test server",
444+
version: "1.0",
445+
},
446+
{
447+
capabilities: {
448+
resources: {},
449+
},
450+
},
451+
);
452+
453+
// Set up server to delay responding to listResources
454+
server.setRequestHandler(
455+
ListResourcesRequestSchema,
456+
async (request, extra) => {
457+
await new Promise((resolve) => setTimeout(resolve, 1000));
458+
return {
459+
resources: [],
460+
};
461+
},
462+
);
463+
464+
const [clientTransport, serverTransport] =
465+
InMemoryTransport.createLinkedPair();
466+
467+
const client = new Client(
468+
{
469+
name: "test client",
470+
version: "1.0",
471+
},
472+
{
473+
capabilities: {},
474+
},
475+
);
476+
477+
await Promise.all([
478+
client.connect(clientTransport),
479+
server.connect(serverTransport),
480+
]);
481+
482+
// Set up abort controller
483+
const controller = new AbortController();
484+
485+
// Issue request but cancel it immediately
486+
const listResourcesPromise = client.listResources(undefined, {
487+
signal: controller.signal,
488+
});
489+
controller.abort("Cancelled by test");
490+
491+
// Request should be rejected
492+
await expect(listResourcesPromise).rejects.toBe("Cancelled by test");
493+
});

src/server/index.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,3 +407,71 @@ test("should typecheck", () => {
407407
},
408408
);
409409
});
410+
411+
test("should handle server cancelling a request", async () => {
412+
const server = new Server(
413+
{
414+
name: "test server",
415+
version: "1.0",
416+
},
417+
{
418+
capabilities: {
419+
sampling: {},
420+
},
421+
},
422+
);
423+
424+
const client = new Client(
425+
{
426+
name: "test client",
427+
version: "1.0",
428+
},
429+
{
430+
capabilities: {
431+
sampling: {},
432+
},
433+
},
434+
);
435+
436+
// Set up client to delay responding to createMessage
437+
client.setRequestHandler(
438+
CreateMessageRequestSchema,
439+
async (_request, extra) => {
440+
await new Promise((resolve) => setTimeout(resolve, 1000));
441+
return {
442+
model: "test",
443+
role: "assistant",
444+
content: {
445+
type: "text",
446+
text: "Test response",
447+
},
448+
};
449+
},
450+
);
451+
452+
const [clientTransport, serverTransport] =
453+
InMemoryTransport.createLinkedPair();
454+
455+
await Promise.all([
456+
client.connect(clientTransport),
457+
server.connect(serverTransport),
458+
]);
459+
460+
// Set up abort controller
461+
const controller = new AbortController();
462+
463+
// Issue request but cancel it immediately
464+
const createMessagePromise = server.createMessage(
465+
{
466+
messages: [],
467+
maxTokens: 10,
468+
},
469+
{
470+
signal: controller.signal,
471+
},
472+
);
473+
controller.abort("Cancelled by test");
474+
475+
// Request should be rejected
476+
await expect(createMessagePromise).rejects.toBe("Cancelled by test");
477+
});

0 commit comments

Comments
 (0)