Files
claude-task-master/tests/integration/commands/expand-task.test.js
2025-10-02 11:54:29 +02:00

149 lines
4.2 KiB
JavaScript

import expandTask from '../../../scripts/modules/task-manager/expand-task.js';
import { readJSON, writeJSON } from '../../../scripts/modules/utils.js';
import fs from 'fs';
import path from 'path';
describe('expand-task 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: 3,
title: 'Build API endpoints',
description: 'Create RESTful API endpoints',
status: 'pending',
dependencies: [2],
priority: 'medium',
details: null,
testStrategy: null,
subtasks: [
{
id: 1,
title: 'Design API schema',
description: 'Create OpenAPI specification',
dependencies: [],
details: 'Use OpenAPI 3.0 specification',
status: 'done'
}
]
}
]
};
fs.writeFileSync(testTasksFile, JSON.stringify(testTasks, null, 2));
});
afterEach(() => {
// Clean up test files
if (fs.existsSync(testTasksFile)) {
fs.unlinkSync(testTasksFile);
}
});
test('should expand task with structured subtasks', async () => {
const result = await expandTask(
testTasksFile,
'2', // taskId as string
3, // numSubtasks
false, // force
'Break down authentication into implementation steps' // additionalContext
);
expect(result).toHaveProperty('task');
expect(result).toHaveProperty('telemetryData');
const { task } = result;
// Verify task was expanded
expect(task.id).toBe(2);
expect(task.subtasks).toBeDefined();
expect(Array.isArray(task.subtasks)).toBe(true);
expect(task.subtasks.length).toBeGreaterThan(0);
// Verify subtask structure
const subtask = task.subtasks[0];
expect(subtask).toHaveProperty('id');
expect(subtask).toHaveProperty('title');
expect(subtask).toHaveProperty('description');
expect(subtask).toHaveProperty('dependencies');
expect(subtask).toHaveProperty('details');
expect(subtask).toHaveProperty('status', 'pending');
// Verify task was written back to file
const savedData = JSON.parse(fs.readFileSync(testTasksFile, 'utf8'));
const savedTask = savedData.tasks.find((t) => t.id === 2);
expect(savedTask.subtasks.length).toBe(task.subtasks.length);
}, 30000); // Increase timeout for AI call
test('should append subtasks when force=false', async () => {
// First expansion
await expandTask(testTasksFile, '3', 2, false);
const dataAfterFirst = JSON.parse(fs.readFileSync(testTasksFile, 'utf8'));
const taskAfterFirst = dataAfterFirst.tasks.find((t) => t.id === 3);
const initialSubtaskCount = taskAfterFirst.subtasks.length;
// Second expansion (append)
await expandTask(
testTasksFile,
'3',
2,
false,
'Add more implementation details'
);
const dataAfterSecond = JSON.parse(fs.readFileSync(testTasksFile, 'utf8'));
const taskAfterSecond = dataAfterSecond.tasks.find((t) => t.id === 3);
// Should have more subtasks than before
expect(taskAfterSecond.subtasks.length).toBeGreaterThan(
initialSubtaskCount
);
}, 60000);
test('should replace subtasks when force=true', async () => {
// First expansion
await expandTask(testTasksFile, '3', 2, false);
// Second expansion with force=true
const result = await expandTask(
testTasksFile,
'3',
3,
true,
'Complete redesign needed'
);
const savedData = JSON.parse(fs.readFileSync(testTasksFile, 'utf8'));
const savedTask = savedData.tasks.find((t) => t.id === 3);
// Should have exactly 3 subtasks (replaced, not appended)
expect(savedTask.subtasks.length).toBe(3);
}, 60000);
});