Updated to latest rspec
[gitorious:georgyos-clone.git] / vendor / plugins / rspec-rails / lib / spec / rails / matchers / redirect_to.rb
1 module Spec
2   module Rails
3     module Matchers
4
5       class RedirectTo  #:nodoc:
6
7         def initialize(request, expected)
8           @expected = expected
9           @request = request
10         end
11
12         def matches?(response)
13           @redirected = response.redirect?
14           @actual = response.redirect_url
15           return false unless @redirected
16           if @expected.instance_of? Hash
17             return false unless @actual =~ %r{^\w+://#{@request.host}}
18             return false unless actual_redirect_to_valid_route
19             return actual_hash == expected_hash
20           else
21             return @actual == expected_url
22           end
23         end
24
25         def actual_hash
26           hash_from_url @actual
27         end
28
29         def expected_hash
30           hash_from_url expected_url
31         end
32
33         def actual_redirect_to_valid_route
34           actual_hash
35         end
36
37         def hash_from_url(url)
38           query_hash(url).merge(path_hash(url)).with_indifferent_access
39         end
40
41         def path_hash(url)
42           path = url.sub(%r{^\w+://#{@request.host}(?::\d+)?}, "").split("?", 2)[0]
43           ActionController::Routing::Routes.recognize_path path
44         end
45
46         def query_hash(url)
47           query = url.split("?", 2)[1] || ""
48           QueryParameterParser.parse_query_parameters(query, @request)
49         end
50
51        def expected_url
52           case @expected
53             when Hash
54               return ActionController::UrlRewriter.new(@request, {}).rewrite(@expected)
55             when :back
56               return @request.env['HTTP_REFERER']
57             when %r{^\w+://.*}
58               return @expected
59             else
60               return "http://#{@request.host}" + (@expected.split('')[0] == '/' ? '' : '/') + @expected
61           end
62         end
63
64         def failure_message
65           if @redirected
66             return %Q{expected redirect to #{@expected.inspect}, got redirect to #{@actual.inspect}}
67           else
68             return %Q{expected redirect to #{@expected.inspect}, got no redirect}
69           end
70         end
71
72         def negative_failure_message
73             return %Q{expected not to be redirected to #{@expected.inspect}, but was} if @redirected
74         end
75
76         def description
77           "redirect to #{@actual.inspect}"
78         end
79
80         class QueryParameterParser
81           def self.parse_query_parameters(query, request)
82             if defined?(CGIMethods)
83               CGIMethods.parse_query_parameters(query)
84             else
85               request.class.parse_query_parameters(query)
86             end
87           end
88         end
89       end
90
91       # :call-seq:
92       #   response.should redirect_to(url)
93       #   response.should redirect_to(:action => action_name)
94       #   response.should redirect_to(:controller => controller_name, :action => action_name)
95       #   response.should_not redirect_to(url)
96       #   response.should_not redirect_to(:action => action_name)
97       #   response.should_not redirect_to(:controller => controller_name, :action => action_name)
98       #
99       # Passes if the response is a redirect to the url, action or controller/action.
100       # Useful in controller specs (integration or isolation mode).
101       #
102       # == Examples
103       #
104       #   response.should redirect_to("path/to/action")
105       #   response.should redirect_to("http://test.host/path/to/action")
106       #   response.should redirect_to(:action => 'list')
107       def redirect_to(opts)
108         RedirectTo.new(request, opts)
109       end
110     end
111
112   end
113 end