npm test # Unit tests (no auth required)
npm run test:integration # Direct integration tests only (requires Google auth)
npm run test:integration:all # All integration tests (direct + multi-account + LLM + docker)
npm run test:all # Unit + all integration testssrc/tests/unit/- Unit tests (mocked, no external dependencies)src/tests/integration/- Integration tests (real Google Calendar API calls)
Requirements: None - fully self-contained
Coverage:
- Request validation and schema compliance
- Error handling and edge cases
- Date/time parsing and timezone conversion logic
- Mock-based handler functionality
- Tool registration and validation
Run with:
npm testIntegration tests are divided into three categories based on their requirements:
Files: direct-integration.test.ts
Requirements:
- Google OAuth credentials file
- Authenticated test account
- Real Google Calendar access
Setup:
# Set environment variables
export GOOGLE_OAUTH_CREDENTIALS="path/to/your/oauth-credentials.json"
export TEST_CALENDAR_ID="your-test-calendar-id"
# Authenticate test account
npm run dev auth:testWhat these tests do:
- ✅ Create, read, update, delete real calendar events
- ✅ Test multi-calendar operations with batch requests
- ✅ Validate timezone handling with actual Google Calendar API
- ✅ Test recurring event patterns and modifications
- ✅ Verify free/busy queries and calendar listings
- ✅ Performance benchmarking with real API latency
Files: claude-mcp-integration.test.ts, openai-mcp-integration.test.ts
Requirements:
- Google OAuth credentials + authenticated test account (from above)
- LLM API keys
- LLM models that support MCP (Claude) or function calling (OpenAI)
Additional setup:
# Set LLM API keys
export CLAUDE_API_KEY="your-claude-api-key"
export OPENAI_API_KEY="your-openai-api-key"
# Optional: specify models (must support MCP/function calling)
export ANTHROPIC_MODEL="claude-3-5-haiku-20241022" # Default
export OPENAI_MODEL="gpt-4o-mini" # DefaultWhat these tests do:
- ✅ Test end-to-end MCP protocol integration with Claude
- ✅ Test end-to-end MCP protocol integration with OpenAI
- ✅ Validate AI assistant can successfully call calendar tools
- ✅ Test complex multi-step AI workflows
Important LLM Compatibility Notes:
- Claude: Only Claude 3.5+ models support MCP. Earlier models will fail.
- OpenAI: Only GPT-4+ and select GPT-3.5-turbo models support function calling.
- If you see "tool not found" or "function not supported" errors, verify your model selection.
# Default integration run (direct tests only; no LLM credits)
npm run test:integration
# Explicit categories
npm run test:integration:direct
npm run test:integration:multi-account
npm run test:integration:llm
npm run test:integration:docker
npm run test:integration:allAll test:integration:* scripts build the project first, so build/index.js is always up to date for integration runs.
| Variable | Required For | Purpose | Example |
|---|---|---|---|
GOOGLE_OAUTH_CREDENTIALS |
All integration tests | Path to OAuth credentials file | ./gcp-oauth.keys.json |
TEST_CALENDAR_ID |
All integration tests | Target calendar for test operations | test-calendar@gmail.com or primary |
CLAUDE_API_KEY |
Claude integration tests | Anthropic API access | sk-ant-api03-... |
OPENAI_API_KEY |
OpenAI integration tests | OpenAI API access | sk-... |
INVITEE_1 |
Attendee tests | Test attendee email | test1@example.com |
INVITEE_2 |
Attendee tests | Test attendee email | test2@example.com |
| Variable | Purpose | Default | Notes |
|---|---|---|---|
GOOGLE_ACCOUNT_MODE |
Default account nickname for auth flows | normal |
Set to any lowercase nickname (e.g., work, personal) before running npm run auth |
DEBUG_LLM_INTERACTIONS |
Debug logging | false |
Set true for verbose LLM logs |
ANTHROPIC_MODEL |
Claude model | claude-3-5-haiku-20241022 |
Must support MCP |
OPENAI_MODEL |
OpenAI model | gpt-4o-mini |
Must support function calling |
MULTI_ACCOUNT_TESTS |
Enable multi-account.test.ts |
false |
Set to true to run cross-account integration tests |
MULTI_ACCOUNT_IDS |
Comma-separated account nicknames | unset | Example: work,personal (requires tokens for each account) |
-
Obtain Google OAuth Credentials:
- Go to Google Cloud Console
- Create a new project or select existing
- Enable Google Calendar API
- Create OAuth 2.0 credentials (Desktop app type)
- Download credentials JSON file
- Save as
gcp-oauth.keys.jsonin project root
-
Create
.envfile in project root:
# Required for all integration tests
GOOGLE_OAUTH_CREDENTIALS=./gcp-oauth.keys.json
TEST_CALENDAR_ID=test-calendar@gmail.com
# Required for LLM integration tests
CLAUDE_API_KEY=sk-ant-api03-...
OPENAI_API_KEY=sk-...
# Required for attendee tests
INVITEE_1=test1@example.com
INVITEE_2=test2@example.com
# Optional configurations
GOOGLE_ACCOUNT_MODE=test
DEBUG_LLM_INTERACTIONS=false
ANTHROPIC_MODEL=claude-3-5-haiku-20241022
OPENAI_MODEL=gpt-4o-mini- Authenticate Test Account:
# Creates tokens in ~/.config/google-calendar-mcp/tokens.json
npm run dev auth:test- Verify Setup:
# Check authentication status
npm run dev account:status
# Run a simple integration test
npm run test:integration:direct- Run multi-account integration tests (optional):
export MULTI_ACCOUNT_TESTS=true
export MULTI_ACCOUNT_IDS=work,personal
npm run test:integration:multi-accountThese tests verify cross-account list-events merging. Each account listed in MULTI_ACCOUNT_IDS must already be authenticated.
Tip: Authenticate multiple accounts with
npm run account auth <nickname>for each one (e.g.,work,personal). All tokens share the same storage file, so integration tests can switch accounts by passing theaccountparameter.
Authentication Errors:
- "No credentials found": Run
npm run dev auth:testto authenticate - "Token expired": Re-authenticate with
npm run dev auth:test - "Invalid credentials": Check
GOOGLE_OAUTH_CREDENTIALSpath is correct - "Refresh token must be passed": Delete tokens and re-authenticate
API Errors:
- Rate limits: Tests include retry logic, but may still hit limits with frequent runs
- Calendar not found: Verify
TEST_CALENDAR_IDexists and is accessible - Permission denied: Ensure test account has write access to the calendar
- "Invalid time range": Free/busy queries limited to 3 months between timeMin and timeMax
LLM Integration Errors:
- "Invalid API key": Check
CLAUDE_API_KEY/OPENAI_API_KEYare set correctly - "Insufficient credits": LLM tests consume API credits - ensure account has balance
- "Model not found": Verify model name and availability in your API plan
- "Tool not found" or "Function not supported":
- Claude: Ensure using Claude 3.5+ model that supports MCP
- OpenAI: Ensure using GPT-4+ or compatible GPT-3.5-turbo model
- "Maximum tokens exceeded": Some complex tests may hit token limits with verbose models
- Network timeouts: LLM tests may take 2-5 minutes due to AI processing time
Calendar Cleanup:
- Tests attempt to clean up created events automatically
- Failed tests may leave test events in your calendar
- Manually delete events with "Integration Test" or "Test Event" in the title if needed
Test Isolation:
- Use a dedicated test calendar (
TEST_CALENDAR_ID) - Don't use your personal calendar for testing
- Consider creating a separate Google account for testing
Test Duration:
- Unit tests: ~2 seconds
- Direct integration tests: ~30-60 seconds
- LLM integration tests: ~2-5 minutes (due to AI processing)
- Full test suite: ~5-10 minutes (can be longer when Docker/LLM tests are included)
Parallel Execution:
- Unit tests run in parallel by default
- Integration tests run sequentially to avoid API conflicts
- Use
--reporter=verbosefor detailed progress during long test runs
- Enable Debug Logging:
# Debug all LLM interactions
export DEBUG_LLM_INTERACTIONS=true- Run Single Test:
# Run specific test by name pattern
npm run test:integration:direct -- -t "should handle timezone"- Interactive Testing:
# Use the dev menu for quick access to test commands
npm run dev- Use Test Data Factory:
import { TestDataFactory } from './test-data-factory.js';
const factory = new TestDataFactory();
const testEvent = factory.createTestEvent({
summary: 'My Test Event',
start: factory.getTomorrowAt(14, 0),
end: factory.getTomorrowAt(15, 0)
});- Track Created Events:
// Events are automatically tracked for cleanup
const eventId = TestDataFactory.extractEventIdFromResponse(result);- LLM Context Logging:
// Wrap LLM operations for automatic error logging
await executeWithContextLogging('Test Name', async () => {
const response = await llmClient.sendMessage('...');
// Test assertions
});-
Environment Isolation:
- Always use
GOOGLE_ACCOUNT_MODE=testfor testing - Use a dedicated test calendar, not personal calendar
- Consider separate Google account for testing
- Always use
-
Cost Management:
- LLM tests consume API credits
- Run specific tests during development
- Use smaller/cheaper models for initial testing
-
Test Data:
- Tests auto-cleanup created events
- Use unique event titles with timestamps
- Verify cleanup in afterEach hooks
-
Debugging Failures:
- Check
DEBUG_LLM_INTERACTIONSoutput for LLM tests - Verify model compatibility for tool/function support
- Check API quotas and rate limits
- Check