Files
admin-web/src/modules/finance/pages/FinanceFormalSettlementLayout.test.ts
T

76 lines
4.5 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 the title and actions in the toolbar and settlement totals before results', () => {
expect(source).toContain('<template #toolbar-start>')
expect(source).toContain('<h1>{{ title }}</h1>')
expect(source).toContain('<template #before-results>')
expect(source).toContain('<dl class="density-detail-overview 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 at most three permitted row actions as shared text buttons', () => {
expect(source.match(/key: 'actions', label: '操作', width: 250/g)).toHaveLength(2)
expect(source).toContain('class="settlement-row-actions density-actions row-actions admin-text-actions"')
for (const action of ['openDetail(row)', 'openReceipt(row)', 'openPayment(row)']) expect(source).toContain('@click="' + action + '"')
expect(source).toContain('data-tone="danger"')
expect(source).toContain('class="density-action"')
expect(source).not.toContain('MoreHorizontal')
expect(source).toContain("props.kind === 'payable' && access.can('platform:finance:payment:create')")
expect(source).toContain("props.kind === 'receivable' && access.can('platform:finance:receipt:create')")
expect(source).toContain("canVoid && row.status === 'ISSUED'")
expect(source).toContain("canVoid && row.status === 'VOIDED'")
})
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 finance-density-detail"')
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.match(/class="density-dialog-section partial-summary"/g)).toHaveLength(2)
expect(source).toContain('density-table density-table--editable settlement-operation-table')
expect(source).toContain('.settlement-operation-table td:not([colspan]) { width: 50%; }')
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"')
})
})