Feb 14 2008
refresh_to plugin rspec matcher
We have been using the refresh_to plugin in one of our projects. For those who do not know, the refresh_to plugin adds a refresh_to method to the ActionController::Base which allows us to avoid the IE security warnings when moving from a secure SSL page to an insecure page.
We are using rspec for our testing and when I went to write some tests to test some code that uses the refresh_to method I found out that the standard redirect_to rspec matcher does not work with refresh_to. The same problem exist for the standard test method assert_response :redirect and assert_redirected_to my_url, but the plugin does supply replacement tests for these methods. The problem is that it does not supply a replacement for the rspec matcher so I had to write my own.
# The standard rspec redirect_to matcher does not work with the refresh_to
# plugin methods, i.e. refresh_to and refresh_back_or_default.
# This is also the case with the with the standard Rails functional
# tests - assert_response :redirect and assert_redirected_to my_url.
# The plugin has replacement test methods for these but they do not
# have an rspec replacement for redirect_to so I’ve had to write my own.
#
module Spec
module Rails
module Matchers
class RefreshTo #:nodoc:def initialize(controller, expected)
@expected = expected
@controller = controller
enddef matches?(response)
match_data = response.body.match(/<meta http-equiv="refresh" content="0;url=([\S]+)">/)
return false if (!match_data)
parts = match_data[1].split("http://test.host")
@actual = parts.last
return match()
end
def match
case @expected.class.to_s
when ‘String’
parts = @expected.split("http://test.host")
@expected = parts.last
return @actual == @expected
when ‘Hash’
@expected = @controller.url_for(@expected)
return match()
end
enddef failure_message
return %Q{expected redirect to #{@expected.inspect}, got redirect to #{@actual.inspect}}
enddef negative_failure_message
return %Q{expected not to be redirected to #{@expected.inspect}, but was}
enddef description
"redirect to #{@actual.inspect}"
end
end
# :call-seq:
# response.should refresh_to(url)
# response.should refresh_to(:action => action_name)
# response.should refresh_to(:controller => controller_name, :action => action_name)
# response.should_not refresh_to(url)
# response.should_not refresh_to(:action => action_name)
# response.should_not refresh_to(:controller => controller_name, :action => action_name)
#
# Passes if the response is a redirect to the url, action or controller/action.
# Useful in controller specs (integration or isolation mode).
#
# == Examples
#
# response.should refresh_to("path/to/action")
# response.should refresh_to("http://test.host/path/to/action")
# response.should refresh_to(:action => ‘list’)
def refresh_to(opts)
RefreshTo.new(controller, opts)
end
endend
end

