76 lines
4.7 KiB
TypeScript
76 lines
4.7 KiB
TypeScript
import { readFileSync } from 'node:fs'
|
|
import { resolve } from 'node:path'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
const source = readFileSync(resolve(process.cwd(), 'src/modules/finance/pages/FinanceFormalSettlementPage.vue'), 'utf8')
|
|
const statementsSource = readFileSync(resolve(process.cwd(), 'src/modules/finance/pages/FinanceCustomerStatementsView.vue'), 'utf8')
|
|
|
|
describe('Finance formal settlement desktop presentation', () => {
|
|
it('keeps settlement totals on the left and list actions on the right of the table toolbar', () => {
|
|
expect(source).toContain('<template #toolbar-start>')
|
|
expect(source).toContain('<div class="settlement-summary" aria-label="结算汇总">')
|
|
expect(source).toContain('<template #toolbar-actions>')
|
|
expect(source).toContain('<div class="settlement-list-actions">')
|
|
expect(source).not.toContain('class="settlement-list-toolbar"')
|
|
})
|
|
|
|
it('paginates customer statements and both settlement lists after filtering', () => {
|
|
for (const pageSource of [statementsSource, source]) {
|
|
expect(pageSource).toContain('const page = ref(1)')
|
|
expect(pageSource).toContain('const pageSize = ref(20)')
|
|
expect(pageSource).toContain('const paginatedRows = computed(() => {')
|
|
expect(pageSource).toContain('filteredRows.value.slice(start, start + pageSize.value)')
|
|
expect(pageSource).toContain('v-model:page="page" v-model:page-size="pageSize" :data="paginatedRows"')
|
|
expect(pageSource).toContain(':total="filteredRows.length"')
|
|
expect(pageSource).toContain('page.value = 1')
|
|
}
|
|
})
|
|
|
|
it('renders up to three row actions as compact icon buttons without wrapping', () => {
|
|
expect(source.match(/key: 'actions', label: '操作', width: 250/g)).toHaveLength(2)
|
|
expect(source).toContain('class="settlement-row-actions"')
|
|
expect(source).toContain('<el-button size="small" plain type="primary" @click="openDetail(row)"><Eye :size="15" />详情</el-button>')
|
|
expect(source).toContain('size="small" type="primary" :loading="receiptBusy" @click="openReceipt(row)"')
|
|
expect(source).toContain('size="small" type="primary" @click="openPayment(row)"')
|
|
expect(source).toContain('size="small" plain type="danger" :loading="actionBusy"')
|
|
expect(source).toContain('size="small" plain type="primary" :loading="actionBusy"')
|
|
expect(source).toContain('.settlement-row-actions { display: flex; align-items: center; flex-wrap: nowrap; gap: 6px; white-space: nowrap; }')
|
|
expect(source).not.toContain('<el-button link')
|
|
expect(source).not.toContain('MoreHorizontal')
|
|
expect(source).toContain('v-if="canReceive && [\'ISSUED\',\'PARTIALLY_PAID\'].includes(String(row.status))"')
|
|
expect(source).toContain('v-if="canPay && [\'ISSUED\',\'PARTIALLY_PAID\'].includes(String(row.status))"')
|
|
expect(source).toContain('v-if="canVoid && row.status === \'ISSUED\'"')
|
|
})
|
|
|
|
it('uses a continuous detail layout with locally scrollable wide tables', () => {
|
|
expect(source).toContain('<DetailPageLayout v-else-if="detailMode" class="settlement-detail-page surface-panel"')
|
|
expect(source).toContain('class="settlement-detail-content"')
|
|
expect(source).toContain('class="detail-table-scroll"')
|
|
expect(source).toContain(':deep(.detail-table-scroll .el-table) { min-width: 920px; }')
|
|
expect(source).not.toContain('class="settlement-detail-card"')
|
|
})
|
|
|
|
it('presents fee sources and revisions as finance business labels', () => {
|
|
expect(source).toContain('financeSourceTypeLabel(scope.row.sourceType)')
|
|
expect(source).not.toContain('prop="sourceVersion" label="来源版本"')
|
|
expect(source).toContain("VOID: '作废'")
|
|
expect(source).toContain("REOPEN: '重开'")
|
|
expect(source).toContain("RECEIPT: '收款登记'")
|
|
expect(source).toContain("PAYMENT: '付款登记'")
|
|
expect(source).toContain('settlementRevisionActionLabel(scope.row.action)')
|
|
expect(source).toContain('operatorDisplayName(scope.row.createdByName)')
|
|
expect(source).toContain('operatorDisplayName(scope.row.operatorName)')
|
|
expect(source).toContain("'名称数据缺失'")
|
|
})
|
|
|
|
it('keeps receipt and payment dialogs readable at desktop width', () => {
|
|
expect(source.match(/width="min\(760px, 94vw\)"/g)).toHaveLength(2)
|
|
expect(source).toContain('.partial-summary { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));')
|
|
expect(source).toContain('.settlement-operation-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));')
|
|
expect(source).toContain('<OperationErrorToast :message="receiptValidationError" />')
|
|
expect(source).toContain('<OperationErrorToast :details="receiptError" />')
|
|
expect(source).not.toContain('<el-alert v-if="receiptValidationError"')
|
|
expect(source).not.toContain('<el-alert v-if="receiptError"')
|
|
})
|
|
})
|