test(03-06): add failing tests for deleteEvent, fetchSyncStatus, and delete/sync Zustand keys

This commit is contained in:
Lucas Berger
2026-06-05 18:34:55 -04:00
parent dbd09bc2bb
commit 8357cf998e
+160
View File
@@ -200,6 +200,115 @@ describe('fetchWritableCalendars', () => {
}) })
}) })
// ── deleteEvent tests ─────────────────────────────────────────────────────────
describe('deleteEvent', () => {
beforeEach(() => {
vi.stubGlobal('fetch', vi.fn())
})
afterEach(() => {
vi.unstubAllGlobals()
})
it('DELETEs /api/events/:uid with credentials:include', async () => {
const mockFetch = vi.mocked(fetch)
mockFetch.mockResolvedValueOnce({
ok: true,
json: async () => ({}),
} as Response)
const { deleteEvent } = await import('./client.js')
await deleteEvent('uid-to-delete')
expect(mockFetch).toHaveBeenCalledWith(
'/api/events/uid-to-delete',
expect.objectContaining({
method: 'DELETE',
credentials: 'include',
}),
)
})
it('resolves void on success (204/202)', async () => {
vi.mocked(fetch).mockResolvedValueOnce({
ok: true,
json: async () => ({}),
} as Response)
const { deleteEvent } = await import('./client.js')
const result = await deleteEvent('uid-abc')
expect(result).toBeUndefined()
})
it('throws on non-ok response', async () => {
vi.mocked(fetch).mockResolvedValueOnce({
ok: false,
status: 404,
} as Response)
const { deleteEvent } = await import('./client.js')
await expect(deleteEvent('missing-uid')).rejects.toThrow()
})
})
// ── fetchSyncStatus tests ─────────────────────────────────────────────────────
describe('fetchSyncStatus', () => {
beforeEach(() => {
vi.stubGlobal('fetch', vi.fn())
})
afterEach(() => {
vi.unstubAllGlobals()
})
it('GETs /api/events/sync-status?uid= with credentials:include', async () => {
vi.mocked(fetch).mockResolvedValueOnce({
ok: true,
json: async () => ({ uid: 'my-uid', status: 'pending' }),
} as Response)
const { fetchSyncStatus } = await import('./client.js')
await fetchSyncStatus('my-uid')
expect(vi.mocked(fetch)).toHaveBeenCalledWith(
'/api/events/sync-status?uid=my-uid',
expect.objectContaining({ credentials: 'include' }),
)
})
it('returns SyncStatus object with uid and status', async () => {
vi.mocked(fetch).mockResolvedValueOnce({
ok: true,
json: async () => ({ uid: 'test-uid', status: 'done' }),
} as Response)
const { fetchSyncStatus } = await import('./client.js')
const result = await fetchSyncStatus('test-uid')
expect(result).toEqual({ uid: 'test-uid', status: 'done' })
})
it('returns SyncStatus with error field for failed status', async () => {
vi.mocked(fetch).mockResolvedValueOnce({
ok: true,
json: async () => ({ uid: 'fail-uid', status: 'failed', error: '412 Conflict' }),
} as Response)
const { fetchSyncStatus } = await import('./client.js')
const result = await fetchSyncStatus('fail-uid')
expect(result).toEqual({ uid: 'fail-uid', status: 'failed', error: '412 Conflict' })
})
it('throws on non-ok response', async () => {
vi.mocked(fetch).mockResolvedValueOnce({
ok: false,
status: 500,
} as Response)
const { fetchSyncStatus } = await import('./client.js')
await expect(fetchSyncStatus('any-uid')).rejects.toThrow()
})
})
// ── Zustand store new keys tests ────────────────────────────────────────────── // ── Zustand store new keys tests ──────────────────────────────────────────────
describe('calendarStore — eventForm keys', () => { describe('calendarStore — eventForm keys', () => {
@@ -249,3 +358,54 @@ describe('calendarStore — eventForm keys', () => {
expect(state.eventFormUid).toBeNull() expect(state.eventFormUid).toBeNull()
}) })
}) })
describe('calendarStore — delete/sync keys', () => {
it('deleteDialogOpen defaults to false', async () => {
const { useCalendarStore } = await import('../store/calendarStore.js')
const state = useCalendarStore.getState()
expect(state.deleteDialogOpen).toBe(false)
})
it('deleteDialogUid defaults to null', async () => {
const { useCalendarStore } = await import('../store/calendarStore.js')
const state = useCalendarStore.getState()
expect(state.deleteDialogUid).toBeNull()
})
it('lastSyncedUid defaults to null', async () => {
const { useCalendarStore } = await import('../store/calendarStore.js')
const state = useCalendarStore.getState()
expect(state.lastSyncedUid).toBeNull()
})
it('setDeleteDialog(true, uid) opens dialog with uid', async () => {
const { useCalendarStore } = await import('../store/calendarStore.js')
useCalendarStore.getState().setDeleteDialog(true, 'delete-uid-999')
const state = useCalendarStore.getState()
expect(state.deleteDialogOpen).toBe(true)
expect(state.deleteDialogUid).toBe('delete-uid-999')
})
it('setDeleteDialog(false) closes dialog', async () => {
const { useCalendarStore } = await import('../store/calendarStore.js')
useCalendarStore.getState().setDeleteDialog(true, 'some-uid')
useCalendarStore.getState().setDeleteDialog(false)
const state = useCalendarStore.getState()
expect(state.deleteDialogOpen).toBe(false)
})
it('setLastSyncedUid sets the UID', async () => {
const { useCalendarStore } = await import('../store/calendarStore.js')
useCalendarStore.getState().setLastSyncedUid('synced-uid-abc')
const state = useCalendarStore.getState()
expect(state.lastSyncedUid).toBe('synced-uid-abc')
})
it('setLastSyncedUid(null) clears the UID', async () => {
const { useCalendarStore } = await import('../store/calendarStore.js')
useCalendarStore.getState().setLastSyncedUid('some-uid')
useCalendarStore.getState().setLastSyncedUid(null)
const state = useCalendarStore.getState()
expect(state.lastSyncedUid).toBeNull()
})
})