UNPKG

@access-mcp/events

Version:

ACCESS-CI Events MCP Server - Get information about workshops, webinars, and training events

302 lines (255 loc) 9.52 kB
import { describe, it, expect, beforeEach } from "vitest"; import { EventsServer } from "../server.js"; // These are integration tests that hit the real API // Run with: npm run test:integration describe("EventsServer Integration Tests", () => { let server: EventsServer; beforeEach(() => { server = new EventsServer(); }); describe("Real API Calls", () => { it("should fetch real events from ACCESS-CI API", async () => { const result = await server["handleToolCall"]({ params: { name: "get_events", arguments: { beginning_date_relative: "today", limit: 5, }, }, }); const responseData = JSON.parse(result.content[0].text); // Check structure of response expect(responseData).toHaveProperty("total_events"); expect(responseData).toHaveProperty("events"); expect(responseData).toHaveProperty("event_types"); expect(responseData).toHaveProperty("popular_tags"); // If there are events, check their structure if (responseData.events.length > 0) { const event = responseData.events[0]; expect(event).toHaveProperty("id"); expect(event).toHaveProperty("title"); expect(event).toHaveProperty("date"); expect(event).toHaveProperty("tags"); // Our enhanced field expect(event).toHaveProperty("duration_hours"); // Our calculated field } }, 10000); // Increase timeout for real API call it("should search for Python events", async () => { const result = await server["handleToolCall"]({ params: { name: "search_events", arguments: { query: "Python", limit: 3, }, }, }); const responseData = JSON.parse(result.content[0].text); expect(responseData).toHaveProperty("search_query"); expect(responseData.search_query).toBe("Python"); expect(responseData).toHaveProperty("total_matches"); expect(responseData).toHaveProperty("events"); // Check that search actually filters if (responseData.events.length > 0) { const hasMatch = responseData.events.some( (event: any) => event.title?.toLowerCase().includes("python") || event.description?.toLowerCase().includes("python") || event.tags?.some((tag: string) => tag.toLowerCase().includes("python"), ), ); expect(hasMatch).toBe(true); } }, 10000); it("should get upcoming office hours events", async () => { const result = await server["handleToolCall"]({ params: { name: "get_upcoming_events", arguments: { event_type: "Office Hours", limit: 3, }, }, }); const responseData = JSON.parse(result.content[0].text); expect(responseData).toHaveProperty("events"); // Check that events are actually upcoming (starts_in_hours >= 0) responseData.events.forEach((event: any) => { if (event.starts_in_hours !== undefined) { expect(event.starts_in_hours).toBeGreaterThanOrEqual(0); } }); }, 10000); it("should get events by AI tag", async () => { const result = await server["handleToolCall"]({ params: { name: "get_events_by_tag", arguments: { tag: "ai", time_range: "upcoming", limit: 5, }, }, }); const responseData = JSON.parse(result.content[0].text); expect(responseData).toHaveProperty("tag"); expect(responseData.tag).toBe("ai"); expect(responseData).toHaveProperty("time_range"); expect(responseData).toHaveProperty("events"); }, 10000); it("should handle date filtering correctly", async () => { const result = await server["handleToolCall"]({ params: { name: "get_events", arguments: { beginning_date: "2025-01-01", end_date: "2025-12-31", limit: 10, }, }, }); const responseData = JSON.parse(result.content[0].text); expect(responseData).toHaveProperty("events"); // Check that events are within the specified date range responseData.events.forEach((event: any) => { const eventDate = new Date(event.date); expect(eventDate.getFullYear()).toBe(2025); }); }, 10000); it("should handle skill level filtering", async () => { const result = await server["handleToolCall"]({ params: { name: "get_events", arguments: { skill_level: "beginner", beginning_date_relative: "today", limit: 5, }, }, }); const responseData = JSON.parse(result.content[0].text); expect(responseData).toHaveProperty("events"); // Check skill levels if events are returned if (responseData.events.length > 0) { responseData.events.forEach((event: any) => { if (event.skill_level) { expect(event.skill_level.toLowerCase()).toContain("beginner"); } }); } }, 10000); it("should handle timezone parameter with relative dates", async () => { const result = await server["handleToolCall"]({ params: { name: "get_events", arguments: { beginning_date_relative: "today", timezone: "America/New_York", limit: 5, }, }, }); const responseData = JSON.parse(result.content[0].text); expect(responseData).toHaveProperty("events"); expect(responseData).toHaveProperty("total_events"); expect(responseData).toHaveProperty("api_info"); // Should successfully handle timezone parameter (v2.1 API feature) expect(typeof responseData.total_events).toBe("number"); expect(responseData.api_info.timezone_used).toBe("America/New_York"); expect(responseData.api_info.endpoint_version).toBe("2.1"); }, 10000); it("should handle upcoming events with timezone", async () => { const result = await server["handleToolCall"]({ params: { name: "get_upcoming_events", arguments: { timezone: "Europe/London", limit: 3, }, }, }); const responseData = JSON.parse(result.content[0].text); expect(responseData).toHaveProperty("events"); expect(responseData).toHaveProperty("api_info"); expect(responseData.api_info.timezone_used).toBe("Europe/London"); }, 10000); it("should handle search with Pacific timezone", async () => { const result = await server["handleToolCall"]({ params: { name: "search_events", arguments: { query: "office", timezone: "America/Los_Angeles", limit: 2, }, }, }); const responseData = JSON.parse(result.content[0].text); expect(responseData).toHaveProperty("search_query"); expect(responseData.search_query).toBe("office"); expect(responseData).toHaveProperty("total_matches"); }, 10000); it("should handle events by tag with timezone", async () => { const result = await server["handleToolCall"]({ params: { name: "get_events_by_tag", arguments: { tag: "ai", time_range: "this_week", timezone: "Asia/Tokyo", limit: 3, }, }, }); const responseData = JSON.parse(result.content[0].text); expect(responseData).toHaveProperty("tag"); expect(responseData.tag).toBe("ai"); expect(responseData).toHaveProperty("time_range"); expect(responseData.time_range).toBe("this_week"); }, 10000); }); describe("Error Handling with Real API", () => { it("should handle invalid date formats gracefully", async () => { const result = await server["handleToolCall"]({ params: { name: "get_events", arguments: { beginning_date: "invalid-date", end_date: "2024-12-31", }, }, }); // Should still return a response (API might ignore invalid params) expect(result.content).toBeDefined(); expect(result.content[0]).toHaveProperty("text"); }, 10000); it("should handle empty results gracefully", async () => { const result = await server["handleToolCall"]({ params: { name: "search_events", arguments: { query: "xyzabc123notfound", limit: 10, }, }, }); const responseData = JSON.parse(result.content[0].text); expect(responseData).toHaveProperty("total_matches"); expect(responseData.total_matches).toBe(0); expect(responseData.events).toHaveLength(0); }, 10000); }); describe("Resource Endpoints", () => { it("should fetch data through resource endpoints", async () => { const result = await server["handleResourceRead"]({ params: { uri: "accessci://events/upcoming" }, }); expect(result.contents).toBeDefined(); expect(result.contents[0]).toHaveProperty("text"); expect(result.contents[0].mimeType).toBe("application/json"); const data = JSON.parse(result.contents[0].text); expect(data).toHaveProperty("events"); }, 10000); }); });