diff --git a/CHANGELOG.md b/CHANGELOG.md index fe29ab7f..aeb0c1d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v1.0.36 (TBA) + +#### Bug fixes + +* [`Pow.Phoenix.ViewHelpers`] Now ensures format for layouts in Phoenix 1.7 is conformed to prevent `conflicting layouts found` warnings + ## v1.0.35 (2024-01-04) Handles Elixir 1.16 deprecations. diff --git a/lib/pow/phoenix/controllers/view_helpers.ex b/lib/pow/phoenix/controllers/view_helpers.ex index 0a6855b5..e755ceb0 100644 --- a/lib/pow/phoenix/controllers/view_helpers.ex +++ b/lib/pow/phoenix/controllers/view_helpers.ex @@ -52,8 +52,8 @@ defmodule Pow.Phoenix.ViewHelpers do @spec layout(Conn.t()) :: Conn.t() def layout(conn) do web_module = web_module(conn) - view = view(conn, web_module) - layout = layout(conn, web_module) + view = html_view(conn, web_module) + layout = html_layout(conn, web_module) conn |> Controller.put_view(view) @@ -66,17 +66,40 @@ defmodule Pow.Phoenix.ViewHelpers do |> Config.get(:web_module) end - defp view(conn, web_module) do + # Credo will complain about unless statement but we want this first + # credo:disable-for-next-line + unless Pow.dependency_vsn_match?(:phoenix, "< 1.7.0") do + defp html_view(conn, web_module) do + [html: conn + |> Controller.view_module("html") + |> build_view_module(web_module)] + end + else + # TODO: Remove this when Phoenix 1.7 is required + defp html_view(conn, web_module) do conn |> Controller.view_module() |> build_view_module(web_module) end + end + - defp layout(conn, web_module) do + # Credo will complain about unless statement but we want this first + # credo:disable-for-next-line + unless Pow.dependency_vsn_match?(:phoenix, "< 1.7.0") do + defp html_layout(conn, web_module) do + [html: conn + |> Controller.layout("html") + |> build_layout(web_module || web_base(conn))] + end + else + # TODO: Remove this when Phoenix 1.7 is required + defp html_layout(conn, web_module) do conn |> Controller.layout() |> build_layout(web_module || web_base(conn)) end + end defp web_base(conn) do ["Endpoint" | web_context] = @@ -118,24 +141,27 @@ defmodule Pow.Phoenix.ViewHelpers do end end - # TODO: Remove `Pow.Phoenix.LayoutView` guard when Phoenix 1.7 is required + # Credo will complain about unless statement but we want this first + # credo:disable-for-next-line + unless Pow.dependency_vsn_match?(:phoenix, "< 1.7.0") do defp build_layout({layout_view, template}, web_module) when layout_view in [Pow.Phoenix.Layouts, Pow.Phoenix.LayoutView] do layouts = Module.concat([web_module, Layouts]) if Code.ensure_loaded?(layouts) do - [html: {layouts, template}] + {layouts, template} else - # TODO: Remove this when Phoenix 1.7 is required + # TODO: Remove this when Phoenix 1.7 is required and Layouts module is required {Module.concat([web_module, LayoutView]), template} end end - # Credo will complain about unless statement but we want this first - # credo:disable-for-next-line - unless Pow.dependency_vsn_match?(:phoenix, "< 1.7.0") do - defp build_layout(layout, _web_module), do: [html: layout] + defp build_layout(layout, _web_module), do: layout else # TODO: Remove this when Phoenix 1.7 is required + defp build_layout({Pow.Phoenix.LayoutView, template}, web_module) do + {Module.concat([web_module, LayoutView]), template} + end + defp build_layout(layout, _web_module), do: layout end diff --git a/test/pow/phoenix/controllers/controller_test.exs b/test/pow/phoenix/controllers/controller_test.exs index b8bf57b9..0f92fc4a 100644 --- a/test/pow/phoenix/controllers/controller_test.exs +++ b/test/pow/phoenix/controllers/controller_test.exs @@ -9,12 +9,12 @@ defmodule Pow.Phoenix.ControllerTest do conn = conn |> Conn.put_private(:pow_config, web_module: Phoenix, user: User) - |> Conn.put_private(:phoenix_view, %{_: SessionHTML}) + |> Conn.put_private(:phoenix_view, %{"html" => SessionHTML}) |> Conn.put_private(:phoenix_router, Router) |> Conn.put_private(:phoenix_action, :new) |> Conn.put_private(:phoenix_endpoint, Endpoint) |> Conn.put_private(:phoenix_format, :html) - |> Conn.put_private(:phoenix_layout, %{html: {LayoutView, :app}}) + |> Conn.put_private(:phoenix_layout, %{"html" => {LayoutView, :app}}) |> Conn.assign(:action, "#") conn = ViewHelpers.layout(conn) diff --git a/test/pow/phoenix/controllers/view_helpers_test.exs b/test/pow/phoenix/controllers/view_helpers_test.exs index cbad3ad4..ca0d2e74 100644 --- a/test/pow/phoenix/controllers/view_helpers_test.exs +++ b/test/pow/phoenix/controllers/view_helpers_test.exs @@ -21,7 +21,7 @@ defmodule Pow.Phoenix.ViewHelpersTest do |> Conn.put_private(:pow_config, []) |> Conn.put_private(:phoenix_endpoint, Pow.Test.Phoenix.Endpoint) |> Conn.put_private(:phoenix_format, "html") - |> Conn.put_private(:phoenix_view, %{_: Pow.Phoenix.SessionHTML}) + |> Conn.put_private(:phoenix_view, %{"html" => Pow.Phoenix.SessionHTML}) |> Conn.put_private(:phoenix_layout, %{"html" => {Pow.Phoenix.Layouts, :app}}) |> Conn.put_private(:phoenix_router, Pow.Test.Phoenix.Router) |> Conn.assign(:changeset, User.changeset(%User{}, %{})) @@ -34,7 +34,7 @@ defmodule Pow.Phoenix.ViewHelpersTest do conn = ViewHelpers.layout(conn) assert conn.private[:phoenix_endpoint] == Pow.Test.Phoenix.Endpoint - assert conn.private[:phoenix_view] == %{_: Pow.Phoenix.SessionHTML} + assert conn.private[:phoenix_view] == %{"html" => Pow.Phoenix.SessionHTML} assert conn.private[:phoenix_layout] == %{"html" => {Pow.Test.Phoenix.Layouts, :app}} end @@ -45,30 +45,30 @@ defmodule Pow.Phoenix.ViewHelpersTest do |> ViewHelpers.layout() assert conn.private[:phoenix_endpoint] == Pow.Test.Phoenix.Endpoint - assert conn.private[:phoenix_view] == %{_: Pow.Test.Phoenix.Pow.SessionHTML} + assert conn.private[:phoenix_view] == %{"html" => Pow.Test.Phoenix.Pow.SessionHTML} assert conn.private[:phoenix_layout] == %{"html" => {Pow.Test.Phoenix.Layouts, :app}} end test "layout/1 in extension", %{conn: conn} do conn = conn - |> Conn.put_private(:phoenix_view, %{_: PowTest.Phoenix.TestHTML}) + |> Conn.put_private(:phoenix_view, %{"html" => PowTest.Phoenix.TestHTML}) |> ViewHelpers.layout() assert conn.private[:phoenix_endpoint] == Pow.Test.Phoenix.Endpoint - assert conn.private[:phoenix_view] == %{_: PowTest.Phoenix.TestHTML} + assert conn.private[:phoenix_view] == %{"html" => PowTest.Phoenix.TestHTML} assert conn.private[:phoenix_layout] == %{"html" => {Pow.Test.Phoenix.Layouts, :app}} end test "layout/1 in extension with `:web_module`", %{conn: conn} do conn = conn - |> Conn.put_private(:phoenix_view, %{_: PowTest.Phoenix.TestHTML}) + |> Conn.put_private(:phoenix_view, %{"html" => PowTest.Phoenix.TestHTML}) |> Conn.put_private(:pow_config, web_module: Pow.Test.Phoenix) |> ViewHelpers.layout() assert conn.private[:phoenix_endpoint] == Pow.Test.Phoenix.Endpoint - assert conn.private[:phoenix_view] == %{_: Pow.Test.Phoenix.PowTest.TestHTML} + assert conn.private[:phoenix_view] == %{"html" => Pow.Test.Phoenix.PowTest.TestHTML} assert conn.private[:phoenix_layout] == %{"html" => {Pow.Test.Phoenix.Layouts, :app}} end @@ -79,7 +79,7 @@ defmodule Pow.Phoenix.ViewHelpersTest do |> ViewHelpers.layout() assert conn.private[:phoenix_endpoint] == Pow.Test.Phoenix.Endpoint - assert conn.private[:phoenix_view] == %{_: Pow.Phoenix.SessionHTML} + assert conn.private[:phoenix_view] == %{"html" => Pow.Phoenix.SessionHTML} assert conn.private[:phoenix_layout] == %{"html" => false} end @@ -90,7 +90,7 @@ defmodule Pow.Phoenix.ViewHelpersTest do |> ViewHelpers.layout() assert conn.private[:phoenix_endpoint] == Pow.Test.Phoenix.Endpoint - assert conn.private[:phoenix_view] == %{_: Pow.Phoenix.SessionHTML} + assert conn.private[:phoenix_view] == %{"html" => Pow.Phoenix.SessionHTML} assert conn.private[:phoenix_layout] == %{"html" => {MyAppWeb.Layouts, :custom}} end end