import updateTasks from '../../../scripts/modules/task-manager/update-tasks.js'; import { readJSON, writeJSON } from '../../../scripts/modules/utils.js'; import fs from 'fs'; import path from 'path'; describe('update-tasks with generateObject', () => { const testTasksFile = path.join(process.cwd(), 'test-tasks.json'); beforeEach(() => { // Create a test tasks file const testTasks = { projectName: 'Test Project', tasks: [ { id: 1, title: 'Setup project structure', description: 'Initialize the project with proper folder structure', status: 'done', dependencies: [], priority: 'high', details: 'Create folders for src, tests, docs', testStrategy: 'Manual verification', subtasks: [] }, { id: 2, title: 'Implement authentication', description: 'Add user authentication with JWT tokens', status: 'pending', dependencies: [1], priority: 'high', details: 'Need to support OAuth2 and traditional login', testStrategy: null, subtasks: [ { id: 1, title: 'Design auth flow', description: 'Create authentication flow diagrams', status: 'done', dependencies: [] } ] }, { id: 3, title: 'Build API endpoints', description: 'Create RESTful API endpoints', status: 'in-progress', dependencies: [2], priority: 'medium', details: 'Use Express.js for the API', testStrategy: 'Integration tests with Jest', subtasks: [] }, { id: 4, title: 'Add database layer', description: 'Implement database models and migrations', status: 'pending', dependencies: [1], priority: 'high', details: null, testStrategy: null, subtasks: [] } ] }; fs.writeFileSync(testTasksFile, JSON.stringify(testTasks, null, 2)); }); afterEach(() => { // Clean up test files if (fs.existsSync(testTasksFile)) { fs.unlinkSync(testTasksFile); } }); test('should update multiple tasks with structured data', async () => { const result = await updateTasks( testTasksFile, 2, // Update from task ID 2 onwards 'Switch to microservices architecture with Docker containers' ); expect(result).toBeDefined(); expect(result).toHaveProperty('updatedTasks'); expect(result).toHaveProperty('telemetryData'); // Read the updated file const updatedData = JSON.parse(fs.readFileSync(testTasksFile, 'utf8')); // Task 1 should remain unchanged (status: done) const task1 = updatedData.tasks.find((t) => t.id === 1); expect(task1.title).toBe('Setup project structure'); expect(task1.status).toBe('done'); // Tasks 2, 3, and 4 should be updated const task2 = updatedData.tasks.find((t) => t.id === 2); expect(task2.description.toLowerCase()).toContain('microservice'); // Completed subtasks should be preserved expect( task2.subtasks.find((st) => st.id === 1 && st.status === 'done') ).toBeDefined(); const task3 = updatedData.tasks.find((t) => t.id === 3); expect(task3.description.toLowerCase()).toContain('docker'); const task4 = updatedData.tasks.find((t) => t.id === 4); expect(task4.description.toLowerCase()).toMatch( /microservice|docker|container/ ); }, 30000); // Increase timeout for AI call test('should preserve completed subtasks when updating', async () => { await updateTasks( testTasksFile, 2, 'Add comprehensive error handling and logging' ); const updatedData = JSON.parse(fs.readFileSync(testTasksFile, 'utf8')); const task2 = updatedData.tasks.find((t) => t.id === 2); // Find the completed subtask const completedSubtask = task2.subtasks.find((st) => st.id === 1); expect(completedSubtask).toBeDefined(); expect(completedSubtask.status).toBe('done'); expect(completedSubtask.title).toBe('Design auth flow'); expect(completedSubtask.description).toBe( 'Create authentication flow diagrams' ); }, 30000); test('should handle no tasks to update', async () => { const result = await updateTasks( testTasksFile, 10, // Start from non-existent task ID 'Update all tasks' ); expect(result).toBeUndefined(); // File should remain unchanged const data = JSON.parse(fs.readFileSync(testTasksFile, 'utf8')); expect(data.tasks.length).toBe(4); }, 30000); });