修复财务页面竞态并整理采购与运输展示
This commit is contained in:
@@ -1,8 +1,51 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import ElementPlus from 'element-plus'
|
||||
import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
|
||||
import { createMemoryHistory, createRouter } from 'vue-router'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { listPlatformTenants } from '@/modules/iam'
|
||||
import { getReceivableStatistics } from '../api/finance'
|
||||
import type { ReceivableStatisticsResult } from '../types'
|
||||
import FinanceReceivableStatisticsView from './FinanceReceivableStatisticsView.vue'
|
||||
|
||||
const can = vi.hoisted(() => vi.fn((_permission: string) => true))
|
||||
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can }) }))
|
||||
vi.mock('@/modules/iam', () => ({ listPlatformTenants: vi.fn() }))
|
||||
vi.mock('@/modules/downloads', () => ({ createPlatformExportTask: vi.fn() }))
|
||||
vi.mock('@/shared/components/exportTaskCreatedDialog', () => ({ showExportTaskCreatedDialog: vi.fn() }))
|
||||
vi.mock('../api/finance', () => ({ getReceivableStatistics: vi.fn() }))
|
||||
|
||||
const page = readFileSync(resolve(process.cwd(), 'src/modules/finance/pages/FinanceReceivableStatisticsView.vue'), 'utf8')
|
||||
const statistics: ReceivableStatisticsResult = {
|
||||
statisticsMonth: '2026-10', currency: 'CNY', totalReceivable: '2600', totalReceived: '2550', totalOutstanding: '50',
|
||||
totalCustomers: 2, page: 1, pageSize: 20,
|
||||
records: [
|
||||
{ customerId: '10001', customerName: '客户A', currency: 'CNY', totalReceivable: '2400', totalReceived: '2400', totalOutstanding: '0' },
|
||||
{ customerId: '10002', customerName: '客户 10002', currency: 'CNY', totalReceivable: '200', totalReceived: '150', totalOutstanding: '50' },
|
||||
],
|
||||
}
|
||||
|
||||
async function mountPage() {
|
||||
const router = createRouter({ history: createMemoryHistory(), routes: [
|
||||
{ path: '/finance/receivable-statistics', name: 'finance-receivable-statistics', component: FinanceReceivableStatisticsView },
|
||||
{ path: '/other', name: 'other-page', component: { template: '<div>其他页面</div>' } },
|
||||
] })
|
||||
await router.push('/finance/receivable-statistics')
|
||||
await router.isReady()
|
||||
const wrapper = mount(FinanceReceivableStatisticsView, { attachTo: document.body, global: { plugins: [ElementPlus, router] } })
|
||||
await flushPromises()
|
||||
return { wrapper, router }
|
||||
}
|
||||
|
||||
enableAutoUnmount(afterEach)
|
||||
beforeEach(() => {
|
||||
can.mockReturnValue(true)
|
||||
vi.stubGlobal('ResizeObserver', class { observe() {} unobserve() {} disconnect() {} })
|
||||
vi.mocked(listPlatformTenants).mockResolvedValue({ records: [{ id: '10002', tenantName: '客户B', status: 'ACTIVE' } as never], page: 1, size: 200, total: 1, pages: 1 })
|
||||
vi.mocked(getReceivableStatistics).mockResolvedValue(statistics)
|
||||
})
|
||||
afterEach(() => { vi.restoreAllMocks(); vi.unstubAllGlobals(); document.body.innerHTML = '' })
|
||||
|
||||
describe('receivable statistics page', () => {
|
||||
it('renders only the approved CNY derived metrics and current-filter actions', () => {
|
||||
@@ -25,4 +68,47 @@ describe('receivable statistics page', () => {
|
||||
expect(page).toContain('当前月份暂无应收数据')
|
||||
expect(page).toContain(':loading="loading"')
|
||||
})
|
||||
|
||||
it('prints an isolated report with all five columns, the loaded month and server totals', async () => {
|
||||
const print = vi.spyOn(window, 'print').mockImplementation(() => {})
|
||||
const { wrapper } = await mountPage()
|
||||
const report = document.body.querySelector(':scope > .receivable-statistics-print')!
|
||||
expect(report).not.toBeNull()
|
||||
expect(report.querySelector('h1')?.textContent).toBe('应收款统计表')
|
||||
expect(report.textContent).toContain('统计月份:2026-10')
|
||||
expect([...report.querySelectorAll('thead th')].map(cell => cell.textContent)).toEqual(['应收单位', '币种', '应收总额(CNY)', '已收合计(CNY)', '余额未收(CNY)'])
|
||||
expect([...report.querySelectorAll('tbody tr')].map(row => [...row.querySelectorAll('td')].map(cell => cell.textContent))).toEqual([
|
||||
['客户A', 'CNY', '2,400.00', '2,400.00', '0.00'],
|
||||
['客户B', 'CNY', '200.00', '150.00', '50.00'],
|
||||
])
|
||||
expect([...report.querySelectorAll('tfoot td')].map(cell => cell.textContent)).toEqual(['2,600.00', '2,550.00', '50.00'])
|
||||
expect(report.querySelector('button, input, .finance-metric-grid, .data-table__pagination')).toBeNull()
|
||||
expect(page).toContain(':global(body:has(> .receivable-statistics-print) > :not(.receivable-statistics-print)) { display: none !important; }')
|
||||
expect(page).toContain('width: 100%; border-collapse: collapse; table-layout: fixed;')
|
||||
await wrapper.findAll('button').find(button => button.text() === '打印')!.trigger('click')
|
||||
expect(print).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('removes the print report when a cached statistics page is no longer the active route', async () => {
|
||||
const { router } = await mountPage()
|
||||
expect(document.querySelector('.receivable-statistics-print')).not.toBeNull()
|
||||
await router.push('/other')
|
||||
await flushPromises()
|
||||
expect(document.querySelector('.receivable-statistics-print')).toBeNull()
|
||||
await router.push('/finance/receivable-statistics')
|
||||
await flushPromises()
|
||||
expect(document.querySelector('.receivable-statistics-print')).not.toBeNull()
|
||||
})
|
||||
|
||||
it.each(['loading', 'error', 'no-permission'])('does not print unavailable statistics: %s', async state => {
|
||||
if (state === 'loading') vi.mocked(getReceivableStatistics).mockReturnValueOnce(new Promise(() => {}))
|
||||
if (state === 'error') vi.mocked(getReceivableStatistics).mockRejectedValueOnce(new Error('不可用'))
|
||||
if (state === 'no-permission') can.mockReturnValue(false)
|
||||
const print = vi.spyOn(window, 'print').mockImplementation(() => {})
|
||||
const { wrapper } = await mountPage()
|
||||
const vm = wrapper.vm as unknown as { printCurrent(): void }
|
||||
expect(document.querySelector('.receivable-statistics-print')).toBeNull()
|
||||
vm.printCurrent()
|
||||
expect(print).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user