68 lines
3.8 KiB
JavaScript
68 lines
3.8 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
import { readFileSync } from 'node:fs'
|
|
import { createRequire } from 'node:module'
|
|
import { computed, reactive, ref } from 'vue'
|
|
import ts from 'typescript'
|
|
|
|
const source = readFileSync(new URL('./WarehouseServiceView.vue', import.meta.url), 'utf8')
|
|
const { default: Schema } = createRequire(import.meta.resolve('element-plus'))('async-validator')
|
|
const rulesSource = source.slice(source.indexOf('const labelingFormRules ='), source.indexOf('const orderInfoCollapsed ='))
|
|
const rulesCode = ts.transpileModule(rulesSource, { compilerOptions: { target: ts.ScriptTarget.ES2022 } }).outputText
|
|
function harness(mode = 'carton', patch = {}) {
|
|
const labelingMode = ref(mode)
|
|
const form = reactive({ warehouse: 'warehouse-a', sourceOrder: 'source-a', contact: '联系人', phone: '12345678', labelDeadline: '2026-11-10T12:00:00', destination: 'FBA-A', deliveryMethod: 'TRUCK', relabel: false, ...patch })
|
|
const rules = new Function('computed', 'labelingMode', 'form', `${rulesCode}\nreturn labelingFormRules`)(computed, labelingMode, form)
|
|
return { form, labelingMode, validate: () => new Schema(rules.value).validate(form) }
|
|
}
|
|
|
|
test('order information reports every missing required field and rejects whitespace contacts', async () => {
|
|
const state = harness('carton', { warehouse: '', sourceOrder: '', contact: ' ', phone: ' ', labelDeadline: '', destination: '', deliveryMethod: '' })
|
|
await assert.rejects(state.validate(), error => {
|
|
assert.deepEqual(Object.keys(error.fields).sort(), ['warehouse', 'sourceOrder', 'contact', 'phone', 'labelDeadline', 'destination', 'deliveryMethod'].sort())
|
|
return true
|
|
})
|
|
})
|
|
|
|
test('SKU-only labeling excludes hidden destination and delivery requirements', async () => {
|
|
const state = harness('sku', { destination: '', deliveryMethod: '' })
|
|
await state.validate()
|
|
state.labelingMode.value = 'carton_and_sku'
|
|
await assert.rejects(state.validate(), error => Object.keys(error.fields).sort().join(',') === 'deliveryMethod,destination')
|
|
})
|
|
|
|
test('shipping label file is required only when express printing is selected', async () => {
|
|
const state = harness('carton', { deliveryMethod: 'EXPRESS', relabel: true })
|
|
await assert.rejects(state.validate(), error => Boolean(error.fields.shippingLabelFile))
|
|
state.form.shippingLabelFile = new File(['label'], 'label.pdf', { type: 'application/pdf' })
|
|
await state.validate()
|
|
state.form.shippingLabelFile = null
|
|
state.form.relabel = false
|
|
await state.validate()
|
|
state.form.relabel = true
|
|
state.form.deliveryMethod = 'TRUCK'
|
|
await state.validate()
|
|
state.form.deliveryMethod = 'EXPRESS'
|
|
state.labelingMode.value = 'sku'
|
|
await state.validate()
|
|
})
|
|
|
|
test('invalid create fields expand the order section and stop before submission logic', async () => {
|
|
const start = source.indexOf("async function submit(action:")
|
|
const end = source.indexOf(" if (props.service === 'transfer' && inventoryTransfer.value", start)
|
|
const preamble = source.slice(start, end) + '\nreturn "continue"\n}'
|
|
const code = ts.transpileModule(preamble, { compilerOptions: { target: ts.ScriptTarget.ES2022 } }).outputText
|
|
const collapsed = ref(true), saving = ref(false), isLabelingCreate = ref(true)
|
|
let validations = 0
|
|
const formRef = ref({ validate: async () => { validations++; throw new Error('invalid') } })
|
|
const submit = new Function('saving', 'isLabelingCreate', 'orderInfoCollapsed', 'nextTick', 'labelingFormRef', `${code}\nreturn submit`)(saving, isLabelingCreate, collapsed, async () => {}, formRef)
|
|
assert.equal(await submit(), undefined)
|
|
assert.equal(collapsed.value, false)
|
|
assert.equal(validations, 1)
|
|
isLabelingCreate.value = false
|
|
assert.equal(await submit(), 'continue')
|
|
assert.equal(validations, 1)
|
|
saving.value = true
|
|
assert.equal(await submit(), undefined)
|
|
})
|