Skip to main content
Glama

Google Calendar and Meet MCP Server

by INSIDE-HAIR
validation.test.ts•12.6 kB
/** * Comprehensive Zod validation tests for all 17 Google Meet MCP Server tools * Tests the complete validation implementation added in Phase 2 */ import { describe, it, expect } from "vitest"; import { validateToolArgs, ValidationSchemas } from "../src/validation/meetSchemas.js"; describe("Zod Validation - All 17 Tools", () => { describe("Schema Coverage", () => { it("should have validation schemas for all tools", () => { const expectedTools = [ // Calendar API v3 Tools (6 herramientas) 'calendar_v3_list_calendars', 'calendar_v3_list_events', 'calendar_v3_get_event', 'calendar_v3_create_event', 'calendar_v3_update_event', 'calendar_v3_delete_event', // Meet API v2 Tools (15 herramientas) 'meet_v2_create_space', 'meet_v2_get_space', 'meet_v2_update_space', 'meet_v2_end_active_conference', 'meet_v2_list_conference_records', 'meet_v2_get_conference_record', 'meet_v2_list_recordings', 'meet_v2_get_recording', 'meet_v2_list_transcripts', 'meet_v2_get_transcript', 'meet_v2_list_transcript_entries', 'meet_v2_get_participant', 'meet_v2_list_participants', 'meet_v2_get_participant_session', 'meet_v2_list_participant_sessions' ]; expect(Object.keys(ValidationSchemas)).toHaveLength(21); expectedTools.forEach(toolName => { expect(ValidationSchemas[toolName]).toBeDefined(); expect(ValidationSchemas[toolName]._def).toBeDefined(); // Zod schema structure }); }); it("should export validateToolArgs function", () => { expect(typeof validateToolArgs).toBe("function"); }); }); describe("Calendar API v3 Validation", () => { describe("calendar_v3_list_calendars", () => { it("should accept empty parameters", () => { expect(() => validateToolArgs('calendar_v3_list_calendars', {})).not.toThrow(); }); }); describe("calendar_v3_list_events", () => { it("should validate valid parameters", () => { const validArgs = { max_results: 10, time_min: "2024-01-01T00:00:00Z", time_max: "2024-12-31T23:59:59Z", calendar_id: "primary" }; expect(() => validateToolArgs('calendar_v3_list_events', validArgs)).not.toThrow(); }); it("should reject invalid max_results", () => { const invalidArgs = { max_results: -1 }; expect(() => validateToolArgs('calendar_v3_list_events', invalidArgs)) .toThrow(/Maximum results must be at least 1/); }); it("should reject invalid time format", () => { const invalidArgs = { time_min: "invalid-date" }; expect(() => validateToolArgs('calendar_v3_list_events', invalidArgs)) .toThrow(/Time min must be in ISO 8601 format/); }); }); describe("calendar_v3_get_event", () => { it("should require event_id", () => { expect(() => validateToolArgs('calendar_v3_get_event', {})) .toThrow(/Required/); }); it("should accept valid event_id", () => { const validArgs = { event_id: "test-event-123" }; expect(() => validateToolArgs('calendar_v3_get_event', validArgs)).not.toThrow(); }); }); describe("calendar_v3_create_event", () => { it("should validate complete event creation", () => { const validArgs = { summary: "Test Meeting", start_time: "2024-08-01T10:00:00Z", end_time: "2024-08-01T11:00:00Z", description: "Test description", attendees: ["test@example.com"], create_meet_conference: true }; expect(() => validateToolArgs('calendar_v3_create_event', validArgs)).not.toThrow(); }); it("should reject invalid time range", () => { const invalidArgs = { summary: "Test", start_time: "2024-08-01T11:00:00Z", end_time: "2024-08-01T10:00:00Z" // End before start }; expect(() => validateToolArgs('calendar_v3_create_event', invalidArgs)) .toThrow(/End time must be after start time/); }); it("should reject invalid email addresses", () => { const invalidArgs = { summary: "Test", start_time: "2024-08-01T10:00:00Z", end_time: "2024-08-01T11:00:00Z", attendees: ["invalid-email"] }; expect(() => validateToolArgs('calendar_v3_create_event', invalidArgs)) .toThrow(/Invalid email address/); }); }); describe("calendar_v3_update_event", () => { it("should require event_id", () => { expect(() => validateToolArgs('calendar_v3_update_event', {})) .toThrow(/Required/); }); it("should accept partial updates", () => { const validArgs = { event_id: "test-event-123", summary: "Updated Meeting" }; expect(() => validateToolArgs('calendar_v3_update_event', validArgs)).not.toThrow(); }); }); describe("calendar_v3_delete_event", () => { it("should require event_id", () => { expect(() => validateToolArgs('calendar_v3_delete_event', {})) .toThrow(/Required/); }); }); }); describe("Meet API v2 Validation", () => { describe("meet_v2_create_space", () => { it("should validate complete space creation", () => { const validArgs = { access_type: "TRUSTED", enable_recording: true, enable_transcription: true, moderation_mode: "ON", chat_restriction: "HOSTS_ONLY" }; expect(() => validateToolArgs('meet_v2_create_space', validArgs)).not.toThrow(); }); it("should reject recording for OPEN access", () => { const invalidArgs = { access_type: "OPEN", enable_recording: true }; expect(() => validateToolArgs('meet_v2_create_space', invalidArgs)) .toThrow(/Recording cannot be enabled for OPEN access meetings/); }); it("should require transcription for smart notes", () => { const invalidArgs = { enable_smart_notes: true, enable_transcription: false }; expect(() => validateToolArgs('meet_v2_create_space', invalidArgs)) .toThrow(/Smart notes require transcription to be enabled/); }); }); describe("meet_v2_get_space", () => { it("should validate space name format", () => { const validArgs = { space_name: "spaces/abc-defg-hij" }; expect(() => validateToolArgs('meet_v2_get_space', validArgs)).not.toThrow(); }); it("should reject invalid space name format", () => { const invalidArgs = { space_name: "invalid-space-name" }; expect(() => validateToolArgs('meet_v2_get_space', invalidArgs)) .toThrow(/Space name must be in format: spaces/); }); }); describe("meet_v2_list_conference_records", () => { it("should validate page_size limits", () => { const validArgs = { page_size: 25 }; expect(() => validateToolArgs('meet_v2_list_conference_records', validArgs)).not.toThrow(); }); it("should reject excessive page_size", () => { const invalidArgs = { page_size: 100 }; expect(() => validateToolArgs('meet_v2_list_conference_records', invalidArgs)) .toThrow(/Page size cannot exceed 50/); }); }); describe("meet_v2_get_conference_record", () => { it("should validate conference record name format", () => { const validArgs = { conference_record_name: "conferenceRecords/test-record-123" }; expect(() => validateToolArgs('meet_v2_get_conference_record', validArgs)).not.toThrow(); }); it("should reject invalid format", () => { const invalidArgs = { conference_record_name: "invalid-record-name" }; expect(() => validateToolArgs('meet_v2_get_conference_record', invalidArgs)) .toThrow(/Conference record name must be in format: conferenceRecords/); }); }); describe("meet_v2_get_recording", () => { it("should validate recording name format", () => { const validArgs = { recording_name: "conferenceRecords/test-record/recordings/test-recording" }; expect(() => validateToolArgs('meet_v2_get_recording', validArgs)).not.toThrow(); }); it("should reject invalid recording format", () => { const invalidArgs = { recording_name: "invalid-recording-name" }; expect(() => validateToolArgs('meet_v2_get_recording', invalidArgs)) .toThrow(/Recording name must be in format: conferenceRecords/); }); }); describe("meet_v2_get_transcript", () => { it("should validate transcript name format", () => { const validArgs = { transcript_name: "conferenceRecords/test-record/transcripts/test-transcript" }; expect(() => validateToolArgs('meet_v2_get_transcript', validArgs)).not.toThrow(); }); }); describe("meet_v2_list_transcript_entries", () => { it("should validate page_size for transcript entries", () => { const validArgs = { transcript_name: "conferenceRecords/test-record/transcripts/test-transcript", page_size: 500 }; expect(() => validateToolArgs('meet_v2_list_transcript_entries', validArgs)).not.toThrow(); }); it("should reject excessive page_size for transcript entries", () => { const invalidArgs = { transcript_name: "conferenceRecords/test-record/transcripts/test-transcript", page_size: 2000 }; expect(() => validateToolArgs('meet_v2_list_transcript_entries', invalidArgs)) .toThrow(/Page size cannot exceed 1000/); }); }); describe("meet_v2_get_participant", () => { it("should validate participant name format", () => { const validArgs = { participant_name: "conferenceRecords/test-record/participants/test-participant" }; expect(() => validateToolArgs('meet_v2_get_participant', validArgs)).not.toThrow(); }); }); describe("meet_v2_get_participant_session", () => { it("should validate participant session name format", () => { const validArgs = { participant_session_name: "conferenceRecords/test-record/participants/test-participant/participantSessions/test-session" }; expect(() => validateToolArgs('meet_v2_get_participant_session', validArgs)).not.toThrow(); }); it("should reject invalid session format", () => { const invalidArgs = { participant_session_name: "invalid-session-name" }; expect(() => validateToolArgs('meet_v2_get_participant_session', invalidArgs)) .toThrow(/Participant session name must be in format/); }); }); }); describe("Error Handling", () => { it("should handle unknown tool names gracefully", () => { expect(() => validateToolArgs('unknown_tool', {})).not.toThrow(); }); it("should provide helpful error messages", () => { try { validateToolArgs('calendar_v3_create_event', { summary: "", start_time: "invalid-date", end_time: "2024-08-01T11:00:00Z" }); } catch (error) { expect(error.message).toContain('āŒ Validation failed for calendar_v3_create_event'); expect(error.message).toContain('šŸ’” Tip:'); } }); it("should validate all required fields", () => { expect(() => validateToolArgs('calendar_v3_create_event', {})) .toThrow(/Required/); }); }); describe("Integration Test", () => { it("should validate all tools without throwing unexpected errors", () => { const testCases = [ { tool: 'calendar_v3_list_calendars', args: {} }, { tool: 'calendar_v3_get_event', args: { event_id: 'test' } }, { tool: 'meet_v2_get_space', args: { space_name: 'spaces/test-space' } }, { tool: 'meet_v2_list_conference_records', args: { page_size: 10 } } ]; testCases.forEach(({ tool, args }) => { expect(() => validateToolArgs(tool, args)).not.toThrow(); }); }); }); });

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/INSIDE-HAIR/mcp-google-calendar-and-meet'

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