81 lines
5.4 KiB
TypeScript
81 lines
5.4 KiB
TypeScript
import { mount } from '@vue/test-utils'
|
||
import { afterEach, expect, it, vi } from 'vitest'
|
||
import WorkCalendarPanel from './WorkCalendarPanel.vue'
|
||
import { workCalendar } from './work.test-support'
|
||
import { workTypes } from './workApi'
|
||
function render() { return mount(WorkCalendarPanel, { props: { anchor: '2026-10-15', mode: 'month', flow: '', types: [...workTypes], calendar: workCalendar, loading: false, failed: false, reference: false, arrivals: [], referenceReady: false } }) }
|
||
afterEach(() => vi.useRealTimers())
|
||
it('keeps a busy day at five type summaries and consumes authoritative transport counts unchanged', async () => {
|
||
const wrapper = render()
|
||
const counts = { PICKUP: 300, WAREHOUSE_RECEIPT: 300, DELIVERY: 2, TRANSPORT: 1, EMPTY_RETURN: 300 }
|
||
await wrapper.setProps({ calendar: { ...workCalendar, days: [{ ...workCalendar.days[0]!, total: 903, typeCounts: counts }] } })
|
||
const day = wrapper.get('[data-date="2026-10-15"]')
|
||
expect(day.findAll('.type-counts button')).toHaveLength(5)
|
||
expect(day.get('[data-type="TRANSPORT"]').text()).toContain('1')
|
||
expect(day.get('[data-type="DELIVERY"]').text()).toContain('2')
|
||
await day.get('[data-type="TRANSPORT"]').trigger('click')
|
||
expect(wrapper.emitted('day')).toEqual([['2026-10-15', 'TRANSPORT']]); wrapper.unmount()
|
||
})
|
||
it('offers all four flows directly and emits the original filter values with an exclusive selection', async () => {
|
||
const wrapper = render()
|
||
const buttons = wrapper.findAll('.flow-controls button')
|
||
expect(buttons.map(button => button.text())).toEqual(['全部流程', '海外仓中转', '整柜直送', '路线待确认'])
|
||
expect(wrapper.find('select').exists()).toBe(false)
|
||
for (const [index, flow] of (['', 'TRANSFER', 'DIRECT', 'UNKNOWN'] as const).entries()) {
|
||
await buttons[index]!.trigger('click')
|
||
expect(wrapper.emitted('flow')?.at(-1)).toEqual([flow])
|
||
await wrapper.setProps({ flow })
|
||
expect(wrapper.findAll('.flow-controls button[aria-pressed=true]')).toHaveLength(1)
|
||
expect(buttons[index]!.attributes('aria-pressed')).toBe('true')
|
||
}
|
||
wrapper.unmount()
|
||
})
|
||
it('distinguishes today from the selected day and type without changing the selected scope', async () => {
|
||
vi.useFakeTimers(); vi.setSystemTime(new Date('2026-10-15T12:00:00'))
|
||
const wrapper = render()
|
||
await wrapper.setProps({ selectedDate: '2026-10-16' })
|
||
expect(wrapper.get('[data-date="2026-10-15"] .day-heading').attributes('aria-current')).toBe('date')
|
||
expect(wrapper.get('[data-date="2026-10-15"] .day-heading').attributes('aria-pressed')).toBe('false')
|
||
expect(wrapper.get('[data-date="2026-10-16"]').classes()).toContain('is-selected')
|
||
await wrapper.setProps({ selectedDate: '2026-10-15', selectedType: 'DELIVERY' })
|
||
expect(wrapper.get('[data-date="2026-10-15"] [data-type="DELIVERY"]').attributes('aria-pressed')).toBe('true')
|
||
expect(wrapper.get('[data-date="2026-10-15"] [data-type="PICKUP"]').attributes('aria-pressed')).toBe('false')
|
||
wrapper.unmount()
|
||
})
|
||
it('shows the actual cross-month interval and hides empty-day zeros while keeping dates clickable', async () => {
|
||
const wrapper = render()
|
||
expect(wrapper.get('.calendar-counts').text()).toContain('2026-09-28 ~ 2026-11-08')
|
||
const empty = wrapper.get('[data-date="2026-10-01"] .day-heading')
|
||
expect(empty.text()).toBe('1')
|
||
expect(empty.attributes('disabled')).toBeUndefined()
|
||
await empty.trigger('click'); expect(wrapper.emitted('day')).toEqual([['2026-10-01']])
|
||
expect(wrapper.get('footer').text()).toContain('未定日期请从上方待办查看')
|
||
await wrapper.setProps({ mode: 'week' })
|
||
expect(wrapper.findAll('.work-day')).toHaveLength(7)
|
||
expect(wrapper.get('.view-switch button:last-child').attributes('aria-pressed')).toBe('true')
|
||
wrapper.unmount()
|
||
})
|
||
it('renders server type counts instead of individual event cards and opens exact date/type details', async () => {
|
||
const wrapper = render()
|
||
expect(wrapper.findAll('.work-day')).toHaveLength(42)
|
||
const day = wrapper.get('[data-date="2026-10-15"]')
|
||
expect(day.get('.day-heading').text()).toContain('2 项')
|
||
await day.get('[data-type="DELIVERY"]').trigger('click')
|
||
expect(wrapper.emitted('day')).toEqual([['2026-10-15', 'DELIVERY']]); wrapper.unmount()
|
||
})
|
||
it('does not conflate arrivals, no-booking requirements or completed work with confirmed work', async () => {
|
||
const wrapper = render()
|
||
await wrapper.setProps({ reference: true, referenceReady: true, arrivals: [{ containerBookingId: '1', cabinetNo: 'D-1', arrivalAt: '2026-10-15T10:00:00', arrivalType: 'ESTIMATED' }] })
|
||
expect(wrapper.get('[data-date="2026-10-15"] .day-heading').text()).toContain('2 项')
|
||
expect(wrapper.get('.calendar-counts').text()).toContain('已完成 1')
|
||
expect(wrapper.get('.calendar-counts').text()).toContain('已落实 0')
|
||
await wrapper.get('.arrival-reference').trigger('click'); expect(wrapper.emitted('arrivals')).toEqual([['2026-10-15']]); wrapper.unmount()
|
||
})
|
||
it('shows explicit all-off and failure states without manufacturing zero aggregates', async () => {
|
||
const wrapper = render(); await wrapper.setProps({ types: [], calendar: null })
|
||
expect(wrapper.text()).toContain('全局待办仍可查看'); expect(wrapper.findAll('.type-counts button')).toHaveLength(0)
|
||
await wrapper.setProps({ types: [...workTypes], failed: true })
|
||
expect(wrapper.get('.calendar-counts').text()).toBe('工作统计加载失败')
|
||
expect(wrapper.get('[data-date="2026-10-15"] .day-heading').text()).not.toContain('0 项'); wrapper.unmount()
|
||
})
|