import { describe, it, expect, vi } from 'vitest' import { mount, flushPromises } from '@vue/test-utils' import { createRouter, createMemoryHistory } from 'vue-router' import EventCreateView from '../EventCreateView.vue' import { api } from '@/api/client' vi.mock('@/api/client', () => ({ api: { POST: vi.fn(), }, })) vi.mock('@/composables/useEventStorage', () => ({ useEventStorage: vi.fn(() => ({ saveCreatedEvent: vi.fn(), getStoredEvents: vi.fn(() => []), getOrganizerToken: vi.fn(), })), })) function createTestRouter() { return createRouter({ history: createMemoryHistory(), routes: [ { path: '/', name: 'home', component: { template: '
' } }, { path: '/create', name: 'create-event', component: EventCreateView }, { path: '/events/:token', name: 'event', component: { template: '' } }, ], }) } describe('EventCreateView', () => { it('renders all form fields', async () => { const router = createTestRouter() await router.push('/create') await router.isReady() const wrapper = mount(EventCreateView, { global: { plugins: [router] }, }) expect(wrapper.find('#title').exists()).toBe(true) expect(wrapper.find('#description').exists()).toBe(true) expect(wrapper.find('#dateTime').exists()).toBe(true) expect(wrapper.find('#location').exists()).toBe(true) expect(wrapper.find('#expiryDate').exists()).toBe(true) }) it('has required attribute on required fields', async () => { const router = createTestRouter() await router.push('/create') await router.isReady() const wrapper = mount(EventCreateView, { global: { plugins: [router] }, }) expect(wrapper.find('#title').attributes('required')).toBeDefined() expect(wrapper.find('#dateTime').attributes('required')).toBeDefined() expect(wrapper.find('#expiryDate').attributes('required')).toBeDefined() }) it('does not have required attribute on optional fields', async () => { const router = createTestRouter() await router.push('/create') await router.isReady() const wrapper = mount(EventCreateView, { global: { plugins: [router] }, }) expect(wrapper.find('#description').attributes('required')).toBeUndefined() expect(wrapper.find('#location').attributes('required')).toBeUndefined() }) it('has a submit button', async () => { const router = createTestRouter() await router.push('/create') await router.isReady() const wrapper = mount(EventCreateView, { global: { plugins: [router] }, }) const button = wrapper.find('button[type="submit"]') expect(button.exists()).toBe(true) expect(button.text()).toBe('Create Event') }) it('shows server error when network request fails', async () => { vi.mocked(api.POST).mockRejectedValueOnce(new TypeError('Failed to fetch')) const router = createTestRouter() await router.push('/create') await router.isReady() const wrapper = mount(EventCreateView, { global: { plugins: [router] }, }) // Fill required fields await wrapper.find('#title').setValue('My Event') await wrapper.find('#dateTime').setValue('2026-12-25T18:00') await wrapper.find('#expiryDate').setValue('2026-12-24') await wrapper.find('form').trigger('submit') await flushPromises() const alerts = wrapper.findAll('[role="alert"]').map((el) => el.text()).filter((t) => t.length > 0) expect(alerts).toContain('Could not reach the server. Please try again.') // Submit button should not remain disabled expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBeUndefined() }) it('clears field error when user types into that field', async () => { const router = createTestRouter() await router.push('/create') await router.isReady() const wrapper = mount(EventCreateView, { global: { plugins: [router] }, }) // Submit empty form to trigger validation errors await wrapper.find('form').trigger('submit') const errorsBefore = wrapper.findAll('[role="alert"]').map((el) => el.text()).filter((t) => t.length > 0) expect(errorsBefore.length).toBeGreaterThanOrEqual(3) // Type into title field await wrapper.find('#title').setValue('My Event') // Title error should be cleared (span removed from DOM), but other errors should remain const titleError = wrapper.find('#title').element.closest('.form-group')!.querySelector('[role="alert"]') expect(titleError).toBeNull() const dateTimeError = wrapper.find('#dateTime').element.closest('.form-group')!.querySelector('[role="alert"]')! expect(dateTimeError.textContent).not.toBe('') const expiryError = wrapper.find('#expiryDate').element.closest('.form-group')!.querySelector('[role="alert"]')! expect(expiryError.textContent).not.toBe('') }) it('shows validation errors when submitting empty form', async () => { const router = createTestRouter() await router.push('/create') await router.isReady() const wrapper = mount(EventCreateView, { global: { plugins: [router] }, }) await wrapper.find('form').trigger('submit') const errorElements = wrapper.findAll('[role="alert"]') const errorTexts = errorElements.map((el) => el.text()).filter((t) => t.length > 0) expect(errorTexts.length).toBeGreaterThanOrEqual(3) }) it('submits successfully, saves to storage, and navigates to event page', async () => { const mockSave = vi.fn() vi.mocked(vi.importActual