Lawrence
Lawrence

Reputation: 10742

How do I test that a 301 redirect takes place with rspec?

I need to test two things:

  1. that certain old paths are correctly redirected to certain new paths
  2. that the redirect is a 301, not a 302.

I'm using Capybara for my acceptance tests, but that can't handle #2. I can test that the redirect happens, but it happens silently, so I can't see that it was a 301.

Controller tests can't handle #1. The "get", "post" etc. verbs that rspec provides for controller tests only allow you to pass in an action, not a specific path, and the redirect is implemented in a single action based on the path, as below:

# controller
class ExampleController
  def redirect301
    redirect_to case request.path
    when '/old_a'
      '/new_a'
    when '/old_b'
      '/new_b'
    end, :status => 301
  end
end

# routes.rb
['old_a', 'old_b'].each do |p| 
  map.connect p, :controller => :example, :action => :redirect301
end

So, what should I do?

Upvotes: 1

Views: 2472

Answers (3)

XP84
XP84

Reputation: 1350

Using rspec-rails 2.12.0 and the modern expect syntax, this is the correct format:

  it "should redirect with a 301 status code to /whatever_path" do
    get :some_action
    expect(response).to redirect_to '/whatever_path' # or a path helper
    expect(response.code).to eq '301'
  end

Notice the string 301 - when I ran this spec with an integer, it failed, comparing 301 against "301" which in Ruby are not equal.

Upvotes: 0

Paz Aricha
Paz Aricha

Reputation: 408

To test response status do this - expect(response.status).to eq(301) And to test response url do this - expect(response.location).to eq(my_path)

So altogether it should look like this:

it "should redirect with a 301 status code to my_path" do
  get :action
  expect(response.status).to eq(301)
  expect(response.location).to eq(my_path)
end

Upvotes: 1

Eimantas
Eimantas

Reputation: 49354

Try this:

it "should redirect with 301" do
  get :action
  response.code.should == 301
end

Upvotes: 4

Related Questions