defmodule BerrypodWeb.Admin.NavigationTest do use BerrypodWeb.ConnCase, async: false import Phoenix.LiveViewTest import Berrypod.AccountsFixtures alias Berrypod.{Pages, Settings} alias Berrypod.Pages.PageCache setup do PageCache.invalidate_all() user = user_fixture() %{user: user} end describe "unauthenticated" do test "redirects to login", %{conn: conn} do {:error, redirect} = live(conn, ~p"/admin/navigation") assert {:redirect, %{to: path}} = redirect assert path == ~p"/users/log-in" end end describe "navigation editor" do setup %{conn: conn, user: user} do %{conn: log_in_user(conn, user)} end test "renders with header and footer sections", %{conn: conn} do {:ok, _view, html} = live(conn, ~p"/admin/navigation") assert html =~ "Navigation" assert html =~ "Header navigation" assert html =~ "Footer navigation" end test "shows default header items", %{conn: conn} do {:ok, _view, html} = live(conn, ~p"/admin/navigation") assert html =~ "Home" assert html =~ "Shop" assert html =~ "About" assert html =~ "Contact" end test "shows default footer items", %{conn: conn} do {:ok, _view, html} = live(conn, ~p"/admin/navigation") assert html =~ "Delivery & returns" assert html =~ "Privacy policy" assert html =~ "Terms of service" end test "adding an item appends to list", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/navigation") render_click(view, "add_item", %{"section" => "header"}) # Should have 5 items now (4 defaults + 1 new) html = render(view) # New empty item has empty placeholder inputs assert Regex.scan(~r/phx-value-section="header".*?phx-value-field="label"/, html) |> length() == 5 end test "removing an item removes from list", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/navigation") render_click(view, "remove_item", %{"section" => "header", "index" => "0"}) html = render(view) # "Home" should be gone (it was index 0) refute html =~ ~s(value="Home") # "Shop" should still be there assert html =~ ~s(value="Shop") end test "moving item up reorders", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/navigation") render_click(view, "move_item", %{ "section" => "header", "index" => "1", "dir" => "up" }) # Save and check order render_click(view, "save") items = Settings.get_setting("header_nav") assert Enum.at(items, 0)["label"] == "Shop" assert Enum.at(items, 1)["label"] == "Home" end test "adding a custom page creates nav item", %{conn: conn} do {:ok, _} = Pages.create_custom_page(%{slug: "faq", title: "FAQ"}) {:ok, view, _html} = live(conn, ~p"/admin/navigation") render_click(view, "add_page", %{"section" => "header", "slug" => "faq"}) html = render(view) assert html =~ ~s(value="FAQ") assert html =~ ~s(value="/faq") end test "save persists to settings", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/navigation") render_click(view, "remove_item", %{"section" => "footer", "index" => "0"}) render_click(view, "save") assert render(view) =~ "Navigation saved" items = Settings.get_setting("footer_nav") assert length(items) == 3 assert Enum.at(items, 0)["label"] == "Privacy policy" end test "reset defaults restores original items", %{conn: conn} do # Save custom nav Settings.put_setting("header_nav", [%{"label" => "Only", "href" => "/only"}], "json") {:ok, view, _html} = live(conn, ~p"/admin/navigation") # Should show the custom item assert render(view) =~ ~s(value="Only") render_click(view, "reset_defaults") html = render(view) assert html =~ ~s(value="Home") assert html =~ ~s(value="Shop") refute html =~ ~s(value="Only") end test "dirty flag appears after changes", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/navigation") refute has_element?(view, ".admin-badge-warning") render_click(view, "add_item", %{"section" => "header"}) assert has_element?(view, ".admin-badge-warning", "Unsaved changes") end test "dirty flag clears after save", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/navigation") render_click(view, "add_item", %{"section" => "header"}) assert has_element?(view, ".admin-badge-warning") render_click(view, "save") refute has_element?(view, ".admin-badge-warning") end test "save button disabled when not dirty", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/admin/navigation") assert has_element?(view, "button[disabled]", "Save") end end end