Presumably there is a way around this or Rack/Test would be useless. Can anyone tell me what I should be doing to get it to work here?
(Edit: What I ultimately want to achieve is to test which page I eventually get, not the status. In the test, the last_response object is pointing to a page that doesn't exist in my app, and certainly not the page you actually get when you run it.)
An example app:
require 'sinatra'
require 'haml'
get "/" do
redirect to('/test')
end
get '/test' do
haml :test
end
This works as you would expect. Going to either '/' or '/test' gets you the contents of views/test.haml.
But this test does not work:
require_relative '../app.rb'
require 'rspec'
require 'rack/test'
describe "test" do
include Rack::Test::Methods
def app
Sinatra::Application
end
it "tests" do
get '/'
expect(last_response.status).to eq(200)
end
end
This is what happens when you run the test:
1) test tests
Failure/Error: expect(last_response.status).to eq(200)
expected: 200
got: 302
And this is what last_response.inspect
looks like:
#<Rack::MockResponse:0x000000035d0838 @original_headers={"Content-Type"=>"text/html;charset=utf-8", "Location"=>"http://example.org/test", "Content-Length"=>"0", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff", "X-Frame-Options"=>"SAMEORIGIN"}, @errors="", @body_string=nil, @status=302, @header={"Content-Type"=>"text/html;charset=utf-8", "Location"=>"http://example.org/test", "Content-Length"=>"0", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff", "X-Frame-Options"=>"SAMEORIGIN"}, @chunked=false, @writer=#<Proc:0x000000035cfeb0@/home/jonea/.rvm/gems/ruby-1.9.3-p547@sandbox/gems/rack-1.5.2/lib/rack/response.rb:27 (lambda)>, @block=nil, @length=0, @body=[]>
I wonder if Rack/Test has just arbitrarily decided to insert 'http://example.org' into the redirect?
As @sirl33tname points out, a redirect is still a redirect, so the best possible status I can expect is 302, not 200. If I want to test whether I got a good page at the end of the redirect, I should test ok?
not the status.
But if I want to test what URL I eventually end up with, though, I need to do a tiny bit more, because Rack/Test is basically a mocking system (sic) and returns a mock of a page on a redirect, not the actual page.
But this is easy enough to override, it turns out, with follow_redirect!
.
The test becomes:
it "tests" do
get '/'
follow_redirect!
expect(last_response.status).to be_ok
# ...and now I can test for the contents of test.haml, too...
expect(last_response.body).to include('foo')
end
And that does the job.