grantforge-api / frontend-react /src /components /company /eligibilitySpineModel.node-test.mjs
GrantForge Bot
Deploy sha-565ad85979610064f6d1c18ab3b6404357d61073 — source build (no GHCR)
ce8f04a
Raw
History Blame Contribute Delete
3.77 kB
/**
* Node built-in test runner for pure eligibility spine display helpers.
* Mirrors eligibilitySpineModel.ts (kept small + isolated).
* Run: node --test src/components/company/eligibilitySpineModel.node-test.mjs
*/
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
const DE_MINIMIS_LIMIT_EUR = 300_000;
const MSP_LABELS = {
mikro: 'Mikroprzedsiębiorstwo',
mala: 'Małe przedsiębiorstwo',
srednia: 'Średnie przedsiębiorstwo',
duza: 'Duże przedsiębiorstwo',
unknown: 'Nieustalony',
};
function normalizeNip(raw) {
return String(raw || '').replace(/\D/g, '');
}
function isValidNip(raw) {
return normalizeNip(raw).length === 10;
}
function mspLabel(status) {
const key = String(status || 'unknown').toLowerCase();
return MSP_LABELS[key] || status || MSP_LABELS.unknown;
}
function deMinimisUsage(dm) {
const limit =
dm?.limit_eur != null && !Number.isNaN(Number(dm.limit_eur))
? Number(dm.limit_eur)
: DE_MINIMIS_LIMIT_EUR;
const used =
dm?.used_eur === null || dm?.used_eur === undefined || Number.isNaN(Number(dm.used_eur))
? null
: Number(dm.used_eur);
let remaining =
dm?.remaining_eur === null ||
dm?.remaining_eur === undefined ||
Number.isNaN(Number(dm.remaining_eur))
? null
: Number(dm.remaining_eur);
if (remaining === null && used !== null) {
remaining = Math.max(0, limit - used);
}
const exhausted =
Boolean(dm?.exhausted) ||
(remaining !== null && remaining <= 0) ||
(used !== null && used >= limit);
const usagePct =
used !== null && limit > 0 ? Math.min(100, Math.max(0, (used / limit) * 100)) : 0;
return { used, limit, remaining, exhausted, usagePct };
}
describe('normalizeNip / isValidNip', () => {
it('strips dashes and spaces', () => {
assert.equal(normalizeNip('521-321-45-67'), '5213214567');
assert.equal(normalizeNip('521 321 45 67'), '5213214567');
});
it('strips non-digit junk', () => {
assert.equal(normalizeNip('NIP: 5213214567'), '5213214567');
});
it('validates exact 10 digits', () => {
assert.equal(isValidNip('5213214567'), true);
assert.equal(isValidNip('521-321-45-67'), true);
assert.equal(isValidNip('123'), false);
assert.equal(isValidNip(''), false);
});
});
describe('mspLabel', () => {
it('maps known statuses', () => {
assert.equal(mspLabel('mikro'), 'Mikroprzedsiębiorstwo');
assert.equal(mspLabel('duza'), 'Duże przedsiębiorstwo');
assert.equal(mspLabel('unknown'), 'Nieustalony');
});
it('falls back for empty', () => {
assert.equal(mspLabel(null), 'Nieustalony');
assert.equal(mspLabel(''), 'Nieustalony');
});
});
describe('deMinimisUsage', () => {
it('defaults limit to 300000', () => {
const u = deMinimisUsage({ used_eur: 50_000 });
assert.equal(u.limit, 300_000);
assert.equal(u.used, 50_000);
assert.equal(u.remaining, 250_000);
assert.equal(u.exhausted, false);
assert.ok(u.usagePct > 16 && u.usagePct < 17);
});
it('marks exhausted at limit', () => {
const u = deMinimisUsage({ used_eur: 300_000, limit_eur: 300_000 });
assert.equal(u.exhausted, true);
assert.equal(u.remaining, 0);
assert.equal(u.usagePct, 100);
});
it('respects explicit remaining and exhausted flag', () => {
const u = deMinimisUsage({
used_eur: 100,
remaining_eur: 0,
exhausted: true,
limit_eur: 300_000,
});
assert.equal(u.remaining, 0);
assert.equal(u.exhausted, true);
});
it('handles missing de minimis blob', () => {
const u = deMinimisUsage(null);
assert.equal(u.used, null);
assert.equal(u.limit, 300_000);
assert.equal(u.remaining, null);
assert.equal(u.usagePct, 0);
});
});