/** * Per-task enqueue-acties zijn gedeprecateerd. cancelClaudeJobAction blijft * actief — gebruikt voor het annuleren van losse jobs (bv. idea-jobs). */ import { describe, it, expect, vi, beforeEach } from 'vitest' const { mockGetSession, mockFindFirstJob, mockUpdateJob, mockExecuteRaw, } = vi.hoisted(() => ({ mockGetSession: vi.fn(), mockFindFirstJob: vi.fn(), mockUpdateJob: vi.fn(), mockExecuteRaw: vi.fn().mockResolvedValue(undefined), })) vi.mock('next/cache', () => ({ revalidatePath: vi.fn() })) vi.mock('@/lib/auth', () => ({ getSession: mockGetSession })) vi.mock('@/lib/prisma', () => ({ prisma: { claudeJob: { findFirst: mockFindFirstJob, update: mockUpdateJob, }, $executeRaw: mockExecuteRaw, }, })) import { enqueueClaudeJobAction, enqueueAllTodoJobsAction, cancelClaudeJobAction, } from '@/actions/claude-jobs' const SESSION_USER = { userId: 'user-1', isDemo: false } beforeEach(() => { vi.clearAllMocks() mockExecuteRaw.mockResolvedValue(undefined) }) describe('enqueueClaudeJobAction (deprecated)', () => { it('retourneert een deprecation-error', async () => { const result = await enqueueClaudeJobAction('task-1') expect(result).toMatchObject({ error: expect.stringContaining('Start Sprint') }) }) }) describe('enqueueAllTodoJobsAction (deprecated)', () => { it('retourneert een deprecation-error', async () => { const result = await enqueueAllTodoJobsAction('prod-1') expect(result).toMatchObject({ error: expect.stringContaining('Start Sprint') }) }) }) describe('cancelClaudeJobAction', () => { it('cancelt een actieve job', async () => { mockGetSession.mockResolvedValue(SESSION_USER) mockFindFirstJob.mockResolvedValue({ id: 'job-1', status: 'QUEUED', task_id: 'task-1', product_id: 'prod-1', }) mockUpdateJob.mockResolvedValue(undefined) const result = await cancelClaudeJobAction('job-1') expect(result).toEqual({ success: true }) expect(mockUpdateJob).toHaveBeenCalledWith({ where: { id: 'job-1' }, data: expect.objectContaining({ status: 'CANCELLED' }), }) }) it('weigert demo-sessie', async () => { mockGetSession.mockResolvedValue({ userId: 'demo', isDemo: true }) const result = await cancelClaudeJobAction('job-1') expect(result).toMatchObject({ error: expect.stringContaining('demo') }) expect(mockUpdateJob).not.toHaveBeenCalled() }) it('retourneert error als job niet gevonden', async () => { mockGetSession.mockResolvedValue(SESSION_USER) mockFindFirstJob.mockResolvedValue(null) const result = await cancelClaudeJobAction('nonexistent') expect(result).toMatchObject({ error: expect.stringContaining('niet gevonden') }) }) it('weigert wanneer job niet meer actief is', async () => { mockGetSession.mockResolvedValue(SESSION_USER) mockFindFirstJob.mockResolvedValue({ id: 'job-1', status: 'DONE', task_id: 'task-1', product_id: 'prod-1', }) const result = await cancelClaudeJobAction('job-1') expect(result).toMatchObject({ error: expect.stringContaining('actieve') }) }) })