5 class RedirectTo #:nodoc:
7 include ActionController::StatusCodes
9 def initialize(request, expected)
14 def matches?(response_or_controller)
15 response = response_or_controller.respond_to?(:response) ?
16 response_or_controller.response :
17 response_or_controller
19 @redirected = response.redirect?
20 @actual = response.redirect_url
21 return false unless @redirected
24 @actual_status = interpret_status(response.code.to_i)
25 @status_matched = @expected_status == @actual_status
27 @status_matched = true
30 if @expected.instance_of? Hash
31 return false unless @actual =~ %r{^\w+://#{@request.host}}
32 return false unless actual_redirect_to_valid_route
33 return actual_hash == expected_hash && @status_matched
35 return @actual == expected_url && @status_matched
44 hash_from_url expected_url
47 def actual_redirect_to_valid_route
51 def hash_from_url(url)
52 query_hash(url).merge(path_hash(url)).with_indifferent_access
56 path = url.sub(%r{^\w+://#{@request.host}(?::\d+)?}, "").split("?", 2)[0]
57 ActionController::Routing::Routes.recognize_path path, { :method => :get }
61 query = url.split("?", 2)[1] || ""
62 Rack::Utils.parse_query(query)
66 @expected_status = interpret_status(options[:status])
73 return ActionController::UrlRewriter.new(@request, {}).rewrite(@expected)
75 return @request.env['HTTP_REFERER']
79 return "http://#{@request.host}" + (@expected.split('')[0] == '/' ? '' : '/') + @expected
83 def failure_message_for_should
86 return %Q{expected redirect to #{@expected.inspect}, got redirect to #{@actual.inspect}}
88 return %Q{expected redirect to #{@expected.inspect} with status #{@expected_status}, got #{@actual_status}}
91 return %Q{expected redirect to #{@expected.inspect}, got no redirect}
95 def failure_message_for_should_not
96 return %Q{expected not to be redirected to #{@expected.inspect}, but was} if @redirected
100 "redirect to #{@expected.inspect}"
105 # response.should redirect_to(url)
106 # response.should redirect_to(:action => action_name)
107 # response.should redirect_to(:controller => controller_name, :action => action_name)
108 # response.should_not redirect_to(url)
109 # response.should_not redirect_to(:action => action_name)
110 # response.should_not redirect_to(:controller => controller_name, :action => action_name)
112 # Passes if the response is a redirect to the url, action or controller/action.
113 # Useful in controller specs (integration or isolation mode).
117 # response.should redirect_to("path/to/action")
118 # response.should redirect_to("http://test.host/path/to/action")
119 # response.should redirect_to(:action => 'list')
120 def redirect_to(opts)
121 RedirectTo.new(request, opts)