views:

79

answers:

2

edited: followed suggestions. See at end of question.

I have a controller with two functions:

 def new
     if login_required
            @discussion = Discussion.new
            respond_to do |format|
                  format.html # new.html.erb
                  format.xml  { render :xml => @discussion }
            end
      end
 end


 def create
     if login_required
         @discussion = Discussion.new(params[:discussion])
         @discussion.update_attribute("user_id",session[:userid])
         respond_to do |format|
         if @discussion.save
            flash[:notice] = 'Discussion was successfully created.'
            format.html { redirect_to(@discussion) }
            format.xml  { render :xml => @discussion, :status => :created, :location => @Discussion }
        else
            format.html { render :action => "new" }
            format.xml  { render :xml => @discussion.errors, :status => :unprocessable_entity }
        end
   end
 end
end

Now, in my integration test file I have:

test "test 1" do  
   post "/users/login",:user=> { :name => "bob", :password => "test_pass" }
   post "/discussions/create", :discussion => { :title => "title 1", :body => "discussion body", :id => "101"} #Create 1
   assert_response :success       #Assert 1
   get "/discussions/101"
   assert_response :success       #Assert 2
end

However, I get a 302 on Assert 1.

If I change "Create 1" to be: post "/discussions/new", :discussion => { :title => "title 1", :body => "discussion body", :id => "101"}

I get a 404 error.

1) What is going on?

2) what tools/options are available to me so that I figure this out myself?

Thanks

update

Followed suggestion (from Ryan Bigg):

  • post :create, { :discussion => { } }, { :user_id => users(:bob).id }

Result:

  • Rack::Lint::LintError: env variable HTTP_USER_ID has non-string value 1976283457

Still unresolved.

A: 

Everything seems to be working correctly in your controller. In your tests you're sending a POST request and the new action doesn't accept POST requests, but only GET's. The create action accepts POST's, but it sends a redirect after successfully creating a discussion.

You should probably replace the first assert_response :success with:

assert_redirected_to :controller => "discussions", :action => "show"`
Tomas Markauskas
+2  A: 

A couple of things:

  1. Try moving login_required to a before_filter.
  2. For your test you should be doing post :create, :discussion => { ... }. The test should already know about the controller if you've set it up correctly. I believe the naming convention is DiscussionsControllerTest off the top of my head.

I think why you're getting the 302 on Assert 1 because it's not actually logging in. Try passing in the credentials in the call to post:

post :create, { :discussion => { } }, { :user_id => users(:bob).id }

The second argument of post is the params Hash and the third argument is the session Hash. Providing you have loaded user fixtures and they have a key called bob, this should find that and use him to log in.

An alternative solution I use in my RSpec tests is to define a login_as method which takes a single argument of the login of the user whom I should log in as. Then every request I do in my controller or integration tests are logged in as that user:

def login_as(name)
  request.session[:user] = users(name).id
end

I think you should be able to do the same thing in your test_helper.rb file, but... I haven't tried it. YMMV.

Ryan Bigg
thanks, I tried your suggestions, now I get: Rack::Lint::LintError: env variable HTTP_USER_ID has non-string value 1976283457
cbrulak
+1 for pointing out before_filter
Dave Sims