fix:some
All checks were successful
构建并部署前端到测试环境 / deploy (push) Successful in 55s

This commit is contained in:
luo
2026-10-20 17:35:12 +08:00
parent 6dedd9f852
commit 22e796ba23
3 changed files with 173 additions and 9 deletions

View File

@@ -38,6 +38,11 @@ const components = Object.fromEntries(
})
)
test('carrier form grid top-aligns items so helper text cannot offset adjacent controls', () => {
const style = components.index.descriptor.styles.map((block) => block.content).join('\n')
assert.match(style, /\.carrier-form-grid\s*\{[^}]*align-items:\s*start\s*;/)
})
const carrier = (enabled) => ({
id: 7,
carrier_code: 'carrier-test',
@@ -51,6 +56,7 @@ const carrier = (enabled) => ({
function harness(userType, responseCarrier = carrier(1)) {
const writes = []
const confirmations = []
const user = vue.reactive({ info: { user_type: userType }, permissions: [], buttons: [] })
const permission = evaluate(read('src/composables/usePermission.ts'), {
vue,
@@ -70,7 +76,12 @@ function harness(userType, responseCarrier = carrier(1)) {
'@/api/modules': { CarrierService: service },
'element-plus': {
ElMessage: { success() {}, warning() {} },
ElMessageBox: {},
ElMessageBox: {
confirm: async (...args) => {
confirmations.push(args)
return 'confirm'
}
},
ElTag: {},
ElSwitch: {},
ElButton: {}
@@ -91,7 +102,14 @@ function harness(userType, responseCarrier = carrier(1)) {
}
const setup = (name) =>
evaluate(components[name].script, imports, runtimeVue).default.setup({}, { expose() {} })
return { list: setup('index'), detail: setup('detail'), writes }
return {
list: setup('index'),
detail: setup('detail'),
writes,
confirmations,
messageBox: imports['element-plus'].ElMessageBox,
service
}
}
const validForm = {
@@ -170,6 +188,113 @@ test('editing then creating resets control state; default creation sends numeric
assert.equal(list.form.realname_control_enabled, 0)
})
for (const userType of [1, 2]) {
test(`user_type=${userType}: enabling control requires confirmation before PUT and sends true`, async () => {
const { list, writes, confirmations, messageBox } = harness(userType)
list.showDialog('edit', carrier(0))
list.form.realname_control_enabled = 1
let confirm
messageBox.confirm = (...args) => {
confirmations.push(args)
return new Promise((resolve) => {
confirm = resolve
})
}
const pending = list.handleSubmit(validForm)
assert.equal(confirmations.length, 1)
assert.match(confirmations[0][0], /未实名的开机卡会在下一次评估时被停机/)
assert.deepEqual(writes, [])
assert.equal(list.submitLoading.value, true)
await list.handleSubmit(validForm)
assert.equal(confirmations.length, 1)
confirm('confirm')
await pending
assert.equal(writes.length, 1)
assert.equal(writes[0].method, 'update')
assert.equal(writes[0].data.realname_control_enabled, 1)
assert.equal(writes[0].data.realname_control_confirm, true)
assert.equal(list.submitLoading.value, false)
})
}
for (const reason of ['cancel', 'close']) {
test(`${reason} of realname confirmation does not submit; retry requires a fresh confirmation`, async () => {
const { list, writes, messageBox } = harness(1)
list.showDialog('edit', carrier(0))
list.form.realname_control_enabled = 1
let prompts = 0
messageBox.confirm = async () => {
prompts += 1
throw reason
}
await list.handleSubmit(validForm)
assert.deepEqual(writes, [])
assert.equal(list.dialogVisible.value, true)
assert.equal(list.submitLoading.value, false)
assert.equal(list.form.realname_control_enabled, 1)
messageBox.confirm = async () => {
prompts += 1
return 'confirm'
}
await list.handleSubmit(validForm)
assert.equal(prompts, 2)
assert.equal(writes[0].data.realname_control_confirm, true)
})
}
test('unchanged, disabled, new, and unauthorized carriers never send confirmation automatically', async () => {
for (const [userType, mode, original, selected] of [
[1, 'edit', 1, 1],
[1, 'edit', 0, 0],
[2, 'edit', 1, 0],
[1, 'add', 0, 1],
[3, 'edit', 0, 1],
[4, 'edit', 0, 1]
]) {
const { list, writes, confirmations } = harness(userType)
list.showDialog(mode, carrier(original))
list.form.realname_control_enabled = selected
await list.handleSubmit(validForm)
assert.equal(confirmations.length, 0)
assert.equal(writes.length, 1)
assert.equal(Object.hasOwn(writes[0].data, 'realname_control_confirm'), false)
}
})
test('opening another carrier resets the original control state after a cancelled enabling', async () => {
const { list, writes, messageBox } = harness(2)
list.showDialog('edit', carrier(0))
list.form.realname_control_enabled = 1
messageBox.confirm = async () => {
throw 'cancel'
}
await list.handleSubmit(validForm)
list.showDialog('edit', { ...carrier(1), id: 8 })
await list.handleSubmit(validForm)
assert.equal(writes[0].id, 8)
assert.equal(Object.hasOwn(writes[0].data, 'realname_control_confirm'), false)
})
test('a failed PUT requires a fresh confirmation on retry', async (t) => {
const { list, writes, confirmations, service } = harness(2)
t.mock.method(console, 'error', () => {})
list.showDialog('edit', carrier(0))
list.form.realname_control_enabled = 1
const updateCarrier = service.updateCarrier
service.updateCarrier = async () => {
throw new Error('PUT failed')
}
await list.handleSubmit(validForm)
assert.equal(confirmations.length, 1)
assert.deepEqual(writes, [])
assert.equal(list.dialogVisible.value, true)
assert.equal(list.submitLoading.value, false)
service.updateCarrier = updateCarrier
await list.handleSubmit(validForm)
assert.equal(confirmations.length, 2)
assert.equal(writes[0].data.realname_control_confirm, true)
})
function findElement(node, predicate) {
if (node.type === 1 && predicate(node)) return node
for (const child of node.children || []) {
@@ -235,11 +360,18 @@ test('carrier endpoints preserve the field in list/detail responses and create/u
assert.equal((await CarrierService.getCarriers()).data.items[0].realname_control_enabled, 1)
assert.equal((await CarrierService.getCarrierDetail(7)).data.realname_control_enabled, 0)
await CarrierService.createCarrier({ ...carrier(1) })
await CarrierService.updateCarrier(7, { realname_control_enabled: 0 })
await CarrierService.updateCarrier(7, {
realname_control_enabled: 1,
realname_control_confirm: true
})
assert.deepEqual(calls, [
{ method: 'GET', url: '/api/admin/carriers' },
{ method: 'GET', url: '/api/admin/carriers/7' },
{ method: 'POST', url: '/api/admin/carriers', data: carrier(1) },
{ method: 'PUT', url: '/api/admin/carriers/7', data: { realname_control_enabled: 0 } }
{
method: 'PUT',
url: '/api/admin/carriers/7',
data: { realname_control_enabled: 1, realname_control_confirm: true }
}
])
})