Skip to content

Commit cada5a4

Browse files
committed
Add client/server version negotiation tests without mocks
* In src/client/index.test.ts added tests: - "should connect new client to old, supported server version" - should negotiate version when client is old, and newer server supports its version" - "should throw when client is old, and server doesn't support its version"
1 parent 84dc914 commit cada5a4

File tree

1 file changed

+195
-0
lines changed

1 file changed

+195
-0
lines changed

src/client/index.test.ts

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,201 @@ test("should reject unsupported protocol version", async () => {
165165
expect(clientTransport.close).toHaveBeenCalled();
166166
});
167167

168+
test("should connect new client to old, supported server version", async () => {
169+
const OLD_VERSION = SUPPORTED_PROTOCOL_VERSIONS[1];
170+
const server = new Server(
171+
{
172+
name: "test server",
173+
version: "1.0",
174+
},
175+
{
176+
capabilities: {
177+
resources: {},
178+
tools: {},
179+
},
180+
},
181+
);
182+
183+
server.setRequestHandler(InitializeRequestSchema, (_request) => ({
184+
protocolVersion: OLD_VERSION,
185+
capabilities: {
186+
resources: {},
187+
tools: {},
188+
},
189+
serverInfo: {
190+
name: "old server",
191+
version: "1.0",
192+
},
193+
}));
194+
195+
server.setRequestHandler(ListResourcesRequestSchema, () => ({
196+
resources: [],
197+
}));
198+
199+
server.setRequestHandler(ListToolsRequestSchema, () => ({
200+
tools: [],
201+
}));
202+
203+
const [clientTransport, serverTransport] =
204+
InMemoryTransport.createLinkedPair();
205+
206+
const client = new Client(
207+
{
208+
name: "new client",
209+
version: "1.0",
210+
protocolVersion: LATEST_PROTOCOL_VERSION,
211+
},
212+
{
213+
capabilities: {
214+
sampling: {},
215+
},
216+
enforceStrictCapabilities: true,
217+
},
218+
);
219+
220+
await Promise.all([
221+
client.connect(clientTransport),
222+
server.connect(serverTransport),
223+
]);
224+
225+
// These should work
226+
// Connection should succeed with the older version
227+
expect(client.getServerVersion()).toEqual({
228+
name: "old server",
229+
version: "1.0",
230+
});
231+
});
232+
233+
test("should negotiate version when client is old, and newer server supports its version", async () => {
234+
const OLD_VERSION = SUPPORTED_PROTOCOL_VERSIONS[1];
235+
const server = new Server(
236+
{
237+
name: "new server",
238+
version: "1.0",
239+
},
240+
{
241+
capabilities: {
242+
resources: {},
243+
tools: {},
244+
},
245+
},
246+
);
247+
248+
server.setRequestHandler(InitializeRequestSchema, (_request) => ({
249+
protocolVersion: LATEST_PROTOCOL_VERSION,
250+
capabilities: {
251+
resources: {},
252+
tools: {},
253+
},
254+
serverInfo: {
255+
name: "new server",
256+
version: "1.0",
257+
},
258+
}));
259+
260+
server.setRequestHandler(ListResourcesRequestSchema, () => ({
261+
resources: [],
262+
}));
263+
264+
server.setRequestHandler(ListToolsRequestSchema, () => ({
265+
tools: [],
266+
}));
267+
268+
const [clientTransport, serverTransport] =
269+
InMemoryTransport.createLinkedPair();
270+
271+
const client = new Client(
272+
{
273+
name: "old client",
274+
version: "1.0",
275+
protocolVersion: OLD_VERSION,
276+
},
277+
{
278+
capabilities: {
279+
sampling: {},
280+
},
281+
enforceStrictCapabilities: true,
282+
},
283+
);
284+
285+
await Promise.all([
286+
client.connect(clientTransport),
287+
server.connect(serverTransport),
288+
]);
289+
290+
// These should work
291+
// Connection should succeed with the older version
292+
expect(client.getServerVersion()).toEqual({
293+
name: "new server",
294+
version: "1.0",
295+
});
296+
});
297+
298+
test("should throw when client is old, and server doesn't support its version", async () => {
299+
const OLD_VERSION = SUPPORTED_PROTOCOL_VERSIONS[1];
300+
const FUTURE_VERSION = "FUTURE_VERSION";
301+
const server = new Server(
302+
{
303+
name: "new server",
304+
version: "1.0",
305+
},
306+
{
307+
capabilities: {
308+
resources: {},
309+
tools: {},
310+
},
311+
},
312+
);
313+
314+
server.setRequestHandler(InitializeRequestSchema, (_request) => ({
315+
protocolVersion: FUTURE_VERSION,
316+
capabilities: {
317+
resources: {},
318+
tools: {},
319+
},
320+
serverInfo: {
321+
name: "new server",
322+
version: "1.0",
323+
},
324+
}));
325+
326+
server.setRequestHandler(ListResourcesRequestSchema, () => ({
327+
resources: [],
328+
}));
329+
330+
server.setRequestHandler(ListToolsRequestSchema, () => ({
331+
tools: [],
332+
}));
333+
334+
const [clientTransport, serverTransport] =
335+
InMemoryTransport.createLinkedPair();
336+
337+
const client = new Client(
338+
{
339+
name: "old client",
340+
version: "1.0",
341+
protocolVersion: OLD_VERSION,
342+
},
343+
{
344+
capabilities: {
345+
sampling: {},
346+
},
347+
enforceStrictCapabilities: true,
348+
},
349+
);
350+
351+
let closed = false;
352+
clientTransport.onerror = () => {closed = true};
353+
354+
await Promise.all([
355+
expect(client.connect(clientTransport)).rejects.toThrow(
356+
"Server's protocol version is not supported: FUTURE_VERSION"
357+
),
358+
server.connect(serverTransport),
359+
]);
360+
361+
});
362+
168363
test("should respect server capabilities", async () => {
169364
const server = new Server(
170365
{

0 commit comments

Comments
 (0)