From 6ab5e2f7070cdfc8d958db6bb2c8135b7ace1218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rling?= Date: Thu, 14 May 2026 16:55:59 +0200 Subject: [PATCH] refactor: remove template from order flow Templates serve as a brand shield (showing the platform facilitates all kinds of messaging), not as a compose-flow form control. Remove them from the data model and compose page. Templates will live as branding elements on the landing page in a future commit. Backend: - Remove template field from Order entity (getter/setter removed) - Remove template from CreateOrderRequest DTO - Remove template from OrderResponse DTO - Remove template param from OrderService.createOrder() - Remove template passthrough in OrderController - Remove /api/templates permitAll from SecurityConfig - Edit V5 migration: remove template column from orders table - Edit V6 migration: remove template from seed data - Update OrderControllerTest (remove template from assertions/requests) - Update OrderServiceTest (remove template from createOrder calls) Frontend: - Remove template from Order interface in api/orders.ts - Remove template param from createOrder() function - Remove template display from OrdersPage.vue cards - Rewrite ComposePage.vue: remove template selector, keep textarea + preview + submit - Update ComposePage.spec.ts (remove template tests, add preview/GDPR tests) - Update OrdersPage.spec.ts (remove template from mock data and display test) - Update compose.spec.ts E2E (remove template selector interactions) - Update order-history.spec.ts E2E (remove template names test) - Fix unused import in Router.spec.ts - Also includes minor Prettier formatting in AppHeader.spec.ts, AdminPage.vue, authStore.ts --- .../se/bilhalsning/config/SecurityConfig.java | 1 - .../controller/OrderController.java | 2 - .../bilhalsning/dto/CreateOrderRequest.java | 3 - .../se/bilhalsning/dto/OrderResponse.java | 1 - .../java/se/bilhalsning/entity/Order.java | 11 ---- .../se/bilhalsning/service/OrderService.java | 3 +- .../db/migration/V5__create_orders_table.sql | 1 - .../db/migration/V6__seed_test_orders.sql | 8 +-- .../controller/OrderControllerTest.java | 13 +--- .../bilhalsning/service/OrderServiceTest.java | 11 ++-- frontend/e2e/compose.spec.ts | 38 ++---------- frontend/e2e/order-history.spec.ts | 14 ----- frontend/src/__tests__/AppHeader.spec.ts | 16 ++--- frontend/src/__tests__/ComposePage.spec.ts | 61 ++++--------------- frontend/src/__tests__/OrdersPage.spec.ts | 14 +---- frontend/src/__tests__/Router.spec.ts | 1 - frontend/src/api/orders.ts | 9 +-- frontend/src/pages/AdminPage.vue | 3 +- frontend/src/pages/ComposePage.vue | 47 +------------- frontend/src/pages/OrdersPage.vue | 5 -- frontend/src/stores/authStore.ts | 11 +++- 21 files changed, 51 insertions(+), 222 deletions(-) diff --git a/backend/src/main/java/se/bilhalsning/config/SecurityConfig.java b/backend/src/main/java/se/bilhalsning/config/SecurityConfig.java index a32a295..c3ddd1d 100644 --- a/backend/src/main/java/se/bilhalsning/config/SecurityConfig.java +++ b/backend/src/main/java/se/bilhalsning/config/SecurityConfig.java @@ -37,7 +37,6 @@ public class SecurityConfig { .requestMatchers("/api/auth/register", "/api/auth/login").permitAll() .requestMatchers("/api/webhooks/**").permitAll() .requestMatchers("/api/vehicles/**").permitAll() - .requestMatchers("/api/templates").permitAll() .anyRequest().authenticated()) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); diff --git a/backend/src/main/java/se/bilhalsning/controller/OrderController.java b/backend/src/main/java/se/bilhalsning/controller/OrderController.java index 36c7801..720f3f1 100644 --- a/backend/src/main/java/se/bilhalsning/controller/OrderController.java +++ b/backend/src/main/java/se/bilhalsning/controller/OrderController.java @@ -51,7 +51,6 @@ public class OrderController { Order order = orderService.createOrder( user.getId(), request.plate(), - request.template(), request.letterText() ); @@ -62,7 +61,6 @@ public class OrderController { return new OrderResponse( order.getId(), order.getPlate(), - order.getTemplate(), order.getStatus().getValue(), order.getTrackingId(), order.getCreatedAt() diff --git a/backend/src/main/java/se/bilhalsning/dto/CreateOrderRequest.java b/backend/src/main/java/se/bilhalsning/dto/CreateOrderRequest.java index 23ec8bc..cb3612d 100644 --- a/backend/src/main/java/se/bilhalsning/dto/CreateOrderRequest.java +++ b/backend/src/main/java/se/bilhalsning/dto/CreateOrderRequest.java @@ -9,9 +9,6 @@ public record CreateOrderRequest( @Pattern(regexp = "^[A-Za-z]{3}\\d{2}[A-Za-z0-9]$", message = "Ogiltigt registreringsnummer") String plate, - @Size(max = 50, message = "Mallnamn får vara max 50 tecken") - String template, - @NotBlank(message = "Brevtext krävs") @Size(min = 1, max = 1000, message = "Brevtexten måste vara mellan 1 och 1000 tecken") String letterText diff --git a/backend/src/main/java/se/bilhalsning/dto/OrderResponse.java b/backend/src/main/java/se/bilhalsning/dto/OrderResponse.java index a383f77..29c5f67 100644 --- a/backend/src/main/java/se/bilhalsning/dto/OrderResponse.java +++ b/backend/src/main/java/se/bilhalsning/dto/OrderResponse.java @@ -6,7 +6,6 @@ import java.util.UUID; public record OrderResponse( UUID id, String plate, - String template, String status, String trackingId, Instant createdAt diff --git a/backend/src/main/java/se/bilhalsning/entity/Order.java b/backend/src/main/java/se/bilhalsning/entity/Order.java index 3d7e2e3..62664dd 100644 --- a/backend/src/main/java/se/bilhalsning/entity/Order.java +++ b/backend/src/main/java/se/bilhalsning/entity/Order.java @@ -24,9 +24,6 @@ public class Order { @Column(name = "plate", nullable = false, length = 10) private String plate; - @Column(name = "template", length = 50) - private String template; - @Column(name = "letter_text", nullable = false, columnDefinition = "text") private String letterText; @@ -86,14 +83,6 @@ public class Order { this.plate = plate; } - public String getTemplate() { - return template; - } - - public void setTemplate(String template) { - this.template = template; - } - public String getLetterText() { return letterText; } diff --git a/backend/src/main/java/se/bilhalsning/service/OrderService.java b/backend/src/main/java/se/bilhalsning/service/OrderService.java index 13b25ef..e2a354d 100644 --- a/backend/src/main/java/se/bilhalsning/service/OrderService.java +++ b/backend/src/main/java/se/bilhalsning/service/OrderService.java @@ -16,11 +16,10 @@ public class OrderService { private final OrderRepository orderRepository; - public Order createOrder(UUID userId, String plate, String template, String letterText) { + public Order createOrder(UUID userId, String plate, String letterText) { Order order = new Order(); order.setUserId(userId); order.setPlate(plate.toUpperCase().trim()); - order.setTemplate(template); order.setLetterText(letterText); order.setStatus(OrderStatus.PENDING_PAYMENT); return orderRepository.save(order); diff --git a/backend/src/main/resources/db/migration/V5__create_orders_table.sql b/backend/src/main/resources/db/migration/V5__create_orders_table.sql index 3a483b9..18a68fb 100644 --- a/backend/src/main/resources/db/migration/V5__create_orders_table.sql +++ b/backend/src/main/resources/db/migration/V5__create_orders_table.sql @@ -2,7 +2,6 @@ CREATE TABLE orders ( id UUID NOT NULL, user_id UUID NOT NULL, plate VARCHAR(10) NOT NULL, - template VARCHAR(50), letter_text TEXT NOT NULL, status VARCHAR(30) NOT NULL DEFAULT 'pending_payment', amount_paid DECIMAL(10,2), diff --git a/backend/src/main/resources/db/migration/V6__seed_test_orders.sql b/backend/src/main/resources/db/migration/V6__seed_test_orders.sql index c017bb6..e270e7b 100644 --- a/backend/src/main/resources/db/migration/V6__seed_test_orders.sql +++ b/backend/src/main/resources/db/migration/V6__seed_test_orders.sql @@ -1,6 +1,6 @@ -- Seed orders for test user (test@bilhalsning.se, id: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11) -INSERT INTO orders (id, user_id, plate, template, letter_text, status, amount_paid, tracking_id, created_at, updated_at) +INSERT INTO orders (id, user_id, plate, letter_text, status, amount_paid, tracking_id, created_at, updated_at) VALUES - ('c1eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'ABC123', 'Komplimang', 'Hej! Jag ville bara säga att du har en väldigt fin bil. Hälsningar från en bilentusiast!', 'sent', 49.00, 'PN123456789', TIMESTAMP '2026-05-11 12:00:00', TIMESTAMP '2026-05-13 12:00:00'), - ('c2eebc99-9c0b-4ef8-bb6d-6bb9bd380a12', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'DEF456', 'Jag vill köpa din bil', 'Hej! Jag är intresserad av att köpa din bil. Kontakta mig gärna på test@example.com så kan vi diskutera ett pris.', 'pending_payment', NULL, NULL, TIMESTAMP '2026-05-14 13:00:00', TIMESTAMP '2026-05-14 13:00:00'), - ('c3eebc99-9c0b-4ef8-bb6d-6bb9bd380a13', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'GHI789', 'Tips / servicebehov', 'Hej! Jag noterade att ditt bakre högra hjul har lite för lågt lufttryck. Tänkte det kan vara bra att veta!', 'delivered', 49.00, 'PN987654321', TIMESTAMP '2026-05-07 10:00:00', TIMESTAMP '2026-05-12 10:00:00'); + ('c1eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'ABC123', 'Hej! Jag ville bara säga att du har en väldigt fin bil. Hälsningar från en bilentusiast!', 'sent', 49.00, 'PN123456789', TIMESTAMP '2026-05-11 12:00:00', TIMESTAMP '2026-05-13 12:00:00'), + ('c2eebc99-9c0b-4ef8-bb6d-6bb9bd380a12', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'DEF456', 'Hej! Jag är intresserad av att köpa din bil. Kontakta mig gärna på test@example.com så kan vi diskutera ett pris.', 'pending_payment', NULL, NULL, TIMESTAMP '2026-05-14 13:00:00', TIMESTAMP '2026-05-14 13:00:00'), + ('c3eebc99-9c0b-4ef8-bb6d-6bb9bd380a13', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'GHI789', 'Hej! Jag noterade att ditt bakre högra hjul har lite för lågt lufttryck. Tänkte det kan vara bra att veta!', 'delivered', 49.00, 'PN987654321', TIMESTAMP '2026-05-07 10:00:00', TIMESTAMP '2026-05-12 10:00:00'); diff --git a/backend/src/test/java/se/bilhalsning/controller/OrderControllerTest.java b/backend/src/test/java/se/bilhalsning/controller/OrderControllerTest.java index 13857ef..2f64887 100644 --- a/backend/src/test/java/se/bilhalsning/controller/OrderControllerTest.java +++ b/backend/src/test/java/se/bilhalsning/controller/OrderControllerTest.java @@ -51,11 +51,6 @@ class OrderControllerTest { when(userService.findByEmail("test@bilhalsning.se")).thenReturn(Optional.of(user)); - OrderResponse order1 = new OrderResponse( - UUID.randomUUID(), "ABC123", "Komplimang", "sent", "PN123456789", Instant.now()); - OrderResponse order2 = new OrderResponse( - UUID.randomUUID(), "DEF456", null, "pending_payment", null, Instant.now()); - when(orderService.getOrdersByUserId(userId)).thenReturn(List.of()); mockMvc.perform(get("/api/orders")) @@ -78,7 +73,6 @@ class OrderControllerTest { order.setId(UUID.fromString("c1eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")); order.setUserId(userId); order.setPlate("ABC123"); - order.setTemplate("Komplimang"); order.setLetterText("Test letter"); order.setStatus(se.bilhalsning.entity.OrderStatus.SENT); order.setTrackingId("PN123456789"); @@ -89,7 +83,6 @@ class OrderControllerTest { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].id").value("c1eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")) .andExpect(jsonPath("$[0].plate").value("ABC123")) - .andExpect(jsonPath("$[0].template").value("Komplimang")) .andExpect(jsonPath("$[0].status").value("sent")) .andExpect(jsonPath("$[0].trackingId").value("PN123456789")); } @@ -125,20 +118,18 @@ class OrderControllerTest { savedOrder.setId(UUID.fromString("d1eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")); savedOrder.setUserId(userId); savedOrder.setPlate("ABC123"); - savedOrder.setTemplate("Komplimang"); savedOrder.setLetterText("Hej fin bil!"); savedOrder.setStatus(se.bilhalsning.entity.OrderStatus.PENDING_PAYMENT); - when(orderService.createOrder(userId, "ABC123", "Komplimang", "Hej fin bil!")) + when(orderService.createOrder(userId, "ABC123", "Hej fin bil!")) .thenReturn(savedOrder); mockMvc.perform(post("/api/orders") .contentType("application/json") - .content("{\"plate\":\"ABC123\",\"template\":\"Komplimang\",\"letterText\":\"Hej fin bil!\"}")) + .content("{\"plate\":\"ABC123\",\"letterText\":\"Hej fin bil!\"}")) .andExpect(status().isCreated()) .andExpect(jsonPath("$.id").value("d1eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")) .andExpect(jsonPath("$.plate").value("ABC123")) - .andExpect(jsonPath("$.template").value("Komplimang")) .andExpect(jsonPath("$.status").value("pending_payment")); } diff --git a/backend/src/test/java/se/bilhalsning/service/OrderServiceTest.java b/backend/src/test/java/se/bilhalsning/service/OrderServiceTest.java index 254acba..32fbb68 100644 --- a/backend/src/test/java/se/bilhalsning/service/OrderServiceTest.java +++ b/backend/src/test/java/se/bilhalsning/service/OrderServiceTest.java @@ -37,7 +37,7 @@ class OrderServiceTest { UUID userId = UUID.randomUUID(); when(orderRepository.save(any(Order.class))).thenAnswer(inv -> inv.getArgument(0)); - Order result = orderService.createOrder(userId, "ABC123", "Komplimang", "Hej fin bil!"); + Order result = orderService.createOrder(userId, "ABC123", "Hej fin bil!"); assertEquals(OrderStatus.PENDING_PAYMENT, result.getStatus()); verify(orderRepository).save(orderCaptor.capture()); @@ -55,7 +55,7 @@ class OrderServiceTest { return order; }); - Order result = orderService.createOrder(userId, "ABC123", null, "Test text"); + Order result = orderService.createOrder(userId, "ABC123", "Test text"); assertNotNull(result.getId()); } @@ -65,7 +65,7 @@ class OrderServiceTest { UUID userId = UUID.randomUUID(); when(orderRepository.save(any(Order.class))).thenAnswer(inv -> inv.getArgument(0)); - Order result = orderService.createOrder(userId, "abc123", null, "Test text"); + Order result = orderService.createOrder(userId, "abc123", "Test text"); assertEquals("ABC123", result.getPlate()); } @@ -75,7 +75,7 @@ class OrderServiceTest { UUID userId = UUID.randomUUID(); when(orderRepository.save(any(Order.class))).thenAnswer(inv -> inv.getArgument(0)); - Order result = orderService.createOrder(userId, " ABC123 ", null, "Test text"); + Order result = orderService.createOrder(userId, " ABC123 ", "Test text"); assertEquals("ABC123", result.getPlate()); } @@ -85,11 +85,10 @@ class OrderServiceTest { UUID userId = UUID.randomUUID(); when(orderRepository.save(any(Order.class))).thenAnswer(inv -> inv.getArgument(0)); - Order result = orderService.createOrder(userId, "ABC123", "Komplimang", "Hej fin bil!"); + Order result = orderService.createOrder(userId, "ABC123", "Hej fin bil!"); assertEquals(userId, result.getUserId()); assertEquals("ABC123", result.getPlate()); - assertEquals("Komplimang", result.getTemplate()); assertEquals("Hej fin bil!", result.getLetterText()); assertNull(result.getAmountPaid()); assertNull(result.getTrackingId()); diff --git a/frontend/e2e/compose.spec.ts b/frontend/e2e/compose.spec.ts index 3b4f958..d4a9e96 100644 --- a/frontend/e2e/compose.spec.ts +++ b/frontend/e2e/compose.spec.ts @@ -19,7 +19,7 @@ test.describe('Compose flow', () => { await expect(page.getByText('Inget registreringsnummer valt')).toBeVisible() }) - test('displays plate and template selector', async ({ page }) => { + test('displays plate and textarea', async ({ page }) => { await page.goto('/logga-in') await page.getByLabel('E-postadress').fill('test@bilhalsning.se') await page.getByLabel('Lösenord').fill('test1234') @@ -32,37 +32,7 @@ test.describe('Compose flow', () => { page.getByRole('heading', { name: 'Skriv ditt brev' }), ).toBeVisible() await expect(page.getByText('ABC123')).toBeVisible() - await expect(page.getByLabel('Välj mall')).toBeVisible() - }) - - test('selecting template fills textarea', async ({ page }) => { - await page.goto('/logga-in') - await page.getByLabel('E-postadress').fill('test@bilhalsning.se') - await page.getByLabel('Lösenord').fill('test1234') - await page.getByRole('button', { name: 'Logga in' }).click() - await page.waitForURL('/') - - await page.goto('/compose?plate=ABC123') - - await page.getByLabel('Välj mall').selectOption('Komplimang') - const textarea = page.getByLabel('Ditt meddelande') - await expect(textarea).toHaveValue(/jättefin/) - }) - - test('can edit textarea after selecting template', async ({ page }) => { - await page.goto('/logga-in') - await page.getByLabel('E-postadress').fill('test@bilhalsning.se') - await page.getByLabel('Lösenord').fill('test1234') - await page.getByRole('button', { name: 'Logga in' }).click() - await page.waitForURL('/') - - await page.goto('/compose?plate=ABC123') - - await page.getByLabel('Välj mall').selectOption('Komplimang') - const textarea = page.getByLabel('Ditt meddelande') - await textarea.fill('Custom text') - - await expect(textarea).toHaveValue('Custom text') + await expect(page.getByLabel('Ditt meddelande')).toBeVisible() }) test('submit button disabled when textarea is empty', async ({ page }) => { @@ -87,7 +57,7 @@ test.describe('Compose flow', () => { await page.goto('/compose?plate=ABC123') - await page.getByLabel('Välj mall').selectOption('Komplimang') + await page.getByLabel('Ditt meddelande').fill('Hej fin bil!') const button = page.getByRole('button', { name: 'Skicka brev (49 kr)' }) await expect(button).toBeEnabled() await button.click() @@ -107,7 +77,7 @@ test.describe('Compose flow', () => { await page.goto('/compose?plate=ABC123') - await page.getByLabel('Välj mall').selectOption('Komplimang') + await page.getByLabel('Ditt meddelande').fill('Testmeddelande') await expect( page.getByText('Detta brev skickades via BilHej.se'), diff --git a/frontend/e2e/order-history.spec.ts b/frontend/e2e/order-history.spec.ts index 8d4366d..c6aef9c 100644 --- a/frontend/e2e/order-history.spec.ts +++ b/frontend/e2e/order-history.spec.ts @@ -71,18 +71,4 @@ test.describe('Order history', () => { const trackingLink2 = page.getByRole('link', { name: 'PN987654321' }) await expect(trackingLink2).toBeVisible() }) - - test('shows template names', async ({ page }) => { - await page.goto('/logga-in') - await page.getByLabel('E-postadress').fill('test@bilhalsning.se') - await page.getByLabel('Lösenord').fill('test1234') - await page.getByRole('button', { name: 'Logga in' }).click() - await page.waitForURL('/') - - await page.goto('/orders') - - await expect(page.getByText('Komplimang')).toBeVisible() - await expect(page.getByText('Jag vill köpa din bil')).toBeVisible() - await expect(page.getByText('Tips / servicebehov')).toBeVisible() - }) }) diff --git a/frontend/src/__tests__/AppHeader.spec.ts b/frontend/src/__tests__/AppHeader.spec.ts index 5c4e641..adfa44d 100644 --- a/frontend/src/__tests__/AppHeader.spec.ts +++ b/frontend/src/__tests__/AppHeader.spec.ts @@ -67,9 +67,7 @@ describe('AppHeader', () => { global: { plugins: [router, createPinia()] }, }) const links = wrapper.findAll('a') - const loginLink = links.find( - (a) => a.attributes('href') === '/logga-in', - ) + const loginLink = links.find((a) => a.attributes('href') === '/logga-in') expect(loginLink).toBeTruthy() expect(loginLink?.text()).toBe('Logga in') }) @@ -109,9 +107,7 @@ describe('AppHeader', () => { global: { plugins: [router, createPinia()] }, }) const links = wrapper.findAll('a') - const ordersLink = links.find( - (a) => a.attributes('href') === '/orders', - ) + const ordersLink = links.find((a) => a.attributes('href') === '/orders') expect(ordersLink).toBeUndefined() }) }) @@ -143,9 +139,7 @@ describe('AppHeader', () => { it('does not show login link', () => { const wrapper = mountAuthenticated() const links = wrapper.findAll('a') - const loginLink = links.find( - (a) => a.attributes('href') === '/logga-in', - ) + const loginLink = links.find((a) => a.attributes('href') === '/logga-in') expect(loginLink).toBeUndefined() }) @@ -161,9 +155,7 @@ describe('AppHeader', () => { it('shows orders link', () => { const wrapper = mountAuthenticated() const links = wrapper.findAll('a') - const ordersLink = links.find( - (a) => a.attributes('href') === '/orders', - ) + const ordersLink = links.find((a) => a.attributes('href') === '/orders') expect(ordersLink).toBeTruthy() expect(ordersLink?.text()).toBe('Mina beställningar') }) diff --git a/frontend/src/__tests__/ComposePage.spec.ts b/frontend/src/__tests__/ComposePage.spec.ts index 4c2492f..bdd50bd 100644 --- a/frontend/src/__tests__/ComposePage.spec.ts +++ b/frontend/src/__tests__/ComposePage.spec.ts @@ -67,27 +67,10 @@ describe('ComposePage', () => { expect(wrapper.text()).toContain('Inget registreringsnummer valt') }) - it('has all 6 template options', async () => { + it('shows textarea for letter input', async () => { const { wrapper } = await mountPage() - const select = wrapper.find('select') - const options = select.findAll('option') - expect(options).toHaveLength(6) - expect(options[0].text()).toBe('Komplimang') - expect(options[5].text()).toBe('Fritt meddelande') - }) - - it('selects Fritt meddelande by default', async () => { - const { wrapper } = await mountPage() - const select = wrapper.find('select') - expect((select.element as HTMLSelectElement).value).toBe('Fritt meddelande') - }) - - it('fills textarea when template is selected', async () => { - const { wrapper } = await mountPage() - const select = wrapper.find('select') - await select.setValue('Komplimang') const textarea = wrapper.find('textarea') - expect(textarea.element.value).toContain('jättefin') + expect(textarea.exists()).toBe(true) }) it('updates character counter on input', async () => { @@ -123,24 +106,19 @@ describe('ComposePage', () => { mockCreateOrder.mockResolvedValue({ id: 'order-1', plate: 'ABC123', - template: 'Komplimang', status: 'pending_payment', trackingId: null, createdAt: '2025-01-01T00:00:00Z', }) const { wrapper } = await mountPage() - const select = wrapper.find('select') - await select.setValue('Komplimang') + const textarea = wrapper.find('textarea') + await textarea.setValue('Hej fin bil!') const button = wrapper.find('button[type="submit"]') await button.trigger('submit') await vi.waitFor(() => { - expect(mockCreateOrder).toHaveBeenCalledWith( - 'ABC123', - 'Komplimang', - expect.stringContaining('jättefin'), - ) + expect(mockCreateOrder).toHaveBeenCalledWith('ABC123', 'Hej fin bil!') }) }) @@ -148,7 +126,6 @@ describe('ComposePage', () => { mockCreateOrder.mockResolvedValue({ id: 'order-1', plate: 'ABC123', - template: null, status: 'pending_payment', trackingId: null, createdAt: '2025-01-01T00:00:00Z', @@ -179,28 +156,16 @@ describe('ComposePage', () => { }) }) - it('sends null template for Fritt meddelande', async () => { - mockCreateOrder.mockResolvedValue({ - id: 'order-1', - plate: 'ABC123', - template: null, - status: 'pending_payment', - trackingId: null, - createdAt: '2025-01-01T00:00:00Z', - }) - + it('shows preview with letter content', async () => { const { wrapper } = await mountPage() const textarea = wrapper.find('textarea') - await textarea.setValue('Custom text') - const button = wrapper.find('button[type="submit"]') - await button.trigger('submit') + await textarea.setValue('Hej!') + expect(wrapper.text()).toContain('Förhandsvisning') + expect(wrapper.text()).toContain('Hej!') + }) - await vi.waitFor(() => { - expect(mockCreateOrder).toHaveBeenCalledWith( - 'ABC123', - null, - 'Custom text', - ) - }) + it('shows GDPR footer in preview', async () => { + const { wrapper } = await mountPage() + expect(wrapper.text()).toContain('Detta brev skickades via BilHej.se') }) }) diff --git a/frontend/src/__tests__/OrdersPage.spec.ts b/frontend/src/__tests__/OrdersPage.spec.ts index 73bf03c..400f6cd 100644 --- a/frontend/src/__tests__/OrdersPage.spec.ts +++ b/frontend/src/__tests__/OrdersPage.spec.ts @@ -38,7 +38,6 @@ const mockOrders = [ { id: 'c1eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', plate: 'ABC123', - template: 'Komplimang', status: 'sent', trackingId: 'PN123456789', createdAt: '2026-05-11T12:00:00Z', @@ -46,7 +45,6 @@ const mockOrders = [ { id: 'c2eebc99-9c0b-4ef8-bb6d-6bb9bd380a12', plate: 'DEF456', - template: null, status: 'pending_payment', trackingId: null, createdAt: '2026-05-14T13:00:00Z', @@ -66,7 +64,9 @@ describe('OrdersPage', () => { const { wrapper } = mountPage() await new Promise((r) => setTimeout(r, 50)) expect(wrapper.text()).toContain('Mina beställningar') - expect(wrapper.text()).toContain('Här kan du se dina tidigare beställningar') + expect(wrapper.text()).toContain( + 'Här kan du se dina tidigare beställningar', + ) }) it('shows loading state initially', async () => { @@ -91,13 +91,6 @@ describe('OrdersPage', () => { expect(wrapper.text()).toContain('DEF456') }) - it('renders template name or fallback for null', async () => { - const { wrapper } = mountPage() - await new Promise((r) => setTimeout(r, 50)) - expect(wrapper.text()).toContain('Komplimang') - expect(wrapper.text()).toContain('Fritt meddelande') - }) - it('renders Swedish status labels', async () => { const { wrapper } = mountPage() await new Promise((r) => setTimeout(r, 50)) @@ -119,7 +112,6 @@ describe('OrdersPage', () => { { id: 'c2eebc99-9c0b-4ef8-bb6d-6bb9bd380a12', plate: 'DEF456', - template: null, status: 'pending_payment', trackingId: null, createdAt: '2026-05-14T13:00:00Z', diff --git a/frontend/src/__tests__/Router.spec.ts b/frontend/src/__tests__/Router.spec.ts index fe20f92..85d5779 100644 --- a/frontend/src/__tests__/Router.spec.ts +++ b/frontend/src/__tests__/Router.spec.ts @@ -1,7 +1,6 @@ import { describe, it, expect, beforeEach } from 'vitest' import { setActivePinia, createPinia } from 'pinia' import router from '@/router' -import { useAuthStore } from '@/stores/authStore' describe('Router', () => { beforeEach(() => { diff --git a/frontend/src/api/orders.ts b/frontend/src/api/orders.ts index 586c110..32a02b8 100644 --- a/frontend/src/api/orders.ts +++ b/frontend/src/api/orders.ts @@ -3,7 +3,6 @@ import { request } from './client' export interface Order { id: string plate: string - template: string | null status: string trackingId: string | null createdAt: string @@ -13,13 +12,9 @@ export function fetchOrders(): Promise { return request('/orders') } -export function createOrder( - plate: string, - template: string | null, - letterText: string, -): Promise { +export function createOrder(plate: string, letterText: string): Promise { return request('/orders', { method: 'POST', - body: JSON.stringify({ plate, template, letterText }), + body: JSON.stringify({ plate, letterText }), }) } diff --git a/frontend/src/pages/AdminPage.vue b/frontend/src/pages/AdminPage.vue index 1247849..7853a1b 100644 --- a/frontend/src/pages/AdminPage.vue +++ b/frontend/src/pages/AdminPage.vue @@ -1,5 +1,4 @@ - +