Reputation: 59
I am currently trying to make a dropbox-esque application from a tutorial and I am having trouble trying to figure out how I would test this controller.
this is the AssetsController page
def index
@assets = current_user.assets
end
def show
@assets = current_user.assets.find(params[:id])
Also, assets belong_to :user and user has_many :assets
How would I go about putting that into an rspec test?
Upvotes: 2
Views: 172
Reputation: 1836
Firstly, be very careful about AssetsController.
Assuming you are using Rails 3, the "assets_path" is also the path used to load your application assets, and hence, anything you write to the session in that controller will be ignored silently. Probably not what you want! I'd strongly consider renaming the controller.
I'd first create the user in a sign-in block
module ControllerMacros
def login_user
before(:each) do
@request.env["devise.mapping"] = Devise.mappings[:user]
@user = Factory.create(:user)
sign_in @user
end
end
end
You can then load this in the spec_helper.rb file
RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
config.extend ControllerMacros, :type => :controller
end
Finally, you can use this in the test
describe MyController do
context "#index" do
login_user
before(:each) do
@assets = []
5.times{ @assets << Factory.create(:asset, :user => @user)}
end
it "should test index" do
get :index
assigns(:assets).should eq(@assets)
end
end
end
Now, that should test your asset list correctly.
EDIT: Just realised, I'm using FactoryGirl/Devise here, you may or may not be!
Upvotes: 3
Reputation: 5651
What exactly is you question? How to setup basic tests for the relations or how to test the management of current_user?
The basic tests for this should be in the Model Specs, since it's the job of the model to sort out such things.
I normally test it like this:
1) define the fixtures (or alternately use something like FactoryGirl) for two users and some assets (three for this example). assets for user a are named asset_a_*, those for user b asset_b_*)
2) The test is simply like this:
users(:users_a).assets.should have(3).records
users(:users_a).assets.should include(assets(:asset_a_a))
users(:users_a).assets.should include(assets(:assets_a_b))
users(:users_a).assets.should include(assets(:assets_a_c))
You can finetune this like users(:users_a).assets.find(assets(:asset_a_a).id).should include(assets(:asset_a_a)) users(:users_a).assets.find(assets(:asset_a_a).id).should_not include(assets(:asset_b_a))
If you absolutely want, you can use similar tests for the controller part.
Though there are quite some discussions if such basic functionality needs testing at all, since it's mostly core Rails functionality to handle the associations you defined in your model.
Personally I do this kind of testing for some reasons. In many cases such permission related associations soon become more complicated and need detailed tests anyway. or somebody may change the parameters of the association and break something.
II - About the current_user part within the controller.
This depends of course on how you handle the authentication to begin with. If you use a plugin like AuthLogic (or whatever) it may have some methods that allow simulating the login in rspec. For authlogic you can do something like this:
before(:each) do
activate_authlogic
UserSession.create(users(:user_a))
end
This will activate authlogic and 'login' user_a. Then you run you controller
get :index
response.should be_success
response.should render_template :index
assigns(:assets).should # => more or less as above, check that there are the right aessets.
Upvotes: 1