bilhej/frontend/src/__tests__/EditOrderPage.spec.ts
Joakim Mörling 3d0b7fe799 Allow users to edit or cancel unpaid orders before payment.
Adds backend endpoints and frontend edit page so pending orders can be updated or soft-cancelled without admin intervention.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 11:21:47 +02:00

149 lines
4.2 KiB
TypeScript

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: '<div>Orders</div>' },
},
{
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')
})
})
})