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.
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.
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.
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
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.
Personally I’d suggest this for every application. Keep the “how someone authenticates” separate from what they represent to the business – mostly for authorization purposes. In some projects they might even be able to switch the latter while the former authentication is valid.