Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | /** * Test Runner API * POST /api/admin/dev-tools/tests - Run tests * GET /api/admin/dev-tools/tests - Get test status */ import { NextRequest, NextResponse } from 'next/server'; import { } from "next-auth"; import { withAdmin, withErrorHandling, successResponse, ApiError, ApiSuccessResponse, ApiErrorResponse } from "@/lib/api"; import { } from "@/lib/api/middleware"; import { runTests, isProcessRunning, killProcess } from '@/lib/dev-tools/command-runner'; import { parseJestOutput } from '@/lib/dev-tools/output-parsers'; import type { CommandStatusResponse } from '@/lib/dev-tools/types'; const PROCESS_ID = 'dev-tools-tests'; // Store last result let lastResult: CommandStatusResponse = { status: 'idle' }; /** * POST - Run tests */ async function handlePost(request: NextRequest): Promise<NextResponse<ApiSuccessResponse<unknown> | ApiErrorResponse>> { // Check if tests are already running if (isProcessRunning(PROCESS_ID)) { throw ApiError.conflict('Tests are already running'); } const body = await request.json().catch(() => ({})); const { pattern, coverage } = body as { pattern?: string; coverage?: boolean }; // Update status to running lastResult = { status: 'running', startedAt: new Date().toISOString() }; // Run tests asynchronously runTests({ pattern, coverage, processId: PROCESS_ID }) .then((result) => { const parsedResult = parseJestOutput(result.output + result.error, result.exitCode); lastResult = { status: result.success ? 'completed' : 'failed', output: result.output + result.error, result: parsedResult, startedAt: lastResult.startedAt, completedAt: new Date().toISOString() }; }) .catch((error) => { lastResult = { status: 'failed', output: error.message, startedAt: lastResult.startedAt, completedAt: new Date().toISOString() }; }); return successResponse({ success: true, message: 'Tests started', status: 'running' }); } /** * GET - Get test status */ async function handleGet(): Promise<NextResponse<ApiSuccessResponse<CommandStatusResponse> | ApiErrorResponse>> { // Check if still running if (lastResult.status === 'running' && !isProcessRunning(PROCESS_ID)) { // Process ended but we didn't catch the result - mark as failed lastResult.status = 'failed'; lastResult.completedAt = new Date().toISOString(); } return successResponse(lastResult); } /** * DELETE - Stop running tests */ async function handleDelete(): Promise<NextResponse<ApiSuccessResponse<unknown> | ApiErrorResponse>> { if (!isProcessRunning(PROCESS_ID)) { throw ApiError.notFound('No tests running'); } const killed = killProcess(PROCESS_ID); if (killed) { lastResult = { status: 'failed', output: 'Tests cancelled by user', startedAt: lastResult.startedAt, completedAt: new Date().toISOString() }; return successResponse({ success: true, message: 'Tests stopped' }); } throw ApiError.internal('Failed to stop tests'); } export const GET = withErrorHandling(withAdmin(handleGet)); export const POST = withErrorHandling(withAdmin(handlePost)); export const DELETE = withErrorHandling(withAdmin(handleDelete)); |