import { describe, expect, it } from 'vitest'; import { generateSkuFromTitle, uniqueSku } from '../domain/sku.js'; describe('generateSkuFromTitle', () => { it('uppercases, strips diacritics and replaces separators with hyphens', () => { expect(generateSkuFromTitle('Espelta ecológica')).toBe('MV-ESPELTA-ECOLOGICA'); expect(generateSkuFromTitle('Aceite de Oliva Virgen Extra')).toBe('MV-ACEITE-DE-OLIVA-VIRGEN-EXTRA'); }); it('handles & by expanding to "AND"', () => { expect(generateSkuFromTitle('Bread & Pastries')).toBe('MV-BREAD-AND-PASTRIES'); }); it('collapses repeated hyphens and trims edges', () => { expect(generateSkuFromTitle(' Hola --- Mundo ')).toBe('MV-HOLA-MUNDO'); }); it('throws when the title is empty or punctuation only', () => { expect(() => generateSkuFromTitle('')).toThrow(); expect(() => generateSkuFromTitle(' ')).toThrow(); expect(() => generateSkuFromTitle('!!!')).toThrow(); }); it('trims to MAX_SKU_LENGTH (100 chars) and strips trailing hyphens', () => { const long = 'a'.repeat(200); const sku = generateSkuFromTitle(long); expect(sku.length).toBeLessThanOrEqual(100); expect(sku.endsWith('-')).toBe(false); }); }); describe('uniqueSku', () => { it('returns the base when free', () => { expect(uniqueSku('MV-ESPELTA', new Set(['MV-OTHER']))).toBe('MV-ESPELTA'); }); it('appends -2, -3, ... on collision', () => { expect(uniqueSku('MV-ESPELTA', new Set(['MV-ESPELTA']))).toBe('MV-ESPELTA-2'); expect(uniqueSku('MV-ESPELTA', new Set(['MV-ESPELTA', 'MV-ESPELTA-2']))).toBe('MV-ESPELTA-3'); }); it('treats existing SKUs case-insensitively', () => { expect(uniqueSku('MV-ESPELTA', new Set(['mv-espelta']))).toBe('MV-ESPELTA-2'); }); it('truncates the base to keep the result <= 100 chars', () => { const base = 'MV-' + 'A'.repeat(120); const result = uniqueSku(base, new Set([base.toLowerCase()])); expect(result.length).toBeLessThanOrEqual(100); expect(result.endsWith('-2')).toBe(true); }); });