Skip to main content
Glama
pshempel

MCP Time Server Node

by pshempel
nextOccurrenceWrapper.test.ts6.14 kB
import { nextOccurrence } from '../../src/tools/nextOccurrence'; import type { NextOccurrenceParams } from '../../src/types'; describe('nextOccurrence - RecurrenceFactory Integration', () => { // Fixed date for consistent testing const fixedDate = new Date('2025-01-29T12:00:00Z'); beforeAll(() => { jest.useFakeTimers(); jest.setSystemTime(fixedDate); }); afterAll(() => { jest.useRealTimers(); }); describe('API Compatibility', () => { it('should return correct shape with next, unix, and days_until', () => { const result = nextOccurrence({ pattern: 'daily', start_from: '2025-01-29T10:00:00Z', }); expect(result).toHaveProperty('next'); expect(result).toHaveProperty('unix'); expect(result).toHaveProperty('days_until'); expect(typeof result.next).toBe('string'); expect(typeof result.unix).toBe('number'); expect(typeof result.days_until).toBe('number'); }); it('should handle snake_case parameters correctly', () => { const result = nextOccurrence({ pattern: 'weekly', start_from: '2025-01-29T10:00:00Z', day_of_week: 3, // Wednesday time: '14:30', }); // Since start_from is Wednesday 10am and we want Wednesday at 14:30, // and 14:30 is after 10am, it should be the same day expect(result.next).toBe('2025-01-29T19:30:00.000Z'); }); it('should handle day_of_month for monthly pattern', () => { const result = nextOccurrence({ pattern: 'monthly', start_from: '2025-01-29T10:00:00Z', day_of_month: 15, time: '12:00', }); // 12:00 UTC in system timezone (UTC-5) becomes 17:00 UTC expect(result.next).toBe('2025-02-15T17:00:00.000Z'); }); }); describe('Pattern Handling', () => { it('should handle daily pattern', () => { const result = nextOccurrence({ pattern: 'daily', start_from: '2025-01-29T10:00:00Z', }); expect(result.next).toBe('2025-01-30T10:00:00.000Z'); // Since we're using fake time of Jan 29, next day is 1 day away expect(result.days_until).toBe(1); }); it('should handle weekly pattern', () => { const result = nextOccurrence({ pattern: 'weekly', start_from: '2025-01-29T10:00:00Z', day_of_week: 1, // Monday }); expect(result.next).toBe('2025-02-03T10:00:00.000Z'); }); it('should handle monthly pattern', () => { const result = nextOccurrence({ pattern: 'monthly', start_from: '2025-01-29T10:00:00Z', day_of_month: 31, }); // Jan 31 is the next occurrence (system timezone UTC-5) expect(result.next).toBe('2025-01-31T05:00:00.000Z'); }); it('should handle yearly pattern', () => { const result = nextOccurrence({ pattern: 'yearly', start_from: '2025-01-29T10:00:00Z', }); expect(result.next).toBe('2026-01-29T10:00:00.000Z'); expect(result.days_until).toBe(365); }); }); describe('Timezone Handling', () => { it('should use system timezone when undefined', () => { const result = nextOccurrence({ pattern: 'daily', start_from: '2025-01-29T10:00:00Z', time: '14:30', // timezone undefined }); // System timezone is UTC-5 in test environment expect(result.next).toBe('2025-01-29T19:30:00.000Z'); }); it('should use UTC when timezone is empty string', () => { const result = nextOccurrence({ pattern: 'daily', start_from: '2025-01-29T10:00:00Z', time: '14:30', timezone: '', }); expect(result.next).toBe('2025-01-29T14:30:00.000Z'); }); it('should use specified timezone', () => { const result = nextOccurrence({ pattern: 'daily', start_from: '2025-01-29T10:00:00Z', time: '14:30', timezone: 'America/New_York', }); expect(result.next).toBe('2025-01-29T19:30:00.000Z'); }); }); describe('Unix Timestamp', () => { it('should return correct unix timestamp', () => { const result = nextOccurrence({ pattern: 'daily', start_from: '2025-01-29T10:00:00Z', }); const expectedUnix = new Date(result.next).getTime() / 1000; expect(result.unix).toBe(Math.floor(expectedUnix)); }); }); describe('Days Until Calculation', () => { it('should calculate days_until correctly for same day', () => { const result = nextOccurrence({ pattern: 'daily', start_from: '2025-01-29T08:00:00Z', time: '20:00', }); expect(result.days_until).toBe(0); }); it('should calculate days_until correctly for future dates', () => { const result = nextOccurrence({ pattern: 'yearly', start_from: '2025-01-29T10:00:00Z', }); expect(result.days_until).toBe(365); // 2025 is not a leap year }); }); describe('Error Handling', () => { it('should throw for invalid pattern', () => { expect(() => { nextOccurrence({ pattern: 'invalid' as any, start_from: '2025-01-29T10:00:00Z', } as NextOccurrenceParams); }).toThrow(); }); it('should throw for missing required parameters', () => { expect(() => { nextOccurrence({ pattern: 'monthly', start_from: '2025-01-29T10:00:00Z', // Missing day_of_month }); }).toThrow(); }); it('should validate timezone', () => { expect(() => { nextOccurrence({ pattern: 'daily', start_from: '2025-01-29T10:00:00Z', timezone: 'Invalid/Timezone', }); }).toThrow(); }); }); describe('Caching', () => { it('should cache results with same parameters', () => { const params: NextOccurrenceParams = { pattern: 'daily', start_from: '2025-01-29T10:00:00Z', }; const result1 = nextOccurrence(params); const result2 = nextOccurrence(params); expect(result1).toEqual(result2); }); }); });

Latest Blog Posts

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/pshempel/mcp-time-server-node'

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