Sessions controller: Generate sessions controller & rspec test cases
The plan is:
* the signin form is handled by the new action
* actually signing in is handled by sending a POST request to the create action
* and signing out is handled by sending a DELETE request to the destroy action
Sessions controller: A failing test case for the new session action and view
Sessions controller: Get the test green by defining named routes, adding controller methods & adding views

By inserting the code into routes.rb
  resources :sessions, only: [:new, :create, :destroy]
  match '/signin',  to: 'sessions#new',         via: 'get'
  match '/signout', to: 'sessions#destroy',     via: 'delete'
We get the following routes (call 'rake routes' for such a list)
     Prefix Verb   URI Pattern               Controller#Action

   sessions POST   /sessions(.:format)       sessions#create
new_session GET    /sessions/new(.:format)   sessions#new
    session DELETE /sessions/:id(.:format)   sessions#destroy
     signin GET    /signin(.:format)         sessions#new
    signout DELETE /signout(.:format)        sessions#destroy

(Note the prefix is prefix of named routes, e.g. sessions_path, sessions_url)
Signin tests: A failing test for signin failure
Signin tests: A failing test case for signin success
Enable colored output of RSpec (on linux)
Signin form: Use 'form_for' helper method to create signin form

Because we don't have a Session model, we specify the name of the resource and the URL to POST
'form_for(:session, url: sessions_path)'
Omitting the ':session' parameter will result in error "undefined method `model_name' for Hash:Class" at line "<%= form_for(url: sessions_path) do |f| %>"
Reviewing form submission: We render 'new' view when user clicks 'Sign in' (--> POST to /sessions, which is handled by SessionsController#create)

This is a minimalist but important step. We inspect what happens when the for gets submitted (by inspecting the debug information at the bottom of the page), and then we know what information we have in parameters and what we could do in the SessionsController#create method
Reviewing form submission: Code skeleton for user signin

Using User.find_by(email: ...) & user.authenticate(password)
Rendering with a flash message: An (unsuccessful) attempt at handling failed signin

The flash error message appears at signin failure, but
What's wrong is that contents of the flash persist for one request, and "render 'new'" doesn't count as a request (but 'redirect_to' counts, as we see in  chapter 7). Thus if user signin failure & then click to navigate to 'Home' page, the flash message is still there because this is the 1st request since form submission
Rendering with a flash message: Add a failing test case for the flash message persists longer than expected issue
Rendering with a flash message: Correct code for failed signin

Use 'flash.now' instead of 'flash', which disappears as soon as there's an additional request
Signin success: The completed Sessions controller create action (not yet working as method 'sign_in' doesn't exist)
Remember me: Including the Sessions helper module into the Application controller

Because all helper methods are visible to all views, but not in the controllers
We will later implement 'sign_in' method in the module which will be called in all controllers & views
Remember me: A first failing test for the remember token

Because our design is 'persistent sessions' - signin status lasts even after browser close, only explicit signout will clear the status - thus we need to persist something at the server for the successfully signed-in user
Remember me: To get the test pass, first call 'rails generate migration add_remember_token_to_users'
Remember me: A migration to add a 'remember_token' to the users table (with non-unique index)
Remember me: Run 'rake db:migrate' & 'rake test:prepare'

Now the test case is green: 'rspec spec/models/user_spec.rb'
Remember me: A failing test for a valid (nonblank) remember token

We test this to ensure every user has a valid remember token right from the start (instead of right after signed-in)
Remember me: Create non-blank 'remember_token' for every user right from start

Now the test is green: rspec spec/models/user_spec.rb

We use several technique:
1. A callback method 'before_create'
2. Method 'urlsafe_base64' for a random 16-digit base64 string
3. SHA1 digest on the 16-digit random string, for a 'remember_token' -> We use SHA1 instead of Bcrypt because it's faster, and because for signed-in users it will be run on every page