/** * lib/ba-rbac-rows — the optional 4th cell (`justification`) of a human row. * RBAC-011 reads a `décision client : ` there as the need-to-know * escape; a 3-cell row stays exactly what it was (no key at all). */ import { describe, expect, it } from 'vitest' import { parseRbacRows } from '../ba-rbac-rows.js' describe('parseRbacRows — the 4th cell', () => { it('captures a justification verbatim and omits the key on a 3-cell row', () => { const rows = parseRbacRows( [ '| Acteur | Permission | Portée | Justification |', '|---|---|---|---|', '| BA-001-AC-003 (Lecteur) | `paie.fiches.export` | toutes | décision client : audit annuel du CFO |', '| BA-001-AC-001 (Gestionnaire) | `paie.fiches.read` | toutes |', '| BA-001-AC-002 | `paie.fiches.read` | les siennes | |', ].join('\n'), ) expect(rows).toEqual([ { actorCode: 'BA-001-AC-003', actorLabel: 'Lecteur', path: 'paie.fiches.export', portee: 'toutes', justification: 'décision client : audit annuel du CFO' }, { actorCode: 'BA-001-AC-001', actorLabel: 'Gestionnaire', path: 'paie.fiches.read', portee: 'toutes' }, { actorCode: 'BA-001-AC-002', path: 'paie.fiches.read', portee: 'les siennes' }, ]) }) it('never swallows the next row when the 4th cell is absent (CRLF included)', () => { const rows = parseRbacRows('| BA-001-AC-001 | `a.b.read` | toutes |\r\n| BA-001-AC-002 | `a.b.read` | toutes |\r\n') expect(rows.map((r) => r.actorCode)).toEqual(['BA-001-AC-001', 'BA-001-AC-002']) expect(rows.every((r) => r.justification === undefined)).toBe(true) }) })