Skip to content

Commit dd9fb36

Browse files
committed
Add integration test
1 parent 128695c commit dd9fb36

File tree

2 files changed

+125
-2
lines changed

2 files changed

+125
-2
lines changed

tests/integration/helpers.ts

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import fs from "fs/promises";
77
import { Session } from "../../src/session.js";
88
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
99
import { MongoClient } from "mongodb";
10+
import { ApiClient } from "../../src/common/atlas/apiClient.js";
1011
import { toIncludeAllMembers } from "jest-extended";
12+
import { Group } from "../../src/common/atlas/openapi.js";
1113

1214
interface ParameterInfo {
1315
name: string;
@@ -21,6 +23,7 @@ type ToolInfo = Awaited<ReturnType<Client["listTools"]>>["tools"][number];
2123
export function jestTestMCPClient(): () => Client {
2224
let client: Client | undefined;
2325
let server: Server | undefined;
26+
let session: Session | undefined;
2427

2528
beforeEach(async () => {
2629
const clientTransport = new InMemoryTransport();
@@ -42,13 +45,16 @@ export function jestTestMCPClient(): () => Client {
4245
}
4346
);
4447

48+
session = jestTestSession();
49+
4550
server = new Server({
4651
mcpServer: new McpServer({
4752
name: "test-server",
4853
version: "1.2.3",
4954
}),
50-
session: new Session(),
55+
session,
5156
});
57+
5258
await server.connect(serverTransport);
5359
await client.connect(clientTransport);
5460
});
@@ -59,13 +65,15 @@ export function jestTestMCPClient(): () => Client {
5965

6066
await server?.close();
6167
server = undefined;
68+
69+
session = undefined;
70+
jest.restoreAllMocks();
6271
});
6372

6473
return () => {
6574
if (!client) {
6675
throw new Error("beforeEach() hook not ran yet");
6776
}
68-
6977
return client;
7078
};
7179
}
@@ -196,3 +204,48 @@ export function validateParameters(tool: ToolInfo, parameters: ParameterInfo[]):
196204
expect(toolParameters).toHaveLength(parameters.length);
197205
expect(toolParameters).toIncludeAllMembers(parameters);
198206
}
207+
208+
const jestTestAtlasData = {
209+
project: {
210+
id: "test-project-id",
211+
name: "test-project",
212+
orgId: "test-org-id",
213+
clusterCount: 0,
214+
created: new Date().toISOString(),
215+
regionUsageRestrictions: "COMMERCIAL_FEDRAMP_REGIONS_ONLY" as const,
216+
withDefaultAlertsSettings: true,
217+
} satisfies Group,
218+
projects: {
219+
results: [],
220+
totalCount: 0,
221+
},
222+
};
223+
224+
function jestTestAtlasClient(): ApiClient {
225+
const apiClient = new ApiClient({
226+
baseUrl: "http://localhost:3000",
227+
userAgent: "AtlasMCP-Test",
228+
credentials: {
229+
clientId: "test-client-id",
230+
clientSecret: "test-client-secret",
231+
},
232+
});
233+
234+
jest.spyOn(apiClient, "createProject").mockResolvedValue(jestTestAtlasData.project);
235+
jest.spyOn(apiClient, "listProjects").mockResolvedValue(jestTestAtlasData.projects);
236+
jest.spyOn(apiClient, "getProject").mockResolvedValue(jestTestAtlasData.project);
237+
238+
return apiClient;
239+
}
240+
241+
function jestTestSession(): Session {
242+
const session = new Session();
243+
const apiClient = jestTestAtlasClient();
244+
245+
Object.defineProperty(session, "apiClient", {
246+
get: () => apiClient,
247+
configurable: true,
248+
});
249+
250+
return session;
251+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { jestTestMCPClient, validateParameters, getResponseContent } from "../../helpers.js";
2+
import { McpError } from "@modelcontextprotocol/sdk/types.js";
3+
4+
describe("createProject tool", () => {
5+
const client = jestTestMCPClient();
6+
// atlas client mockk
7+
8+
it("should have correct metadata", async () => {
9+
const { tools } = await client().listTools();
10+
const createProject = tools.find((tool) => tool.name === "atlas-create-project")!;
11+
expect(createProject).toBeDefined();
12+
expect(createProject.description).toBe("Create a MongoDB Atlas project");
13+
14+
// Validate the parameters match the schema
15+
validateParameters(createProject, [
16+
{
17+
name: "projectName",
18+
type: "string",
19+
description: "Name for the new project",
20+
required: true,
21+
},
22+
{
23+
name: "organizationId",
24+
type: "string",
25+
description: "Organization ID for the new project",
26+
required: true,
27+
},
28+
]);
29+
});
30+
31+
describe("with invalid arguments", () => {
32+
const args = [
33+
{}, // Empty args
34+
{ projectName: 123, organizationId: "org-1" }, // Invalid projectName type
35+
{ projectName: "Test Project" }, // Missing organizationId
36+
{ projectName: "Test Project", organizationId: 456 }, // Invalid organizationId type
37+
{ projectName: "", organizationId: "org-1" }, // Empty projectName
38+
];
39+
40+
for (const arg of args) {
41+
it(`throws a schema error for: ${JSON.stringify(arg)}`, async () => {
42+
try {
43+
await client().callTool({ name: "atlas-create-project", arguments: arg });
44+
expect.fail("Expected an error to be thrown");
45+
} catch (error) {
46+
expect(error).toBeInstanceOf(McpError);
47+
const mcpError = error as McpError;
48+
expect(mcpError.code).toEqual(-32602);
49+
expect(mcpError.message).toContain("Invalid arguments for tool atlas-create-project");
50+
}
51+
});
52+
}
53+
});
54+
55+
describe("with valid arguments", () => {
56+
it("creates a new project", async () => {
57+
const projectName = "Test Project";
58+
const organizationId = "test-org-id";
59+
60+
const response = await client().callTool({
61+
name: "atlas-create-project",
62+
arguments: { projectName, organizationId },
63+
});
64+
65+
expect(response).toBeDefined();
66+
const content = getResponseContent(response.content);
67+
expect(content).toEqual(`Project "${projectName}" created successfully.`);
68+
});
69+
});
70+
});

0 commit comments

Comments
 (0)