81 lines
5.0 KiB
TypeScript
81 lines
5.0 KiB
TypeScript
import { mount } from '@vue/test-utils'
|
|
import { describe, expect, it } from 'vitest'
|
|
import AppointmentCalendarPanel from './AppointmentCalendarPanel.vue'
|
|
import { scheduleTypes, type ScheduleEvent } from './schedule'
|
|
|
|
const event = (type: ScheduleEvent['type'], index = 0): ScheduleEvent => ({ key: `${type}-${index}`, type, date: '2026-10-19', time: '', title: `TEST-CONT ${type}`, fields: [{ label: '仓库', value: 'ONT8' }] })
|
|
const render = (events: ScheduleEvent[] = []) => mount(AppointmentCalendarPanel, { props: { initialDate: '2026-10-19', events },
|
|
global: { stubs: { ElButton: { template: '<button><slot /></button>' } } } })
|
|
describe('four-type appointment calendar', () => {
|
|
it('shows all four types by default with a calendar and persistent daily detail', () => {
|
|
const wrapper = render(scheduleTypes.map(type => event(type)))
|
|
expect(wrapper.findAll('[aria-label="安排类型"] input')).toHaveLength(4)
|
|
expect(wrapper.get('[aria-label="安排类型"]').text()).toBe('到港排车还柜计划到仓')
|
|
expect(wrapper.findAll('.detail-event')).toHaveLength(4)
|
|
expect(wrapper.get('[aria-label="当天安排"] header').text()).toContain('4 项安排')
|
|
expect(wrapper.findAll('.calendar-day')).toHaveLength(35)
|
|
expect(wrapper.find('[data-date="2026-11-01"]').exists()).toBe(true)
|
|
expect(wrapper.find('[data-date="2026-11-02"]').exists()).toBe(false)
|
|
expect(wrapper.text()).not.toMatch(/新增预约|全局待办|需复核|中转|直送/)
|
|
})
|
|
it('filters locally without requesting another range', async () => {
|
|
const wrapper = render([event('arrival'), event('dispatch')])
|
|
await wrapper.get('[aria-label="安排类型"] input').setValue(false)
|
|
expect(wrapper.findAll('.detail-event')).toHaveLength(1)
|
|
await wrapper.get('[aria-label="搜索当前日历"]').setValue('missing')
|
|
expect(wrapper.text()).toContain('当天暂无安排')
|
|
expect(wrapper.emitted('range')).toBeUndefined()
|
|
})
|
|
it('offers creation in the header only when authorized', async () => {
|
|
const wrapper = render()
|
|
expect(wrapper.findAll('button').some(button => button.text() === '新增预约')).toBe(false)
|
|
await wrapper.setProps({ canCreate: true })
|
|
await wrapper.findAll('.calendar-controls button').find(button => button.text() === '新增预约')!.trigger('click')
|
|
expect(wrapper.emitted('create')).toEqual([[]])
|
|
expect(wrapper.emitted('range')).toBeUndefined()
|
|
wrapper.unmount()
|
|
})
|
|
it('changes the selected date locally and requests one range per mode or period change', async () => {
|
|
const wrapper = render()
|
|
await wrapper.get('[data-date="2026-10-20"]').trigger('click')
|
|
expect(wrapper.emitted('range')).toBeUndefined()
|
|
expect(wrapper.get('[aria-label="当天安排"]').text()).toContain('2026-10-20')
|
|
await wrapper.get('[aria-label="预约视图"]').findAll('button')[1]!.trigger('click')
|
|
expect(wrapper.emitted('range')).toEqual([[{ from: '2026-10-19', to: '2026-10-26' }]])
|
|
await wrapper.get('[aria-label="下一周"]').trigger('click')
|
|
expect(wrapper.emitted('range')?.at(-1)).toEqual([{ from: '2026-10-26', to: '2026-11-02' }])
|
|
})
|
|
it('limits previews to three while retaining every event in the daily details', () => {
|
|
const wrapper = render(Array.from({ length: 23 }, (_, index) => event('arrival', index)))
|
|
expect(wrapper.get('[data-date="2026-10-19"]').findAll('.event-chip')).toHaveLength(3)
|
|
expect(wrapper.get('.event-more').text()).toBe('还有 20 条')
|
|
expect(wrapper.findAll('.detail-event')).toHaveLength(23)
|
|
})
|
|
it('keeps undated records outside date cells and exposes them explicitly', async () => {
|
|
const wrapper = render([{ ...event('warehouse'), date: null }])
|
|
expect(wrapper.findAll('.event-chip')).toHaveLength(0)
|
|
await wrapper.get('.undated-button').trigger('click')
|
|
expect(wrapper.findAll('.detail-event')).toHaveLength(1)
|
|
expect(wrapper.get('[aria-label="当天安排"]').text()).toContain('日期未定')
|
|
})
|
|
it('retains business links and exposes editing only with authoritative eligibility', async () => {
|
|
const row = { ...event('warehouse'), sourcePath: '/container-loading/overseas/1', canEdit: true }
|
|
const wrapper = render([row])
|
|
await wrapper.get('.detail-event footer').findAll('button')[0]!.trigger('click')
|
|
await wrapper.get('.detail-event footer').findAll('button')[1]!.trigger('click')
|
|
expect(wrapper.emitted('open')).toEqual([[row]])
|
|
expect(wrapper.emitted('edit')).toEqual([[row]])
|
|
await wrapper.setProps({ events: [{ ...row, canEdit: false, sourcePath: undefined }] })
|
|
expect(wrapper.find('.detail-event footer').exists()).toBe(false)
|
|
})
|
|
it('distinguishes loading and partial failure from a complete empty day', async () => {
|
|
const wrapper = render()
|
|
await wrapper.setProps({ loading: true })
|
|
expect(wrapper.text()).toContain('正在读取安排')
|
|
expect(wrapper.text()).not.toContain('当天暂无安排')
|
|
await wrapper.setProps({ loading: false, incomplete: true })
|
|
expect(wrapper.text()).toContain('部分数据不可用')
|
|
expect(wrapper.text()).not.toContain('当天暂无安排')
|
|
})
|
|
})
|