import { describe, it, expect } from 'vitest'; import fs from 'fs'; import path from 'path'; import matter from 'gray-matter'; import { getAllProducts } from '../lib/products'; const productsDir = path.join(process.cwd(), 'content', 'products'); const productFiles = fs.readdirSync(productsDir).filter((f) => f.endsWith('.mdx')); interface CatalogEntry { slug: string; parseable: boolean; error?: string; declaresImages: boolean; } // Single parse pass at module load, mirroring the production loader's first // touch of each file (gray-matter caches per input string, so re-parsing the // same file inside individual tests would not re-throw parse errors). const catalog: CatalogEntry[] = productFiles.map((file) => { const raw = fs.readFileSync(path.join(productsDir, file), 'utf-8'); try { const { data } = matter(raw); return { slug: file.replace('.mdx', ''), parseable: true, declaresImages: Array.isArray(data.images) && data.images.length > 0, }; } catch (error) { return { slug: file.replace('.mdx', ''), parseable: false, error: `${file}: ${(error as Error).message.split('\n')[0]}`, // An unparseable file cannot declare anything and must never silently // shrink the expected catalog — require it to be listed. declaresImages: true, }; } }); const ALUMINIUM_LOW_VOLTAGE_SLUGS = ['nayy', 'naycwy', 'nay2y', 'na2xy', 'na2x2y']; describe('Product catalog content contract', () => { it('every product file has parseable frontmatter', () => { expect(catalog.filter((entry) => !entry.parseable).map((e) => e.error)).toEqual([]); }); it('exposes every product that declares images in the catalog listing', async () => { const expected = catalog .filter((entry) => entry.declaresImages) .map((e) => e.slug) .sort(); const actual = (await getAllProducts('de')).map((p) => p.slug).sort(); expect(actual).toEqual(expected); }); it('lists all aluminium low-voltage cable types (NAYY, NAYCWY, NAY2Y, NA2XY, NA2X2Y)', async () => { const slugs = (await getAllProducts('de')).map((p) => p.slug); for (const slug of ALUMINIUM_LOW_VOLTAGE_SLUGS) { expect(slugs).toContain(slug); } }); it('categorizes the aluminium low-voltage types as Niederspannungskabel', async () => { const products = await getAllProducts('de'); for (const slug of ALUMINIUM_LOW_VOLTAGE_SLUGS) { const product = products.find((p) => p.slug === slug); expect(product?.frontmatter.categories[0]).toBe('Niederspannungskabel'); } }); });