Files
pwa/backend/tests/scoring.test.ts
T

63 lines
2.2 KiB
TypeScript
Raw Normal View History

import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import {
PCQ_QUESTION_IDS,
applyReverseScoring,
isReverseScored,
parseLikertValue,
scoreAnswer,
scoreAssessment,
ScoringValidationError,
validateAnswers,
} from '../src/modules/assessments/scoring/index.js';
function answersWithValue(value: string | number) {
return PCQ_QUESTION_IDS.map((questionId) => ({ questionId, selectedValue: value }));
}
describe('PCQ-24 scoring engine', () => {
it('reverse-scores pcq_13, pcq_20, and pcq_23 with 7 - raw', () => {
assert.equal(isReverseScored('pcq_13'), true);
assert.equal(isReverseScored('pcq_20'), true);
assert.equal(isReverseScored('pcq_23'), true);
assert.equal(isReverseScored('pcq_01'), false);
assert.equal(applyReverseScoring(1), 6);
assert.equal(applyReverseScoring(6), 1);
assert.equal(applyReverseScoring('4'), 3);
});
it('keeps raw Likert and stores reverse-scored points separately', () => {
const scored = scoreAnswer('pcq_13', '2');
assert.ok(scored);
assert.equal(scored.selectedValue, 2);
assert.equal(scored.rawScore, 5);
assert.equal(scored.dimension, 'resilience');
assert.equal(scored.isReverseScored, true);
});
it('scores a uniform Likert-4 attempt with known totals', () => {
const result = scoreAssessment('pre', answersWithValue(4));
assert.equal(result.totalScore, 93);
assert.equal(result.dimensions.efficacy, 24);
assert.equal(result.dimensions.hope, 24);
assert.equal(result.dimensions.resilience, 23);
assert.equal(result.dimensions.optimism, 22);
const reverse = result.answers.filter((answer) => answer.isReverseScored);
assert.equal(reverse.length, 3);
for (const answer of reverse) {
assert.equal(answer.selectedValue, 4);
assert.equal(answer.rawScore, 3);
}
});
it('rejects incomplete or out-of-range answers', () => {
assert.equal(validateAnswers(answersWithValue(4).slice(0, 23)).isValid, false);
assert.equal(parseLikertValue('7'), null);
assert.throws(
() => scoreAssessment('pre', answersWithValue(7)),
(err: unknown) => err instanceof ScoringValidationError,
);
});
});