diff --git a/src/__tests__/api/sync/preview.test.ts b/src/__tests__/api/sync/preview.test.ts new file mode 100644 index 0000000..45e18ef --- /dev/null +++ b/src/__tests__/api/sync/preview.test.ts @@ -0,0 +1,63 @@ +import { GET } from '@/app/api/sync/preview/route' +import { NextRequest } from 'next/server' + +jest.mock('@/lib/googleSheets', () => ({ + readSheetProducts: jest.fn(), +})) +jest.mock('@/lib/shopifySync', () => ({ + fetchAllShopifyProducts: jest.fn(), +})) +jest.mock('@/lib/syncDiff', () => ({ + computeDiff: jest.fn(), +})) + +import { readSheetProducts } from '@/lib/googleSheets' +import { fetchAllShopifyProducts } from '@/lib/shopifySync' +import { computeDiff } from '@/lib/syncDiff' + +const mockSheets = readSheetProducts as jest.Mock +const mockShopify = fetchAllShopifyProducts as jest.Mock +const mockDiff = computeDiff as jest.Mock + +describe('GET /api/sync/preview', () => { + beforeEach(() => jest.clearAllMocks()) + + it('retourne le DiffResult complet', async () => { + const fakeSheetProducts = [{ ref: 'REF-1', handle: 'ref-1', title: 'T', description: '', price: '10.00', stock: 1, status: 'active' }] + const fakeShopifyProducts = [] + const fakeDiff = { + changes: [{ type: 'create', ref: 'REF-1', sheetProduct: fakeSheetProducts[0] }], + summary: { create: 1, update: 0, deactivate: 0, unchanged: 0 }, + } + + mockSheets.mockResolvedValue(fakeSheetProducts) + mockShopify.mockResolvedValue(fakeShopifyProducts) + mockDiff.mockReturnValue(fakeDiff) + + const req = new NextRequest('http://localhost/api/sync/preview') + const res = await GET(req) + + expect(res.status).toBe(200) + const data = await res.json() + expect(data.summary.create).toBe(1) + expect(data.changes).toHaveLength(1) + expect(mockDiff).toHaveBeenCalledWith(fakeSheetProducts, fakeShopifyProducts) + }) + + it('retourne 500 si Google Sheets échoue', async () => { + mockSheets.mockRejectedValue(new Error('Google Auth error')) + const req = new NextRequest('http://localhost/api/sync/preview') + const res = await GET(req) + expect(res.status).toBe(500) + const data = await res.json() + expect(data.error).toBeTruthy() + }) + + it('retourne 500 si Shopify échoue', async () => { + mockSheets.mockResolvedValue([]) + mockShopify.mockRejectedValue(new Error('Shopify error')) + const req = new NextRequest('http://localhost/api/sync/preview') + const res = await GET(req) + expect(res.status).toBe(500) + }) +}) diff --git a/src/app/api/sync/preview/route.ts b/src/app/api/sync/preview/route.ts new file mode 100644 index 0000000..dadf785 --- /dev/null +++ b/src/app/api/sync/preview/route.ts @@ -0,0 +1,19 @@ +import { NextRequest, NextResponse } from 'next/server' +import { readSheetProducts } from '@/lib/googleSheets' +import { fetchAllShopifyProducts } from '@/lib/shopifySync' +import { computeDiff } from '@/lib/syncDiff' + +export async function GET(_req: NextRequest) { + try { + const [sheetProducts, shopifyProducts] = await Promise.all([ + readSheetProducts(), + fetchAllShopifyProducts(), + ]) + + const diff = computeDiff(sheetProducts, shopifyProducts) + return NextResponse.json(diff) + } catch (err) { + const message = err instanceof Error ? err.message : 'Erreur inconnue' + return NextResponse.json({ error: message }, { status: 500 }) + } +}