diff --git a/src/app/api/creation/preview/route.test.ts b/src/app/api/creation/preview/route.test.ts new file mode 100644 index 0000000..6035751 --- /dev/null +++ b/src/app/api/creation/preview/route.test.ts @@ -0,0 +1,50 @@ +import { GET } from './route' +import * as creationSheets from '@/lib/creationSheets' +import { getServerSession } from 'next-auth' + +jest.mock('next-auth') +jest.mock('@/lib/creationSheets') +jest.mock('@/lib/prisma', () => ({ + prisma: { productCreation: { findMany: jest.fn().mockResolvedValue([]) } }, +})) + +const mockSession = getServerSession as jest.MockedFunction +const mockFetch = creationSheets.fetchPendingProducts as jest.MockedFunction + +const makePending = (tab: string, row: number, specific: Record = {}) => ({ + tab, rowNumber: row, sku: `SKU-${row}`, title: `Produit ${row}`, + priceMarket: '99', priceActual: '79', stock: 5, weightKg: 2, + vendor: 'BOSCH', famille: tab, sousFamille: '', comment: '', + collectionId: '10', subCollectionId: '', hasPhoto: false, + specificFields: specific, +}) + +describe('GET /api/creation/preview', () => { + beforeEach(() => { + mockSession.mockResolvedValue({ user: { id: 'u1', role: 'admin' } } as never) + mockFetch.mockResolvedValue([ + makePending('OUTILLAGE', 2, { 'Puissance (AN)': '1500W' }), + makePending('CARRELAGE', 3), + ]) + }) + + it('retourne 401 sans session', async () => { + mockSession.mockResolvedValue(null) + const res = await GET(new Request('http://localhost') as never) + expect(res.status).toBe(401) + }) + + it('retourne les produits groupés par onglet', async () => { + const res = await GET(new Request('http://localhost') as never) + const body = await res.json() + expect(body.byTab['OUTILLAGE']).toHaveLength(1) + expect(body.byTab['CARRELAGE']).toHaveLength(1) + expect(body.total).toBe(2) + }) + + it('liste les colonnes spécifiques uniques', async () => { + const res = await GET(new Request('http://localhost') as never) + const body = await res.json() + expect(body.specificColumns).toContain('Puissance (AN)') + }) +}) diff --git a/src/app/api/creation/preview/route.ts b/src/app/api/creation/preview/route.ts new file mode 100644 index 0000000..dd6746e --- /dev/null +++ b/src/app/api/creation/preview/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from 'next/server' +import { getServerSession } from 'next-auth' +import { authOptions } from '@/lib/auth' +import { fetchPendingProducts } from '@/lib/creationSheets' +import { prisma } from '@/lib/prisma' +import type { PendingProduct } from '@/types/creation' + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export async function GET(_req: NextRequest) { + const session = await getServerSession(authOptions) + if (!session) return NextResponse.json({ error: 'Non authentifié' }, { status: 401 }) + try { + const existing = await prisma.productCreation.findMany({ select: { sheetTab: true, sheetRow: true } }) + const alreadyCreated = new Set(existing.map(e => `${e.sheetTab}:${e.sheetRow}`)) + const pending = await fetchPendingProducts(alreadyCreated) + const byTab: Record = {} + const specificColumns = new Set() + for (const p of pending) { + if (!byTab[p.tab]) byTab[p.tab] = [] + byTab[p.tab].push(p) + Object.keys(p.specificFields).forEach(k => specificColumns.add(k)) + } + return NextResponse.json({ byTab, total: pending.length, specificColumns: Array.from(specificColumns).sort() }) + } catch (err) { + const message = err instanceof Error ? err.message : 'Erreur inconnue' + return NextResponse.json({ error: message }, { status: 500 }) + } +}