UNPKG

alnilam-cli

Version:

Git-native AI career coach that converts multi-year ambitions into weekly execution

242 lines (241 loc) 10.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // Mock the API module before importing the goal command jest.mock('../api.js', () => ({ createGoal: jest.fn(), listGoals: jest.fn(), })); const api_js_1 = require("../api.js"); describe('Goal Management', () => { beforeEach(() => { jest.clearAllMocks(); // Reset console methods jest.spyOn(console, 'log').mockImplementation(() => { }); jest.spyOn(console, 'error').mockImplementation(() => { }); jest.spyOn(process, 'exit').mockImplementation(() => { throw new Error('process.exit called'); }); }); afterEach(() => { jest.restoreAllMocks(); }); describe('Goal Creation', () => { it('should validate horizon values', async () => { const validHorizons = ['multi-year', 'annual', 'quarterly', 'weekly']; validHorizons.forEach(horizon => { expect(validHorizons.includes(horizon)).toBe(true); }); const invalidHorizons = ['daily', 'monthly', 'invalid']; invalidHorizons.forEach(horizon => { expect(validHorizons.includes(horizon)).toBe(false); }); }); it('should create goal with required fields', async () => { const mockGoal = { id: 'test-id', title: 'Test Goal', horizon: 'weekly', created_at: '2025-07-02T10:00:00Z', updated_at: '2025-07-02T10:00:00Z' }; api_js_1.createGoal.mockResolvedValue(mockGoal); const goalData = { title: 'Test Goal', horizon: 'weekly', description: undefined, target_date: undefined, }; const result = await (0, api_js_1.createGoal)(goalData); expect(api_js_1.createGoal).toHaveBeenCalledWith(goalData); expect(result).toEqual(mockGoal); }); it('should create goal with optional fields', async () => { const mockGoal = { id: 'test-id', title: 'Test Goal with Details', horizon: 'quarterly', description: 'A detailed test goal', target_date: '2025-12-31', created_at: '2025-07-02T10:00:00Z', updated_at: '2025-07-02T10:00:00Z' }; api_js_1.createGoal.mockResolvedValue(mockGoal); const goalData = { title: 'Test Goal with Details', horizon: 'quarterly', description: 'A detailed test goal', target_date: '2025-12-31', }; const result = await (0, api_js_1.createGoal)(goalData); expect(api_js_1.createGoal).toHaveBeenCalledWith(goalData); expect(result).toEqual(mockGoal); }); it('should handle createGoal API errors', async () => { const errorMessage = 'Failed to create goal'; api_js_1.createGoal.mockRejectedValue(new Error(errorMessage)); const goalData = { title: 'Test Goal', horizon: 'weekly', description: undefined, target_date: undefined, }; await expect((0, api_js_1.createGoal)(goalData)).rejects.toThrow(errorMessage); }); }); describe('Goal Listing', () => { it('should list goals without filters', async () => { const mockGoals = [ { id: 'goal-1', title: 'Goal 1', horizon: 'weekly', status: 'active', created_at: '2025-07-01T10:00:00Z', }, { id: 'goal-2', title: 'Goal 2', horizon: 'quarterly', status: 'active', created_at: '2025-07-02T10:00:00Z', } ]; api_js_1.listGoals.mockResolvedValue(mockGoals); const result = await (0, api_js_1.listGoals)({}); expect(api_js_1.listGoals).toHaveBeenCalledWith({}); expect(result).toEqual(mockGoals); expect(result).toHaveLength(2); }); it('should list goals with horizon filter', async () => { const mockGoals = [ { id: 'goal-1', title: 'Weekly Goal', horizon: 'weekly', status: 'active', created_at: '2025-07-01T10:00:00Z', } ]; api_js_1.listGoals.mockResolvedValue(mockGoals); const params = { horizon: 'weekly', status: 'active' }; const result = await (0, api_js_1.listGoals)(params); expect(api_js_1.listGoals).toHaveBeenCalledWith(params); expect(result).toEqual(mockGoals); expect(result[0].horizon).toBe('weekly'); }); it('should validate horizon filter values', async () => { const validHorizons = ['multi-year', 'annual', 'quarterly', 'weekly']; validHorizons.forEach(horizon => { expect(validHorizons.includes(horizon)).toBe(true); }); const invalidHorizons = ['daily', 'monthly', 'invalid']; invalidHorizons.forEach(horizon => { expect(validHorizons.includes(horizon)).toBe(false); }); }); it('should handle empty goal list', async () => { api_js_1.listGoals.mockResolvedValue([]); const result = await (0, api_js_1.listGoals)({}); expect(api_js_1.listGoals).toHaveBeenCalledWith({}); expect(result).toEqual([]); expect(result).toHaveLength(0); }); it('should handle listGoals API errors', async () => { const errorMessage = 'Failed to fetch goals'; api_js_1.listGoals.mockRejectedValue(new Error(errorMessage)); await expect((0, api_js_1.listGoals)({})).rejects.toThrow(errorMessage); }); }); describe('Goal Data Validation', () => { it('should handle goals with all optional fields', async () => { const completeGoal = { id: 'complete-goal', title: 'Complete Goal', horizon: 'annual', description: 'A goal with all fields', target_date: '2025-12-31', status: 'active', created_at: '2025-07-02T10:00:00Z', updated_at: '2025-07-02T10:00:00Z' }; api_js_1.listGoals.mockResolvedValue([completeGoal]); const result = await (0, api_js_1.listGoals)({}); expect(result[0]).toMatchObject({ id: expect.any(String), title: expect.any(String), horizon: expect.stringMatching(/^(multi-year|annual|quarterly|weekly)$/), description: expect.any(String), target_date: expect.stringMatching(/^\d{4}-\d{2}-\d{2}$/), status: expect.any(String), created_at: expect.any(String), updated_at: expect.any(String) }); }); it('should handle goals with minimal fields', async () => { const minimalGoal = { id: 'minimal-goal', title: 'Minimal Goal', horizon: 'weekly', status: 'active', created_at: '2025-07-02T10:00:00Z', }; api_js_1.listGoals.mockResolvedValue([minimalGoal]); const result = await (0, api_js_1.listGoals)({}); expect(result[0]).toMatchObject({ id: expect.any(String), title: expect.any(String), horizon: expect.stringMatching(/^(multi-year|annual|quarterly|weekly)$/), status: expect.any(String), created_at: expect.any(String) }); // Optional fields should be undefined expect(result[0].description).toBeUndefined(); expect(result[0].target_date).toBeUndefined(); expect(result[0].updated_at).toBeUndefined(); }); }); describe('Date Handling', () => { it('should handle valid date formats', () => { const validDates = [ '2025-07-02', '2025-12-31', '2026-01-01' ]; validDates.forEach(date => { expect(date).toMatch(/^\d{4}-\d{2}-\d{2}$/); expect(new Date(date).toString()).not.toBe('Invalid Date'); }); }); it('should detect invalid date formats', () => { const invalidDates = [ '07-02-2025', '2025/07/02', '2025-13-01', 'invalid-date' ]; invalidDates.forEach(date => { if (date.match(/^\d{4}-\d{2}-\d{2}$/)) { // Check if it's a valid date even if format is correct const dateObj = new Date(date); expect(dateObj.toString()).toBe('Invalid Date'); } else { // Format is incorrect expect(date).not.toMatch(/^\d{4}-\d{2}-\d{2}$/); } }); }); }); describe('Status Values', () => { it('should handle valid status values', () => { const validStatuses = ['active', 'completed', 'paused', 'cancelled']; validStatuses.forEach(status => { expect(['active', 'completed', 'paused', 'cancelled']).toContain(status); }); }); it('should default to active status', () => { const defaultStatus = 'active'; expect(['active', 'completed', 'paused', 'cancelled']).toContain(defaultStatus); }); }); });