This commit is contained in:
2026-08-19 09:14:35 +08:00
parent c188482c24
commit 80cfca5056
36 changed files with 854 additions and 1044 deletions
@@ -4,12 +4,15 @@ import { resolve } from 'node:path'
import { createPinia, setActivePinia } from 'pinia'
import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { ElMessageBox } from 'element-plus'
import { ApiResponseError } from '@/shared/api/http'
import { useAccessPreviewStore } from '@/core/access/accessPreview'
import { useAuthStore } from '@/core/auth/auth'
import {
adjustPublishedInboundFee,
confirmInboundFee,
getLatestInboundFee,
sendInboundFee,
} from './api'
import type { InboundFeeSnapshot } from './types'
import InboundFeePanel from './InboundFeePanel.vue'
@@ -20,6 +23,8 @@ vi.mock('./api', async () => {
...actual,
getLatestInboundFee: vi.fn(),
adjustPublishedInboundFee: vi.fn(),
confirmInboundFee: vi.fn(),
sendInboundFee: vi.fn(),
}
})
@@ -52,7 +57,12 @@ function setupPermissions(permissions: string[]) {
return pinia
}
function mountPanel(permissions = ['firstleg:fba-pricing:view', 'firstleg:fba-pricing:adjust']) {
function mountPanel(permissions = [
'firstleg:fba-pricing:view',
'firstleg:fba-pricing:adjust',
'firstleg:fba-pricing:confirm',
'firstleg:inbound:send-fee',
]) {
const pinia = setupPermissions(permissions)
return mount(InboundFeePanel, {
attachTo: document.body,
@@ -67,6 +77,8 @@ describe('InboundFeePanel', () => {
document.body.innerHTML = ''
vi.mocked(getLatestInboundFee).mockResolvedValue(snapshot)
vi.mocked(adjustPublishedInboundFee).mockResolvedValue({ ...snapshot, feeVersion: 3, feeNo: 'FBAF-88-3' })
vi.mocked(confirmInboundFee).mockResolvedValue({ ...snapshot, feeStatus: 'CONFIRMED', confirmedAt: '2026-08-04T10:01:00', sentAt: null })
vi.mocked(sendInboundFee).mockResolvedValue(snapshot)
})
it('shows the immutable calculation basis, versions, amount, and timestamps', async () => {
@@ -88,6 +100,7 @@ describe('InboundFeePanel', () => {
expect(document.body.textContent).toContain('时间记录')
expect(document.body.textContent).toContain('发布')
expect(document.body.textContent).not.toContain('重新试算')
expect(document.body.textContent).not.toContain('确认费用')
expect(document.body.textContent).not.toContain('发送费用')
})
@@ -201,6 +214,33 @@ describe('InboundFeePanel', () => {
expect(wrapper.find('[data-testid="adjust-fee-button"]').exists()).toBe(true)
})
it('confirms and then sends a calculated fee through the implemented backend transitions', async () => {
vi.mocked(getLatestInboundFee).mockResolvedValue({ ...snapshot, feeStatus: 'CALCULATED', confirmedAt: null, sentAt: null })
vi.spyOn(ElMessageBox, 'confirm').mockResolvedValue(undefined as never)
const wrapper = mountPanel()
await flushPromises()
await wrapper.get('[data-testid="confirm-fee-button"]').trigger('click')
await flushPromises()
expect(confirmInboundFee).toHaveBeenCalledWith('10001', '88', expect.stringMatching(/^fee-confirm-/))
expect(wrapper.find('[data-testid="send-fee-button"]').exists()).toBe(true)
await wrapper.get('[data-testid="send-fee-button"]').trigger('click')
await flushPromises()
expect(sendInboundFee).toHaveBeenCalledWith('10001', '88', expect.stringMatching(/^fee-send-/))
expect(wrapper.emitted('changed')).toHaveLength(2)
expect(wrapper.find('[data-testid="send-fee-button"]').exists()).toBe(false)
})
it('does not expose fee transitions without their independent permissions', async () => {
vi.mocked(getLatestInboundFee).mockResolvedValue({ ...snapshot, feeStatus: 'CALCULATED', confirmedAt: null, sentAt: null })
const wrapper = mountPanel(['firstleg:fba-pricing:view', 'firstleg:fba-pricing:adjust'])
await flushPromises()
expect(wrapper.find('[data-testid="confirm-fee-button"]').exists()).toBe(false)
expect(wrapper.find('[data-testid="send-fee-button"]').exists()).toBe(false)
})
it('submits a reasoned adjustment and emits the refreshed snapshot', async () => {
vi.mocked(getLatestInboundFee).mockResolvedValue({ ...snapshot, feeStatus: 'CALCULATED' })
const wrapper = mountPanel()