export const mockTask = {
id: 'test_task_001',
name: 'Test Task',
status: { status: 'to do', color: '#d3d3d3', type: 'open' },
priority: { id: '3', priority: 'normal', color: '#6fddff' },
date_created: '1695000000000',
date_updated: '1695000000000',
due_date: null,
assignees: [],
tags: [],
url: 'https://app.clickup.com/t/test_task_001',
list: { id: '900100200300', name: 'Test List' },
folder: { id: '456', name: 'Test Folder' },
space: { id: '789' },
custom_fields: [],
};
export const mockTeam = {
teams: [{
id: '1234567',
name: 'Test Workspace',
members: [{ user: { id: 183, username: 'testuser', email: 'test@example.com' } }],
}],
};
export function mockClickUpFetch() {
return vi.fn(async (url: string, options?: RequestInit) => {
const path = new URL(url).pathname.replace('/api/v2', '');
const routes: Record<string, any> = {
'/team': mockTeam,
'/user': { user: { id: 183, username: 'testuser' } },
};
if (path.match(/^\/task\/.+/)) return jsonResponse(mockTask);
if (path.match(/^\/list\/.+\/task$/) && options?.method === 'POST') {
return jsonResponse({ ...mockTask, ...JSON.parse(options.body as string) });
}
return jsonResponse(routes[path] ?? {}, routes[path] ? 200 : 404);
});
}
function jsonResponse(data: any, status = 200) {
return new Response(JSON.stringify(data), {
status,
headers: {
'Content-Type': 'application/json',
'X-RateLimit-Remaining': '95',
'X-RateLimit-Limit': '100',
'X-RateLimit-Reset': String(Math.floor(Date.now() / 1000) + 60),
},
});
}
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mockClickUpFetch, mockTask } from '../mocks/clickup';
describe('ClickUp Task Operations', () => {
beforeEach(() => {
vi.stubGlobal('fetch', mockClickUpFetch());
vi.stubEnv('CLICKUP_API_TOKEN', 'pk_test_token');
});
it('creates a task with required fields', async () => {
const { createTask } = await import('../../src/clickup/tasks');
const task = await createTask('list123', { name: 'New Task' });
expect(task.name).toBe('New Task');
expect(fetch).toHaveBeenCalledWith(
expect.stringContaining('/list/list123/task'),
expect.objectContaining({ method: 'POST' }),
);
});
it('gets a task by ID', async () => {
const { getTask } = await import('../../src/clickup/tasks');
const task = await getTask('test_task_001');
expect(task.id).toBe(mockTask.id);
});
});
import { describe, it, expect } from 'vitest';
import 'dotenv/config';
const LIVE = process.env.CLICKUP_LIVE === '1';
describe.skipIf(!LIVE)('ClickUp Live API', () => {
it('authenticates and lists workspaces', async () => {
const response = await fetch('https://api.clickup.com/api/v2/team', {
headers: { 'Authorization': process.env.CLICKUP_API_TOKEN! },
});
expect(response.ok).toBe(true);
const data = await response.json();
expect(data.teams.length).toBeGreaterThan(0);
});
});