import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; import { describe, expect, it } from 'vitest'; const paymentApi = readFileSync(resolve(process.cwd(), 'src/api/payment.ts'), 'utf8'); const paymentPage = readFileSync(resolve(process.cwd(), 'src/pages/finance/PaymentsPage.vue'), 'utf8'); describe('page-15 payment control exceptions', () => { it('models warnings and normalizes server-controlled actions', () => { expect(paymentApi).toContain("result: 'PASS' | 'WARNING' | 'BLOCK'"); expect(paymentApi).toContain("| 'REQUEST_CONTROL_EXCEPTION'"); expect(paymentApi).toContain('controlExceptions: (Array.isArray(detail?.controlExceptions)'); expect(paymentApi).toContain('attachmentExceptions: (Array.isArray(detail?.attachmentExceptions)'); expect(paymentApi).toContain('allowedActions: Array.isArray(item?.allowedActions) ? item.allowedActions : []'); }); it('exposes request and independent review commands with idempotency headers', () => { expect(paymentApi).toContain('`/payments/' + '$' + '{paymentPublicId}/control-exceptions`'); expect(paymentApi).toContain( '`/payments/' + '$' + '{paymentPublicId}/control-exceptions/' + '$' + '{exceptionPublicId}/review`', ); expect(paymentApi).toContain("commandHeaders('payment-control-exception-request', idempotencyKey)"); expect(paymentApi).toContain("commandHeaders('payment-control-exception-review', idempotencyKey)"); }); it('gates request and review actions with backend allowedActions and optimistic versions', () => { expect(paymentPage).toContain("detail.value?.payment.allowedActions.includes('REQUEST_CONTROL_EXCEPTION')"); expect(paymentPage).toContain("row.allowedActions.includes('REVIEW')"); expect(paymentPage).toContain('当前附件不涉及申请不可复核,请刷新后重试。'); expect(paymentPage).toContain('paymentVersion: detail.value.payment.version'); expect(paymentPage).toContain('version: row.version'); expect(paymentPage).toContain('await loadDetail(paymentId, true)'); }); it('uses TDesign dialogs, tables, select, date picker and text areas for the workflow', () => { expect(paymentPage).toContain('aria-label="付款检查例外"'); expect(paymentPage).toContain('v-model:visible="controlExceptionRequestVisible"'); expect(paymentPage).toContain('v-model:visible="controlExceptionReviewVisible"'); expect(paymentPage).toContain('