Skip to main content
Glama

Apple MCP Server

calendar.test.ts13.2 kB
import { describe, it, expect } from "bun:test"; import { TEST_DATA } from "../fixtures/test-data.js"; import { assertNotEmpty, assertValidDate, sleep } from "../helpers/test-utils.js"; import calendarModule from "../../utils/calendar.js"; describe("Calendar Integration Tests", () => { describe("getEvents", () => { it("should retrieve calendar events for next week", async () => { const events = await calendarModule.getEvents(10); expect(Array.isArray(events)).toBe(true); console.log(`Found ${events.length} events in the next 7 days`); if (events.length > 0) { for (const event of events) { expect(typeof event.title).toBe("string"); expect(typeof event.calendarName).toBe("string"); expect(event.title.length).toBeGreaterThan(0); if (event.startDate) { assertValidDate(event.startDate); } if (event.endDate) { assertValidDate(event.endDate); } console.log(` - "${event.title}" (${event.calendarName})`); if (event.startDate && event.endDate) { const startDate = new Date(event.startDate); const endDate = new Date(event.endDate); console.log(` ${startDate.toLocaleString()} - ${endDate.toLocaleString()}`); } if (event.location) { console.log(` Location: ${event.location}`); } } } else { console.log("ℹ️ No upcoming events found - this is normal"); } }, 20000); it("should retrieve events with custom date range", async () => { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); tomorrow.setHours(0, 0, 0, 0); const nextWeek = new Date(tomorrow); nextWeek.setDate(tomorrow.getDate() + 7); nextWeek.setHours(23, 59, 59, 999); const events = await calendarModule.getEvents( 20, tomorrow.toISOString(), nextWeek.toISOString() ); expect(Array.isArray(events)).toBe(true); console.log(`Found ${events.length} events between ${tomorrow.toLocaleDateString()} and ${nextWeek.toLocaleDateString()}`); // Verify events are within the date range if (events.length > 0) { for (const event of events) { if (event.startDate) { const eventDate = new Date(event.startDate); expect(eventDate.getTime()).toBeGreaterThanOrEqual(tomorrow.getTime()); expect(eventDate.getTime()).toBeLessThanOrEqual(nextWeek.getTime()); } } console.log("✅ All events are within the specified date range"); } }, 15000); it("should limit event count correctly", async () => { const limit = 3; const events = await calendarModule.getEvents(limit); expect(Array.isArray(events)).toBe(true); expect(events.length).toBeLessThanOrEqual(limit); console.log(`Requested ${limit} events, got ${events.length}`); }, 15000); }); describe("createEvent", () => { it("should create a basic calendar event", async () => { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); tomorrow.setHours(14, 0, 0, 0); // 2 PM tomorrow const eventEndTime = new Date(tomorrow); eventEndTime.setHours(15, 0, 0, 0); // 3 PM tomorrow const testEventTitle = `${TEST_DATA.CALENDAR.testEvent.title} ${Date.now()}`; const result = await calendarModule.createEvent( testEventTitle, tomorrow.toISOString(), eventEndTime.toISOString(), TEST_DATA.CALENDAR.testEvent.location, TEST_DATA.CALENDAR.testEvent.notes ); expect(result.success).toBe(true); expect(result.eventId).toBeTruthy(); console.log(`✅ Created event: "${testEventTitle}"`); console.log(` Event ID: ${result.eventId}`); console.log(` Time: ${tomorrow.toLocaleString()} - ${eventEndTime.toLocaleString()}`); }, 15000); it("should create an all-day event", async () => { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 2); tomorrow.setHours(0, 0, 0, 0); const eventEnd = new Date(tomorrow); eventEnd.setHours(23, 59, 59, 999); const allDayEventTitle = `All Day Test Event ${Date.now()}`; const result = await calendarModule.createEvent( allDayEventTitle, tomorrow.toISOString(), eventEnd.toISOString(), "All Day Location", "This is an all-day event", true // isAllDay ); expect(result.success).toBe(true); expect(result.eventId).toBeTruthy(); console.log(`✅ Created all-day event: "${allDayEventTitle}"`); console.log(` Event ID: ${result.eventId}`); }, 15000); it("should create event in specific calendar if specified", async () => { const eventTime = new Date(); eventTime.setDate(eventTime.getDate() + 3); eventTime.setHours(16, 0, 0, 0); const eventEndTime = new Date(eventTime); eventEndTime.setHours(17, 0, 0, 0); const specificCalendarEvent = `Specific Calendar Event ${Date.now()}`; const result = await calendarModule.createEvent( specificCalendarEvent, eventTime.toISOString(), eventEndTime.toISOString(), "Test Location", "Event in specific calendar", false, TEST_DATA.CALENDAR.calendarName ); if (result.success) { console.log(`✅ Created event in specific calendar: "${specificCalendarEvent}"`); } else { console.log(`ℹ️ Could not create in specific calendar (${result.message}), but this is expected if the calendar doesn't exist`); } }, 15000); }); describe("searchEvents", () => { it("should search for events by title", async () => { // First create a searchable event const searchEventTime = new Date(); searchEventTime.setDate(searchEventTime.getDate() + 4); searchEventTime.setHours(10, 0, 0, 0); const searchEventEndTime = new Date(searchEventTime); searchEventEndTime.setHours(11, 0, 0, 0); const searchableEventTitle = `Searchable Test Event ${Date.now()}`; await calendarModule.createEvent( searchableEventTitle, searchEventTime.toISOString(), searchEventEndTime.toISOString(), "Search Test Location", "This event is for search testing" ); await sleep(3000); // Wait for event to be indexed // Now search for it const searchResults = await calendarModule.searchEvents("Searchable Test", 10); expect(Array.isArray(searchResults)).toBe(true); if (searchResults.length > 0) { console.log(`✅ Found ${searchResults.length} events matching "Searchable Test"`); const matchingEvent = searchResults.find(event => event.title.includes("Searchable Test") ); if (matchingEvent) { console.log(` - "${matchingEvent.title}"`); console.log(` Calendar: ${matchingEvent.calendarName}`); console.log(` ID: ${matchingEvent.id}`); } } else { console.log("ℹ️ No events found for 'Searchable Test' - may need time for indexing"); } }, 25000); it("should search events with date range", async () => { const nextMonth = new Date(); nextMonth.setMonth(nextMonth.getMonth() + 1); const monthAfterNext = new Date(nextMonth); monthAfterNext.setMonth(monthAfterNext.getMonth() + 1); const searchResults = await calendarModule.searchEvents( "meeting", 5, nextMonth.toISOString(), monthAfterNext.toISOString() ); expect(Array.isArray(searchResults)).toBe(true); console.log(`Found ${searchResults.length} "meeting" events in future date range`); if (searchResults.length > 0) { for (const event of searchResults.slice(0, 3)) { console.log(` - "${event.title}" (${event.calendarName})`); } } }, 20000); it("should handle search with no results", async () => { const searchResults = await calendarModule.searchEvents("VeryUniqueEventTitle12345", 5); expect(Array.isArray(searchResults)).toBe(true); expect(searchResults.length).toBe(0); console.log("✅ Handled search with no results correctly"); }, 15000); }); describe("openEvent", () => { it("should open an existing event", async () => { // First get some events to find one we can open const existingEvents = await calendarModule.getEvents(5); if (existingEvents.length > 0 && existingEvents[0].id) { const eventToOpen = existingEvents[0]; const result = await calendarModule.openEvent(eventToOpen.id); if (result.success) { console.log(`✅ Successfully opened event: ${result.message}`); } else { console.log(`ℹ️ Could not open event: ${result.message}`); } expect(typeof result.success).toBe("boolean"); expect(typeof result.message).toBe("string"); } else { console.log("ℹ️ No existing events found to test opening"); } }, 15000); it("should handle opening non-existent event", async () => { const result = await calendarModule.openEvent("non-existent-event-id-12345"); expect(result.success).toBe(false); expect(typeof result.message).toBe("string"); console.log("✅ Handled non-existent event correctly"); }, 10000); }); describe("Error Handling", () => { it("should handle invalid date formats gracefully", async () => { try { const result = await calendarModule.createEvent( "Invalid Date Test", "invalid-start-date", "invalid-end-date" ); expect(result.success).toBe(false); expect(result.message).toBeTruthy(); console.log("✅ Invalid dates were correctly rejected"); } catch (error) { console.log("✅ Invalid dates threw error (expected behavior)"); expect(error instanceof Error).toBe(true); } }, 10000); it("should handle empty event title gracefully", async () => { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const eventEnd = new Date(tomorrow); eventEnd.setHours(tomorrow.getHours() + 1); try { const result = await calendarModule.createEvent( "", tomorrow.toISOString(), eventEnd.toISOString() ); expect(result.success).toBe(false); console.log("✅ Empty title was correctly rejected"); } catch (error) { console.log("✅ Empty title threw error (expected behavior)"); expect(error instanceof Error).toBe(true); } }, 10000); it("should handle past dates gracefully", async () => { const yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); const pastEventEnd = new Date(yesterday); pastEventEnd.setHours(yesterday.getHours() + 1); try { const result = await calendarModule.createEvent( "Past Event Test", yesterday.toISOString(), pastEventEnd.toISOString() ); // Past events might be allowed, so check if it succeeded or failed gracefully if (result.success) { console.log("ℹ️ Past event was allowed (this may be normal behavior)"); } else { console.log("✅ Past event was correctly rejected"); } expect(typeof result.success).toBe("boolean"); } catch (error) { console.log("✅ Past event threw error (expected behavior)"); expect(error instanceof Error).toBe(true); } }, 10000); it("should handle end time before start time gracefully", async () => { const startTime = new Date(); startTime.setDate(startTime.getDate() + 1); startTime.setHours(15, 0, 0, 0); const endTime = new Date(startTime); endTime.setHours(14, 0, 0, 0); // End before start try { const result = await calendarModule.createEvent( "Invalid Time Range Test", startTime.toISOString(), endTime.toISOString() ); expect(result.success).toBe(false); console.log("✅ Invalid time range was correctly rejected"); } catch (error) { console.log("✅ Invalid time range threw error (expected behavior)"); expect(error instanceof Error).toBe(true); } }, 10000); it("should handle empty search text gracefully", async () => { const searchResults = await calendarModule.searchEvents("", 5); expect(Array.isArray(searchResults)).toBe(true); console.log("✅ Handled empty search text correctly"); }, 10000); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/supermemoryai/apple-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server