grantforge-api / frontend-react /src /components /project /GenerationReadinessPanel.node-test.mjs
GrantForge Bot
Deploy sha-565ad85979610064f6d1c18ab3b6404357d61073 — source build (no GHCR)
ce8f04a
Raw
History Blame Contribute Delete
9.08 kB
/**
* Node built-in test runner for pure GenerationReadinessPanel helpers.
* Mirrors pure exports in GenerationReadinessPanel.tsx (kept isolated — no React).
* Run: node --test src/components/project/GenerationReadinessPanel.node-test.mjs
*/
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
const MSP_LABELS = {
mikro: 'Mikro',
mala: 'Mała',
srednia: 'Średnia',
duza: 'Duża',
unknown: 'Nieustalony',
};
function formatMspLabel(status) {
const key = String(status || 'unknown').toLowerCase().trim();
return MSP_LABELS[key] || MSP_LABELS.unknown;
}
function formatEur(value) {
if (value === null || value === undefined || Number.isNaN(Number(value))) {
return 'brak danych';
}
return `${Number(value).toLocaleString('pl-PL', { maximumFractionDigits: 0 })} EUR`;
}
function shouldShowEligibilitySection(readiness) {
if (!readiness) return false;
if (readiness.eligibility && typeof readiness.eligibility === 'object') return true;
const missing = readiness.missing_fields || [];
return missing.some((m) => m.category === 'eligibility');
}
function isEligibilitySpineEnforced(readiness) {
if (!readiness) return true;
const elig = readiness.eligibility;
if (readiness.eligibility_spine_enforced === false) return false;
if (elig && typeof elig === 'object' && elig.spine_enabled === false) return false;
return true;
}
function isEligibilityBlocking(readiness) {
if (!readiness) return true;
const elig = readiness.eligibility;
if (!elig || typeof elig !== 'object') {
return (readiness.missing_fields || []).some((m) => m.category === 'eligibility');
}
if (Array.isArray(elig.blockers) && elig.blockers.length > 0) return true;
if (!isEligibilitySpineEnforced(readiness)) {
return false;
}
if (elig.ready_for_full_autopilot === true) return false;
if (elig.ready_for_full_autopilot === false) return true;
const mspStatus = String(elig.msp?.status || 'unknown').toLowerCase().trim();
if (mspStatus === 'unknown' || Boolean(elig.msp?.is_large)) return true;
if (Boolean(elig.de_minimis?.exhausted)) return true;
if (elig.de_minimis?.used_eur === null || elig.de_minimis?.used_eur === undefined) {
return true;
}
return false;
}
function eligibilityBannerMessage(readiness) {
if (isEligibilityBlocking(readiness)) {
return {
tone: 'blocked',
text:
'Full Autopilot zablokowany do czasu weryfikacji kwalifikowalności (fail-closed). ' +
'Brak wiarygodnego statusu MŚP lub de minimis nie jest traktowany jako „OK”.',
};
}
if (!isEligibilitySpineEnforced(readiness)) {
return {
tone: 'info',
text:
'Spine kwalifikowalności w trybie informacyjnym (nie egzekwowany) — nie bramkuje Full Autopilot. ' +
'Status MŚP / de minimis poniżej tylko do wglądu.',
};
}
return {
tone: 'ok',
text: 'Spine kwalifikowalności OK — MŚP i de minimis nie blokują Full Autopilot.',
};
}
describe('formatMspLabel', () => {
it('maps known statuses', () => {
assert.equal(formatMspLabel('mikro'), 'Mikro');
assert.equal(formatMspLabel('duza'), 'Duża');
assert.equal(formatMspLabel('unknown'), 'Nieustalony');
});
it('fails closed on empty', () => {
assert.equal(formatMspLabel(null), 'Nieustalony');
assert.equal(formatMspLabel(''), 'Nieustalony');
assert.equal(formatMspLabel('weird'), 'Nieustalony');
});
});
describe('formatEur', () => {
it('formats numbers', () => {
assert.match(formatEur(45000), /45\s?000/);
assert.match(formatEur(0), /0/);
});
it('fails closed on null/undefined/NaN', () => {
assert.equal(formatEur(null), 'brak danych');
assert.equal(formatEur(undefined), 'brak danych');
assert.equal(formatEur(Number.NaN), 'brak danych');
});
});
describe('shouldShowEligibilitySection', () => {
it('false when no readiness', () => {
assert.equal(shouldShowEligibilitySection(null), false);
assert.equal(shouldShowEligibilitySection({}), false);
});
it('true when eligibility report present', () => {
assert.equal(
shouldShowEligibilitySection({ eligibility: { blockers: [] } }),
true,
);
});
it('true when missing_fields category eligibility', () => {
assert.equal(
shouldShowEligibilitySection({
missing_fields: [{ field: 'msp_status', label: 'MŚP', category: 'eligibility' }],
}),
true,
);
});
it('false when only other missing categories', () => {
assert.equal(
shouldShowEligibilitySection({
missing_fields: [{ field: 'title', label: 'Tytuł', category: 'project' }],
}),
false,
);
});
});
describe('isEligibilityBlocking (fail-closed)', () => {
it('blocks when readiness null', () => {
assert.equal(isEligibilityBlocking(null), true);
});
it('blocks on eligibility missing_fields without report', () => {
assert.equal(
isEligibilityBlocking({
missing_fields: [{ field: 'nip', label: 'NIP', category: 'eligibility' }],
}),
true,
);
});
it('does not block on unrelated missing fields without report', () => {
assert.equal(
isEligibilityBlocking({
missing_fields: [{ field: 'title', label: 'Tytuł', category: 'project' }],
}),
false,
);
});
it('blocks on explicit blockers always', () => {
assert.equal(
isEligibilityBlocking({
eligibility_spine_enforced: false,
eligibility: {
spine_enabled: false,
ready_for_full_autopilot: true,
blockers: ['Status duża firma'],
msp: { status: 'duza', is_large: true },
de_minimis: { used_eur: 0 },
},
}),
true,
);
});
it('does not claim FA blocked when spine not enforced (no blockers)', () => {
assert.equal(
isEligibilityBlocking({
eligibility_spine_enforced: false,
eligibility: {
spine_enabled: false,
ready_for_full_autopilot: false,
blockers: [],
msp: { status: 'unknown' },
de_minimis: {},
},
}),
false,
);
});
it('honors ready_for_full_autopilot when enforced', () => {
assert.equal(
isEligibilityBlocking({
eligibility_spine_enforced: true,
eligibility: {
ready_for_full_autopilot: true,
blockers: [],
msp: { status: 'mikro' },
de_minimis: { used_eur: 10_000, exhausted: false },
},
}),
false,
);
assert.equal(
isEligibilityBlocking({
eligibility_spine_enforced: true,
eligibility: {
ready_for_full_autopilot: false,
blockers: [],
msp: { status: 'mikro' },
de_minimis: { used_eur: 10_000 },
},
}),
true,
);
});
it('fail-closed heuristics when ready flag absent', () => {
assert.equal(
isEligibilityBlocking({
eligibility: {
blockers: [],
msp: { status: 'unknown' },
de_minimis: { used_eur: 0 },
},
}),
true,
);
assert.equal(
isEligibilityBlocking({
eligibility: {
blockers: [],
msp: { status: 'mikro', is_large: true },
de_minimis: { used_eur: 0 },
},
}),
true,
);
assert.equal(
isEligibilityBlocking({
eligibility: {
blockers: [],
msp: { status: 'mikro' },
de_minimis: { used_eur: 300_000, exhausted: true },
},
}),
true,
);
assert.equal(
isEligibilityBlocking({
eligibility: {
blockers: [],
msp: { status: 'mikro' },
de_minimis: { used_eur: null },
},
}),
true,
);
});
it('treats used_eur 0 as known (not missing)', () => {
assert.equal(
isEligibilityBlocking({
eligibility: {
blockers: [],
msp: { status: 'srednia' },
de_minimis: { used_eur: 0, remaining_eur: 300_000, exhausted: false },
},
}),
false,
);
});
});
describe('eligibilityBannerMessage', () => {
it('blocked tone on blockers', () => {
const b = eligibilityBannerMessage({
eligibility: { blockers: ['x'], msp: { status: 'duza' } },
});
assert.equal(b.tone, 'blocked');
assert.match(b.text, /fail-closed/i);
});
it('info tone when spine not enforced', () => {
const b = eligibilityBannerMessage({
eligibility_spine_enforced: false,
eligibility: {
spine_enabled: false,
blockers: [],
msp: { status: 'unknown' },
},
});
assert.equal(b.tone, 'info');
assert.match(b.text, /informacyjnym/i);
});
it('ok tone when ready', () => {
const b = eligibilityBannerMessage({
eligibility_spine_enforced: true,
eligibility: {
ready_for_full_autopilot: true,
blockers: [],
msp: { status: 'mikro' },
de_minimis: { used_eur: 1 },
},
});
assert.equal(b.tone, 'ok');
});
});