defmodule BerrypodWeb.Admin.OrdersTest do use BerrypodWeb.ConnCase, async: false import Phoenix.LiveViewTest import Berrypod.AccountsFixtures import Berrypod.OrdersFixtures setup do user = user_fixture() %{user: user} end describe "unauthenticated" do test "redirects to login", %{conn: conn} do {:error, redirect} = live(conn, ~p"/admin/orders") assert {:redirect, %{to: path}} = redirect assert path == ~p"/users/log-in" end end describe "order list" do setup %{conn: conn, user: user} do conn = log_in_user(conn, user) %{conn: conn} end test "renders empty state when no orders", %{conn: conn} do {:ok, _view, html} = live(conn, ~p"/admin/orders") assert html =~ "No orders yet" assert html =~ "Orders" end test "renders orders table", %{conn: conn} do order = order_fixture(payment_status: "paid", customer_email: "test@shop.com") {:ok, _view, html} = live(conn, ~p"/admin/orders") assert html =~ order.order_number assert html =~ "test@shop.com" assert html =~ "paid" end test "filters by status", %{conn: conn} do paid = order_fixture(payment_status: "paid") _pending = order_fixture() {:ok, view, _html} = live(conn, ~p"/admin/orders") html = render_click(view, "filter", %{"status" => "paid"}) assert html =~ paid.order_number end test "navigates to order detail", %{conn: conn} do order = order_fixture(payment_status: "paid") {:ok, _view, html} = live(conn, ~p"/admin/orders") assert html =~ ~p"/admin/orders/#{order}" end end describe "order detail" do setup %{conn: conn, user: user} do conn = log_in_user(conn, user) %{conn: conn} end test "renders order details", %{conn: conn} do order = order_fixture(payment_status: "paid", customer_email: "buyer@example.com") {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}") assert html =~ order.order_number assert html =~ "buyer@example.com" assert html =~ "paid" assert html =~ "Order details" end test "shows line items", %{conn: conn} do order = order_fixture(product_name: "Cool T-shirt", variant_title: "Blue / XL") {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}") assert html =~ "Cool T-shirt" assert html =~ "Blue / XL" end test "shows shipping address", %{conn: conn} do order = order_fixture(payment_status: "paid") {:ok, updated_order} = Berrypod.Orders.update_order(order, %{ shipping_address: %{ "name" => "Jane Doe", "line1" => "42 Test Street", "city" => "London", "postal_code" => "SW1A 1AA", "country" => "GB" } }) {:ok, _view, html} = live(conn, ~p"/admin/orders/#{updated_order}") assert html =~ "Jane Doe" assert html =~ "42 Test Street" assert html =~ "London" assert html =~ "SW1A 1AA" end test "redirects when order not found", %{conn: conn} do fake_id = Ecto.UUID.generate() {:error, {:live_redirect, %{to: "/admin/orders"}}} = live(conn, ~p"/admin/orders/#{fake_id}") end test "shows timeline card", %{conn: conn} do order = order_fixture(payment_status: "paid") {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}") assert html =~ "Timeline" assert html =~ "unfulfilled" end test "shows submit button for paid unfulfilled orders", %{conn: conn} do order = order_fixture(payment_status: "paid") {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}") assert html =~ "Submit to provider" end test "shows retry button for failed fulfilment", %{conn: conn} do order = order_fixture(payment_status: "paid") {:ok, order} = Berrypod.Orders.update_fulfilment(order, %{fulfilment_status: "failed"}) {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}") assert html =~ "Retry submission" end test "shows refresh button for submitted orders", %{conn: conn} do {order, _v, _p, _c} = Berrypod.OrdersFixtures.submitted_order_fixture() {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}") assert html =~ "Refresh status" end test "shows tracking info when available", %{conn: conn} do {order, _v, _p, _c} = Berrypod.OrdersFixtures.submitted_order_fixture() {:ok, order} = Berrypod.Orders.update_fulfilment(order, %{ fulfilment_status: "shipped", tracking_number: "TRACK123", tracking_url: "https://track.example.com/TRACK123", shipped_at: DateTime.utc_now() |> DateTime.truncate(:second) }) {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}") assert html =~ "TRACK123" assert html =~ "https://track.example.com/TRACK123" end end describe "order timeline" do setup %{conn: conn, user: user} do conn = log_in_user(conn, user) %{conn: conn} end test "renders timeline entries for an order", %{conn: conn} do order = order_fixture(payment_status: "paid") Berrypod.ActivityLog.log_event("order.created", "Order placed", order_id: order.id) Berrypod.ActivityLog.log_event("order.submitted", "Submitted to provider", order_id: order.id ) {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}") assert html =~ "Order placed" assert html =~ "Submitted to provider" end test "shows empty state when no timeline entries", %{conn: conn} do order = order_fixture(payment_status: "paid") {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}") assert html =~ "No activity recorded yet" end test "updates timeline via PubSub", %{conn: conn} do order = order_fixture(payment_status: "paid") {:ok, view, _html} = live(conn, ~p"/admin/orders/#{order}") Berrypod.ActivityLog.log_event("order.submitted", "Submitted to provider", order_id: order.id ) html = render(view) assert html =~ "Submitted to provider" end end describe "order list fulfilment column" do setup %{conn: conn, user: user} do conn = log_in_user(conn, user) %{conn: conn} end test "shows fulfilment badge in table", %{conn: conn} do order_fixture(payment_status: "paid") {:ok, _view, html} = live(conn, ~p"/admin/orders") assert html =~ "Fulfilment" assert html =~ "unfulfilled" end end end