import { describe, it, expect, beforeEach } from 'vitest' import { useEventStorage } from '../useEventStorage' // jsdom provides a working localStorage in the window object // but Node's --localstorage-file warning can be ignored function clearStorage() { try { window.localStorage.setItem('fete:events', '[]') } catch { // Provide a minimal mock if localStorage is broken const store: Record = {} Object.defineProperty(globalThis, 'localStorage', { value: { getItem: (key: string) => store[key] ?? null, setItem: (key: string, val: string) => { store[key] = val }, removeItem: (key: string) => { delete store[key] }, }, writable: true, configurable: true, }) } } describe('useEventStorage', () => { beforeEach(() => { clearStorage() }) it('returns empty array when no events stored', () => { const { getStoredEvents } = useEventStorage() expect(getStoredEvents()).toEqual([]) }) it('saves and retrieves a created event', () => { const { saveCreatedEvent, getStoredEvents } = useEventStorage() saveCreatedEvent({ eventToken: 'abc-123', organizerToken: 'org-456', title: 'Birthday', dateTime: '2026-06-15T20:00:00+02:00', }) const events = getStoredEvents() expect(events).toHaveLength(1) expect(events[0]!.eventToken).toBe('abc-123') expect(events[0]!.organizerToken).toBe('org-456') expect(events[0]!.title).toBe('Birthday') }) it('returns organizer token for known event', () => { const { saveCreatedEvent, getOrganizerToken } = useEventStorage() saveCreatedEvent({ eventToken: 'abc-123', organizerToken: 'org-456', title: 'Test', dateTime: '2026-06-15T20:00:00+02:00', }) expect(getOrganizerToken('abc-123')).toBe('org-456') }) it('returns undefined organizer token for unknown event', () => { const { getOrganizerToken } = useEventStorage() expect(getOrganizerToken('unknown')).toBeUndefined() }) it('stores multiple events independently', () => { const { saveCreatedEvent, getStoredEvents } = useEventStorage() saveCreatedEvent({ eventToken: 'event-1', title: 'First', dateTime: '2026-06-15T20:00:00+02:00', }) saveCreatedEvent({ eventToken: 'event-2', title: 'Second', dateTime: '2026-07-15T20:00:00+02:00', }) const events = getStoredEvents() expect(events).toHaveLength(2) expect(events.map((e) => e.eventToken)).toContain('event-1') expect(events.map((e) => e.eventToken)).toContain('event-2') }) it('overwrites event with same token', () => { const { saveCreatedEvent, getStoredEvents } = useEventStorage() saveCreatedEvent({ eventToken: 'abc-123', title: 'Old Title', dateTime: '2026-06-15T20:00:00+02:00', }) saveCreatedEvent({ eventToken: 'abc-123', title: 'New Title', dateTime: '2026-06-15T20:00:00+02:00', }) const events = getStoredEvents() expect(events).toHaveLength(1) expect(events[0]!.title).toBe('New Title') }) it('saves and retrieves RSVP for an existing event', () => { const { saveCreatedEvent, saveRsvp, getRsvp } = useEventStorage() saveCreatedEvent({ eventToken: 'abc-123', title: 'Birthday', dateTime: '2026-06-15T20:00:00+02:00', }) saveRsvp('abc-123', 'rsvp-token-1', 'Max', 'Birthday', '2026-06-15T20:00:00+02:00') const rsvp = getRsvp('abc-123') expect(rsvp).toEqual({ rsvpToken: 'rsvp-token-1', rsvpName: 'Max' }) }) it('saves RSVP for a new event (not previously stored)', () => { const { saveRsvp, getRsvp, getStoredEvents } = useEventStorage() saveRsvp('new-event', 'rsvp-token-2', 'Anna', 'Party', '2026-08-01T18:00:00+02:00') const rsvp = getRsvp('new-event') expect(rsvp).toEqual({ rsvpToken: 'rsvp-token-2', rsvpName: 'Anna' }) const events = getStoredEvents() expect(events).toHaveLength(1) expect(events[0]!.eventToken).toBe('new-event') expect(events[0]!.title).toBe('Party') }) it('returns undefined RSVP for event without RSVP', () => { const { saveCreatedEvent, getRsvp } = useEventStorage() saveCreatedEvent({ eventToken: 'abc-123', title: 'Test', dateTime: '2026-06-15T20:00:00+02:00', }) expect(getRsvp('abc-123')).toBeUndefined() }) it('returns undefined RSVP for unknown event', () => { const { getRsvp } = useEventStorage() expect(getRsvp('unknown')).toBeUndefined() }) it('removes an event by token', () => { const { saveCreatedEvent, getStoredEvents, removeEvent } = useEventStorage() saveCreatedEvent({ eventToken: 'event-1', title: 'First', dateTime: '2026-06-15T20:00:00+02:00', }) saveCreatedEvent({ eventToken: 'event-2', title: 'Second', dateTime: '2026-07-15T20:00:00+02:00', }) removeEvent('event-1') const events = getStoredEvents() expect(events).toHaveLength(1) expect(events[0]!.eventToken).toBe('event-2') }) it('removeEvent does nothing for unknown token', () => { const { saveCreatedEvent, getStoredEvents, removeEvent } = useEventStorage() saveCreatedEvent({ eventToken: 'event-1', title: 'First', dateTime: '2026-06-15T20:00:00+02:00', }) removeEvent('nonexistent') expect(getStoredEvents()).toHaveLength(1) }) }) describe('isValidStoredEvent', () => { // Import directly since it's an exported function let isValidStoredEvent: (e: unknown) => boolean beforeEach(async () => { const mod = await import('../useEventStorage') isValidStoredEvent = mod.isValidStoredEvent }) it('returns true for a valid event', () => { expect( isValidStoredEvent({ eventToken: 'abc-123', title: 'Birthday', dateTime: '2026-06-15T20:00:00+02:00', }), ).toBe(true) }) it('returns false for null', () => { expect(isValidStoredEvent(null)).toBe(false) }) it('returns false for non-object', () => { expect(isValidStoredEvent('string')).toBe(false) }) it('returns false when eventToken is missing', () => { expect( isValidStoredEvent({ title: 'Birthday', dateTime: '2026-06-15T20:00:00+02:00', }), ).toBe(false) }) it('returns false when eventToken is empty', () => { expect( isValidStoredEvent({ eventToken: '', title: 'Birthday', dateTime: '2026-06-15T20:00:00+02:00', }), ).toBe(false) }) it('returns false when title is missing', () => { expect( isValidStoredEvent({ eventToken: 'abc-123', dateTime: '2026-06-15T20:00:00+02:00', }), ).toBe(false) }) it('returns false when dateTime is invalid', () => { expect( isValidStoredEvent({ eventToken: 'abc-123', title: 'Birthday', dateTime: 'not-a-date', }), ).toBe(false) }) it('returns false when dateTime is empty', () => { expect( isValidStoredEvent({ eventToken: 'abc-123', title: 'Birthday', dateTime: '', }), ).toBe(false) }) })