Files
itinova-budget-si/server/payrollParser.test.ts

81 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from "vitest";
import { extractPayrollBulletins } from "./payrollParser";
const SAMPLE_BULLETIN = `
##BULLETIN##05-2026##009999##DUPONT##TEST##
Matricule : 009999
Emploi : RESPONSABLE APPLICATIF Monsieur TEST DUPONT
Salaire de base (Forfait 218 jours) 3 650.00
Prime d'astreinte 200.00
Prime d'astreinte 200.00
Prime d'activité 150.00
Salaire brut 4 200.00
N° SS : ne-pas-extraire
Iban / Rib : ne-pas-extraire
Net à payer avant impôt sur le revenu 2 000.00
`;
describe("extractPayrollBulletins", () => {
it("n'extrait que les champs métier autorisés et additionne les astreintes", () => {
const result = extractPayrollBulletins(SAMPLE_BULLETIN);
expect(result).toMatchObject({ statutExtraction: "ready", erreurExtraction: null });
expect(result.bulletins).toEqual([
expect.objectContaining({
matricule: "009999",
nom: "DUPONT",
prenom: "TEST",
poste: "RESPONSABLE APPLICATIF",
brutMensuelCents: 365000,
brutAvecPrimesCents: 420000,
primeAstreinteCents: 40000,
}),
]);
expect(Object.keys(result.bulletins[0]!)).not.toContain("iban");
expect(JSON.stringify(result)).not.toContain("ne-pas-extraire");
});
it("signale une liasse non indexable sans prétendre perdre le PDF", () => {
expect(extractPayrollBulletins("contenu PDF non reconnu")).toEqual({
bulletins: [],
statutExtraction: "a_controler",
erreurExtraction: "Aucun bulletin na pu être indexé automatiquement. Le PDF reste conservé et consultable.",
});
});
it("indexe chaque salarié lorsque le texte PDF concatène les pages sans séparateur", () => {
const secondBulletin = SAMPLE_BULLETIN
.replace("##009999##DUPONT##TEST##", "##008888##MARTIN##EXEMPLE##")
.replaceAll("009999", "008888")
.replaceAll("TEST DUPONT", "EXEMPLE MARTIN");
const result = extractPayrollBulletins(`${SAMPLE_BULLETIN}\n${secondBulletin}`);
expect(result.bulletins).toHaveLength(2);
expect(result.bulletins.map((bulletin) => bulletin.matricule)).toEqual(["009999", "008888"]);
});
it("accepte un emploi suivi de la civilité par un seul espace, comme certains PDF extraits", () => {
const compacted = SAMPLE_BULLETIN.replace(" Monsieur", " Monsieur");
expect(extractPayrollBulletins(compacted).bulletins).toHaveLength(1);
});
it("lit un poste sur sa seule ligne lorsque la civilité est rendue à la ligne suivante", () => {
const separateCivilite = SAMPLE_BULLETIN.replace(" Monsieur TEST DUPONT", "\nMonsieur TEST DUPONT");
expect(extractPayrollBulletins(separateCivilite).bulletins).toHaveLength(1);
});
it("refuse une extraction d'emploi répartie sur plusieurs lignes pour ne jamais persister de donnée personnelle", () => {
const unsafeLayout = SAMPLE_BULLETIN.replace(
/Emploi\s*:[^\n]*/,
"Emploi :\nAdresse personnelle à ignorer\nRESPONSABLE APPLICATIF\nMonsieur TEST DUPONT",
);
expect(extractPayrollBulletins(unsafeLayout)).toMatchObject({
bulletins: [],
statutExtraction: "a_controler",
});
});
});