fix: stabilize calendar detail lifecycle
ci / gitleaks (push) Successful in 7s
ci / docker (push) Successful in 5m34s

This commit is contained in:
2026-09-21 16:31:00 +08:00
parent 8125174263
commit 9b8f55cf46
3 changed files with 16 additions and 6 deletions
+12 -1
View File
@@ -7,7 +7,7 @@ const subscriptions = [{ id:'s1', name:'工作', url:'https://example.com/work.i
const events = [{ id:'e1', title:'发布会', starts_at:'2026-09-22T02:00:00Z', ends_at:'2026-09-22T03:00:00Z', all_day:false, description:'产品发布', location:'会议室', source_id:'s1', source_name:'工作', color:'#f15a29' }]
const json = (value:unknown, status=200) => new Response(JSON.stringify(value), { status, headers:{'content-type':'application/json'} })
async function flush(){ await Promise.resolve(); await new Promise(r=>vi.isFakeTimers()?vi.advanceTimersByTimeAsync(0).then(()=>r(undefined)):setTimeout(r,0)); await nextTick() }
async function mount(fetchMock:ReturnType<typeof vi.fn>){ vi.stubGlobal('fetch',fetchMock); const host=document.createElement('div');document.body.append(host);const notices:string[]=[];const app=createApp(()=>h(CalendarPanel,{compactLayout:true,onNotice:(v:string)=>notices.push(v)}));app.mount(host);cleanups.push(()=>{app.unmount();host.remove()});await flush();return {host,notices} }
async function mount(fetchMock:ReturnType<typeof vi.fn>,compactLayout=true){ vi.stubGlobal('fetch',fetchMock); const shell=document.createElement('div');shell.className='shell';const host=document.createElement('div');shell.append(host);document.body.append(shell);const notices:string[]=[];const errors:unknown[]=[];const app=createApp(()=>h(CalendarPanel,{compactLayout,onNotice:(v:string)=>notices.push(v)}));app.config.errorHandler=error=>errors.push(error);app.mount(host);cleanups.push(()=>{app.unmount();shell.remove()});await flush();return {host,shell,notices,errors} }
afterEach(()=>{cleanups.splice(0).forEach(fn=>fn());vi.useRealTimers();vi.unstubAllGlobals();vi.restoreAllMocks()})
describe('CalendarPanel',()=>{
@@ -66,6 +66,17 @@ describe('CalendarPanel',()=>{
expect(host.querySelector('[data-event-id="e1"]')).toBeNull()
vi.useRealTimers()
})
it('opens and closes desktop event detail without teleport patch errors',async()=>{
vi.useFakeTimers();vi.setSystemTime(new Date(2026,8,22,10))
const fetchMock=vi.fn((url:string)=>Promise.resolve(json(url.includes('calendar-events')?{events,sources:[]}:subscriptions)))
const {host,shell,errors}=await mount(fetchMock,false)
host.querySelector<HTMLButtonElement>('[data-event-id="e1"]')!.click();await nextTick()
expect(shell.querySelector('.calendar-event-detail')).not.toBeNull()
shell.querySelector<HTMLButtonElement>('[aria-label="关闭日程详情"]')!.click();await nextTick()
expect(shell.querySelector('.calendar-event-detail')).toBeNull()
expect(errors).toEqual([])
vi.useRealTimers()
})
it('filters duplicate source names by source id',async()=>{
vi.useFakeTimers();vi.setSystemTime(new Date(2026,8,20,10))
const duplicateSubscriptions=[subscriptions[0],{...subscriptions[0],id:'s2',url:'https://example.com/personal.ics',color:'#334455'}]