diff --git a/tests/mcp-server.test.ts b/tests/mcp-server.test.ts index cb7e461..b47a81b 100644 --- a/tests/mcp-server.test.ts +++ b/tests/mcp-server.test.ts @@ -261,5 +261,87 @@ describe("End-to-End Live Tool Calling over MCP Client", () => { await mcpServer.stop(); } }); + + runLiveTests("calls meetings, wikis, and activities tools via Client", async () => { + const mcpServer = createServer({ baseUrl, apiKey: apiKey || "skip", readOnly: false }); + const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); + await mcpServer.start(serverTransport); + + const client = new Client({ name: "test-runner", version: "1" }); + await client.connect(clientTransport); + + try { + // openproject_list_meetings + const listMeetingsRes = (await client.callTool({ + name: "openproject_list_meetings", + arguments: { projectId: 1 }, + })) as { content: Array<{ type: string; text: string }>; isError?: boolean }; + expect(listMeetingsRes.isError).toBeFalsy(); + const meetingsData = JSON.parse(listMeetingsRes.content[0]?.text ?? "{}"); + expect(meetingsData.total).toBeGreaterThanOrEqual(4); + expect(meetingsData.elements.length).toBeGreaterThan(0); + + // openproject_get_meeting + const getMeetingRes = (await client.callTool({ + name: "openproject_get_meeting", + arguments: { id: 2, includeAgendaItems: true }, + })) as { content: Array<{ type: string; text: string }>; isError?: boolean }; + expect(getMeetingRes.isError).toBeFalsy(); + const meetingData = JSON.parse(getMeetingRes.content[0]?.text ?? "{}"); + expect(meetingData.id).toBe(2); + expect(meetingData.title).toBe("Weekly"); + expect(meetingData.agendaItems.length).toBeGreaterThan(0); + + // openproject_search_meetings + const searchMeetingsRes = (await client.callTool({ + name: "openproject_search_meetings", + arguments: { query: "Weekly" }, + })) as { content: Array<{ type: string; text: string }>; isError?: boolean }; + expect(searchMeetingsRes.isError).toBeFalsy(); + const searchMeetingsData = JSON.parse(searchMeetingsRes.content[0]?.text ?? "{}"); + expect(searchMeetingsData.total).toBeGreaterThan(0); + expect(searchMeetingsData.elements.length).toBeGreaterThan(0); + + // openproject_get_wiki_page + const getWikiRes = (await client.callTool({ + name: "openproject_get_wiki_page", + arguments: { id: 1 }, + })) as { content: Array<{ type: string; text: string }>; isError?: boolean }; + expect(getWikiRes.isError).toBeFalsy(); + const wikiData = JSON.parse(getWikiRes.content[0]?.text ?? "{}"); + expect(wikiData.id).toBe(1); + expect(wikiData.title).toBe("Wiki"); + expect(wikiData.project.id).toBe(1); + + // openproject_search_wiki_pages + const searchWikiRes = (await client.callTool({ + name: "openproject_search_wiki_pages", + arguments: { query: "Wiki" }, + })) as { content: Array<{ type: string; text: string }>; isError?: boolean }; + expect(searchWikiRes.isError).toBeFalsy(); + const searchWikiData = JSON.parse(searchWikiRes.content[0]?.text ?? "[]"); + expect(Array.isArray(searchWikiData)).toBe(true); + expect(searchWikiData.length).toBeGreaterThan(0); + expect( + searchWikiData.some( + (w: { id: number; title: string }) => w.id === 1 && w.title === "Wiki" + ) + ).toBe(true); + + // openproject_list_work_package_activities + const activitiesRes = (await client.callTool({ + name: "openproject_list_work_package_activities", + arguments: { workPackageId: 38 }, + })) as { content: Array<{ type: string; text: string }>; isError?: boolean }; + expect(activitiesRes.isError).toBeFalsy(); + const activitiesData = JSON.parse(activitiesRes.content[0]?.text ?? "[]"); + expect(Array.isArray(activitiesData)).toBe(true); + expect(activitiesData.length).toBeGreaterThan(0); + expect(activitiesData[0].id).toBeDefined(); + } finally { + await client.close(); + await mcpServer.stop(); + } + }); }); diff --git a/tests/services.test.ts b/tests/services.test.ts index e574fae..a091796 100644 --- a/tests/services.test.ts +++ b/tests/services.test.ts @@ -720,5 +720,59 @@ describe("Live Container Integration (Domain Services)", () => { const users = await domainServices.listUsers({ pageSize: 5 }, client); expect(users.items.length).toBeGreaterThan(0); }); + + runLiveTests("live: meetings service operations", async () => { + const client = new OpenProjectClient({ baseUrl: liveBaseUrl, apiKey: liveApiKey! }); + + // list meetings (should return meetings 2..5) + const meetings = await domainServices.listMeetings({ projectId: 1 }, client); + expect(meetings.elements.length).toBeGreaterThanOrEqual(4); + const meetingIds = meetings.elements.map((m) => m.id); + expect(meetingIds).toContain(2); + expect(meetingIds).toContain(3); + expect(meetingIds).toContain(4); + expect(meetingIds).toContain(5); + + // get meeting (should return meeting with title "Weekly" and agenda items) + const meeting = await domainServices.getMeeting(2, { includeAgendaItems: true }, client); + expect(meeting.id).toBe(2); + expect(meeting.title).toBe("Weekly"); + expect(meeting.agendaItems).toBeDefined(); + expect(meeting.agendaItems!.length).toBeGreaterThan(0); + expect(meeting.agendaItems![0]!.title).toBeDefined(); + + // search meetings (should return results with matching items) + const searchRes = await domainServices.searchMeetings({ query: "Weekly" }, client); + expect(searchRes.elements.length).toBeGreaterThan(0); + const match = searchRes.elements.find((r) => r.meeting.title.includes("Weekly")); + expect(match).toBeDefined(); + }); + + runLiveTests("live: wikis service operations", async () => { + const client = new OpenProjectClient({ baseUrl: liveBaseUrl, apiKey: liveApiKey! }); + + // get wiki page (should return title "Wiki", project id 1) + const wiki = await domainServices.getWikiPage(1, client); + expect(wiki.id).toBe(1); + expect(wiki.title).toBe("Wiki"); + expect(wiki.project.id).toBe(1); + + // search wiki pages (should discover and return wiki page 1) + const searchRes = await domainServices.searchWikiPages({ query: "Wiki" }, client); + expect(searchRes.length).toBeGreaterThan(0); + const found = searchRes.find((w) => w.id === 1); + expect(found).toBeDefined(); + expect(found!.title).toBe("Wiki"); + expect(found!.project.id).toBe(1); + }); + + runLiveTests("live: activities service operations", async () => { + const client = new OpenProjectClient({ baseUrl: liveBaseUrl, apiKey: liveApiKey! }); + + // list work package activities (should return activities for WP 38) + const activities = await domainServices.listWorkPackageActivities({ workPackageId: 38 }, client); + expect(activities.length).toBeGreaterThan(0); + expect(activities[0]!.id).toBeDefined(); + }); });