import { describe, it, expect, beforeAll } from 'vitest'; const BASE_URL = process.env.TEST_URL || process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'; describe('OG Image Generation', () => { const locales = ['de', 'en']; const productSlugs = ['nay2y']; let isServerUp = false; beforeAll(async () => { try { const response = await fetch(`${BASE_URL}/health`).catch(() => null); if (response && response.ok) { const text = await response.text(); if (text.includes('OK')) { isServerUp = true; return; } } console.log( `\n⚠️ KLZ Application not detected at ${BASE_URL}. Skipping integration tests.\n`, ); } catch (e) { isServerUp = false; } }); async function verifyImageResponse(response: Response) { expect(response.status, `Failed to fetch OG image: ${response.url}`).toBe(200); const contentType = response.headers.get('content-type'); expect(contentType, `Incorrect content type: ${contentType}`).toContain('image/png'); const buffer = await response.arrayBuffer(); const bytes = new Uint8Array(buffer); // Check for PNG signature: 89 50 4E 47 0D 0A 1A 0A expect(bytes[0]).toBe(0x89); expect(bytes[1]).toBe(0x50); expect(bytes[2]).toBe(0x4e); expect(bytes[3]).toBe(0x47); // Check that the image is not empty and has a reasonable size expect(bytes.length, `Image size too small: ${bytes.length} bytes`).toBeGreaterThan(4000); } locales.forEach((locale) => { it(`should generate main OG image for ${locale}`, async ({ skip }) => { if (!isServerUp) skip(); const url = `${BASE_URL}/${locale}/opengraph-image`; const response = await fetch(url); await verifyImageResponse(response); }, 30000); it(`should generate product OG image for ${locale} with slug ${productSlugs[0]}`, async ({ skip, }) => { if (!isServerUp) skip(); const url = `${BASE_URL}/${locale}/api/og/product?slug=${productSlugs[0]}`; const response = await fetch(url); await verifyImageResponse(response); }, 30000); it(`should return 400 for product OG image without slug in ${locale}`, async ({ skip }) => { if (!isServerUp) skip(); const url = `${BASE_URL}/${locale}/api/og/product`; const response = await fetch(url); expect(response.status).toBe(400); }, 30000); }); it('should generate static blog overview OG image', async ({ skip }) => { if (!isServerUp) skip(); const url = `${BASE_URL}/de/blog/opengraph-image`; const response = await fetch(url); await verifyImageResponse(response); }, 30000); it('should generate dynamic blog post OG image with featured photo', async ({ skip }) => { if (!isServerUp) skip(); // Discover a real blog slug from the sitemap const sitemapRes = await fetch(`${BASE_URL}/sitemap.xml`); const sitemapXml = await sitemapRes.text(); const blogMatch = sitemapXml.match(/[^<]*\/de\/blog\/([^<]+)<\/loc>/); const slug = blogMatch ? blogMatch[1] : null; if (!slug) { console.log('⚠️ No blog post found in sitemap, skipping dynamic OG test'); skip(); return; } const url = `${BASE_URL}/de/blog/${slug}/opengraph-image`; const response = await fetch(url); await verifyImageResponse(response); // Verify the image is substantially large (>50KB) to confirm it actually // contains the featured photo and isn't just a tiny fallback/text-only image const buffer = await response.clone().arrayBuffer(); expect( buffer.byteLength, `OG image for "${slug}" is suspiciously small (${buffer.byteLength} bytes) — likely missing featured photo`, ).toBeGreaterThan(50000); }, 30000); });