Il repo resta al sito: app in radice, piattaforme nel loro repo
apps/sito passa in radice, apps/platforms si toglie: vive in gitea:Adriano/InsanityLab-platforms, con la storia del repo comune. I piani e le specifiche di Longevity e Campus lasciano docs/ e seguono le piattaforme. README e compose: deploy da /opt/docker/insanitylab/src; al primo deploy .env va spostato da apps/sito/.env alla radice. Refs #20 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { avvisi, calendari } from '../src/data/calendari';
|
||||
import { generaCalendariPdf, nomeFilePdf } from '../src/lib/calendario-pdf';
|
||||
|
||||
describe('PDF del calendario', () => {
|
||||
for (const cal of calendari) {
|
||||
it(`${cal.id}: produce un PDF valido`, async () => {
|
||||
const pdf = await generaCalendariPdf([cal]);
|
||||
// Un PDF comincia sempre con %PDF- e finisce con %%EOF: se il documento non venisse
|
||||
// chiuso (`doc.end()` mancante, o un errore a metà) il file arriverebbe monco al
|
||||
// browser, che mostrerebbe una pagina bianca invece di un errore.
|
||||
expect(pdf.subarray(0, 5).toString()).toBe('%PDF-');
|
||||
expect(pdf.subarray(-8).toString()).toContain('%%EOF');
|
||||
expect(pdf.length).toBeGreaterThan(2000);
|
||||
});
|
||||
}
|
||||
|
||||
// La griglia deve stare in una pagina sola: l'incrocio giorno/ora è proprio ciò che si va a
|
||||
// cercare, e spezzarlo a metà rende il documento inutile. Il conteggio si legge dall'oggetto
|
||||
// /Type /Pages, che dichiara quante pagine contiene.
|
||||
it('sta in una pagina sola, anche con le giornate fuori griglia in fondo', async () => {
|
||||
for (const cal of calendari) {
|
||||
const pdf = await generaCalendariPdf([cal], avvisi);
|
||||
const conteggio = /\/Type\s*\/Pages[^>]*?\/Count\s+(\d+)/s.exec(pdf.toString('latin1'));
|
||||
expect(conteggio, `${cal.id}: numero di pagine non dichiarato`).not.toBeNull();
|
||||
expect(Number(conteggio![1]), `${cal.id}: il calendario occupa più di una pagina`).toBe(1);
|
||||
}
|
||||
});
|
||||
|
||||
it('il nome del file distingue i due periodi', () => {
|
||||
const nomi = calendari.map((c) => nomeFilePdf([c]));
|
||||
expect(new Set(nomi).size).toBe(nomi.length);
|
||||
for (const n of nomi) expect(n).toMatch(/^insanitylab-calendario-[a-z0-9-]+\.pdf$/);
|
||||
// Più orari insieme: un nome che nominasse solo il primo farebbe credere che dentro ci
|
||||
// sia quello e basta.
|
||||
expect(nomeFilePdf(calendari)).toBe('insanitylab-calendario-class.pdf');
|
||||
});
|
||||
|
||||
// Un orario per pagina: due griglie sullo stesso foglio si confonderebbero fra loro, e
|
||||
// spezzarne una a metà toglie proprio ciò che si va a cercare, l'incrocio giorno/ora.
|
||||
it('con più orari fa una pagina per ciascuno', async () => {
|
||||
const pdf = await generaCalendariPdf(calendari, avvisi);
|
||||
const conteggio = /\/Type\s*\/Pages[^>]*?\/Count\s+(\d+)/s.exec(pdf.toString('latin1'));
|
||||
expect(conteggio).not.toBeNull();
|
||||
expect(Number(conteggio![1])).toBe(calendari.length);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user