Starkers
Starkers

Reputation: 10541

Setting http status codes

redirect_to browse_path(asset.parent_id), notice: "successfully created file!", status: 201

201 is the status you should set if you've created a resource. While the above method works for a create action, the spec for its action no longer does:

subject { response }
describe '.create' do
    context 'when orphan' do
      before do
        post :create, asset: { parent_id: nil, uploaded_file: file }
      end

      it { should have_http_status 201 }
      it { should redirect_to '/' }
    end
end

The status expectation passes, but the redirect_to expectation fails:

Expected response to be a <redirect>, but was <201>

I accept that it's no longer a 302 redirect, but it does still redirect the user to a new route (which I want to test). The redirect_to spec passes if I set it to the "wrong" code of 302, rather than 201:

redirect_to browse_path(asset.parent_id), notice: "successfully created file!", status: 302

so should I bother with setting status codes? I'll admit I actually have no idea how the browser uses them and my applications functions just as well if I painstakingly set them in my actions or don't (just use 302 redirects and 200 successes).

If status codes are important, how should I get my above specs to pass?

Upvotes: 2

Views: 728

Answers (3)

BookOfGreg
BookOfGreg

Reputation: 3706

You can assert off response.body or other response attributes within rspec. In this case the thing you are after is response.header["Location"]

You can choose to dodge the problem with capybara/rspec where you can assert current_url and still assert the status code.

redirect_to is just a dumb mid level helper and you need to reach to a slightly lower level in response.something or higher level with capybara to get where you want to be.

Upvotes: 0

zetetic
zetetic

Reputation: 47548

From the docs:

The status code can either be a standard HTTP Status code as an integer, or a symbol representing the downcased, underscored and symbolized description. Note that the status code must be a 3xx HTTP code, or redirection will not occur.

(emphasis added)

Simply put, it is an error to redirect with a 201 status code.

Upvotes: 1

Starkers
Starkers

Reputation: 10541

One way is this:

its(:status){ should eq 201 }
its(:location){ should eq 'http://test.host/' }

Upvotes: 0

Related Questions