Some checks failed
Validation applicative / TypeScript, tests et build (push) Failing after 1m54s
81 lines
3.5 KiB
TypeScript
81 lines
3.5 KiB
TypeScript
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 n’a 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",
|
||
});
|
||
});
|
||
});
|