feat: finalize lease documents and IRL revisions
This commit is contained in:
1 parent
f127c69a28
commit
1bf6a3449c
196 files changed
+20564
-666
No files matched your search
@@ -0,0 +1,123 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { vi } from 'vitest';
|
||||
import { LeaseRevisionMetadata } from '../../services/lease.service';
|
||||
import { LeaseFinalizationForm } from './lease-finalization-form';
|
||||
|
||||
describe('LeaseFinalizationForm', () => {
|
||||
const revision: LeaseRevisionMetadata = {
|
||||
number: 4,
|
||||
templateVersion: '2026.10',
|
||||
sourceFingerprint: 'source',
|
||||
sha256: 'sha256',
|
||||
generatedAt: '2026-07-19T10:00:00Z',
|
||||
authorId: 'owner-1',
|
||||
annexes: [],
|
||||
warningCodes: [],
|
||||
warnings: [],
|
||||
};
|
||||
|
||||
function createForm(warningCodes: string[] = []) {
|
||||
const fixture = TestBed.createComponent(LeaseFinalizationForm);
|
||||
fixture.componentRef.setInput('revision', revision);
|
||||
fixture.componentRef.setInput('warningCodes', warningCodes);
|
||||
fixture.componentRef.setInput(
|
||||
'warnings',
|
||||
warningCodes.map((code) => ({ code, ruleVersion: '2026-07-01' })),
|
||||
);
|
||||
fixture.detectChanges();
|
||||
return fixture;
|
||||
}
|
||||
|
||||
it('emits the exact civil date string and confirmations', () => {
|
||||
const fixture = createForm([
|
||||
'SECURITY_DEPOSIT_ABOVE_TWO_MONTHS',
|
||||
'IRL_REVISION_WITH_F_OR_G_DPE',
|
||||
'FUTURE_WARNING',
|
||||
]);
|
||||
const component = fixture.componentInstance;
|
||||
const file = new File(['lease'], 'bail-signe.pdf', { type: 'application/pdf' });
|
||||
const requested = vi.fn();
|
||||
component.finalizationRequested.subscribe(requested);
|
||||
component.signedLease.set(file);
|
||||
component.lastSignatureDate.set('2026-07-19');
|
||||
component.allPartiesSigned.set(true);
|
||||
component.revisionMatches.set(true);
|
||||
component.setWarning('SECURITY_DEPOSIT_ABOVE_TWO_MONTHS', true);
|
||||
component.setWarning('IRL_REVISION_WITH_F_OR_G_DPE', true);
|
||||
component.setWarning('FUTURE_WARNING', true);
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(requested).toHaveBeenCalledWith({
|
||||
signedLease: file,
|
||||
revisionNumber: 4,
|
||||
lastSignatureDate: '2026-07-19',
|
||||
allPartiesSigned: true,
|
||||
revisionMatches: true,
|
||||
confirmedWarningCodes: [
|
||||
'SECURITY_DEPOSIT_ABOVE_TWO_MONTHS',
|
||||
'IRL_REVISION_WITH_F_OR_G_DPE',
|
||||
'FUTURE_WARNING',
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('uses actionable French warning labels without exposing raw codes', () => {
|
||||
const fixture = createForm([
|
||||
'SECURITY_DEPOSIT_ABOVE_TWO_MONTHS',
|
||||
'IRL_REVISION_WITH_F_OR_G_DPE',
|
||||
'FUTURE_WARNING',
|
||||
]);
|
||||
const text = fixture.nativeElement.textContent;
|
||||
|
||||
expect(text).toContain('dépasse deux mois de loyer hors charges');
|
||||
expect(text).toContain('confirme forcer ce montant');
|
||||
expect(text).toContain('classé F ou G');
|
||||
expect(text).toContain('maintenir la clause de révision IRL');
|
||||
expect(text).toContain('avertissement légal signalé');
|
||||
expect(text).not.toContain('SECURITY_DEPOSIT_ABOVE_TWO_MONTHS');
|
||||
expect(text).not.toContain('FUTURE_WARNING');
|
||||
expect(text).not.toContain('IRL_REVISION_WITH_F_OR_G_DPE');
|
||||
expect(text).toContain('Version de règle : 2026-07-01');
|
||||
});
|
||||
|
||||
it('explains every document warning precisely in French', () => {
|
||||
const warningCodes = [
|
||||
'DPE_MISSING',
|
||||
'DPE_EXPIRED',
|
||||
'DIAGNOSTIC_EXPIRED',
|
||||
'CO_OWNERSHIP_RULES_EXTRACT_MISSING',
|
||||
'PRIOR_RENTAL_AUTHORIZATION_MISSING',
|
||||
];
|
||||
const fixture = createForm(warningCodes);
|
||||
const text = fixture.nativeElement.textContent;
|
||||
|
||||
expect(text).toContain('DPE est absent du dossier');
|
||||
expect(text).toContain('DPE présent dans le dossier est expiré');
|
||||
expect(text).toContain('diagnostic autre que le DPE est expiré');
|
||||
expect(text).toContain('extrait du règlement de copropriété manque');
|
||||
expect(text).toContain('autorisation préalable de mise en location manque');
|
||||
for (const code of warningCodes) expect(text).not.toContain(code);
|
||||
});
|
||||
|
||||
it('blocks an incomplete submission with an actionable error', () => {
|
||||
const fixture = createForm(['SECURITY_DEPOSIT_ABOVE_TWO_MONTHS']);
|
||||
const requested = vi.fn();
|
||||
fixture.componentInstance.finalizationRequested.subscribe(requested);
|
||||
|
||||
fixture.componentInstance.submit();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(requested).not.toHaveBeenCalled();
|
||||
expect(fixture.nativeElement.textContent).toContain('Sélectionnez le bail signé');
|
||||
});
|
||||
|
||||
it('blocks finalization while a required guarantee deed is missing', () => {
|
||||
const fixture = createForm();
|
||||
fixture.componentRef.setInput('guaranteesComplete', false);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.nativeElement.querySelector('button[type=submit]').disabled).toBe(true);
|
||||
expect(fixture.nativeElement.textContent).toContain('Téléversez tous les actes');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user