'use strict'; const assert = require('node:assert/strict'); const Score = require('../js/skin-score'); const dims = (firm, vita, stab) => ({ firm: { S: firm }, vita: { S: vita }, stab: { S: stab } }); for (const [scores, total] of [ [[8, 9, 8.5], 85], [[10, 10, 10], 99], [[7, 7, 7], 70], [[10, 7, 7], 82], [[7, 10, 7], 79], [[7, 7, 10], 79], [[8.01, 8.82, 8], 83], [[7.69, 8.72, 9.1], 84] ]) assert.equal(Score.weightedTotal(dims(...scores)), total, scores.join('/')); for (const invalid of [null, undefined, NaN, Infinity, -Infinity, '9', -1, 11]) { for (const key of ['firm', 'vita', 'stab']) { const d = dims(8, 9, 8.5); d[key].S = invalid; assert.equal(Score.weightedTotal(d), null, 'no reweighting invalid/missing ' + key); } } for (const d of [null, {}, { firm: { S: 9 }, vita: { S: 8 } }]) assert.equal(Score.weightedTotal(d), null); const input = JSON.parse(JSON.stringify(Score.MOCK_RESULT)); const before = JSON.stringify(input); const expected = Score.buildViewModel(input, Score.MOCK_SIDE, {}); assert.equal(expected.totalRule, 'dimensions-433-v1'); assert.equal(JSON.stringify(input), before, 'preserve raw upstream data'); for (const value of [0, 100, null, undefined]) { const r = JSON.parse(JSON.stringify(input)); if (value === undefined) delete r.score_info.total_score; else r.score_info.total_score = value; const changed = Score.buildViewModel(r, Score.MOCK_SIDE, {}); assert.equal(changed.total, expected.total, 'API total has no influence'); assert.deepEqual(changed.dims, expected.dims); assert.deepEqual(changed.recommendation, expected.recommendation); } assert.equal(Score.buildViewModel({}, null, {}).total, null); console.log('PASS weighted total: 4:3:3, integer/half rounding, missing/invalid dimensions, API total ignored, source/scores/recommendation unchanged');