elder-yudao-pro/yudao-ui-admin-vue3/tests/collection-family.test.cjs

184 lines
6.9 KiB
JavaScript

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 } = require('vue/compiler-sfc')
const esbuild = createRequire(require.resolve('vite'))('esbuild')
const directory = path.join(__dirname, '../src/views/health/identity')
const familyModule = { exports: {} }
vm.runInNewContext(
esbuild.transformSync(fs.readFileSync(path.join(directory, 'collectionFamily.ts'), 'utf8'), {
loader: 'ts',
format: 'cjs'
}).code,
{ module: familyModule, exports: familyModule.exports }
)
const helpers = familyModule.exports
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(directory, 'CollectionFamilySteps.vue')
const { descriptor } = parse(fs.readFileSync(componentPath, 'utf8'), { filename: componentPath })
const script = compileScript(descriptor, { id: 'collection-family-tests' })
const compiled = esbuild.transformSync(script.content, { loader: 'ts', format: 'cjs' }).code
function fixture({ activeStep = 1, readOnly = false, data = {} } = {}) {
const module = { exports: {} }
vm.runInNewContext(compiled, {
module,
exports: module.exports,
require: (id) => {
if (id === 'vue') return vue
if (id === './collectionFamily') return helpers
if (id === '@/utils/healthPrivacy') return privacyModule.exports
throw new Error(`Unexpected import: ${id}`)
}
})
const props = vue.reactive({ activeStep, readOnly, data })
const scope = vue.effectScope()
const component = scope.run(() => module.exports.default.setup(props, { expose: () => {} }))
return { props, component, stop: () => scope.stop() }
}
test('both collection step sections and form fields compile without a nested form', () => {
const result = compileTemplate({
source: descriptor.template.content,
filename: componentPath,
id: 'collection-family-tests',
compilerOptions: { bindingMetadata: script.bindings }
})
assert.deepEqual(result.errors, [])
assert.doesNotMatch(descriptor.template.content, /<el-form\s/)
})
test('opening a form does not create a contact until entering step seven', async (t) => {
const f = fixture()
t.after(f.stop)
assert.equal(f.props.data.emergencyContacts, undefined)
f.props.activeStep = 7
await vue.nextTick()
assert.equal(f.props.data.emergencyContacts.length, 1)
assert.equal(f.props.data.emergencyContacts[0].primary, true)
assert.equal(f.props.data.emergencyContacts[0].contactOnly, true)
assert.equal(f.props.data.emergencyContacts[0].relationship, '')
})
test('selecting a priority contact replaces the previous selection and deleting it chooses the remaining first', (t) => {
const f = fixture({ activeStep: 7 })
t.after(f.stop)
f.component.addContact()
f.component.addContact()
f.component.primaryIndex.value = 2
assert.deepEqual(
Array.from(f.props.data.emergencyContacts, (contact) => contact.primary),
[false, false, true]
)
f.component.removeContact(2)
assert.deepEqual(
Array.from(f.props.data.emergencyContacts, (contact) => contact.primary),
[true, false]
)
f.component.removeContact(1)
f.component.removeContact(0)
assert.equal(f.component.contacts.value.length, 0)
f.component.addContact()
assert.equal(f.component.contacts.value[0].primary, true)
})
test('deleting a non-primary contact preserves the existing choice and stable contact key', (t) => {
const f = fixture({ activeStep: 7 })
t.after(f.stop)
f.component.addContact()
const second = f.component.contacts.value[1]
const key = f.component.contactKey(second)
f.component.primaryIndex.value = 1
f.component.removeContact(0)
assert.equal(f.component.contacts.value[0], second)
assert.equal(second.primary, true)
assert.equal(f.component.contactKey(second), key)
})
test('adding stops at ten contacts and normalizes multiple or missing priority flags on step seven', (t) => {
const f = fixture({
activeStep: 7,
data: {
emergencyContacts: [
helpers.createEmergencyContact(true),
helpers.createEmergencyContact(true)
]
}
})
t.after(f.stop)
for (let index = 0; index < 15; index++) f.component.addContact()
assert.equal(f.component.contacts.value.length, 10)
assert.equal(f.component.contacts.value.filter((contact) => contact.primary).length, 1)
const contacts = [helpers.createEmergencyContact(), helpers.createEmergencyContact()]
helpers.ensureOnePrimaryContact(contacts)
assert.equal(contacts[0].primary, true)
helpers.selectPrimaryContact(contacts, -1)
helpers.removeEmergencyContact(contacts, 20)
assert.equal(contacts.length, 2)
assert.equal(contacts[0].primary, true)
})
test('parent selection clears hidden reasons and detail independently', (t) => {
const f = fixture({
data: {
fatherAlive: 2,
fatherDeathReason: 4,
fatherDeathReasonDetail: '父亲原因',
motherAlive: 2,
motherDeathReason: 4,
motherDeathReasonDetail: '母亲原因'
}
})
t.after(f.stop)
f.component.setParentAlive('father', 3)
assert.equal(f.props.data.fatherDeathReason, null)
assert.equal(f.props.data.fatherDeathReasonDetail, null)
assert.equal(f.props.data.motherDeathReasonDetail, '母亲原因')
f.component.setParentDeathReason('mother', 2)
assert.equal(f.props.data.motherDeathReason, 2)
assert.equal(f.props.data.motherDeathReasonDetail, null)
f.component.setParentDeathReason('mother', 4)
f.component.setParentDetail('mother', '新增其他原因')
assert.equal(f.props.data.motherDeathReasonDetail, '新增其他原因')
f.component.setParentDeathReason('mother', '')
assert.equal(f.props.data.motherDeathReason, null)
assert.equal(f.props.data.motherDeathReasonDetail, null)
})
test('read-only viewing never initializes or changes any fields', async (t) => {
const data = {
fatherAlive: 1,
fatherDeathReason: 4,
fatherDeathReasonDetail: '历史资料',
emergencyContacts: [helpers.createEmergencyContact(true), helpers.createEmergencyContact(true)]
}
const original = JSON.stringify(data)
const f = fixture({ activeStep: 7, readOnly: true, data })
t.after(f.stop)
f.component.addContact()
f.component.removeContact(0)
f.component.primaryIndex.value = 1
f.component.setParentAlive('father', 2)
f.component.setParentDeathReason('father', 3)
f.component.setParentDetail('father', '改动')
assert.equal(JSON.stringify(f.props.data), original)
const empty = fixture({ activeStep: 7, readOnly: true })
t.after(empty.stop)
assert.equal(empty.props.data.emergencyContacts, undefined)
f.props.activeStep = 6
await vue.nextTick()
assert.equal(JSON.stringify(f.props.data), original)
})