Improve testability standards, and reliability for RegistrationForm.

Review Request #10838 — Created Jan. 19, 2020 and submitted

Information

Djblets
release-2.0.x

Reviewers

Djblets provides a RegistrationForm for helping register new users,
taking in a username, password, full name, and e-mail address. The code
for doing this is a bit old, wasn't unit tested, and had some warts.

There's improvements now in the documentation and coding style, bringing
it up to modern standards. The biggest changes, though, are in the
saving logic. We previously created the object in the parent database
transaction, and if there was a conflict, we'd try to fetch an existing
user to confirm and then provide an error to the user on the form.

The problem with this is that we'd break the transaction by way of
the constraint error, and then we'd try to look up the other user in the
same transaction. This didn't always work, and was a dangerous way of
doing it. Instead, we needed to ensure we were creating the object in
its own transaction, using transaction.atomic(). This is the same
approach used by methods like Model.objects.get_or_create().

We also no longer fetch an entire User when checking for duplicates.
We just check if a row exists in the database. This speeds things up a
bit.

Unit tests have been added for all of RegistrationForm's
functionality.

Unit tests pass on all supported versions of Django and Python.

Summary ID
Improve testability standards, and reliability for RegistrationForm.
Djblets provides a `RegistrationForm` for helping register new users, taking in a username, password, full name, and e-mail address. The code for doing this is a bit old, wasn't unit tested, and had some warts. There's improvements now in the documentation and coding style, bringing it up to modern standards. The biggest changes, though, are in the saving logic. We previously created the object in the parent database transaction, and if there was a conflict, we'd try to fetch an existing user to confirm and then provide an error to the user on the form. The problem with this is that we'd break the transaction by way of the constraint error, and then we'd try to look up the other user in the same transaction. This didn't always work, and was a dangerous way of doing it. Instead, we needed to ensure we were creating the object in its own transaction, using `transaction.atomic()`. This is the same approach used by methods like `Model.objects.get_or_create()`. We also no longer fetch an entire `User` when checking for duplicates. We just check if a row exists in the database. This speeds things up a bit. Unit tests have been added for all of `RegistrationForm`'s functionality.
a7bec9b7a13dc45bae1d7609daf5c89f26452ce5
david
  1. Ship It!
  2. 
      
chipx86
Review request changed
Status:
Completed
Change Summary:
Pushed to release-2.0.x (99ddd6e)