Controller Testing - YaleSTC/reservations GitHub Wiki
During its usual run, the Reservations app has a number of barriers, without the setup of which it will lock you out of much functionality (i.e. redirect you to go and set up the app).
Authorization and happy paths: best practice
CanCan Authorization maintains permissions; these manifest in access to controller actions. At worst, this means you might have up to eight separate behaviors with different authorization level.
In such a case, best practice is to write the happy/unhappy paths for the controller code itself into a shared_examples
block, then follow up with separate context
blocks for every authorization level/situation in which you will include the appropriate shared example groups (via include_examples
or it_behaves_like
).
AppConfig
and current_user
Every controller checks that AppConfig exists and current_user has (whatever) privileges. Therefore, preface your controller tests with
before(:all) do
@app_config = FactoryGirl.create(:app_config)
end
before(:each) do
@controller.stub(:first_time_user).and_return(FactoryGirl.create(:user))
@controller.stub(:current_user).and_return(FactoryGirl.create(:admin)) # Or whatever other role
end
This is because unless Reservations detects a valid AppConfig and a user with proper authorization, it will redirect to a set-up page (or bad-authentication page). That is, however, not immediately clear from the tests failing.
It is worth noting, too, that FactoryGirl cleans up after itself; consequently, it is not necessary to add an after(:all) { @app_config.destroy }
hook. In fact, it breaks the database state (for some reason), so don't do it.
Cart
The Cart
object lives in session[:cart]. In order to set it, it needs to be passed as a third argument to the HTTP request verb, e.g.
get :new, nil, { cart: FactoryGirl.build(:cart_with_items, reserver_id: @user.id) }