add admin CRUD for custom CMS pages
All checks were successful
deploy / deploy (push) Successful in 1m21s
All checks were successful
deploy / deploy (push) Successful in 1m21s
New settings form for creating and editing custom page metadata (title, slug, meta description, published, nav settings). Pages index shows custom pages section with draft badges and delete. Editor shows settings button for custom pages, hides reset to defaults. 20 new tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -701,6 +701,202 @@ defmodule BerrypodWeb.Admin.PagesTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "custom pages on index" do
|
||||
setup %{conn: conn, user: user} do
|
||||
%{conn: log_in_user(conn, user)}
|
||||
end
|
||||
|
||||
test "shows new page button", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages")
|
||||
assert has_element?(view, "a[href='/admin/pages/new']", "New page")
|
||||
end
|
||||
|
||||
test "shows custom pages section when pages exist", %{conn: conn} do
|
||||
{:ok, _} = Pages.create_custom_page(%{slug: "faq", title: "FAQ"})
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages")
|
||||
|
||||
assert has_element?(view, ".page-group-title", "Custom pages")
|
||||
assert has_element?(view, ".page-card-title", "FAQ")
|
||||
end
|
||||
|
||||
test "does not show custom pages section when empty", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages")
|
||||
refute has_element?(view, ".page-group-title", "Custom pages")
|
||||
end
|
||||
|
||||
test "shows draft badge for unpublished pages", %{conn: conn} do
|
||||
{:ok, _} =
|
||||
Pages.create_custom_page(%{slug: "draft-page", title: "Draft", published: false})
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages")
|
||||
assert has_element?(view, ".admin-badge-warning", "Draft")
|
||||
end
|
||||
|
||||
test "custom page card links to editor", %{conn: conn} do
|
||||
{:ok, _} = Pages.create_custom_page(%{slug: "faq", title: "FAQ"})
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages")
|
||||
|
||||
assert has_element?(view, "a[href='/admin/pages/faq']")
|
||||
end
|
||||
|
||||
test "shows slug in card meta", %{conn: conn} do
|
||||
{:ok, _} = Pages.create_custom_page(%{slug: "our-story", title: "Our story"})
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages")
|
||||
|
||||
assert has_element?(view, ".page-card-meta", "/our-story")
|
||||
end
|
||||
|
||||
test "delete removes page from list", %{conn: conn} do
|
||||
{:ok, _} = Pages.create_custom_page(%{slug: "faq", title: "FAQ"})
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages")
|
||||
|
||||
assert has_element?(view, ".page-card-title", "FAQ")
|
||||
|
||||
view
|
||||
|> element("button[phx-click='delete_custom_page'][phx-value-slug='faq']")
|
||||
|> render_click()
|
||||
|
||||
refute has_element?(view, ".page-card-title", "FAQ")
|
||||
assert render(view) =~ "Page deleted"
|
||||
end
|
||||
end
|
||||
|
||||
describe "custom page creation" do
|
||||
setup %{conn: conn, user: user} do
|
||||
%{conn: log_in_user(conn, user)}
|
||||
end
|
||||
|
||||
test "renders creation form", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/new")
|
||||
|
||||
assert has_element?(view, "h1", "New page")
|
||||
assert has_element?(view, "#custom-page-form")
|
||||
end
|
||||
|
||||
test "creating with valid data redirects to editor", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/new")
|
||||
|
||||
view
|
||||
|> form("#custom-page-form", page: %{title: "FAQ", slug: "faq"})
|
||||
|> render_submit()
|
||||
|
||||
assert_redirect(view, ~p"/admin/pages/faq")
|
||||
end
|
||||
|
||||
test "creating with empty title shows error", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/new")
|
||||
|
||||
view
|
||||
|> form("#custom-page-form", page: %{title: "", slug: "faq"})
|
||||
|> render_submit()
|
||||
|
||||
assert has_element?(view, "#custom-page-form")
|
||||
end
|
||||
|
||||
test "creating with reserved slug shows error", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/new")
|
||||
|
||||
html =
|
||||
view
|
||||
|> form("#custom-page-form", page: %{title: "Admin", slug: "admin"})
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "is reserved"
|
||||
end
|
||||
|
||||
test "creating with duplicate slug shows error", %{conn: conn} do
|
||||
{:ok, _} = Pages.create_custom_page(%{slug: "faq", title: "FAQ"})
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/new")
|
||||
|
||||
html =
|
||||
view
|
||||
|> form("#custom-page-form", page: %{title: "FAQ 2", slug: "faq"})
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "has already been taken"
|
||||
end
|
||||
|
||||
test "auto-slugifies title during validation", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/new")
|
||||
|
||||
html =
|
||||
view
|
||||
|> form("#custom-page-form", page: %{title: "Our Story"})
|
||||
|> render_change()
|
||||
|
||||
assert html =~ ~s(value="our-story")
|
||||
end
|
||||
end
|
||||
|
||||
describe "custom page settings" do
|
||||
setup %{conn: conn, user: user} do
|
||||
{:ok, _} = Pages.create_custom_page(%{slug: "help-page", title: "Help"})
|
||||
%{conn: log_in_user(conn, user)}
|
||||
end
|
||||
|
||||
test "renders settings form", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/help-page/settings")
|
||||
|
||||
assert has_element?(view, "h1", "Page settings")
|
||||
assert has_element?(view, "#custom-page-form")
|
||||
end
|
||||
|
||||
test "updating title saves correctly", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/help-page/settings")
|
||||
|
||||
view
|
||||
|> form("#custom-page-form", page: %{title: "Help centre"})
|
||||
|> render_submit()
|
||||
|
||||
assert_redirect(view, ~p"/admin/pages/help-page")
|
||||
|
||||
page = Pages.get_page("help-page")
|
||||
assert page.title == "Help centre"
|
||||
end
|
||||
|
||||
test "updating slug redirects to new editor path", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/help-page/settings")
|
||||
|
||||
view
|
||||
|> form("#custom-page-form", page: %{slug: "support"})
|
||||
|> render_submit()
|
||||
|
||||
assert_redirect(view, ~p"/admin/pages/support")
|
||||
end
|
||||
|
||||
test "settings for nonexistent page redirects", %{conn: conn} do
|
||||
assert {:error, {:live_redirect, %{to: "/admin/pages"}}} =
|
||||
live(conn, ~p"/admin/pages/nonexistent/settings")
|
||||
end
|
||||
end
|
||||
|
||||
describe "editor for custom pages" do
|
||||
setup %{conn: conn, user: user} do
|
||||
{:ok, _} = Pages.create_custom_page(%{slug: "size-guide", title: "Size guide"})
|
||||
%{conn: log_in_user(conn, user)}
|
||||
end
|
||||
|
||||
test "shows settings button for custom pages", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/size-guide")
|
||||
|
||||
assert has_element?(view, "a[href='/admin/pages/size-guide/settings']", "Settings")
|
||||
end
|
||||
|
||||
test "does not show reset to defaults for custom pages", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/size-guide")
|
||||
|
||||
refute has_element?(view, "button", "Reset to defaults")
|
||||
end
|
||||
|
||||
test "shows reset to defaults for system pages", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/admin/pages/home")
|
||||
|
||||
assert has_element?(view, "button", "Reset to defaults")
|
||||
refute has_element?(view, "a[href='/admin/pages/home/settings']")
|
||||
end
|
||||
end
|
||||
|
||||
defp count_repeater_items(html) do
|
||||
Regex.scan(~r/class="repeater-item"/, html) |> length()
|
||||
end
|
||||
|
||||
@@ -9,6 +9,8 @@ defmodule BerrypodWeb.Shop.CustomPageTest do
|
||||
|
||||
setup do
|
||||
PageCache.invalidate_all()
|
||||
# Clear redirect ETS cache to avoid stale entries from other tests
|
||||
if :ets.whereis(:redirects_cache) != :undefined, do: :ets.delete_all_objects(:redirects_cache)
|
||||
user = user_fixture()
|
||||
{:ok, _} = Berrypod.Settings.set_site_live(true)
|
||||
%{user: user}
|
||||
|
||||
Reference in New Issue
Block a user