import ElementPlus from 'element-plus' import { createPinia, setActivePinia } from 'pinia' import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { getCustomerDimensionConfig, updateCustomerDimensionConfig, type CustomerDimensionConfig, } from '@/modules/dimension-config' import { useAccessPreviewStore } from '@/core/access/accessPreview' import { useAuthStore } from '@/core/auth/auth' import CustomerBillingRulesPanel from './CustomerBillingRulesPanel.vue' vi.mock('@/modules/dimension-config', () => ({ getCustomerDimensionConfig: vi.fn(), updateCustomerDimensionConfig: vi.fn(), })) const rule: CustomerDimensionConfig = { tenantId: '8', edgeAdditionCm: 2, version: 3, updatedAt: '2026-08-07T10:20:00', } enableAutoUnmount(afterEach) describe('CustomerBillingRulesPanel', () => { beforeEach(() => { vi.clearAllMocks() document.body.innerHTML = '' const pinia = createPinia() setActivePinia(pinia) const auth = useAuthStore() auth.token = 'token' auth.permissions = ['firstleg:dimension-config:view', 'firstleg:dimension-config:edit'] useAccessPreviewStore().initializeAfterLogin() vi.mocked(getCustomerDimensionConfig).mockResolvedValue(rule) vi.mocked(updateCustomerDimensionConfig).mockResolvedValue({ ...rule, version: 4 }) }) it('shows one customer dimension rule instead of the old pricing versions', async () => { mount(CustomerBillingRulesPanel, { attachTo: document.body, props: { customerId: '8', customerName: '柏悦物流', customerCode: 'TEN8' }, global: { plugins: [ElementPlus] }, }) await flushPromises() expect(getCustomerDimensionConfig).toHaveBeenCalledWith('8') expect(document.body.textContent).toContain('尺寸计算规则') expect(document.body.textContent).toContain('当前每侧加宽') expect(document.body.textContent).toContain('+2cm') expect(document.body.textContent).toContain('34 × 24 × 24 cm') expect(document.body.textContent).toContain('0.020 CBM') expect(document.body.textContent).not.toContain('规则版本') expect(document.body.textContent).not.toContain('小箱') }) it('edits the single value and submits the optimistic lock version', async () => { mount(CustomerBillingRulesPanel, { attachTo: document.body, props: { customerId: '8', customerName: '柏悦物流' }, global: { plugins: [ElementPlus] }, }) await flushPromises() const editButton = [...document.querySelectorAll('button')] .find((button) => button.textContent?.trim() === '编辑规则') editButton?.click() await flushPromises() expect(document.body.textContent).toContain('编辑尺寸计算规则') expect(document.body.textContent).toContain('实际内径 30 × 20 × 20 cm') const saveButton = [...document.querySelectorAll('button')] .find((button) => button.textContent?.trim() === '保存规则') saveButton?.click() await flushPromises() expect(updateCustomerDimensionConfig).toHaveBeenCalledWith('8', { edgeAdditionCm: 2, version: 3, }) }) it('keeps the editor open when the versioned save fails', async () => { vi.mocked(updateCustomerDimensionConfig).mockRejectedValueOnce(new Error('规则已被其他人更新')) mount(CustomerBillingRulesPanel, { attachTo: document.body, props: { customerId: '8', customerName: '柏悦物流' }, global: { plugins: [ElementPlus] }, }) await flushPromises() const editButton = [...document.querySelectorAll('button')] .find((button) => button.textContent?.trim() === '编辑规则') editButton?.click() await flushPromises() const saveButton = [...document.querySelectorAll('button')] .find((button) => button.textContent?.trim() === '保存规则') saveButton?.click() await flushPromises() expect(document.body.textContent).toContain('编辑尺寸计算规则') expect(updateCustomerDimensionConfig).toHaveBeenCalledWith('8', expect.objectContaining({ version: 3 })) }) })