Files
parenthese/backend/test/gedcom-photos.test.ts
T
IliesAllaliandClaude Opus 5.5 83443ac9dc Premières photos : import dès la création, photos du logiciel retrouvées, premiers visages
- Création d'arbre : « J'ai déjà un arbre » importe le .ged sans fiche « vous » en double.
- Import GEDCOM : lit les photos citées (OBJE / FILE, en ligne ou par renvoi, _PRIM d'abord)
  et renvoie leur chemin ; rien n'est gardé côté serveur.
- Fenêtre « Il manque les visages » après un import : dossier des photos apparié par nom de
  fichier, cinq visages à demander (famille de « Moi », sinon les plus jeunes).
- Portrait vide chez le propriétaire : cadre cliquable sur la fiche hors édition, « + photo »
  au survol sur l'arbre.
- Photos de plus de 5 Mo réduites à 2000 px avant l'envoi ; portraits à 120 envois par minute.
- PostHog : gedcom_imported, portraits_bulk_placed, portrait_added (effectifs arrondis).
- Corrigé : une union à un seul parent connu relie ses enfants à ce parent, sous un seul
  « Inconnu », au lieu de les laisser sans lien.
- Corrigé : réimporter un GEDCOM reprend les personnes, unions et liens déjà présents au lieu
  de tout doubler.

Recette locale (vraie API, vraie base) : 29/29 sur le parcours photos, 47/47 sur la recette
de non-régression des parcours. Tests 123 serveur, 107 app, lint et build propres.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 18:54:56 +02:00

75 lines
2.1 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { indexObjeRecords, photoPathForPerson } from '../src/lib/gedcom-photos'
import { parseGedcom } from '../src/routes/gedcom'
function photosOf(text: string): Record<string, string | null> {
const roots = parseGedcom(text)
const objes = indexObjeRecords(roots)
const out: Record<string, string | null> = {}
for (const indi of roots.filter((n) => n.tag === 'INDI' && n.xref)) {
out[indi.xref!] = photoPathForPerson(indi, objes)
}
return out
}
describe('photos citées par un GEDCOM', () => {
it('lit un OBJE écrit sous la personne (GEDCOM 5.5)', () => {
const text = [
'0 @I1@ INDI',
'1 NAME Jean /Dupont/',
'1 OBJE',
'2 FORM jpg',
'2 FILE C:\\Genealogie\\Photos\\jean.jpg',
].join('\n')
expect(photosOf(text)).toEqual({ I1: 'C:\\Genealogie\\Photos\\jean.jpg' })
})
it('suit un renvoi vers un enregistrement OBJE (Gramps, GEDCOM 5.5.1)', () => {
const text = [
'0 @I1@ INDI',
'1 NAME Marie /Martin/',
'1 OBJE @M7@',
'0 @M7@ OBJE',
'1 FILE photos/marie 1920.png',
'2 FORM png',
].join('\n')
expect(photosOf(text)).toEqual({ I1: 'photos/marie 1920.png' })
})
it('préfère la photo marquée principale, sinon la première image', () => {
const text = [
'0 @I1@ INDI',
'1 OBJE',
'2 FILE acte-naissance.pdf',
'1 OBJE',
'2 FILE groupe.jpg',
'1 OBJE',
'2 FILE portrait.jpg',
'2 _PRIM Y',
'0 @I2@ INDI',
'1 OBJE',
'2 FILE acte.pdf',
'1 OBJE',
'2 FILE premier.JPEG',
'1 OBJE',
'2 FILE second.jpg',
].join('\n')
expect(photosOf(text)).toEqual({ I1: 'portrait.jpg', I2: 'premier.JPEG' })
})
it('ignore les adresses web, les documents et les renvois cassés', () => {
const text = [
'0 @I1@ INDI',
'1 OBJE',
'2 FILE https://exemple.org/photo.jpg',
'1 OBJE @M404@',
'1 OBJE',
'2 FILE registre.pdf',
'0 @I2@ INDI',
'1 NAME Sans /Photo/',
].join('\n')
expect(photosOf(text)).toEqual({ I1: null, I2: null })
})
})