const { test } = require('node:test') const assert = require('node:assert/strict') const fs = require('node:fs') const path = require('node:path') const vm = require('node:vm') const { createRequire } = require('node:module') const vue = require('vue') const { parse, compileScript, compileTemplate, compileStyle } = require('vue/compiler-sfc') const esbuild = createRequire(require.resolve('vite'))('esbuild') const privacyModule = { exports: {} } vm.runInNewContext( esbuild.transformSync( fs.readFileSync(path.join(__dirname, '../src/utils/healthPrivacy.ts'), 'utf8'), { loader: 'ts', format: 'cjs' } ).code, { module: privacyModule, exports: privacyModule.exports } ) const componentPath = path.join(__dirname, '../src/views/health/identity/CollectionHealthSteps.vue') const { descriptor, errors } = parse(fs.readFileSync(componentPath, 'utf8'), { filename: componentPath }) const script = compileScript(descriptor, { id: 'collection-health-tests' }) const compiled = esbuild.transformSync(script.content, { loader: 'ts', format: 'cjs' }).code function fixture(data = {}, readOnly = false) { const module = { exports: {} } vm.runInNewContext(compiled, { module, exports: module.exports, require: (id) => { if (id === 'vue') return vue if (id === '@/utils/healthPrivacy') return privacyModule.exports throw new Error(`Unexpected import: ${id}`) } }) const props = vue.reactive({ activeStep: 5, readOnly, data }) const component = module.exports.default.setup(props, { expose: () => {} }) return { props, component } } test('health steps compile as child form fields and use persistent, animated sections', () => { assert.deepEqual(errors, []) const template = compileTemplate({ source: descriptor.template.content, filename: componentPath, id: 'collection-health-tests', compilerOptions: { bindingMetadata: script.bindings } }) assert.deepEqual(template.errors, []) const css = compileStyle({ source: descriptor.styles[0].content, filename: componentPath, id: 'collection-health-tests', scoped: true, preprocessLang: 'scss' }) assert.deepEqual(css.errors, []) assert.doesNotMatch(descriptor.template.content, //g).length, 3) }) test('self care and no disability clear hidden details without changing the active step', () => { const f = fixture({ careLevel: 2, disabled: true, disabilityType: 'physical', disabilityReason: '原因' }) f.component.changeCareLevel(1) assert.equal(f.props.data.careLevel, 1) assert.equal(f.props.data.disabled, false) assert.equal(f.props.data.disabilityType, null) assert.equal(f.props.data.disabilityReason, null) assert.equal(f.props.activeStep, 5) Object.assign(f.props.data, { careLevel: 3, disabled: true, disabilityType: 'visual', disabilityReason: '原因' }) f.component.changeDisabled(false) assert.equal(f.props.data.disabled, false) assert.equal(f.props.data.disabilityType, null) assert.equal(f.props.data.disabilityReason, null) }) test('disease selection preserves existing details, removes deselected entries and deduplicates codes', () => { const f = fixture({ chronicDiseaseStatus: 1, chronicDiseases: [ { code: 'diabetes', diagnosedDate: '2020-01-01', treatmentStatus: 2, currentDisease: false }, { code: 'other', otherName: '原名称' } ] }) const original = f.props.data.chronicDiseases[0] f.component.changeDiseases(['diabetes', 'uncertain', 'diabetes']) assert.equal(f.props.data.chronicDiseases.length, 2) assert.equal(f.props.data.chronicDiseases[0], original) assert.equal(f.props.data.chronicDiseases[0].currentDisease, false) assert.equal(f.props.data.chronicDiseases[0].diagnosedDate, '2020-01-01') assert.equal(f.props.data.chronicDiseases[1].code, 'uncertain') f.component.removeDisease('diabetes') assert.deepEqual(Array.from(f.component.selectedDiseaseCodes.value), ['uncertain']) }) test('no, unsure and declined chronic answers clear details, while yes accepts an empty list', () => { const f = fixture() for (const status of [2, 3, 4]) { f.props.data.chronicDiseases = [{ code: 'hypertension' }] f.component.changeChronicStatus(status) assert.equal(f.props.data.chronicDiseaseStatus, status) assert.equal(f.props.data.chronicDiseases.length, 0) } f.component.changeChronicStatus(1) assert.equal(f.props.data.chronicDiseases.length, 0) }) test('loading legacy data and invoking read-only handlers leave values intact, including zero and false', () => { const data = { incomeRange: 0, careLevel: 1, disabled: true, disabilityType: 'physical', disabilityReason: '旧数据', chronicDiseaseStatus: 2, chronicDiseases: [{ code: 'diabetes', currentDisease: false }] } const before = JSON.stringify(data) const editable = fixture(data) assert.equal(JSON.stringify(editable.props.data), before) const f = fixture(data, true) f.component.changeCareLevel(1) f.component.changeDisabled(false) f.component.changeChronicStatus(3) f.component.changeDiseases([]) f.component.removeDisease('diabetes') assert.equal(JSON.stringify(f.props.data), before) }) test('diagnosis picker accepts today and earlier dates and disables future dates', () => { const f = fixture() const tomorrow = new Date() tomorrow.setDate(tomorrow.getDate() + 1) tomorrow.setHours(0, 0, 0, 0) assert.equal(f.component.disabledFutureDate(new Date('2020-01-01')), false) assert.equal(f.component.disabledFutureDate(new Date()), false) assert.equal(f.component.disabledFutureDate(tomorrow), true) }) test('read-only insurance display masks the number without rewriting the archived value', () => { const f = fixture({ medicalInsuranceNumber: '123456789012' }, true) assert.equal(f.component.maskHealthInsurance(f.props.data.medicalInsuranceNumber), '********9012') assert.equal(f.props.data.medicalInsuranceNumber, '123456789012') assert.notEqual(f.component.maskHealthInsurance('123'), '123') })