161 lines
8.6 KiB
TypeScript
161 lines
8.6 KiB
TypeScript
import ElementPlus from 'element-plus'
|
|
import { createPinia, setActivePinia } from 'pinia'
|
|
import { createMemoryHistory, createRouter } from 'vue-router'
|
|
import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
|
import { useAuthStore } from '@/core/auth/auth'
|
|
import { createPlatformExportTask } from '@/modules/downloads'
|
|
import { listPlatformTenants } from '@/modules/iam'
|
|
import { showExportTaskCreatedDialog } from '@/shared/components/exportTaskCreatedDialog'
|
|
import { getFinanceSettlement, listFinancePayableSettlements, listFinanceReceivableSettlements } from '../api/finance'
|
|
import type { FinanceSettlementDetail } from '../types'
|
|
import FinanceFormalSettlementPage from './FinanceFormalSettlementPage.vue'
|
|
|
|
vi.mock('@/modules/downloads', () => ({ createPlatformExportTask: vi.fn() }))
|
|
vi.mock('@/modules/iam', () => ({ listPlatformTenants: vi.fn() }))
|
|
vi.mock('@/modules/suppliers', () => ({ categoryLabels: {}, listSuppliers: vi.fn() }))
|
|
vi.mock('@/shared/components/exportTaskCreatedDialog', () => ({ showExportTaskCreatedDialog: vi.fn() }))
|
|
vi.mock('../api/finance', async (importOriginal) => ({
|
|
...await importOriginal<typeof import('../api/finance')>(),
|
|
getFinanceSettlement: vi.fn(),
|
|
listFinancePayableSettlements: vi.fn(),
|
|
listFinanceReceivableSettlements: vi.fn(),
|
|
}))
|
|
|
|
class ResizeObserverStub implements ResizeObserver {
|
|
observe() {}
|
|
unobserve() {}
|
|
disconnect() {}
|
|
}
|
|
|
|
function createMemoryStorage(): Storage {
|
|
const values = new Map<string, string>()
|
|
return {
|
|
get length() { return values.size }, clear: () => values.clear(), getItem: (key) => values.get(key) ?? null,
|
|
key: (index) => [...values.keys()][index] ?? null, removeItem: (key) => values.delete(key), setItem: (key, value) => values.set(key, value),
|
|
}
|
|
}
|
|
|
|
function piniaWithPermissions(permissions: string[]) {
|
|
const pinia = createPinia()
|
|
setActivePinia(pinia)
|
|
const auth = useAuthStore()
|
|
auth.token = 'token'
|
|
auth.permissions = permissions
|
|
useAccessPreviewStore().initializeAfterLogin()
|
|
return pinia
|
|
}
|
|
|
|
function testRouter() {
|
|
return createRouter({
|
|
history: createMemoryHistory(),
|
|
routes: [
|
|
{ path: '/', name: 'settlements', component: { template: '<div />' } },
|
|
{ path: '/downloads', name: 'download-center', component: { template: '<div />' } },
|
|
],
|
|
})
|
|
}
|
|
|
|
const detail: FinanceSettlementDetail = {
|
|
id: '701', settlementNo: 'AR-701', customerId: '10001', reconciliationStatementId: '501', direction: 'RECEIVABLE',
|
|
amount: 300, paidAmount: 0, outstandingAmount: 300, currency: 'CNY', status: 'ISSUED', version: 0,
|
|
lines: [], transactions: [], revisions: [],
|
|
}
|
|
|
|
enableAutoUnmount(afterEach)
|
|
|
|
describe('formal settlement download-center exports', () => {
|
|
beforeEach(() => {
|
|
vi.stubGlobal('ResizeObserver', ResizeObserverStub)
|
|
vi.stubGlobal('localStorage', createMemoryStorage())
|
|
vi.stubGlobal('sessionStorage', createMemoryStorage())
|
|
vi.mocked(listPlatformTenants).mockReset().mockResolvedValue({ records: [], page: 1, size: 200, total: 0, pages: 1 })
|
|
vi.mocked(listFinanceReceivableSettlements).mockReset().mockResolvedValue([])
|
|
vi.mocked(listFinancePayableSettlements).mockReset().mockResolvedValue([])
|
|
vi.mocked(getFinanceSettlement).mockReset().mockResolvedValue(detail)
|
|
vi.mocked(createPlatformExportTask).mockReset().mockResolvedValue({ taskName: '应收结算单列表', taskNo: 'EXP-001' } as never)
|
|
vi.mocked(showExportTaskCreatedDialog).mockReset().mockResolvedValue(false)
|
|
})
|
|
|
|
it('creates an AR list task with current filters and no paging or direction parameters', async () => {
|
|
const router = testRouter()
|
|
await router.push('/'); await router.isReady()
|
|
const pinia = piniaWithPermissions(['platform:finance:settlement-ar:list', 'platform:finance:settlement-ar:export', 'platform:download:list'])
|
|
const wrapper = mount(FinanceFormalSettlementPage, { props: { kind: 'receivable' }, global: { plugins: [pinia, ElementPlus, router] } })
|
|
await flushPromises()
|
|
const vm = wrapper.vm as unknown as { filters: Record<string, unknown>; exportRows(): Promise<void> }
|
|
vm.filters = { customerId: '10001', status: 'ISSUED', settlementNo: ' AR-001 ', supplierName: '' }
|
|
|
|
await vm.exportRows()
|
|
|
|
expect(createPlatformExportTask).toHaveBeenCalledWith({
|
|
exportType: 'FINANCE_RECEIVABLE_SETTLEMENT_LIST', format: 'XLSX', taskName: '应收结算单列表',
|
|
parameters: { customerId: '10001', status: 'ISSUED', settlementNo: 'AR-001' },
|
|
})
|
|
expect(createPlatformExportTask).not.toHaveBeenCalledWith(expect.objectContaining({ parameters: expect.objectContaining({ direction: expect.anything(), page: expect.anything(), pageSize: expect.anything() }) }))
|
|
})
|
|
|
|
it('creates an AP list task with the supplier filter', async () => {
|
|
const router = testRouter()
|
|
await router.push('/'); await router.isReady()
|
|
const pinia = piniaWithPermissions(['platform:finance:settlement-ap:list', 'platform:finance:settlement-ap:export', 'platform:download:list'])
|
|
const wrapper = mount(FinanceFormalSettlementPage, { props: { kind: 'payable' }, global: { plugins: [pinia, ElementPlus, router] } })
|
|
await flushPromises()
|
|
const vm = wrapper.vm as unknown as { filters: Record<string, unknown>; exportRows(): Promise<void> }
|
|
vm.filters = { customerId: '10002', status: 'PARTIALLY_PAID', settlementNo: 'AP-002', supplierName: '承运供应商' }
|
|
|
|
await vm.exportRows()
|
|
|
|
expect(createPlatformExportTask).toHaveBeenCalledWith({
|
|
exportType: 'FINANCE_PAYABLE_SETTLEMENT_LIST', format: 'XLSX', taskName: '应付结算单列表',
|
|
parameters: { customerId: '10002', status: 'PARTIALLY_PAID', settlementNo: 'AP-002', supplierName: '承运供应商' },
|
|
})
|
|
})
|
|
|
|
it('exports a detail by settlement business key and opens the download center on confirmation', async () => {
|
|
vi.mocked(createPlatformExportTask).mockResolvedValueOnce({ taskName: '应收结算单详情', taskNo: 'EXP-DETAIL-1' } as never)
|
|
vi.mocked(showExportTaskCreatedDialog).mockResolvedValueOnce(true)
|
|
const router = testRouter()
|
|
await router.push('/'); await router.isReady()
|
|
const pinia = piniaWithPermissions(['platform:finance:settlement-ar:list', 'platform:finance:settlement-ar:export', 'platform:download:list'])
|
|
const wrapper = mount(FinanceFormalSettlementPage, { props: { kind: 'receivable', settlementId: '701' }, global: { plugins: [pinia, ElementPlus, router] } })
|
|
await flushPromises()
|
|
const vm = wrapper.vm as unknown as { exportDetail(): Promise<void> }
|
|
|
|
await vm.exportDetail()
|
|
|
|
expect(createPlatformExportTask).toHaveBeenCalledWith({
|
|
exportType: 'FINANCE_RECEIVABLE_SETTLEMENT_DETAIL', format: 'XLSX', taskName: '应收结算单详情', parameters: { settlementId: '701' },
|
|
})
|
|
expect(showExportTaskCreatedDialog).toHaveBeenCalledWith({ taskName: '应收结算单详情', taskNo: 'EXP-DETAIL-1', dense: true })
|
|
expect(router.currentRoute.value.name).toBe('download-center')
|
|
})
|
|
|
|
it('uses the payable detail type without a direction parameter', async () => {
|
|
vi.mocked(getFinanceSettlement).mockResolvedValueOnce({ ...detail, id: '801', settlementNo: 'AP-801', direction: 'PAYABLE' })
|
|
vi.mocked(createPlatformExportTask).mockResolvedValueOnce({ taskName: '应付结算单详情', taskNo: 'EXP-DETAIL-2' } as never)
|
|
const router = testRouter()
|
|
await router.push('/'); await router.isReady()
|
|
const pinia = piniaWithPermissions(['platform:finance:settlement-ap:list', 'platform:finance:settlement-ap:export', 'platform:download:list'])
|
|
const wrapper = mount(FinanceFormalSettlementPage, { props: { kind: 'payable', settlementId: '801' }, global: { plugins: [pinia, ElementPlus, router] } })
|
|
await flushPromises()
|
|
|
|
await (wrapper.vm as unknown as { exportDetail(): Promise<void> }).exportDetail()
|
|
|
|
expect(createPlatformExportTask).toHaveBeenCalledWith({
|
|
exportType: 'FINANCE_PAYABLE_SETTLEMENT_DETAIL', format: 'XLSX', taskName: '应付结算单详情', parameters: { settlementId: '801' },
|
|
})
|
|
})
|
|
|
|
it('hides export actions unless both export and download-list permissions are present', async () => {
|
|
const router = testRouter()
|
|
await router.push('/'); await router.isReady()
|
|
const pinia = piniaWithPermissions(['platform:finance:settlement-ar:list', 'platform:download:list'])
|
|
const wrapper = mount(FinanceFormalSettlementPage, { props: { kind: 'receivable' }, global: { plugins: [pinia, ElementPlus, router] } })
|
|
await flushPromises()
|
|
|
|
expect(wrapper.find('.settlement-list-actions').text()).not.toContain('导出')
|
|
})
|
|
})
|