Is there a way to add new fields to `phx.gen.auth` easier?

Is there a way to add new fields to phx.gen.auth easier?

I added an username field and it works just fine, but it took quite a time and I had to update a lot of stuff for a simple username.

Also, there are like 110 tests that don’t include the new fields and I really don’t want to change them manually.

Is there an easier way to change them? Or should I just remove all of them and only add the ones that are really important?

Thanks!

Do you mean 110 tests started failing or rather that 110 tests needed changing? If so, the question would be why the 110 tests would need to change. :slight_smile:

1 Like

I mean, since the tests are only for the email and password fields, I think I have to update most of them, if not all of them.

And yeah, most of them are failing because of the changes I’ve made :slightly_smiling_face:

Can’t advise you on how to change 110 existing tests but it’s a good opportunity to make test helper functions that assert on certain common structs and conditions and start replacing all hardcoded tests with using those helper functions. That way in the Future™ you would only change things in 2-3 places.

2 Likes

Alright, I see.

Thanks!

I did this recently and feel like I only updated a few tests (maybe five or six?). So long as email remains a key identifier of a Accounts.User, you shouldn’t need to go adding username everywhere you see email and password (or even just email) in the tests. So long as you have some tests asserting that a username is required, present, and unique, that should be enough coverage around it. Apart from that, you just need to update the fixture to ensure you don’t have to worry about adding a username for tests that aren’t concerned with it.

Of course, if you are going to allow users to login with their username instead of their password, that’s a different story. It still shouldn’t be that many test changes. You’d need to update any place that fetches by username/password, but once you have a loaded user, the rest of the functions that use email can stay the same.

Another route I’ve taken in a multi-tenant app is to leave the Accounts context completely alone. Once a user logs in with their email and password, they become an OrgMember in an Orgs context (for example) and choose a username post-registration. OrgMember can either be its own table or it could point to the users table (there are pros and cons to both ways). In either scenario, the only thing OrgMember schema needs to know from User is email. This way, way you have really clean separation between authorization and the rest of your app and you don’t have to futz about with generated code.

2 Likes

Thanks for the answer! I guess I shouldn’t add username to everything that has email and password in it.

1 Like

Update, I updated the fixture and some other tests and now I only have around 15 tests that fail :slightly_smiling_face:

Thanks for the help!

2 Likes

Hello a asking , the way in

mix phx.gen.html Accounts Driver drivers name:string age:int status:string

Makes schema,html,and migration for Drivers

why can’t we do that again with auth.

What if we need to seriously authenticate those Drivers.

Do you know an easier way. I don want o make login and signups from scratch.

Generating working code from nothing is easy, generating working code on top of existing code (like the Driver schema created by phx.gen.html) is massively harder.

You could try running phx.gen.auth in a brand-new Phoenix project and copy over the relevant bits of the output to your current project.

1 Like

Thanks
I did phx.gen.auth Accounts User users

Then changed users schema, to have other fields like first name ,last…, Gender

Then changed the html.heex to have those inputs

Then changed some generated code through controller to take in those
fields like [:first name, :gender]

it worked well as functioning register and login .

there’s no easy way to add extra fields there, in case you want to login by other means. (or just have extra fields in general)

I was in the same situation as OP. The hundreds of test are easily solved with test/support/fixtures/accounts_fixtures.ex and adding the new fields in valid_user_attributes.

but then i started to get dozens of

  1. test GET /users/log_in renders log in page (MyappWeb.UserSessionControllerTest)
    test/myapp_web/controllers/user_session_controller_test.exs:11
    ** (UndefinedFunctionError) function HTML.Form.normalize_value/2 is undefined (module HTML.Form is not available)

and the stack trace shows liveview all over the place, which is confusing as i opted out of liveview features for gen.auth. … most of the failing tests are not using the test fixtures and I suspected that is the cause.

post(conn, ~p"/users/log_in", %{
   "user" => %{"email" => user.email, "password" => "invalid_password"}
})

edit: only 3 tests failed because of the hardcoded values. While the UndefinedFunctionError looks like a generator issue:

--- lib/myapp_web/components/core_components.ex
+++ lib/myapp_web/components/core_components.ex
@@ -287,7 +287,7 @@ defmodule MyApp.CoreComponents do
 
   def input(%{type: "checkbox", value: value} = assigns) do
     assigns =
-      assign_new(assigns, :checked, fn -> HTML.Form.normalize_value("checkbox", value) end)
+      assign_new(assigns, :checked, fn -> Phoenix.HTML.Form.normalize_value("checkbox", value) end)
 

weird. But in the end i guess it is indeed pretty straight forward to add extra fields. Just more involved to actually log in with them…