安排/归档失败改为可执行原因;证件保存后自动启用、只读不再假启用; customer_category 归档超额改为客户+品类证件池,避免误查合同绑证。 Co-authored-by: Cursor <cursoragent@cursor.com>
127 lines
4.5 KiB
TypeScript
127 lines
4.5 KiB
TypeScript
import test from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
|
|
test('web contract detail embeds customer cert panel and renamed tab', () => {
|
|
const source = readFileSync(
|
|
new URL('../src/views/crm/contract/components/ContractDetailDialog.vue', import.meta.url),
|
|
'utf8'
|
|
)
|
|
assert.match(source, /label="客户证件与额度"/)
|
|
assert.match(source, /CustomerCertQuotaPanel/)
|
|
assert.doesNotMatch(source, /ContractQuotaPanel/)
|
|
assert.match(source, /:customer-id="detailContract\.customerId"/)
|
|
})
|
|
|
|
test('h5 contract detail includes customer cert tab', () => {
|
|
const source = readFileSync(
|
|
new URL('../src/views/m/crm/contract/detail.vue', import.meta.url),
|
|
'utf8'
|
|
)
|
|
assert.match(source, /CustomerCertQuotaTab/)
|
|
assert.match(source, /客户证件与额度/)
|
|
assert.match(source, /canViewQuotaCert/)
|
|
assert.match(source, /:customer-id="contract\.customerId"/)
|
|
})
|
|
|
|
test('customer cert panel lists by customerId without contract bindings', () => {
|
|
const source = readFileSync(
|
|
new URL('../src/views/pl/contract-quota/CustomerCertQuotaPanel.vue', import.meta.url),
|
|
'utf8'
|
|
)
|
|
assert.match(source, /quotaCertApi\.list\('purchase', \{ customerId \}\)/)
|
|
assert.match(source, /quotaCertApi\.list\('transport', \{ customerId \}\)/)
|
|
assert.match(source, /有效次数/)
|
|
assert.match(source, /singleUseConsumed/)
|
|
assert.doesNotMatch(source, /saveBindings|openCreate|bindings\(/)
|
|
})
|
|
|
|
test('standalone contract-quota page is customer quota list', () => {
|
|
const panel = readFileSync(
|
|
new URL('../src/views/pl/contract-quota/CustomerQuotaPanel.vue', import.meta.url),
|
|
'utf8'
|
|
)
|
|
const wrapper = readFileSync(
|
|
new URL('../src/views/pl/contract-quota/ContractQuotaPanel.vue', import.meta.url),
|
|
'utf8'
|
|
)
|
|
const router = readFileSync(new URL('../src/router/modules/pl.ts', import.meta.url), 'utf8')
|
|
assert.match(panel, /客户用证/)
|
|
assert.match(panel, /quotaStatisticsApi\.customers/)
|
|
assert.match(wrapper, /CustomerQuotaPanel/)
|
|
assert.match(router, /title: '客户用证'/)
|
|
})
|
|
|
|
test('web customer quota panel uses toQueryParams from useServerColumnFilters', () => {
|
|
const panel = readFileSync(
|
|
new URL('../src/views/pl/contract-quota/CustomerQuotaPanel.vue', import.meta.url),
|
|
'utf8'
|
|
)
|
|
assert.match(panel, /toQueryParams/)
|
|
assert.match(panel, /\.\.\.toQueryParams\(\)/)
|
|
assert.doesNotMatch(panel, /\bbuildQuery\b/)
|
|
assert.doesNotMatch(panel, /\bresetFilters\b/)
|
|
assert.match(panel, /clearAllFilters/)
|
|
assert.match(panel, /watchVisibleColumns/)
|
|
})
|
|
|
|
test('web customer quota panel computes visibleDefs locally (not from composable)', () => {
|
|
const panel = readFileSync(
|
|
new URL('../src/views/pl/contract-quota/CustomerQuotaPanel.vue', import.meta.url),
|
|
'utf8'
|
|
)
|
|
assert.doesNotMatch(
|
|
panel,
|
|
/const \{[^}]*\bvisibleDefs\b[^}]*\} = usePersistedListColumns/
|
|
)
|
|
assert.match(
|
|
panel,
|
|
/const \{ visibleColumns, checkAll, isIndeterminate, resetToDefault \} = usePersistedListColumns/
|
|
)
|
|
assert.match(
|
|
panel,
|
|
/const visibleDefs = computed\(\(\) =>\s*columns\.filter\(\(column\) => visibleColumns\.value\.includes\(column\.prop\)\)/
|
|
)
|
|
assert.match(panel, /v-for="column in visibleDefs"/)
|
|
})
|
|
|
|
test('h5 customer tab renders customer fields without persisted column defs', () => {
|
|
const tab = readFileSync(
|
|
new URL('../src/views/m/pl/plan-cert/CustomerTab.vue', import.meta.url),
|
|
'utf8'
|
|
)
|
|
assert.doesNotMatch(tab, /usePersistedListColumns/)
|
|
assert.doesNotMatch(tab, /visibleDefs/)
|
|
assert.match(tab, /row\.customerName/)
|
|
assert.match(tab, /row\.customerNo/)
|
|
assert.match(tab, /row\.certCount/)
|
|
})
|
|
|
|
test('h5 customer quota tab does not call buildQuery', () => {
|
|
const tab = readFileSync(
|
|
new URL('../src/views/m/pl/plan-cert/CustomerTab.vue', import.meta.url),
|
|
'utf8'
|
|
)
|
|
assert.doesNotMatch(tab, /\bbuildQuery\b/)
|
|
assert.match(tab, /quotaStatisticsApi\.customers/)
|
|
})
|
|
|
|
test('web customer quota panel wires viewport height like StatisticsPanel', () => {
|
|
const panel = readFileSync(
|
|
new URL('../src/views/pl/contract-quota/CustomerQuotaPanel.vue', import.meta.url),
|
|
'utf8'
|
|
)
|
|
assert.match(panel, /useElementSize\(tableWrapRef\)/)
|
|
assert.match(
|
|
panel,
|
|
/const expansionStyle = computed\(\(\) => \(\{[\s\S]*width: tableViewportWidth/
|
|
)
|
|
assert.match(panel, /tableEl: tableWrapRef/)
|
|
assert.match(panel, /pagerEl: pagerRef/)
|
|
assert.doesNotMatch(panel, /\bwrapRef\s*:/)
|
|
assert.doesNotMatch(
|
|
panel,
|
|
/const \{[^}]*\bexpansionStyle\b[^}]*\} = useListTableViewportHeight/
|
|
)
|
|
})
|