Repository: phoenixframework/phoenix
Pull request #5349 (2023-03-11 14:54:28)

Fix hard coded paths in tests generated by `phx.gen.auth`
In some tests generated by `phx.gen.auth` the paths are hard coded to `~p"/users/..."`, so the tests fail when a different schema module or web namespace is used.

To fix this problem, interpolate `<%= schema.route_prefix %>` into `~p` instead of hard coding `/users`.
 
I tested this PR manually with two examples from the official documentation:

```
$ mix phx.gen.auth Accounts User users --web Warehouse
$ mix phx.gen.auth Backoffice Admin admins
```

Please let me know if you would like additional assertions in `test/mix/tasks/phx.gen.auth_test.exs` for this PR. By reading through the existing tests I came to the conclusion that this bug is too specific to warrant its own regression test. Maybe adding a test for a schema module other than `User` might be a good idea, though?


Patch:
diff --git a/guides/deployment/fly.md b/guides/deployment/fly.md
index b9edb519e..1388a0a9b 100644
--- a/guides/deployment/fly.md
+++ b/guides/deployment/fly.md
@@ -398,6 +398,6 @@ Refer to the [Fly.io Elixir documentation](https://fly.io/docs/getting-started/e
 
 ## Troubleshooting
 
-See [Troubleshooting](https://fly.io/docs/getting-started/troubleshooting/#welcome-message)
+See [Troubleshooting](https://fly.io/docs/getting-started/troubleshooting/) and [Elixir Troubleshooting](https://fly.io/docs/elixir/the-basics/troubleshooting/)
 
 Visit the [Fly.io Community](https://community.fly.io/) to find solutions and ask questions.
diff --git a/guides/deployment/heroku.md b/guides/deployment/heroku.md
index 990251386..8d9cdf275 100644
--- a/guides/deployment/heroku.md
+++ b/guides/deployment/heroku.md
@@ -52,13 +52,13 @@ $ git add .
 $ git commit -m "Initial commit"
 ```
 
-Heroku offers some great information on how it is using Git [here](https://devcenter.heroku.com/articles/git#tracking-your-app-in-git).
+Heroku offers some great information on how it is using Git [here](https://devcenter.heroku.com/articles/git#prerequisites-install-git-and-the-heroku-cli).
 
 ## Signing up for Heroku
 
 Signing up to Heroku is very simple, just head over to [https://signup.heroku.com/](https://signup.heroku.com/) and fill in the form.
 
-The Free plan will give us one web [dyno](https://devcenter.heroku.com/articles/dynos#dynos) and one worker dyno, as well as a PostgreSQL and Redis instance for free.
+The Free plan will give us one web [dyno](https://devcenter.heroku.com/articles/dynos) and one worker dyno, as well as a PostgreSQL and Redis instance for free.
 
 These are meant to be used for testing and development, and come with some limitations. In order to run a production application, please consider upgrading to a paid plan.
 
diff --git a/guides/howto/using_ssl.md b/guides/howto/using_ssl.md
index 88ed92334..93183c75c 100644
--- a/guides/howto/using_ssl.md
+++ b/guides/howto/using_ssl.md
@@ -31,7 +31,7 @@ Without the `otp_app:` key, we need to provide absolute paths to the files where
 Path.expand("../../../some/path/to/ssl/key.pem", __DIR__)
 ```
 
-The options under the `https:` key are passed to the Plug adapter, typically `Plug.Cowboy`, which in turn uses `Plug.SSL` to select the TLS socket options. Please refer to the documentation for [Plug.SSL.configure/1](https://hexdocs.pm/plug/Plug.SSL.html#configure/1) for more information on the available options and their defaults. The [Plug HTTPS Guide](https://hexdocs.pm/plug/https.html) and the [Erlang/OTP ssl](https://erlang.org/doc/man/ssl.html) documentation also provide valuable information.
+The options under the `https:` key are passed to the Plug adapter, typically `Plug.Cowboy`, which in turn uses `Plug.SSL` to select the TLS socket options. Please refer to the documentation for [Plug.SSL.configure/1](https://hexdocs.pm/plug/Plug.SSL.html#configure/1) for more information on the available options and their defaults. The [Plug HTTPS Guide](https://hexdocs.pm/plug/https.html) and the [Erlang/OTP ssl](https://www.erlang.org/doc/man/ssl.html) documentation also provide valuable information.
 
 ## SSL in Development
 
diff --git a/guides/introduction/community.md b/guides/introduction/community.md
index 5af987313..9cc142369 100644
--- a/guides/introduction/community.md
+++ b/guides/introduction/community.md
@@ -24,15 +24,15 @@ There are a number of places to connect with community members at all experience
 
   * [Programming Phoenix LiveView - Interactive Elixir Web Programming Without Writing Any JavaScript - 2021 (by Bruce Tate and Sophie DeBenedetto)](https://pragprog.com/titles/liveview/programming-phoenix-liveview/)
 
-  * [Real-Time Phoenix - Build Highly Scalable Systems with Channels (by Stephen Bussey - 2020)](https://pragprog.com/book/sbsockets/real-time-phoenix)
+  * [Real-Time Phoenix - Build Highly Scalable Systems with Channels (by Stephen Bussey - 2020)](https://pragprog.com/titles/sbsockets/real-time-phoenix/)
 
-  * [Programming Phoenix 1.4 (by Bruce Tate and Phoenix core team members Chris McCord and José Valim - 2019)](https://pragprog.com/book/phoenix14/programming-phoenix-1-4)
+  * [Programming Phoenix 1.4 (by Bruce Tate and Phoenix core team members Chris McCord and José Valim - 2019)](https://pragprog.com/titles/phoenix14/programming-phoenix-1-4/)
 
   * [Phoenix in Action (by Geoffrey Lessel - 2019)](https://manning.com/books/phoenix-in-action)
 
   * [Phoenix Inside Out - Book Series (by Shankar Dhanasekaran - 2017)](https://shankardevy.com/phoenix-book/)
 
-  * [Functional Web Development with Elixir, OTP, and Phoenix Rethink the Modern Web App (by Lance Halvorsen - 2017)](https://pragprog.com/book/lhelph/functional-web-development-with-elixir-otp-and-phoenix)
+  * [Functional Web Development with Elixir, OTP, and Phoenix Rethink the Modern Web App (by Lance Halvorsen - 2017)](https://pragprog.com/titles/lhelph/functional-web-development-with-elixir-otp-and-phoenix/)
 
 ## Screencasts/Courses
 
diff --git a/lib/mix/tasks/phx.gen.ex b/lib/mix/tasks/phx.gen.ex
index 16b00f046..71c9e4093 100644
--- a/lib/mix/tasks/phx.gen.ex
+++ b/lib/mix/tasks/phx.gen.ex
@@ -5,19 +5,19 @@ defmodule Mix.Tasks.Phx.Gen do
 
   @moduledoc """
   Lists all available Phoenix generators.
-  
+
   ## CRUD related generators
 
   The table below shows a summary of the contents created by the CRUD generators:
 
   | Task | Schema | Migration | Context | Controller | View | LiveView |
   |:------------------ |:-:|:-:|:-:|:-:|:-:|:-:|
-  | `phx.gen.embedded` | ✓ |   |   |   |   |   |
-  | `phx.gen.schema`   | ✓ | ✓ |   |   |   |   |
-  | `phx.gen.context`  | ✓ | ✓ | ✓ |   |   |   |
-  | `phx.gen.live`     | ✓ | ✓ | ✓ |   |   | ✓ |
-  | `phx.gen.json`     | ✓ | ✓ | ✓ | ✓ | ✓ |   |
-  | `phx.gen.html`     | ✓ | ✓ | ✓ | ✓ | ✓ |   |
+  | `phx.gen.embedded` | x |   |   |   |   |   |
+  | `phx.gen.schema`   | x | x |   |   |   |   |
+  | `phx.gen.context`  | x | x | x |   |   |   |
+  | `phx.gen.live`     | x | x | x |   |   | x |
+  | `phx.gen.json`     | x | x | x | x | x |   |
+  | `phx.gen.html`     | x | x | x | x | x |   |
   """
 
   def run(_args) do
diff --git a/priv/templates/phx.gen.auth/forgot_password_live.ex b/priv/templates/phx.gen.auth/forgot_password_live.ex
index 862160186..191888a84 100644
--- a/priv/templates/phx.gen.auth/forgot_password_live.ex
+++ b/priv/templates/phx.gen.auth/forgot_password_live.ex
@@ -19,7 +19,7 @@ defmodule <%= inspect context.web_module %>.<%= inspect Module.concat(schema.web
           </.button>
         </:actions>
       </.simple_form>
-      <p class="text-center mt-4">
+      <p class="text-center text-sm mt-4">
         <.link href={~p"<%= schema.route_prefix %>/register"}>Register</.link>
         |
         <.link href={~p"<%= schema.route_prefix %>/log_in"}>Log in</.link>
diff --git a/priv/templates/phx.gen.auth/reset_password_edit.html.heex b/priv/templates/phx.gen.auth/reset_password_edit.html.heex
index 82727a142..9fda2a2f2 100644
--- a/priv/templates/phx.gen.auth/reset_password_edit.html.heex
+++ b/priv/templates/phx.gen.auth/reset_password_edit.html.heex
@@ -21,7 +21,7 @@
       </.button>
     </:actions>
   </.simple_form>
-  <p class="text-center mt-4">
+  <p class="text-center text-sm mt-4">
     <.link href={~p"<%= schema.route_prefix %>/register"}>Register</.link>
     |
     <.link href={~p"<%= schema.route_prefix %>/log_in"}>Log in</.link>
diff --git a/priv/templates/phx.gen.auth/reset_password_live.ex b/priv/templates/phx.gen.auth/reset_password_live.ex
index 84d1a3f0c..b09d802de 100644
--- a/priv/templates/phx.gen.auth/reset_password_live.ex
+++ b/priv/templates/phx.gen.auth/reset_password_live.ex
@@ -30,7 +30,7 @@ defmodule <%= inspect context.web_module %>.<%= inspect Module.concat(schema.web
         </:actions>
       </.simple_form>
 
-      <p class="text-center mt-4">
+      <p class="text-center text-sm mt-4">
         <.link href={~p"<%= schema.route_prefix %>/register"}>Register</.link>
         |
         <.link href={~p"<%= schema.route_prefix %>/log_in"}>Log in</.link>
diff --git a/priv/templates/phx.gen.auth/reset_password_new.html.heex b/priv/templates/phx.gen.auth/reset_password_new.html.heex
index ee1a2ff34..2e694277a 100644
--- a/priv/templates/phx.gen.auth/reset_password_new.html.heex
+++ b/priv/templates/phx.gen.auth/reset_password_new.html.heex
@@ -12,7 +12,7 @@
       </.button>
     </:actions>
   </.simple_form>
-  <p class="text-center mt-4">
+  <p class="text-center text-sm mt-4">
     <.link href={~p"<%= schema.route_prefix %>/register"}>Register</.link>
     |
     <.link href={~p"<%= schema.route_prefix %>/log_in"}>Log in</.link>


Test patch:
diff --git a/priv/templates/phx.gen.auth/forgot_password_live_test.exs b/priv/templates/phx.gen.auth/forgot_password_live_test.exs
index ef417c907..7dd7cd6b4 100644
--- a/priv/templates/phx.gen.auth/forgot_password_live_test.exs
+++ b/priv/templates/phx.gen.auth/forgot_password_live_test.exs
@@ -12,8 +12,8 @@ defmodule <%= inspect context.web_module %>.<%= inspect Module.concat(schema.web
       {:ok, lv, html} = live(conn, ~p"<%= schema.route_prefix %>/reset_password")
 
       assert html =~ "Forgot your password?"
-      assert has_element?(lv, ~s|a[href="#{~p"/users/register"}"]|, "Register")
-      assert has_element?(lv, ~s|a[href="#{~p"/users/log_in"}"]|, "Log in")
+      assert has_element?(lv, ~s|a[href="#{~p"<%= schema.route_prefix %>/register"}"]|, "Register")
+      assert has_element?(lv, ~s|a[href="#{~p"<%= schema.route_prefix %>/log_in"}"]|, "Log in")
     end
 
     test "redirects if already logged in", %{conn: conn} do
diff --git a/priv/templates/phx.gen.auth/registration_controller_test.exs b/priv/templates/phx.gen.auth/registration_controller_test.exs
index 06d5defd7..2682277b0 100644
--- a/priv/templates/phx.gen.auth/registration_controller_test.exs
+++ b/priv/templates/phx.gen.auth/registration_controller_test.exs
@@ -8,8 +8,8 @@ defmodule <%= inspect context.web_module %>.<%= inspect Module.concat(schema.web
       conn = get(conn, ~p"<%= schema.route_prefix %>/register")
       response = html_response(conn, 200)
       assert response =~ "Register"
-      assert response =~ ~p"/users/log_in"
-      assert response =~ ~p"/users/register"
+      assert response =~ ~p"<%= schema.route_prefix %>/log_in"
+      assert response =~ ~p"<%= schema.route_prefix %>/register"
     end
 
     test "redirects if already logged in", %{conn: conn} do
@@ -36,8 +36,8 @@ defmodule <%= inspect context.web_module %>.<%= inspect Module.concat(schema.web
       conn = get(conn, ~p"/")
       response = html_response(conn, 200)
       assert response =~ email
-      assert response =~ ~p"/users/settings"
-      assert response =~ ~p"/users/log_out"
+      assert response =~ ~p"<%= schema.route_prefix %>/settings"
+      assert response =~ ~p"<%= schema.route_prefix %>/log_out"
     end
 
     test "render errors for invalid data", %{conn: conn} do
diff --git a/priv/templates/phx.gen.auth/session_controller_test.exs b/priv/templates/phx.gen.auth/session_controller_test.exs
index a6700ac43..70473c2ce 100644
--- a/priv/templates/phx.gen.auth/session_controller_test.exs
+++ b/priv/templates/phx.gen.auth/session_controller_test.exs
@@ -12,7 +12,7 @@ defmodule <%= inspect context.web_module %>.<%= inspect Module.concat(schema.web
       conn = get(conn, ~p"<%= schema.route_prefix %>/log_in")
       response = html_response(conn, 200)
       assert response =~ "Log in"
-      assert response =~ ~p"/users/register"
+      assert response =~ ~p"<%= schema.route_prefix %>/register"
       assert response =~ "Forgot your password?"
     end
 
@@ -36,8 +36,8 @@ defmodule <%= inspect context.web_module %>.<%= inspect Module.concat(schema.web
       conn = get(conn, ~p"/")
       response = html_response(conn, 200)
       assert response =~ <%= schema.singular %>.email
-      assert response =~ ~p"/users/settings"
-      assert response =~ ~p"/users/log_out"
+      assert response =~ ~p"<%= schema.route_prefix %>/settings"
+      assert response =~ ~p"<%= schema.route_prefix %>/log_out"
     end
 
     test "logs the <%= schema.singular %> in with remember me", %{conn: conn, <%= schema.singular %>: <%= schema.singular %>} do