Skip to main content
Glama
pshempel

MCP Time Server Node

by pshempel
calculateBusinessHours.extracted.test.ts8.57 kB
/** * Tests for extracted functions from calculateBusinessHours refactor * Following TDD approach - writing tests before implementation */ import type { BusinessHours, DayBusinessHours } from '../../src/types'; import { generateDateRange, processSingleBusinessDay, buildBusinessHoursResult, } from '../../src/tools/calculateBusinessHours'; describe('calculateBusinessHours extracted functions', () => { describe('generateDateRange', () => { it('should generate single date for same day range', () => { const startDate = new Date('2025-01-20T10:00:00Z'); const endDate = new Date('2025-01-20T15:00:00Z'); const timezone = 'America/New_York'; // Expected: Just one date const expected = ['2025-01-20']; const result = generateDateRange(startDate, endDate, timezone); expect(result).toEqual(expected); }); it('should generate multiple dates for multi-day range', () => { const startDate = new Date('2025-01-20T10:00:00Z'); const endDate = new Date('2025-01-22T15:00:00Z'); const timezone = 'America/New_York'; // Expected: Three consecutive dates const expected = ['2025-01-20', '2025-01-21', '2025-01-22']; const result = generateDateRange(startDate, endDate, timezone); expect(result).toEqual(expected); }); it('should handle timezone correctly for date boundaries', () => { // Test case where UTC date differs from local date const startDate = new Date('2025-01-20T23:00:00Z'); // Jan 21 in Tokyo const endDate = new Date('2025-01-21T01:00:00Z'); // Jan 21 in Tokyo const timezone = 'Asia/Tokyo'; // Expected: Just Jan 21 in Tokyo timezone const expected = ['2025-01-21']; const result = generateDateRange(startDate, endDate, timezone); expect(result).toEqual(expected); }); it('should not duplicate dates', () => { // Edge case: range spans midnight const startDate = new Date('2025-01-20T22:00:00Z'); const endDate = new Date('2025-01-21T02:00:00Z'); const timezone = 'UTC'; // Expected: Two dates without duplicates const expected = ['2025-01-20', '2025-01-21']; const result = generateDateRange(startDate, endDate, timezone); expect(result).toEqual(expected); }); }); describe('processSingleBusinessDay', () => { const defaultBusinessHours: BusinessHours = { start: { hour: 9, minute: 0 }, end: { hour: 17, minute: 0 }, }; it('should calculate full day business hours', () => { const params = { dayDateStr: '2025-01-20', startDate: new Date('2025-01-20T08:00:00Z'), // Before business hours endDate: new Date('2025-01-20T18:00:00Z'), // After business hours timezone: 'UTC', businessHours: defaultBusinessHours, holidayDates: [], include_weekends: false, dayOfWeek: 1, // Monday isWeekend: false, }; // Expected: 8 hours (9 AM - 5 PM) const expectedMinutes = 480; const expectedDayResult = { date: '2025-01-20', day_of_week: 'Monday', business_minutes: 480, is_weekend: false, is_holiday: false, }; const result = processSingleBusinessDay(params); expect(result.minutes).toBe(expectedMinutes); expect(result.dayResult).toEqual(expectedDayResult); }); it('should calculate partial day at start', () => { const params = { dayDateStr: '2025-01-20', startDate: new Date('2025-01-20T10:00:00Z'), // 10 AM - after business start endDate: new Date('2025-01-20T18:00:00Z'), // After business hours timezone: 'UTC', businessHours: defaultBusinessHours, holidayDates: [], include_weekends: false, dayOfWeek: 1, // Monday isWeekend: false, }; // Expected: 7 hours (10 AM - 5 PM) const expectedMinutes = 420; const result = processSingleBusinessDay(params); expect(result.minutes).toBe(expectedMinutes); }); it('should calculate partial day at end', () => { const params = { dayDateStr: '2025-01-20', startDate: new Date('2025-01-20T08:00:00Z'), // Before business hours endDate: new Date('2025-01-20T15:00:00Z'), // 3 PM - before business end timezone: 'UTC', businessHours: defaultBusinessHours, holidayDates: [], include_weekends: false, dayOfWeek: 1, // Monday isWeekend: false, }; // Expected: 6 hours (9 AM - 3 PM) const expectedMinutes = 360; const result = processSingleBusinessDay(params); expect(result.minutes).toBe(expectedMinutes); }); it('should return 0 minutes for weekend when not included', () => { const params = { dayDateStr: '2025-01-25', startDate: new Date('2025-01-25T08:00:00Z'), endDate: new Date('2025-01-25T18:00:00Z'), timezone: 'UTC', businessHours: defaultBusinessHours, holidayDates: [], include_weekends: false, dayOfWeek: 6, // Saturday isWeekend: true, }; const expectedMinutes = 0; const expectedDayResult = { date: '2025-01-25', day_of_week: 'Saturday', business_minutes: 0, is_weekend: true, is_holiday: false, }; const result = processSingleBusinessDay(params); expect(result.minutes).toBe(expectedMinutes); expect(result.dayResult).toEqual(expectedDayResult); }); it('should return 0 minutes for holiday', () => { // Create holiday date that will format to '2025-01-20' in UTC // Since we're using UTC timezone, create the date at UTC midnight const holidayDate = new Date(Date.UTC(2025, 0, 20, 0, 0, 0)); const params = { dayDateStr: '2025-01-20', startDate: new Date('2025-01-20T08:00:00Z'), endDate: new Date('2025-01-20T18:00:00Z'), timezone: 'UTC', businessHours: defaultBusinessHours, holidayDates: [holidayDate], include_weekends: false, dayOfWeek: 1, // Monday isWeekend: false, }; const expectedMinutes = 0; const expectedDayResult = { date: '2025-01-20', day_of_week: 'Monday', business_minutes: 0, is_weekend: false, is_holiday: true, }; const result = processSingleBusinessDay(params); expect(result.minutes).toBe(expectedMinutes); expect(result.dayResult).toEqual(expectedDayResult); }); it('should include weekend when include_weekends is true', () => { const params = { dayDateStr: '2025-01-25', startDate: new Date('2025-01-25T08:00:00Z'), endDate: new Date('2025-01-25T18:00:00Z'), timezone: 'UTC', businessHours: defaultBusinessHours, holidayDates: [], include_weekends: true, // Include weekends dayOfWeek: 6, // Saturday isWeekend: true, }; const expectedMinutes = 480; // Full business day const result = processSingleBusinessDay(params); expect(result.minutes).toBe(expectedMinutes); }); }); describe('buildBusinessHoursResult', () => { it('should aggregate results correctly', () => { const breakdown: DayBusinessHours[] = [ { date: '2025-01-20', day_of_week: 'Monday', business_minutes: 480, is_weekend: false, is_holiday: false, }, { date: '2025-01-21', day_of_week: 'Tuesday', business_minutes: 360, is_weekend: false, is_holiday: false, }, { date: '2025-01-22', day_of_week: 'Wednesday', business_minutes: 0, is_weekend: false, is_holiday: true, }, ]; const totalMinutes = 840; // 480 + 360 const expected = { total_business_minutes: 840, total_business_hours: 14, // 840 / 60 breakdown, }; const result = buildBusinessHoursResult(breakdown, totalMinutes); expect(result).toEqual(expected); }); it('should handle empty breakdown', () => { const breakdown: DayBusinessHours[] = []; const totalMinutes = 0; const expected = { total_business_minutes: 0, total_business_hours: 0, breakdown: [], }; const result = buildBusinessHoursResult(breakdown, totalMinutes); expect(result).toEqual(expected); }); }); });

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