import { CalendarService } from '../../src/services/CalendarService';
import { DatabaseManager } from '../../src/database';
import { CacheManager } from '../../src/cache';
import { testUtils } from '../setup';
import { CreateEventInput, CalendarProvider } from '../../src/types';
describe('CalendarService', () => {
let calendarService: CalendarService;
let mockDatabase: jest.Mocked<DatabaseManager>;
let mockCache: jest.Mocked<CacheManager>;
beforeEach(() => {
mockDatabase = testUtils.mockDatabase as jest.Mocked<DatabaseManager>;
mockCache = {
getCalendars: jest.fn().mockResolvedValue(null),
setCalendars: jest.fn().mockResolvedValue(undefined),
getEvents: jest.fn().mockResolvedValue(null),
setEvents: jest.fn().mockResolvedValue(undefined),
invalidateEvents: jest.fn().mockResolvedValue(undefined),
getFreeTime: jest.fn().mockResolvedValue(null),
setFreeTime: jest.fn().mockResolvedValue(undefined),
getUserPreferences: jest.fn().mockResolvedValue(null),
setUserPreferences: jest.fn().mockResolvedValue(undefined),
getContactSuggestions: jest.fn().mockResolvedValue(null),
setContactSuggestions: jest.fn().mockResolvedValue(undefined),
invalidateUser: jest.fn().mockResolvedValue(undefined),
clear: jest.fn().mockResolvedValue(undefined),
ping: jest.fn().mockResolvedValue(true)
};
calendarService = new CalendarService(mockCache, mockDatabase);
});
afterEach(() => {
jest.clearAllMocks();
});
describe('getCalendars', () => {
it('should return cached calendars if available', async () => {
const mockCalendars = [
{
id: 'primary',
title: 'Test Calendar',
timezone: 'UTC',
accessRole: 'owner' as const
}
];
mockCache.getCalendars.mockResolvedValue(mockCalendars);
const result = await calendarService.getCalendars('test-user-id');
expect(result.success).toBe(true);
expect(result.data).toEqual(mockCalendars);
expect(mockCache.getCalendars).toHaveBeenCalledWith('test-user-id');
expect(mockDatabase.getUser).not.toHaveBeenCalled();
});
it('should return error if user not found', async () => {
mockCache.getCalendars.mockResolvedValue(null);
mockDatabase.getUser.mockResolvedValue(null);
const result = await calendarService.getCalendars('nonexistent-user-id');
expect(result.success).toBe(false);
expect(result.error?.code).toBe('USER_NOT_FOUND');
});
});
describe('createEvent', () => {
it('should return error if user not found', async () => {
const eventData: CreateEventInput = {
calendarId: 'primary',
title: 'Test Event',
startTime: '2024-01-01T10:00:00Z',
endTime: '2024-01-01T11:00:00Z'
};
mockDatabase.getUser.mockResolvedValue(null);
const result = await calendarService.createEvent('nonexistent-user-id', eventData);
expect(result.success).toBe(false);
expect(result.error?.code).toBe('USER_NOT_FOUND');
});
});
describe('findFreeTime', () => {
it('should return cached free time if available', async () => {
const criteria = {
calendarIds: ['primary'],
startDate: '2024-01-01T00:00:00Z',
endDate: '2024-01-01T23:59:59Z',
durationMinutes: 60
};
const mockFreeSlots = [
{
start: new Date('2024-01-01T10:00:00Z'),
end: new Date('2024-01-01T11:00:00Z'),
available: true
}
];
mockCache.getFreeTime.mockResolvedValue(mockFreeSlots);
const result = await calendarService.findFreeTime('test-user-id', criteria);
expect(result.success).toBe(true);
expect(result.data).toEqual(mockFreeSlots);
expect(mockDatabase.getUser).not.toHaveBeenCalled();
});
});
describe('getContactSuggestions', () => {
it('should return cached suggestions if available', async () => {
const cachedSuggestions = ['john.doe@example.com', 'john.smith@example.com'];
mockCache.getContactSuggestions.mockResolvedValue(cachedSuggestions);
const result = await calendarService.getContactSuggestions('test-user-id', 'john', 5);
expect(result.success).toBe(true);
expect(result.data).toEqual(cachedSuggestions);
expect(mockDatabase.getUser).not.toHaveBeenCalled();
});
});
});