fix(admin): align supplier carrier master data
This commit is contained in:
@@ -1,27 +1,32 @@
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import { reactive, nextTick } from 'vue'
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
|
||||
import { defineComponent, reactive, nextTick, ref } from 'vue'
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import ElementPlus from 'element-plus'
|
||||
import type { Component } from 'vue'
|
||||
import type { Supplier } from '@/modules/suppliers/types'
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
route: null as null | { params: { id: string } },
|
||||
push: vi.fn(), getSupplier: vi.fn(), updateSupplier: vi.fn(),
|
||||
push: vi.fn(), getSupplier: vi.fn(), updateSupplier: vi.fn(), createSupplier: vi.fn(),
|
||||
listSuppliers: vi.fn(), getSupplierStats: vi.fn(), changeSupplierStatus: vi.fn(),
|
||||
can: vi.fn((permission: string) => permission === 'platform:supplier:list' || permission === 'platform:supplier:edit' || permission === 'platform:supplier:create'),
|
||||
}))
|
||||
const routeState = reactive({ params: { id: 'A' } })
|
||||
mocks.route = routeState
|
||||
let SupplierFormView: Component
|
||||
let SupplierDetailView: Component
|
||||
let SuppliersView: Component
|
||||
|
||||
vi.mock('vue-router', () => ({ useRoute: () => mocks.route, useRouter: () => ({ push: mocks.push }) }))
|
||||
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: mocks.can }) }))
|
||||
vi.mock('@/core/unsaved-work/useUnsavedWorkRegistration', () => ({ useUnsavedWorkRegistration: () => ({ captureBaseline: vi.fn() }) }))
|
||||
vi.mock('@/modules/suppliers/api/platformSuppliers', () => ({ getSupplier: mocks.getSupplier, updateSupplier: mocks.updateSupplier, createSupplier: vi.fn() }))
|
||||
vi.mock('@/modules/suppliers/api/platformSuppliers', () => ({
|
||||
getSupplier: mocks.getSupplier, updateSupplier: mocks.updateSupplier, createSupplier: mocks.createSupplier,
|
||||
listSuppliers: mocks.listSuppliers, getSupplierStats: mocks.getSupplierStats, changeSupplierStatus: mocks.changeSupplierStatus,
|
||||
}))
|
||||
|
||||
function supplier(id: string, name: string): Supplier {
|
||||
return { id, tenantId: '0', name, category: 'BOOKING', carrierCode: 'MATSON', region: '宁波', legalRepresentative: '法人', contactName: '联系人', phone: '13800000000', email: null, address: null, businessLicenseNo: null, licenseFileId: null, status: 'ACTIVE', settlementPeriod: 'MONTHLY_30', remark: null, createdBy: null, createdAt: '', updatedBy: null, updatedAt: '', deleted: false, version: 1 }
|
||||
return { id, tenantId: '0', name, category: 'BOOKING', carrierCodes: ['MATSON', 'SML'], region: '宁波', legalRepresentative: '法人', contactName: '联系人', phone: '13800000000', email: null, address: null, businessLicenseNo: null, licenseFileId: null, status: 'ACTIVE', settlementPeriod: 'MONTHLY_30', remark: null, createdBy: null, createdAt: '', updatedBy: null, updatedAt: '', deleted: false, version: 1 }
|
||||
}
|
||||
|
||||
function deferred<T>() {
|
||||
@@ -37,16 +42,25 @@ const stubs = {
|
||||
ApiErrorMeta: { template: '<span />' },
|
||||
LoadErrorState: { template: '<div class="load-error"><slot name="details" /></div>' },
|
||||
SupplierLicenseDialog: { template: '<div />' },
|
||||
ListPageLayout: { template: '<section><slot name="toolbar"/><slot name="state"/><slot/></section>' },
|
||||
QueryToolbar: { template: '<div />' },
|
||||
DataTable: { template: '<div><slot name="toolbar-actions"/></div>' },
|
||||
StatusBadge: { template: '<span />' },
|
||||
}
|
||||
enableAutoUnmount(afterEach)
|
||||
|
||||
describe('supplier route reuse', () => {
|
||||
beforeAll(async () => {
|
||||
SupplierFormView = (await import('@/modules/suppliers/pages/SupplierFormView.vue')).default
|
||||
SupplierDetailView = (await import('@/modules/suppliers/pages/SupplierDetailView.vue')).default
|
||||
SuppliersView = (await import('@/modules/suppliers/pages/SuppliersView.vue')).default
|
||||
})
|
||||
beforeEach(() => {
|
||||
routeState.params.id = 'A'
|
||||
mocks.push.mockReset(); mocks.getSupplier.mockReset(); mocks.updateSupplier.mockReset().mockResolvedValue(null)
|
||||
mocks.push.mockReset(); mocks.getSupplier.mockReset(); mocks.updateSupplier.mockReset().mockResolvedValue(null); mocks.createSupplier.mockReset().mockResolvedValue('99')
|
||||
mocks.listSuppliers.mockReset().mockResolvedValue({ records: [], page: 1, size: 20, total: 0, pages: 0 })
|
||||
mocks.getSupplierStats.mockReset().mockResolvedValue({ booking: 0, customs: 0, trucking: 0, certificate: 0 })
|
||||
mocks.changeSupplierStatus.mockReset().mockResolvedValue(null)
|
||||
mocks.can.mockClear()
|
||||
})
|
||||
|
||||
@@ -69,7 +83,7 @@ describe('supplier route reuse', () => {
|
||||
expect(saveButton).toBeDefined()
|
||||
await saveButton!.trigger('click')
|
||||
await flushPromises()
|
||||
expect(mocks.updateSupplier).toHaveBeenCalledWith('B', expect.objectContaining({ name: '供应商B' }))
|
||||
expect(mocks.updateSupplier).toHaveBeenCalledWith('B', expect.objectContaining({ name: '供应商B', carrierCodes: ['MATSON', 'SML'] }))
|
||||
expect(mocks.push).toHaveBeenCalledWith({ name: 'supplier-list' })
|
||||
})
|
||||
|
||||
@@ -84,4 +98,44 @@ describe('supplier route reuse', () => {
|
||||
expect(wrapper.text()).toContain('供应商B')
|
||||
expect(wrapper.text()).not.toContain('供应商A')
|
||||
})
|
||||
|
||||
it('resets a cached create form every time it is activated', async () => {
|
||||
routeState.params.id = ''
|
||||
const active = ref(true)
|
||||
const Host = defineComponent({
|
||||
components: { SupplierFormView },
|
||||
setup: () => ({ active }),
|
||||
template: '<KeepAlive><SupplierFormView v-if="active" /></KeepAlive>',
|
||||
})
|
||||
const wrapper = mount(Host, { global: { plugins: [ElementPlus], stubs } })
|
||||
await nextTick()
|
||||
const name = wrapper.find('input[placeholder="请输入供应商名称"]')
|
||||
await name.setValue('上一次新增的数据')
|
||||
expect((name.element as HTMLInputElement).value).toBe('上一次新增的数据')
|
||||
|
||||
active.value = false; await nextTick()
|
||||
active.value = true; await nextTick()
|
||||
|
||||
expect((wrapper.find('input[placeholder="请输入供应商名称"]').element as HTMLInputElement).value).toBe('')
|
||||
expect(mocks.getSupplier).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('reloads the cached supplier list every time it is activated', async () => {
|
||||
routeState.params.id = ''
|
||||
const active = ref(true)
|
||||
const Host = defineComponent({
|
||||
components: { SuppliersView },
|
||||
setup: () => ({ active }),
|
||||
template: '<KeepAlive><SuppliersView v-if="active" /></KeepAlive>',
|
||||
})
|
||||
mount(Host, { global: { plugins: [ElementPlus], stubs } })
|
||||
await flushPromises()
|
||||
expect(mocks.listSuppliers).toHaveBeenCalledTimes(1)
|
||||
|
||||
active.value = false; await nextTick()
|
||||
active.value = true; await flushPromises()
|
||||
|
||||
expect(mocks.listSuppliers).toHaveBeenCalledTimes(2)
|
||||
expect(mocks.getSupplierStats).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user