Files
admin-web/src/modules/audit/components/CustomerAuditLogsPanel.test.ts
T
2026-08-18 09:46:34 +08:00

135 lines
7.8 KiB
TypeScript

import ElementPlus from 'element-plus'
import { createPinia, setActivePinia } from 'pinia'
import { flushPromises, mount } from '@vue/test-utils'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { useAccessPreviewStore } from '@/core/access/accessPreview'
import { useAuthStore } from '@/core/auth/auth'
import QueryToolbar from '@/shared/components/QueryToolbar.vue'
import { getPlatformAuditLog, listPlatformAuditLogs } from '../api/platformAudit'
import CustomerAuditLogsPanel from './CustomerAuditLogsPanel.vue'
vi.mock('../api/platformAudit', () => ({ getPlatformAuditLog: vi.fn(), listPlatformAuditLogs: vi.fn() }))
const row = { id: '1', eventId: 'evt', eventType: 'PLATFORM_TENANT_UPDATE', resourceType: 'TENANT', resourceId: '8', description: '编辑客户', accountId: '8', operatorTenantId: '0', userId: '9', username: 'platform_admin', appCode: 'ADMIN', clientType: 'WEB', clientIp: '127.0.0.1', requestId: 'req', traceId: 'trace', serviceName: 'iam-service', success: true, errorCode: null, errorMessage: null, occurredAt: '2026-08-13T01:00:00Z', createdAt: '2026-08-13T09:00:00' }
function mountPanel(permissions: string[]) {
const pinia = createPinia(); setActivePinia(pinia)
const auth = useAuthStore(); auth.token = 'token'; auth.permissions = permissions
useAccessPreviewStore().initializeAfterLogin()
return mount(CustomerAuditLogsPanel, { props: { customerId: '8', customerName: '柏悦物流' }, global: { plugins: [pinia, ElementPlus] } })
}
describe('CustomerAuditLogsPanel', () => {
beforeEach(() => { vi.clearAllMocks(); vi.mocked(listPlatformAuditLogs).mockResolvedValue({ records: [row], page: 1, size: 20, total: 1, pages: 1 }) })
it('queries logs with the current customer id', async () => {
const wrapper = mountPanel(['platform:audit:list']); await flushPromises()
expect(listPlatformAuditLogs).toHaveBeenCalledWith({ accountId: '8', page: 1, size: 20 })
expect(wrapper.text()).toContain('编辑客户')
expect(wrapper.text()).toContain('127.0.0.1')
expect(wrapper.text()).toContain('编辑客户档案')
expect(wrapper.text()).not.toContain('PLATFORM_TENANT_UPDATE')
expect(wrapper.text()).toContain('平台管理员')
expect(wrapper.text()).toContain('客户与权限服务')
})
it('shows inbound audit events in Chinese without wrapping technical codes into the table', async () => {
vi.mocked(listPlatformAuditLogs).mockResolvedValue({ records: [{ ...row, eventType: 'INBOUND_MEASURE_APPROVE', description: '测量审核通过', serviceName: 'firstleg-service' }], page: 1, size: 20, total: 1, pages: 1 })
const wrapper = mountPanel(['platform:audit:list']); await flushPromises()
expect(wrapper.text()).toContain('入库测量审核通过')
expect(wrapper.text()).toContain('头程履约服务')
expect(wrapper.text()).not.toContain('INBOUND_MEASURE_APPROVE')
})
it('shows the server total instead of the current page row count', async () => {
vi.mocked(listPlatformAuditLogs).mockResolvedValue({ records: [row], page: 1, size: 20, total: 13, pages: 1 })
const wrapper = mountPanel(['platform:audit:list']); await flushPromises()
expect(wrapper.text()).toContain('共 13 条客户操作记录')
})
it('applies keyword, result and local date range only after search', async () => {
const wrapper = mountPanel(['platform:audit:list']); await flushPromises()
vi.mocked(listPlatformAuditLogs).mockClear()
const toolbar = wrapper.findComponent(QueryToolbar)
toolbar.vm.$emit('update:modelValue', { keyword: ' admin ', success: false, occurredRange: ['2026-08-01', '2026-08-13'] })
await wrapper.vm.$nextTick()
expect(listPlatformAuditLogs).not.toHaveBeenCalled()
toolbar.vm.$emit('search', { keyword: ' admin ', success: false, occurredRange: ['2026-08-01', '2026-08-13'] })
await flushPromises()
expect(listPlatformAuditLogs).toHaveBeenCalledTimes(1)
expect(listPlatformAuditLogs).toHaveBeenCalledWith({
accountId: '8', page: 1, size: 20, keyword: 'admin', success: false,
occurredFrom: new Date(2026, 7, 1, 0, 0, 0, 0).toISOString(),
occurredTo: new Date(2026, 7, 13, 23, 59, 59, 999).toISOString(),
})
})
it('resets to all logs and requests once on the first page', async () => {
const wrapper = mountPanel(['platform:audit:list']); await flushPromises()
const toolbar = wrapper.findComponent(QueryToolbar)
toolbar.vm.$emit('update:modelValue', { keyword: 'admin', success: true, occurredRange: ['2026-08-01', '2026-08-13'] })
toolbar.vm.$emit('search', { keyword: 'admin', success: true, occurredRange: ['2026-08-01', '2026-08-13'] })
await flushPromises()
vi.mocked(listPlatformAuditLogs).mockClear()
;(toolbar.vm as unknown as { reset: () => void }).reset()
await flushPromises()
expect(listPlatformAuditLogs).toHaveBeenCalledTimes(1)
expect(wrapper.findComponent(QueryToolbar).props('modelValue')).toEqual({ keyword: '', success: '', occurredRange: [] })
expect(listPlatformAuditLogs).toHaveBeenCalledWith({ accountId: '8', page: 1, size: 20, keyword: undefined, success: undefined, occurredFrom: undefined, occurredTo: undefined })
})
it('does not query without audit permission', async () => {
const wrapper = mountPanel([]); await flushPromises()
expect(listPlatformAuditLogs).not.toHaveBeenCalled()
expect(wrapper.text()).toContain('暂无操作日志查看权限')
})
it('loads detail and formats json snapshots', async () => {
vi.mocked(getPlatformAuditLog).mockResolvedValue({ ...row, eventType: 'INBOUND_MEASURE_APPROVE', resourceType: 'INBOUND_MEASUREMENT', serviceName: 'firstleg-service', httpMethod: 'PUT', requestUri: '/tenants/8', clientIp: '127.0.0.1', durationMs: 12, beforeData: '{"name":"旧名称"}', afterData: '{"name":"新名称"}' })
const wrapper = mountPanel(['platform:audit:list']); await flushPromises()
await wrapper.get('button[aria-label="查看操作日志1详情"]').trigger('click'); await flushPromises()
expect(getPlatformAuditLog).toHaveBeenCalledWith('1')
expect(wrapper.text()).toContain('旧名称')
expect(wrapper.text()).toContain('新名称')
expect(wrapper.text()).toContain('入库测量审核通过')
expect(wrapper.text()).toContain('入库测量')
expect(wrapper.text()).toContain('头程履约服务')
expect(wrapper.text()).toContain('更新')
expect(wrapper.find('.audit-detail-grid').exists()).toBe(true)
})
it('loads the selected audit page', async () => {
const wrapper = mountPanel(['platform:audit:list']); await flushPromises()
wrapper.findComponent(QueryToolbar).vm.$emit('search', { keyword: 'tenant', success: true, occurredRange: [] })
await flushPromises()
vi.mocked(listPlatformAuditLogs).mockClear()
;(wrapper.vm as unknown as { page: number }).page = 2
await flushPromises()
expect(listPlatformAuditLogs).toHaveBeenCalledWith({ accountId: '8', page: 2, size: 20, keyword: 'tenant', success: true, occurredFrom: undefined, occurredTo: undefined })
})
it('clears draft and applied filters when switching customers', async () => {
const wrapper = mountPanel(['platform:audit:list']); await flushPromises()
const toolbar = wrapper.findComponent(QueryToolbar)
toolbar.vm.$emit('update:modelValue', { keyword: 'draft', success: false, occurredRange: [] })
toolbar.vm.$emit('search', { keyword: 'applied', success: true, occurredRange: [] })
await flushPromises()
vi.mocked(listPlatformAuditLogs).mockClear()
await wrapper.setProps({ customerId: '9' })
await flushPromises()
expect(wrapper.findComponent(QueryToolbar).props('modelValue')).toEqual({ keyword: '', success: '', occurredRange: [] })
expect(listPlatformAuditLogs).toHaveBeenCalledTimes(1)
expect(listPlatformAuditLogs).toHaveBeenCalledWith({ accountId: '9', page: 1, size: 20, keyword: undefined, success: undefined, occurredFrom: undefined, occurredTo: undefined })
})
})