import { describe, it, expect } from 'vitest'; import { getNav, findArea, findLesson, chapterOf, readLessonHtml, resolveAsset } from '../src/lib/campus'; // I test girano sui contenuti reali generati da `npm run sync-campus`. const nav = getNav(); describe('getNav', () => { it('carica aree e capitoli dai contenuti generati', () => { expect(nav).not.toBeNull(); expect(nav!.count).toBeGreaterThan(100); expect(nav!.areas.map((a) => a.slug)).toEqual( ['corso-base', 'slide', 'live-e-ospiti', 'consulenze-masterclass', 'qa']); for (const a of nav!.areas) expect(a.chapters.length).toBeGreaterThan(0); }); }); describe('lookup', () => { it('trova area e guida, e il capitolo della guida', () => { const area = findArea(nav!, 'corso-base'); expect(area?.title).toBe('Corso base'); const l = findLesson(nav!, 'lezione-01-ottimizzazione-del-sonno'); expect(l).toMatchObject({ area: 'corso-base', chapter: 1, label: 'L1' }); expect(chapterOf(nav!, l!)?.title).toBe('Sonno e ritmi'); }); it('ritorna null per slug inesistenti', () => { expect(findArea(nav!, 'inventata')).toBeNull(); expect(findLesson(nav!, 'lezione-99-inventata')).toBeNull(); }); it('la catena prev/next collega tutte le guide in ordine', () => { const all = nav!.areas.flatMap((a) => a.chapters.flatMap((c) => c.lessons)); expect(all[0].prev).toBeNull(); expect(all.at(-1)!.next).toBeNull(); for (let i = 0; i < all.length - 1; i++) expect(all[i].next?.slug).toBe(all[i + 1].slug); }); }); describe('readLessonHtml', () => { it('legge il frammento di una guida esistente', () => { const html = readLessonHtml('lezione-01-ottimizzazione-del-sonno'); expect(html).toContain(''); }); it('ritorna null per una guida inesistente', () => { expect(readLessonHtml('non-esiste')).toBeNull(); }); it('le immagini puntano alla route protetta', () => { const html = readLessonHtml('slide-hrv')!; expect(html).toContain('src="/campus/assets/'); expect(html).not.toContain('src="assets/'); }); }); describe('resolveAsset', () => { it('risolve un asset esistente', () => { expect(resolveAsset('slide/slide-hrv')).toMatch(/campus-content\/assets\/slide\/slide-hrv$/); }); it('rifiuta i path traversal e i path assoluti', () => { expect(resolveAsset('../pages/lezione-01-ottimizzazione-del-sonno.html')).toBeNull(); expect(resolveAsset('../../package.json')).toBeNull(); expect(resolveAsset('/etc/passwd')).toBeNull(); }); it('ritorna null per un asset inesistente', () => { expect(resolveAsset('slide/non-esiste.png')).toBeNull(); }); });