add custom page LiveView with catch-all routing
Shop.CustomPage handles /:slug catch-all for CMS pages. Restructured router so the catch-all is last — all admin, auth, setup, and SEO routes defined before the shop scope to prevent interception. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
123
test/berrypod_web/live/shop/custom_page_test.exs
Normal file
123
test/berrypod_web/live/shop/custom_page_test.exs
Normal file
@@ -0,0 +1,123 @@
|
||||
defmodule BerrypodWeb.Shop.CustomPageTest do
|
||||
use BerrypodWeb.ConnCase, async: false
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
import Berrypod.AccountsFixtures
|
||||
|
||||
alias Berrypod.Pages
|
||||
alias Berrypod.Pages.PageCache
|
||||
|
||||
setup do
|
||||
PageCache.invalidate_all()
|
||||
user = user_fixture()
|
||||
{:ok, _} = Berrypod.Settings.set_site_live(true)
|
||||
%{user: user}
|
||||
end
|
||||
|
||||
describe "published custom page" do
|
||||
setup do
|
||||
{:ok, _} =
|
||||
Pages.create_custom_page(%{
|
||||
slug: "our-story",
|
||||
title: "Our story",
|
||||
meta_description: "Learn about us"
|
||||
})
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "renders at /:slug", %{conn: conn} do
|
||||
{:ok, _view, html} = live(conn, "/our-story")
|
||||
assert html =~ "Our story"
|
||||
end
|
||||
|
||||
test "sets page title", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, "/our-story")
|
||||
assert page_title(view) =~ "Our story"
|
||||
end
|
||||
end
|
||||
|
||||
describe "unpublished custom page" do
|
||||
setup do
|
||||
{:ok, _} =
|
||||
Pages.create_custom_page(%{
|
||||
slug: "draft-page",
|
||||
title: "Draft page",
|
||||
published: false
|
||||
})
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "redirects anonymous users to home", %{conn: conn} do
|
||||
{:error, {:live_redirect, %{to: "/"}}} = live(conn, "/draft-page")
|
||||
end
|
||||
|
||||
test "renders for admin users", %{conn: conn, user: user} do
|
||||
conn = log_in_user(conn, user)
|
||||
{:ok, _view, html} = live(conn, "/draft-page")
|
||||
assert html =~ "Draft page"
|
||||
end
|
||||
end
|
||||
|
||||
describe "nonexistent page" do
|
||||
test "redirects to home with flash", %{conn: conn} do
|
||||
{:error, {:live_redirect, %{to: "/"}}} = live(conn, "/does-not-exist")
|
||||
end
|
||||
end
|
||||
|
||||
describe "system routes are unaffected" do
|
||||
test "/about still routes to Content LiveView", %{conn: conn} do
|
||||
{:ok, _view, html} = live(conn, "/about")
|
||||
assert html =~ "About"
|
||||
end
|
||||
|
||||
test "/cart still routes to Cart LiveView", %{conn: conn} do
|
||||
{:ok, _view, html} = live(conn, "/cart")
|
||||
assert html =~ "cart"
|
||||
end
|
||||
end
|
||||
|
||||
describe "custom page with blocks" do
|
||||
setup do
|
||||
{:ok, _} =
|
||||
Pages.create_custom_page(%{
|
||||
slug: "faq",
|
||||
title: "FAQ",
|
||||
blocks: [
|
||||
%{
|
||||
"id" => "blk_test1",
|
||||
"type" => "hero",
|
||||
"settings" => %{
|
||||
"title" => "Frequently asked questions",
|
||||
"description" => "Answers to common questions",
|
||||
"variant" => "page"
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "renders blocks", %{conn: conn} do
|
||||
{:ok, _view, html} = live(conn, "/faq")
|
||||
assert html =~ "Frequently asked questions"
|
||||
end
|
||||
end
|
||||
|
||||
describe "page editor on custom pages" do
|
||||
setup do
|
||||
{:ok, _} =
|
||||
Pages.create_custom_page(%{slug: "editable", title: "Editable page"})
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "editing works with ?edit=true", %{conn: conn, user: user} do
|
||||
conn = log_in_user(conn, user)
|
||||
{:ok, view, _html} = live(conn, "/editable?edit=true")
|
||||
assert has_element?(view, ".page-editor-sidebar")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -9,12 +9,13 @@ defmodule BerrypodWeb.Plugs.BrokenUrlTrackerTest do
|
||||
end
|
||||
|
||||
test "records broken URL on 404", %{conn: conn} do
|
||||
conn = get(conn, "/zz-nonexistent-path")
|
||||
# Multi-segment path — not caught by the /:slug catch-all route
|
||||
conn = get(conn, "/zz/nonexistent-path")
|
||||
|
||||
assert conn.status in [404, 500]
|
||||
|
||||
[broken_url] = Redirects.list_broken_urls()
|
||||
assert broken_url.path == "/zz-nonexistent-path"
|
||||
assert broken_url.path == "/zz/nonexistent-path"
|
||||
assert broken_url.recent_404_count == 1
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user