PS pension module: optional federal PSSA engine + UI (PSPC-accurate, EN/FR)

This commit is contained in:
krisf committed 2026-10-09 11:44:40 -04:00
1 parent fe62022a32
commit 583b5ee2f8
14 files changed
+1991 -27

No files matched your search

+40 -5
View File
@@ -55,12 +55,13 @@ function buildShim() {
global.confirm = () => true;
global.fetch = () => Promise.resolve({ ok: true, json: () => Promise.resolve({}) });
}
function load(lang) {
function load(lang, psState) {
buildShim();
global.window.RetireEngine = require(path.join(SITE, 'engine', 'engine.js'));
global.window.RetireCanada = require(path.join(SITE, 'engine', 'canada.js'));
global.window.RetirePS = require(path.join(SITE, 'engine', 'pspension.js'));
// persisted state in the target language: fresh answers, dropped at the quiz start
store[LS] = JSON.stringify({ a: {}, step: 0, screen: 'quiz', lang: lang });
store[LS] = psState ? JSON.stringify(psState) : JSON.stringify({ a: {}, step: 0, screen: 'quiz', lang: lang });
eval(fs.readFileSync(path.join(SITE, 'i18n.js'), 'utf8'));
eval(fs.readFileSync(path.join(SITE, 'app.js'), 'utf8'));
}
@@ -81,7 +82,7 @@ function run(lang, M, done) {
ok('intro wiring: begin button has handler', !!q('#btn-begin')._l.click);
click('btn-begin');
ok('step 1 title', M.title.test(q('#step-body')._html), N(q('#step-body')._html).slice(0, 60));
ok('step count', /1 \/ 14/.test(q('#step-count').textContent), q('#step-count').textContent);
ok('step count', /1 \/ 15/.test(q('#step-count').textContent), q('#step-count').textContent);
ok('province step requires a pick (Next disabled)', q('#btn-next').disabled === true);
ok('validation message', createdEls.some(e => M.needProvince.test(N(e.textContent))));
@@ -173,9 +174,43 @@ const FR = {
wiCtrb: /\/mois/,
};
run('en', EN, () => run('fr', FR, () => {
/* PS module flow: federal public servant answers → results card + chart series, per language. */
function runPs(lang, M, done) {
console.log('\n--- ' + lang.toUpperCase() + ' (PS module) ---');
load(lang, {
a: {
province: 'ON', age: 60, retireAge: 60, household: 'single',
income: 0, rrsp: 100000, tfsa: 30000, nonreg: 20000, monthlyContribution: 0,
spendingAnnual: 50000,
psPension: true, psJoinYear: 2000, psServiceYears: 30, psAvgSalary: 100000,
psOccupation: 'it', psItLevel: 'IT-02', psItStep: 1
}, step: 0, screen: 'results', lang: lang });
setTimeout(() => {
const card = q('#ps-card');
ok('PS results card visible', card.hidden === false);
const h = N(card._html);
ok('PS card title localized', M.psCard.test(h), h.slice(0, 70));
ok('PS card pension at 60 (2%×100k×30 = 60,000)', M.psAt.test(h), (h.match(M.psAt) || [''])[0]);
ok('PS card from-65 (lifetime 46,012.50)', M.psFrom.test(h), (h.match(M.psFrom) || [''])[0]);
ok('PS card bridge line (13,987.50)', M.psBridge.test(h), (h.match(M.psBridge) || [''])[0]);
ok('PS card sources link PSPC canada.ca', /href="https:\/\/www\.canada\.ca/.test(h));
ok('PS card IT agreement source (2024-12-22)', /2024-12-22/.test(h));
ok('PS series in G2 chart', M.psSeries.test(N(q('#g2')._html)), N(q('#g2')._html).slice(0, 40));
ok('PS insight in live panel', M.psInsight.test(N(q('#panel-insight')._html)), N(q('#panel-insight')._html).slice(0, 70));
done();
}, 400);
}
run('en', EN, () => run('fr', FR, () => runPs('en', {
psCard: /federal public service pension/, psAt: /60,000/, psFrom: /46,012\.50/,
psBridge: /13,987\.50/, psSeries: /Public service pension/, psInsight: /covers about/
}, () => runPs('fr', {
psCard: /pension de la fonction publique fédérale/, psAt: /60[\s\u00a0\u202f]000/, psFrom: /46[\s\u00a0\u202f]012,50/,
psBridge: /13[\s\u00a0\u202f]987,50/, psSeries: /Pension de la fonction publique/, psInsight: /couvre environ/
}, () => {
ok('EN privacy line present in index.html', /never leave your browser/.test(fs.readFileSync(path.join(SITE, 'index.html'), 'utf8')));
ok('FR privacy string present in i18n.js', /ne quittent jamais votre navigateur/.test(fs.readFileSync(path.join(SITE, 'i18n.js'), 'utf8')));
console.log(fails ? '\nSMOKE-FAIL: ' + fails + ' of ' + total : '\nSMOKE-OK all ui smoke checks passed (' + total + ')');
process.exit(fails ? 1 : 0);
}));
}))))
;