The aim of post is to create only the User Sign Up Page through TDD cycle of creating User Resource, Controller, Model and View.
The User Model will be very simple having only:
- Email - required, update is disabled once it is created.
- Password - required, should be greater or equal than 8 characters.
- Full Name - required, just for human readable displaying of the user name instead of email.
Note:
The first intention of this blog post was full User authentication, but since it uses TDD step-by-step development, and there is a lot from creating Route, Controller, Model and View this post will be only creating Sign Up page. Second and maybe third post will have validation, saving, authenticating and updating user!
Generate User Integration Test
First we will start with generating Rails integration_test residing in spec/requests folder:
| 1 2 3 |  | 
First we will remove a GET /users as describe block generated by default in spec/requests/users_spec.rb
and left simple as:
| 1 2 3 4 |  | 
Create User Test
In the users_spec.rb we will add a context block that will call the new route and
expect to have fields for email, password, password_confirmation, full_name and button Sign Up:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |  | 
There are quite few asserts in this test, that is certainly not good practice in testing, but to make this post shorter, it is like this!
TDD Step 1: Routing (Resource)
After running RSpec test or viewing from Guard the expected error on saving file should be:
| 1 2 3 4 5 |  | 
The problem is that there is no users route created.
Open config/routes.rb, remove all commented code and add users resource:
| 1 2 3 |  | 
After run command to examine Rails routes:
| 1 2 3 4 5 6 7 8 |  | 
You will see the new_user path, but to actually get the path it is needed to be called
with _path added to the route name as we called it in first test visit new_user_path.
For this simple authentication we will only need creating and updating of user account, but in future, we may need, a full administration of users, including listing all and destroy them as well!
Guard Routing Error
If there is a LoadError after applying the route in Guard terminal:
| 1
 |  | 
Create a spec/routing folder, to fix the issue:
| 1
 |  | 
After applying the user route (and Guard fix), there is a expected message complaining for existence of users controller.
TDD Step 2: Controller
To make test green, we need to create a user controller and the action or method called new
in the app/controllors/users_controller.rb:
| 1 2 3 4 5 |  | 
We are creating a new User and setting it to a instance variable @user, so it will be
visible within the View page!
The RSpec test will be failing since it doesn’t know what the User is:
| 1 2 3 4 |  | 
TDD Step 3: Model
To make test green, we need to create a User model in app/models and it will have
email, passmord_digest and full_name.
Having a password_digest field is important as it’s the default name that’s used with Rails
has_secure_password feature and we’ll be using this feature later.
Use this command to generate User:
| 1 2 3 4 5 6 7 8 |  | 
Change the generate attr_accessible to include  email, password, password_confirmation
and full_name needed for user create and edit form:
| 1 2 3 4 5 |  | 
We also added has_secure_password to the User model. This was introduced in Rails 3.1
and adds some simple authentication support to the model using that password_digest column.
Note:
To have this
bcrypt-rubygem must be inGemfile(we included it in first post) as this gem handles hashing the password before its stored in the database.
The generator will create a Model, Migration, RSpec test and a Factory Girl factory since we use it instead default Rails fixtures!
We will have another error regarding database:
| 1 2 3 4 |  | 
Migration
To have a database and make green our test, run command:
| 1 2 3 4 5 |  | 
Note:
This migration will create
development.sqlite3SQLite 3 database indbfolder anduserstable.
We also need to prepare database for testing with:
| 1
 |  | 
Note:
This migration will create
test.sqlite3SQLite 3 database indbfolder, anduserstable.
The RSpec test still will be failing with complaint on not having a view for user:
| 1 2 3 4 5 |  | 
TDD Step 4: View
As we noted in first tutorial, instead of default Template View Engine erb, we will use
far more better haml View Engine.
Converting the erb layout to haml
But before using the haml View Engine we need to convert default layout generated with
application:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |  | 
to much more readable haml default layout for application:
| 1 2 3 4 5 6 7 8 9 10 |  | 
New User View page
We need to create a view for user called new, and it needs to have a fields for email,
full_name, password, confirm password and Sign Up button.
Create a app/views/users/new.html.haml:
| 1 2 3 |  | 
User Form Partial
Since the creating and updating User form will be identical, we shall create a partial to reuse
user form on create and update views:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |  | 
And finally the test will be green, ignore for now that spec/models/user_spec.rb is currently pending!
Testing Sign Up Page with Browser
The beauty of it all, is that we didn’t even start browser, so we can do it now for test by running Rails server (Thin):
| 1 2 3 4 5 6 7 8 |  | 
Open page:
http://localhost:3000/users/new
The design it is not really attractive at all, but it was not scope of the post, and should not be while creating application. When designers create full design it can be applied very easily. Functionality matters for now!
Creating the SignUp route
The /users/new route name is descriptive but having just /signup, I think is far more
better route name!
SignUp Route Test
Create a new test context in spec/resources/users_spec.rb:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |  | 
The GET /signup context is added that is now visiting the signup_path!
Test fails:
| 1 2 3 4 |  | 
There is no signup_path so we need to create it in routes:
| 1 2 3 4 |  | 
The test passes and it is green, you can now try testing it in browser:
localhost:3000/signup
It should work just fine!
Conclusion
This post intended to absorb whole authentication of user, but currently is just too long and I will stop here and in second post will introduce validation, saving and maybe yet in third post authenticating and updating user!
Code
The code is hosted on GitHub and can be cloned from the xajler/just-todo-it.
Github xajler/just-todo-it commit for this post: