actionpack 1.8.1 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +309 -16
- data/README +1 -1
- data/lib/action_controller.rb +5 -0
- data/lib/action_controller/assertions.rb +57 -12
- data/lib/action_controller/auto_complete.rb +47 -0
- data/lib/action_controller/base.rb +288 -258
- data/lib/action_controller/benchmarking.rb +8 -3
- data/lib/action_controller/caching.rb +88 -42
- data/lib/action_controller/cgi_ext/cgi_ext.rb +1 -1
- data/lib/action_controller/cgi_ext/cgi_methods.rb +41 -11
- data/lib/action_controller/cgi_ext/multipart_progress.rb +169 -0
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +30 -12
- data/lib/action_controller/cgi_process.rb +39 -11
- data/lib/action_controller/code_generation.rb +235 -0
- data/lib/action_controller/cookies.rb +14 -8
- data/lib/action_controller/deprecated_renders_and_redirects.rb +76 -0
- data/lib/action_controller/filters.rb +8 -7
- data/lib/action_controller/helpers.rb +41 -6
- data/lib/action_controller/layout.rb +45 -16
- data/lib/action_controller/request.rb +86 -23
- data/lib/action_controller/rescue.rb +1 -0
- data/lib/action_controller/response.rb +1 -1
- data/lib/action_controller/routing.rb +536 -272
- data/lib/action_controller/scaffolding.rb +30 -25
- data/lib/action_controller/session/active_record_store.rb +251 -50
- data/lib/action_controller/streaming.rb +133 -0
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +0 -7
- data/lib/action_controller/templates/scaffolds/edit.rhtml +2 -2
- data/lib/action_controller/templates/scaffolds/layout.rhtml +22 -18
- data/lib/action_controller/templates/scaffolds/list.rhtml +3 -3
- data/lib/action_controller/templates/scaffolds/new.rhtml +2 -2
- data/lib/action_controller/templates/scaffolds/show.rhtml +1 -1
- data/lib/action_controller/test_process.rb +68 -47
- data/lib/action_controller/upload_progress.rb +421 -0
- data/lib/action_controller/url_rewriter.rb +8 -11
- data/lib/action_controller/vendor/html-scanner/html/document.rb +6 -5
- data/lib/action_controller/vendor/html-scanner/html/node.rb +70 -14
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +17 -10
- data/lib/action_controller/vendor/html-scanner/html/version.rb +3 -3
- data/lib/action_controller/vendor/xml_simple.rb +1019 -0
- data/lib/action_controller/verification.rb +36 -30
- data/lib/action_view/base.rb +21 -14
- data/lib/action_view/helpers/active_record_helper.rb +15 -13
- data/lib/action_view/helpers/asset_tag_helper.rb +26 -9
- data/lib/action_view/helpers/benchmark_helper.rb +24 -0
- data/lib/action_view/helpers/capture_helper.rb +7 -5
- data/lib/action_view/helpers/date_helper.rb +63 -46
- data/lib/action_view/helpers/form_helper.rb +7 -1
- data/lib/action_view/helpers/form_options_helper.rb +19 -11
- data/lib/action_view/helpers/form_tag_helper.rb +5 -1
- data/lib/action_view/helpers/javascript_helper.rb +403 -35
- data/lib/action_view/helpers/javascripts/controls.js +261 -0
- data/lib/action_view/helpers/javascripts/dragdrop.js +476 -0
- data/lib/action_view/helpers/javascripts/effects.js +570 -0
- data/lib/action_view/helpers/javascripts/prototype.js +633 -371
- data/lib/action_view/helpers/number_helper.rb +11 -13
- data/lib/action_view/helpers/tag_helper.rb +1 -2
- data/lib/action_view/helpers/text_helper.rb +69 -6
- data/lib/action_view/helpers/upload_progress_helper.rb +433 -0
- data/lib/action_view/helpers/url_helper.rb +98 -3
- data/lib/action_view/partials.rb +14 -8
- data/lib/action_view/vendor/builder/xmlmarkup.rb +11 -0
- data/rakefile +13 -5
- data/test/abstract_unit.rb +1 -1
- data/test/controller/action_pack_assertions_test.rb +52 -9
- data/test/controller/active_record_assertions_test.rb +119 -120
- data/test/controller/active_record_store_test.rb +111 -0
- data/test/controller/addresses_render_test.rb +45 -0
- data/test/controller/caching_filestore.rb +92 -0
- data/test/controller/capture_test.rb +39 -0
- data/test/controller/cgi_test.rb +40 -3
- data/test/controller/helper_test.rb +65 -13
- data/test/controller/multipart_progress_testx.rb +365 -0
- data/test/controller/new_render_test.rb +263 -0
- data/test/controller/redirect_test.rb +64 -0
- data/test/controller/render_test.rb +20 -21
- data/test/controller/request_test.rb +83 -3
- data/test/controller/routing_test.rb +702 -0
- data/test/controller/send_file_test.rb +2 -0
- data/test/controller/test_test.rb +44 -8
- data/test/controller/upload_progress_testx.rb +89 -0
- data/test/controller/verification_test.rb +94 -29
- data/test/fixtures/addresses/list.rhtml +1 -0
- data/test/fixtures/test/capturing.rhtml +4 -0
- data/test/fixtures/test/list.rhtml +1 -1
- data/test/fixtures/test/update_element_with_capture.rhtml +9 -0
- data/test/template/active_record_helper_test.rb +30 -15
- data/test/template/asset_tag_helper_test.rb +12 -5
- data/test/template/benchmark_helper_test.rb +72 -0
- data/test/template/date_helper_test.rb +69 -0
- data/test/template/form_helper_test.rb +18 -10
- data/test/template/form_options_helper_test.rb +40 -5
- data/test/template/javascript_helper.rb +149 -2
- data/test/template/number_helper_test.rb +2 -0
- data/test/template/tag_helper_test.rb +4 -0
- data/test/template/text_helper_test.rb +36 -0
- data/test/template/upload_progress_helper_testx.rb +272 -0
- data/test/template/url_helper_test.rb +30 -0
- metadata +30 -6
- data/test/controller/layout_test.rb +0 -49
- data/test/controller/routing_tests.rb +0 -543
@@ -0,0 +1,133 @@
|
|
1
|
+
module ActionController #:nodoc:
|
2
|
+
# Methods for sending files and streams to the browser instead of rendering.
|
3
|
+
module Streaming
|
4
|
+
DEFAULT_SEND_FILE_OPTIONS = {
|
5
|
+
:type => 'application/octet-stream'.freeze,
|
6
|
+
:disposition => 'attachment'.freeze,
|
7
|
+
:stream => true,
|
8
|
+
:buffer_size => 4096
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
protected
|
12
|
+
# Sends the file by streaming it 4096 bytes at a time. This way the
|
13
|
+
# whole file doesn't need to be read into memory at once. This makes
|
14
|
+
# it feasible to send even large files.
|
15
|
+
#
|
16
|
+
# Be careful to sanitize the path parameter if it coming from a web
|
17
|
+
# page. send_file(@params['path']) allows a malicious user to
|
18
|
+
# download any file on your server.
|
19
|
+
#
|
20
|
+
# Options:
|
21
|
+
# * <tt>:filename</tt> - suggests a filename for the browser to use.
|
22
|
+
# Defaults to File.basename(path).
|
23
|
+
# * <tt>:type</tt> - specifies an HTTP content type.
|
24
|
+
# Defaults to 'application/octet-stream'.
|
25
|
+
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
|
26
|
+
# Valid values are 'inline' and 'attachment' (default).
|
27
|
+
# * <tt>:stream</tt> - whether to send the file to the user agent as it is read (true)
|
28
|
+
# or to read the entire file before sending (false). Defaults to true.
|
29
|
+
# * <tt>:buffer_size</tt> - specifies size (in bytes) of the buffer used to stream the file.
|
30
|
+
# Defaults to 4096.
|
31
|
+
#
|
32
|
+
# The default Content-Type and Content-Disposition headers are
|
33
|
+
# set to download arbitrary binary files in as many browsers as
|
34
|
+
# possible. IE versions 4, 5, 5.5, and 6 are all known to have
|
35
|
+
# a variety of quirks (especially when downloading over SSL).
|
36
|
+
#
|
37
|
+
# Simple download:
|
38
|
+
# send_file '/path/to.zip'
|
39
|
+
#
|
40
|
+
# Show a JPEG in browser:
|
41
|
+
# send_file '/path/to.jpeg', :type => 'image/jpeg', :disposition => 'inline'
|
42
|
+
#
|
43
|
+
# Read about the other Content-* HTTP headers if you'd like to
|
44
|
+
# provide the user with more information (such as Content-Description).
|
45
|
+
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11
|
46
|
+
#
|
47
|
+
# Also be aware that the document may be cached by proxies and browsers.
|
48
|
+
# The Pragma and Cache-Control headers declare how the file may be cached
|
49
|
+
# by intermediaries. They default to require clients to validate with
|
50
|
+
# the server before releasing cached responses. See
|
51
|
+
# http://www.mnot.net/cache_docs/ for an overview of web caching and
|
52
|
+
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
|
53
|
+
# for the Cache-Control header spec.
|
54
|
+
def send_file(path, options = {}) #:doc:
|
55
|
+
raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)
|
56
|
+
|
57
|
+
options[:length] ||= File.size(path)
|
58
|
+
options[:filename] ||= File.basename(path)
|
59
|
+
send_file_headers! options
|
60
|
+
|
61
|
+
@performed_render = false
|
62
|
+
|
63
|
+
if options[:stream]
|
64
|
+
render :text => Proc.new {
|
65
|
+
logger.info "Streaming file #{path}" unless logger.nil?
|
66
|
+
len = options[:buffer_size] || 4096
|
67
|
+
File.open(path, 'rb') do |file|
|
68
|
+
if $stdout.respond_to?(:syswrite)
|
69
|
+
begin
|
70
|
+
while true
|
71
|
+
$stdout.syswrite file.sysread(len)
|
72
|
+
end
|
73
|
+
rescue EOFError
|
74
|
+
end
|
75
|
+
else
|
76
|
+
while buf = file.read(len)
|
77
|
+
$stdout.write buf
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
}
|
82
|
+
else
|
83
|
+
logger.info "Sending file #{path}" unless logger.nil?
|
84
|
+
File.open(path, 'rb') { |file| render :text => file.read }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Send binary data to the user as a file download. May set content type, apparent file name,
|
89
|
+
# and specify whether to show data inline or download as an attachment.
|
90
|
+
#
|
91
|
+
# Options:
|
92
|
+
# * <tt>:filename</tt> - Suggests a filename for the browser to use.
|
93
|
+
# * <tt>:type</tt> - specifies an HTTP content type.
|
94
|
+
# Defaults to 'application/octet-stream'.
|
95
|
+
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
|
96
|
+
# Valid values are 'inline' and 'attachment' (default).
|
97
|
+
#
|
98
|
+
# Generic data download:
|
99
|
+
# send_data buffer
|
100
|
+
#
|
101
|
+
# Download a dynamically-generated tarball:
|
102
|
+
# send_data generate_tgz('dir'), :filename => 'dir.tgz'
|
103
|
+
#
|
104
|
+
# Display an image Active Record in the browser:
|
105
|
+
# send_data image.data, :type => image.content_type, :disposition => 'inline'
|
106
|
+
#
|
107
|
+
# See +send_file+ for more information on HTTP Content-* headers and caching.
|
108
|
+
def send_data(data, options = {}) #:doc:
|
109
|
+
logger.info "Sending data #{options[:filename]}" unless logger.nil?
|
110
|
+
send_file_headers! options.merge(:length => data.size)
|
111
|
+
@performed_render = false
|
112
|
+
render :text => data
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
def send_file_headers!(options)
|
117
|
+
options.update(DEFAULT_SEND_FILE_OPTIONS.merge(options))
|
118
|
+
[:length, :type, :disposition].each do |arg|
|
119
|
+
raise ArgumentError, ":#{arg} option required" if options[arg].nil?
|
120
|
+
end
|
121
|
+
|
122
|
+
disposition = options[:disposition].dup || 'attachment'
|
123
|
+
disposition <<= %(; filename="#{options[:filename]}") if options[:filename]
|
124
|
+
|
125
|
+
@headers.update(
|
126
|
+
'Content-Length' => options[:length],
|
127
|
+
'Content-Type' => options[:type].strip, # fixes a problem with extra '\r' with some browsers
|
128
|
+
'Content-Disposition' => disposition,
|
129
|
+
'Content-Transfer-Encoding' => 'binary'
|
130
|
+
);
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -33,10 +33,6 @@
|
|
33
33
|
request_dump = request_parameters_without_action.inspect.gsub(/,/, ",\n")
|
34
34
|
session_dump = @request.session.instance_variable_get("@data").inspect.gsub(/,/, ",\n")
|
35
35
|
response_dump = @response.inspect.gsub(/,/, ",\n")
|
36
|
-
|
37
|
-
template_assigns = @response.template.instance_variable_get("@assigns")
|
38
|
-
%w( response exception template session request template_root template_class url ignore_missing_templates logger cookies headers params ).each { |t| template_assigns.delete(t) }
|
39
|
-
template_dump = template_assigns.inspect.gsub(/,/, ",\n")
|
40
36
|
%>
|
41
37
|
|
42
38
|
<h2 style="margin-top: 30px">Request</h2>
|
@@ -48,6 +44,3 @@
|
|
48
44
|
|
49
45
|
<h2 style="margin-top: 30px">Response</h2>
|
50
46
|
<b>Headers</b>: <%=h @response.headers.inspect.gsub(/,/, ",\n") %><br/>
|
51
|
-
|
52
|
-
<p><a href="#" onclick="document.getElementById('template_dump').style.display='block'; return false;">Show template parameters</a></p>
|
53
|
-
<div id="template_dump" style="display:none"><%= debug(template_assigns) %></div>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<h1>Editing <%= @scaffold_singular_name %></h1>
|
2
2
|
|
3
3
|
<%= error_messages_for(@scaffold_singular_name) %>
|
4
|
-
<%= form(@scaffold_singular_name, :action => "update
|
4
|
+
<%= form(@scaffold_singular_name, :action => "update#{@scaffold_suffix}") %>
|
5
5
|
|
6
|
-
<%= link_to "Show", :action => "show#{@scaffold_suffix}", :id => instance_variable_get("@#{@scaffold_singular_name}")
|
6
|
+
<%= link_to "Show", :action => "show#{@scaffold_suffix}", :id => instance_variable_get("@#{@scaffold_singular_name}") %> |
|
7
7
|
<%= link_to "Back", :action => "list#{@scaffold_suffix}" %>
|
@@ -1,3 +1,5 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/html4/loose.dtd">
|
1
3
|
<html>
|
2
4
|
<head>
|
3
5
|
<title>Scaffolding</title>
|
@@ -28,38 +30,40 @@
|
|
28
30
|
|
29
31
|
#ErrorExplanation {
|
30
32
|
width: 400px;
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
border: 2px solid 'red';
|
34
|
+
padding: 7px;
|
35
|
+
padding-bottom: 12px;
|
36
|
+
margin-bottom: 20px;
|
37
|
+
background-color: #f0f0f0;
|
36
38
|
}
|
37
39
|
|
38
40
|
#ErrorExplanation h2 {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
text-align: left;
|
42
|
+
font-weight: bold;
|
43
|
+
padding: 5px 5px 5px 15px;
|
44
|
+
font-size: 12px;
|
45
|
+
margin: -7px;
|
46
|
+
background-color: #c00;
|
47
|
+
color: #fff;
|
46
48
|
}
|
47
49
|
|
48
50
|
#ErrorExplanation p {
|
49
|
-
|
50
|
-
|
51
|
-
|
51
|
+
color: #333;
|
52
|
+
margin-bottom: 0;
|
53
|
+
padding: 5px;
|
52
54
|
}
|
53
55
|
|
54
56
|
#ErrorExplanation ul li {
|
55
|
-
|
56
|
-
|
57
|
+
font-size: 12px;
|
58
|
+
list-style: square;
|
57
59
|
}
|
58
60
|
</style>
|
59
61
|
</head>
|
60
62
|
<body>
|
61
63
|
|
64
|
+
<p style="color: green"><%= flash[:notice] %></p>
|
65
|
+
|
62
66
|
<%= @content_for_layout %>
|
63
67
|
|
64
68
|
</body>
|
65
|
-
</html>
|
69
|
+
</html>
|
@@ -12,9 +12,9 @@
|
|
12
12
|
<% for column in @scaffold_class.content_columns %>
|
13
13
|
<td><%= entry.send(column.name) %></td>
|
14
14
|
<% end %>
|
15
|
-
<td><%= link_to "Show", :action => "show#{@scaffold_suffix}", :id => entry
|
16
|
-
<td><%= link_to "Edit", :action => "edit#{@scaffold_suffix}", :id => entry
|
17
|
-
<td><%= link_to "Destroy", :action => "destroy#{@scaffold_suffix}", :id => entry
|
15
|
+
<td><%= link_to "Show", :action => "show#{@scaffold_suffix}", :id => entry %></td>
|
16
|
+
<td><%= link_to "Edit", :action => "edit#{@scaffold_suffix}", :id => entry %></td>
|
17
|
+
<td><%= link_to "Destroy", :action => "destroy#{@scaffold_suffix}", :id => entry, :confirm => "Are you sure?" %></td>
|
18
18
|
</tr>
|
19
19
|
<% end %>
|
20
20
|
</table>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<h1>New <%= @scaffold_singular_name %></h1>
|
2
2
|
|
3
3
|
<%= error_messages_for(@scaffold_singular_name) %>
|
4
|
-
<%= form(@scaffold_singular_name, :action => "create
|
4
|
+
<%= form(@scaffold_singular_name, :action => "create#{@scaffold_suffix}") %>
|
5
5
|
|
6
|
-
<%= link_to "Back", :action => "list#{@scaffold_suffix}" %>
|
6
|
+
<%= link_to "Back", :action => "list#{@scaffold_suffix}" %>
|
@@ -5,5 +5,5 @@
|
|
5
5
|
</p>
|
6
6
|
<% end %>
|
7
7
|
|
8
|
-
<%= link_to "Edit", :action => "edit#{@scaffold_suffix}", :id => instance_variable_get("@#{@scaffold_singular_name}")
|
8
|
+
<%= link_to "Edit", :action => "edit#{@scaffold_suffix}", :id => instance_variable_get("@#{@scaffold_singular_name}") %> |
|
9
9
|
<%= link_to "Back", :action => "list#{@scaffold_suffix}" %>
|
@@ -1,29 +1,13 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/assertions'
|
2
2
|
require File.dirname(__FILE__) + '/deprecated_assertions'
|
3
3
|
|
4
|
-
if defined?(RAILS_ROOT)
|
5
|
-
# Temporary hack for getting functional tests in Rails running under 1.8.2
|
6
|
-
class Object #:nodoc:
|
7
|
-
alias_method :require_without_load_path_reloading, :require
|
8
|
-
def require(file_name)
|
9
|
-
begin
|
10
|
-
require_without_load_path_reloading(file_name)
|
11
|
-
rescue Object => e
|
12
|
-
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) }
|
13
|
-
require_without_load_path_reloading(file_name)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
|
20
4
|
module ActionController #:nodoc:
|
21
5
|
class Base
|
22
6
|
# Process a test request called with a +TestRequest+ object.
|
23
7
|
def self.process_test(request)
|
24
8
|
new.process_test(request)
|
25
9
|
end
|
26
|
-
|
10
|
+
|
27
11
|
def process_test(request) #:nodoc:
|
28
12
|
process(request, TestResponse.new)
|
29
13
|
end
|
@@ -32,13 +16,13 @@ module ActionController #:nodoc:
|
|
32
16
|
class TestRequest < AbstractRequest #:nodoc:
|
33
17
|
attr_accessor :cookies
|
34
18
|
attr_accessor :query_parameters, :request_parameters, :path, :session, :env
|
35
|
-
attr_accessor :host
|
19
|
+
attr_accessor :host
|
36
20
|
|
37
21
|
def initialize(query_parameters = nil, request_parameters = nil, session = nil)
|
38
22
|
@query_parameters = query_parameters || {}
|
39
23
|
@request_parameters = request_parameters || {}
|
40
24
|
@session = session || TestSession.new
|
41
|
-
|
25
|
+
|
42
26
|
initialize_containers
|
43
27
|
initialize_default_values
|
44
28
|
|
@@ -47,8 +31,8 @@ module ActionController #:nodoc:
|
|
47
31
|
|
48
32
|
def reset_session
|
49
33
|
@session = {}
|
50
|
-
end
|
51
|
-
|
34
|
+
end
|
35
|
+
|
52
36
|
def port=(number)
|
53
37
|
@env["SERVER_PORT"] = number.to_i
|
54
38
|
end
|
@@ -57,7 +41,7 @@ module ActionController #:nodoc:
|
|
57
41
|
@query_parameters.update({ "action" => action_name })
|
58
42
|
@parameters = nil
|
59
43
|
end
|
60
|
-
|
44
|
+
|
61
45
|
# Used to check AbstractRequest's request_uri functionality.
|
62
46
|
# Disables the use of @path and @request_uri so superclass can handle those.
|
63
47
|
def set_REQUEST_URI(value)
|
@@ -71,6 +55,10 @@ module ActionController #:nodoc:
|
|
71
55
|
@path = uri.split("?").first
|
72
56
|
end
|
73
57
|
|
58
|
+
def remote_addr=(addr)
|
59
|
+
@env['REMOTE_ADDR'] = addr
|
60
|
+
end
|
61
|
+
|
74
62
|
def request_uri
|
75
63
|
@request_uri || super()
|
76
64
|
end
|
@@ -78,27 +66,45 @@ module ActionController #:nodoc:
|
|
78
66
|
def path
|
79
67
|
@path || super()
|
80
68
|
end
|
69
|
+
|
70
|
+
def assign_parameters(controller_path, action, parameters)
|
71
|
+
parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action)
|
72
|
+
extra_keys = ActionController::Routing::Routes.extra_keys(parameters)
|
73
|
+
non_path_parameters = get? ? query_parameters : request_parameters
|
74
|
+
parameters.each do |key, value|
|
75
|
+
if extra_keys.include?(key.to_sym)
|
76
|
+
non_path_parameters[key] = value
|
77
|
+
else
|
78
|
+
path_parameters[key] = value.to_s
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
81
82
|
|
83
|
+
def recycle!
|
84
|
+
self.request_parameters = {}
|
85
|
+
self.query_parameters = {}
|
86
|
+
self.path_parameters = {}
|
87
|
+
end
|
82
88
|
|
83
89
|
private
|
84
90
|
def initialize_containers
|
85
91
|
@env, @cookies = {}, {}
|
86
92
|
end
|
87
|
-
|
93
|
+
|
88
94
|
def initialize_default_values
|
89
95
|
@host = "test.host"
|
90
96
|
@request_uri = "/"
|
91
|
-
|
97
|
+
self.remote_addr = "0.0.0.0"
|
92
98
|
@env["SERVER_PORT"] = 80
|
93
99
|
end
|
94
100
|
end
|
95
|
-
|
101
|
+
|
96
102
|
class TestResponse < AbstractResponse #:nodoc:
|
97
103
|
# the response code of the request
|
98
104
|
def response_code
|
99
105
|
headers['Status'][0,3].to_i rescue 0
|
100
106
|
end
|
101
|
-
|
107
|
+
|
102
108
|
# was the response successful?
|
103
109
|
def success?
|
104
110
|
response_code == 200
|
@@ -113,7 +119,7 @@ module ActionController #:nodoc:
|
|
113
119
|
def redirect?
|
114
120
|
(300..399).include?(response_code)
|
115
121
|
end
|
116
|
-
|
122
|
+
|
117
123
|
# was there a server-side error?
|
118
124
|
def error?
|
119
125
|
(500..599).include?(response_code)
|
@@ -125,7 +131,7 @@ module ActionController #:nodoc:
|
|
125
131
|
def redirect_url
|
126
132
|
redirect? ? headers['location'] : nil
|
127
133
|
end
|
128
|
-
|
134
|
+
|
129
135
|
# does the redirect location match this regexp pattern?
|
130
136
|
def redirect_url_match?( pattern )
|
131
137
|
return false if redirect_url.nil?
|
@@ -134,7 +140,7 @@ module ActionController #:nodoc:
|
|
134
140
|
return false if p.nil?
|
135
141
|
p.match(redirect_url) != nil
|
136
142
|
end
|
137
|
-
|
143
|
+
|
138
144
|
# returns the template path of the file which was used to
|
139
145
|
# render this response (or nil)
|
140
146
|
def rendered_file(with_controller=false)
|
@@ -156,7 +162,7 @@ module ActionController #:nodoc:
|
|
156
162
|
def flash
|
157
163
|
session['flash'] || {}
|
158
164
|
end
|
159
|
-
|
165
|
+
|
160
166
|
# do we have a flash?
|
161
167
|
def has_flash?
|
162
168
|
!session['flash'].empty?
|
@@ -181,12 +187,12 @@ module ActionController #:nodoc:
|
|
181
187
|
def template_objects
|
182
188
|
template.assigns || {}
|
183
189
|
end
|
184
|
-
|
190
|
+
|
185
191
|
# does the specified template object exist?
|
186
192
|
def has_template_object?(name=nil)
|
187
193
|
!template_objects[name].nil?
|
188
194
|
end
|
189
|
-
|
195
|
+
|
190
196
|
# Returns the response cookies, converted to a Hash of (name => CGI::Cookie) pairs
|
191
197
|
# Example:
|
192
198
|
#
|
@@ -226,11 +232,11 @@ end
|
|
226
232
|
def []=(key, value)
|
227
233
|
@attributes[key] = value
|
228
234
|
end
|
229
|
-
|
235
|
+
|
230
236
|
def session_id
|
231
237
|
""
|
232
238
|
end
|
233
|
-
|
239
|
+
|
234
240
|
def update() end
|
235
241
|
def close() end
|
236
242
|
def delete() @attributes = {} end
|
@@ -243,18 +249,26 @@ module Test
|
|
243
249
|
private
|
244
250
|
# execute the request and set/volley the response
|
245
251
|
def process(action, parameters = nil, session = nil, flash = nil)
|
252
|
+
@request.recycle!
|
253
|
+
|
254
|
+
# Sanity check for required instance variables so we can give an understandable error message.
|
255
|
+
%w(controller request response).each do |iv_name|
|
256
|
+
assert_not_nil instance_variable_get("@#{iv_name}"), "@#{iv_name} is nil: make sure you set it in your test's setup method."
|
257
|
+
end
|
258
|
+
|
246
259
|
@html_document = nil
|
247
260
|
@request.env['REQUEST_METHOD'] ||= "GET"
|
248
261
|
@request.action = action.to_s
|
249
|
-
|
250
|
-
|
251
|
-
@request.
|
262
|
+
|
263
|
+
parameters ||= {}
|
264
|
+
@request.assign_parameters(@controller.class.controller_path, action.to_s, parameters)
|
265
|
+
|
252
266
|
@request.session = ActionController::TestSession.new(session) unless session.nil?
|
253
267
|
@request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash
|
254
268
|
build_request_uri(action, parameters)
|
255
269
|
@controller.process(@request, @response)
|
256
270
|
end
|
257
|
-
|
271
|
+
|
258
272
|
# execute the request simulating a specific http method and set/volley the response
|
259
273
|
%w( get post put delete head ).each do |method|
|
260
274
|
class_eval <<-EOV
|
@@ -275,7 +289,7 @@ module Test
|
|
275
289
|
if @response.redirected_to[:controller]
|
276
290
|
raise "Can't follow redirects outside of current controller (#{@response.redirected_to[:controller]})"
|
277
291
|
end
|
278
|
-
|
292
|
+
|
279
293
|
get(@response.redirected_to.delete(:action), @response.redirected_to.stringify_keys)
|
280
294
|
end
|
281
295
|
|
@@ -286,7 +300,7 @@ module Test
|
|
286
300
|
@response.template.assigns[key.to_s]
|
287
301
|
end
|
288
302
|
end
|
289
|
-
|
303
|
+
|
290
304
|
def session
|
291
305
|
@response.session
|
292
306
|
end
|
@@ -304,18 +318,20 @@ module Test
|
|
304
318
|
end
|
305
319
|
|
306
320
|
def build_request_uri(action, parameters)
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
321
|
+
unless @request.env['REQUEST_URI']
|
322
|
+
options = @controller.send(:rewrite_options, parameters)
|
323
|
+
options.update(:only_path => true, :action => action)
|
324
|
+
|
325
|
+
url = ActionController::UrlRewriter.new(@request, parameters)
|
326
|
+
@request.set_REQUEST_URI(url.rewrite(options))
|
327
|
+
end
|
312
328
|
end
|
313
329
|
|
314
330
|
def html_document
|
315
331
|
require_html_scanner
|
316
332
|
@html_document ||= HTML::Document.new(@response.body)
|
317
333
|
end
|
318
|
-
|
334
|
+
|
319
335
|
def find_tag(conditions)
|
320
336
|
html_document.find(conditions)
|
321
337
|
end
|
@@ -331,6 +347,11 @@ module Test
|
|
331
347
|
$:.unshift File.dirname(__FILE__) + "/vendor/html-scanner"
|
332
348
|
require 'html/document'
|
333
349
|
end
|
334
|
-
|
350
|
+
|
351
|
+
def method_missing(selector, *args)
|
352
|
+
return @controller.send(selector, *args) if ActionController::Routing::NamedRoutes::Helpers.include?(selector)
|
353
|
+
return super
|
354
|
+
end
|
355
|
+
end
|
335
356
|
end
|
336
357
|
end
|