import { describe, it, expect, vi, beforeEach } from 'vitest' import { mount } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import { createRouter, createMemoryHistory } from 'vue-router' import EditOrderPage from '@/pages/EditOrderPage.vue' import PaymentRedirect from '@/pages/PaymentRedirect.vue' vi.mock('@/api/orders', () => ({ fetchOrder: vi.fn(), updateOrder: vi.fn(), })) import { fetchOrder, updateOrder } from '@/api/orders' const mockFetchOrder = vi.mocked(fetchOrder) const mockUpdateOrder = vi.mocked(updateOrder) const pendingOrder = { id: 'c2eebc99-9c0b-4ef8-bb6d-6bb9bd380a12', plate: 'DEF456', letterText: 'Vill köpa din bil.', status: 'pending_payment', trackingId: null, amountPaid: null, createdAt: '2026-05-14T13:00:00Z', } function createTestRouter() { return createRouter({ history: createMemoryHistory(), routes: [ { path: '/orders', name: 'orders', component: { template: '
Orders
' }, }, { path: '/bestallning/:orderId/redigera', name: 'edit-order', component: EditOrderPage, }, { path: '/betalning/:orderId', name: 'payment', component: PaymentRedirect, }, ], }) } async function mountPage(orderId = pendingOrder.id) { const pinia = createPinia() setActivePinia(pinia) const router = createTestRouter() await router.push({ name: 'edit-order', params: { orderId } }) await router.isReady() const wrapper = mount(EditOrderPage, { global: { plugins: [router, pinia], }, }) return { wrapper, router } } describe('EditOrderPage', () => { beforeEach(() => { vi.clearAllMocks() mockFetchOrder.mockResolvedValue(pendingOrder) mockUpdateOrder.mockResolvedValue(pendingOrder) }) it('shows loading state while fetching', async () => { mockFetchOrder.mockImplementation(() => new Promise(() => {})) const { wrapper } = await mountPage() expect(wrapper.text()).toContain('Laddar beställning...') }) it('loads order and pre-fills textarea', async () => { const { wrapper } = await mountPage() await vi.waitFor(() => { expect(mockFetchOrder).toHaveBeenCalledWith(pendingOrder.id) }) const textarea = wrapper.find('textarea') expect(textarea.element.value).toBe('Vill köpa din bil.') expect(wrapper.text()).toContain('DEF456') expect(wrapper.text()).toContain('Redigera brev') }) it('shows error when order is not pending_payment', async () => { mockFetchOrder.mockResolvedValue({ ...pendingOrder, status: 'sent', }) const { wrapper } = await mountPage() await vi.waitFor(() => { expect(wrapper.text()).toContain( 'Den här beställningen kan inte redigeras', ) }) expect(wrapper.find('textarea').exists()).toBe(false) expect(wrapper.text()).toContain('Tillbaka till beställningar') }) it('submit calls updateOrder and navigates to payment', async () => { const { wrapper, router } = await mountPage() await vi.waitFor(() => { expect(wrapper.find('textarea').exists()).toBe(true) }) const textarea = wrapper.find('textarea') await textarea.setValue('Uppdaterat meddelande') const button = wrapper.find('button[type="submit"]') await button.trigger('submit') await vi.waitFor(() => { expect(mockUpdateOrder).toHaveBeenCalledWith( pendingOrder.id, 'Uppdaterat meddelande', ) expect(router.currentRoute.value.name).toBe('payment') expect(router.currentRoute.value.params.orderId).toBe(pendingOrder.id) expect(router.currentRoute.value.query.plate).toBe('DEF456') }) }) it('shows error message on update failure', async () => { mockUpdateOrder.mockRejectedValue(new Error('Network error')) const { wrapper } = await mountPage() await vi.waitFor(() => { expect(wrapper.find('textarea').exists()).toBe(true) }) const textarea = wrapper.find('textarea') await textarea.setValue('Uppdaterat meddelande') const button = wrapper.find('button[type="submit"]') await button.trigger('submit') await vi.waitFor(() => { expect(wrapper.text()).toContain('Kunde inte spara ändringarna') }) }) })