Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 671 lines (585 sloc) 22.605 kB
eab7120 @jeremy Performance: integration test benchmarking and profiling. [Jeremy Ke…
jeremy authored
1 require 'stringio'
2 require 'uri'
89978f1 @fxn moves Object#singleton_class to Kernel#singleton_class to match Ruby …
fxn authored
3 require 'active_support/core_ext/kernel/singleton_class'
4f7565c @fxn adds missing requires for Object#try
fxn authored
4 require 'active_support/core_ext/object/try'
3a20e83 @sikachu Add missing require for String#strip_heredoc
sikachu authored
5 require 'active_support/core_ext/string/strip'
ee395fe @josh TestProcess belongs in AD
josh authored
6 require 'rack/test'
4efb36e @spastorino Revert "Merge pull request #15305 from tgxworld/remove_unnecessary_re…
spastorino authored
7 require 'minitest'
4a55d1d @josh Move integration test runner into ActionDispatch
josh authored
8
9 module ActionDispatch
dfd953e @dhh Fixed docs
dhh authored
10 module Integration #:nodoc:
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
11 module RequestHelpers
12 # Performs a GET request with the given parameters.
13 #
14 # - +path+: The URI (as a String) on which you want to perform a GET
15 # request.
7814f90 @rafaelfranca Use fixed fonts only in the name of the parameter
rafaelfranca authored
16 # - +params+: The HTTP parameters that you want to pass. This may
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
17 # be +nil+,
18 # a Hash, or a String that is appropriately encoded
19 # (<tt>application/x-www-form-urlencoded</tt> or
20 # <tt>multipart/form-data</tt>).
7814f90 @rafaelfranca Use fixed fonts only in the name of the parameter
rafaelfranca authored
21 # - +headers+: Additional headers to pass, as a Hash. The headers will be
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
22 # merged into the Rack env hash.
7814f90 @rafaelfranca Use fixed fonts only in the name of the parameter
rafaelfranca authored
23 # - +env+: Additional env to pass, as a Hash. The headers will be
17eedd8 @Vaysman references to the old behavior removed
Vaysman authored
24 # merged into the Rack env hash.
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
25 #
dc69220 @robin850 Fix a typo
robin850 authored
26 # This method returns a Response object, which one can use to
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
27 # inspect the details of the response. Furthermore, if this method was
4a55d1d @josh Move integration test runner into ActionDispatch
josh authored
28 # called from an ActionDispatch::IntegrationTest object, then that
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
29 # object's <tt>@response</tt> instance variable will point to the same
30 # response object.
31 #
002713c @dlee Add config.default_method_for_update to support PATCH
dlee authored
32 # You can also perform POST, PATCH, PUT, DELETE, and HEAD requests with
33 # +#post+, +#patch+, +#put+, +#delete+, and +#head+.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
34 #
35 # Example:
36 #
37 # get '/feed', params: { since: 201501011400 }
bb6fe7e @rafaelfranca Consistent usage of spaces in hashes across our codebase
rafaelfranca authored
38 # post '/profile', headers: { "X-Test-Header" => "testvalue" }
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
39 def get(path, *args)
40 process_with_kwargs(:get, path, *args)
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
41 end
42
07054fe @jfirebaugh Fix grammar, formatting, and cross references
jfirebaugh authored
43 # Performs a POST request with the given parameters. See +#get+ for more
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
44 # details.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
45 def post(path, *args)
46 process_with_kwargs(:post, path, *args)
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
47 end
48
002713c @dlee Add config.default_method_for_update to support PATCH
dlee authored
49 # Performs a PATCH request with the given parameters. See +#get+ for more
50 # details.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
51 def patch(path, *args)
52 process_with_kwargs(:patch, path, *args)
002713c @dlee Add config.default_method_for_update to support PATCH
dlee authored
53 end
54
07054fe @jfirebaugh Fix grammar, formatting, and cross references
jfirebaugh authored
55 # Performs a PUT request with the given parameters. See +#get+ for more
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
56 # details.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
57 def put(path, *args)
58 process_with_kwargs(:put, path, *args)
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
59 end
60
07054fe @jfirebaugh Fix grammar, formatting, and cross references
jfirebaugh authored
61 # Performs a DELETE request with the given parameters. See +#get+ for
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
62 # more details.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
63 def delete(path, *args)
64 process_with_kwargs(:delete, path, *args)
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
65 end
66
07054fe @jfirebaugh Fix grammar, formatting, and cross references
jfirebaugh authored
67 # Performs a HEAD request with the given parameters. See +#get+ for more
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
68 # details.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
69 def head(path, *args)
70 process_with_kwargs(:head, path, *args)
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
71 end
72
73 # Performs an XMLHttpRequest request with the given parameters, mirroring
74 # a request from the Prototype library.
75 #
002713c @dlee Add config.default_method_for_update to support PATCH
dlee authored
76 # The request_method is +:get+, +:post+, +:patch+, +:put+, +:delete+ or
77 # +:head+; the parameters are +nil+, a hash, or a url-encoded or multipart
17eedd8 @Vaysman references to the old behavior removed
Vaysman authored
78 # string; the headers are a hash.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
79 #
80 # Example:
81 #
82 # xhr :get, '/feed', params: { since: 201501011400 }
83 def xml_http_request(request_method, path, *args)
e260975 @eileencodes Use `args` instead of `*args` in `kwargs_request?` method
eileencodes authored
84 if kwarg_request?(args)
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
85 params, headers, env = args.first.values_at(:params, :headers, :env)
86 else
87 params = args[0]
88 headers = args[1]
89 env = {}
90
91 if params.present? || headers.present?
92 non_kwarg_request_warning
93 end
94 end
95
b19999f @kirs Migrating xhr methods to keyword arguments syntax
kirs authored
96 ActiveSupport::Deprecation.warn(<<-MSG.strip_heredoc)
97 xhr and xml_http_request methods are deprecated in favor of
98 `get "/posts", xhr: true` and `post "/posts/1", xhr: true`
99 MSG
100
101 process(request_method, path, params: params, headers: headers, xhr: true)
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
102 end
103 alias xhr :xml_http_request
104
105 # Follow a single redirect response. If the last response was not a
106 # redirect, an exception will be raised. Otherwise, the redirect is
107 # performed on the location header.
108 def follow_redirect!
109 raise "not a redirect! #{status} #{status_message}" unless redirect?
110 get(response.location)
111 status
112 end
113
114 # Performs a request using the specified method, following any subsequent
115 # redirect. Note that the redirects are followed until the response is
116 # not a redirect--this means you may run into an infinite loop if your
117 # redirect loops back to itself.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
118 #
119 # Example:
120 #
121 # request_via_redirect :post, '/welcome',
122 # params: { ref_id: 14 },
bb6fe7e @rafaelfranca Consistent usage of spaces in hashes across our codebase
rafaelfranca authored
123 # headers: { "X-Test-Header" => "testvalue" }
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
124 def request_via_redirect(http_method, path, *args)
125 process_with_kwargs(http_method, path, *args)
126
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
127 follow_redirect! while redirect?
128 status
129 end
130
131 # Performs a GET request, following any subsequent redirect.
132 # See +request_via_redirect+ for more information.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
133 def get_via_redirect(path, *args)
751f752 @aditya-kapoor Deprecate *_via_redirect integration test methods
aditya-kapoor authored
134 ActiveSupport::Deprecation.warn('`get_via_redirect` is deprecated and will be removed in the next version of Rails. Please use follow_redirect! manually after the request call for the same behavior.')
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
135 request_via_redirect(:get, path, *args)
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
136 end
137
138 # Performs a POST request, following any subsequent redirect.
139 # See +request_via_redirect+ for more information.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
140 def post_via_redirect(path, *args)
751f752 @aditya-kapoor Deprecate *_via_redirect integration test methods
aditya-kapoor authored
141 ActiveSupport::Deprecation.warn('`post_via_redirect` is deprecated and will be removed in the next version of Rails. Please use follow_redirect! manually after the request call for the same behavior.')
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
142 request_via_redirect(:post, path, *args)
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
143 end
144
002713c @dlee Add config.default_method_for_update to support PATCH
dlee authored
145 # Performs a PATCH request, following any subsequent redirect.
146 # See +request_via_redirect+ for more information.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
147 def patch_via_redirect(path, *args)
751f752 @aditya-kapoor Deprecate *_via_redirect integration test methods
aditya-kapoor authored
148 ActiveSupport::Deprecation.warn('`patch_via_redirect` is deprecated and will be removed in the next version of Rails. Please use follow_redirect! manually after the request call for the same behavior.')
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
149 request_via_redirect(:patch, path, *args)
002713c @dlee Add config.default_method_for_update to support PATCH
dlee authored
150 end
151
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
152 # Performs a PUT request, following any subsequent redirect.
153 # See +request_via_redirect+ for more information.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
154 def put_via_redirect(path, *args)
751f752 @aditya-kapoor Deprecate *_via_redirect integration test methods
aditya-kapoor authored
155 ActiveSupport::Deprecation.warn('`put_via_redirect` is deprecated and will be removed in the next version of Rails. Please use follow_redirect! manually after the request call for the same behavior.')
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
156 request_via_redirect(:put, path, *args)
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
157 end
158
159 # Performs a DELETE request, following any subsequent redirect.
160 # See +request_via_redirect+ for more information.
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
161 def delete_via_redirect(path, *args)
751f752 @aditya-kapoor Deprecate *_via_redirect integration test methods
aditya-kapoor authored
162 ActiveSupport::Deprecation.warn('`delete_via_redirect` is deprecated and will be removed in the next version of Rails. Please use follow_redirect! manually after the request call for the same behavior.')
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
163 request_via_redirect(:delete, path, *args)
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
164 end
165 end
166
591e87f @tilsammans Expanded routing documentation with current best practices
tilsammans authored
167 # An instance of this class represents a set of requests and responses
168 # performed sequentially by a test process. Because you can instantiate
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
169 # multiple sessions and run them side-by-side, you can also mimic (to some
170 # limited extent) multiple simultaneous users interacting with your system.
171 #
ebec9d4 @josh Make integration test runner more Rack friendly and clean out old CGI…
josh authored
172 # Typically, you will instantiate a new session using
173 # IntegrationTest#open_session, rather than instantiating
174 # Integration::Session directly.
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
175 class Session
0029d5e @brynary Integrating Rack::MockSession (from Rack::Test)
brynary authored
176 DEFAULT_HOST = "www.example.com"
177
7bae292 @vipulnsward Change all `MiniTest` to `Minitest` since, `MiniTest` namespace has b…
vipulnsward authored
178 include Minitest::Assertions
ee395fe @josh TestProcess belongs in AD
josh authored
179 include TestProcess, RequestHelpers, Assertions
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
180
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
181 %w( status status_message headers body redirect? ).each do |method|
182 delegate method, :to => :response, :allow_nil => true
183 end
5b5d0e3 @josh Use Rack::Head middleware to ensure the body is discarded for HEAD re…
josh authored
184
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
185 %w( path ).each do |method|
186 delegate method, :to => :request, :allow_nil => true
187 end
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
188
189 # The hostname used in the last request.
570c54c @josh Fix cookie access in integration tests with other host names
josh authored
190 def host
191 @host || DEFAULT_HOST
192 end
193 attr_writer :host
fe94ba1 @dhh Added access to remote_addr in integration tests (closes #4266) [Chad…
dhh authored
194
195 # The remote_addr used in the last request.
196 attr_accessor :remote_addr
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
197
9d7de52 @jamis Add Integration::Session.accept for setting the HTTP Accept header to…
jamis authored
198 # The Accept header to send.
199 attr_accessor :accept
200
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
201 # A map of the cookies returned by the last response, and which will be
202 # sent with the next request.
0029d5e @brynary Integrating Rack::MockSession (from Rack::Test)
brynary authored
203 def cookies
570c54c @josh Fix cookie access in integration tests with other host names
josh authored
204 _mock_session.cookie_jar
0029d5e @brynary Integrating Rack::MockSession (from Rack::Test)
brynary authored
205 end
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
206
207 # A reference to the controller instance used by the last request.
208 attr_reader :controller
209
210 # A reference to the request instance used by the last request.
211 attr_reader :request
212
213 # A reference to the response instance used by the last request.
214 attr_reader :response
215
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
216 # A running counter of the number of requests processed.
217 attr_accessor :request_count
218
0508318 If IntegrationSession is initialized with an objects that responds to…
Carlhuda authored
219 include ActionDispatch::Routing::UrlFor
220
98dc582 @lifo Merge docrails.
lifo authored
221 # Create and initialize a new Session instance.
acfeec5 @josh Allow integration test rack app to be set with "@app" ivar instead of…
josh authored
222 def initialize(app)
b1ae796 @josevalim Fix an error on 1.8.7.
josevalim authored
223 super()
acfeec5 @josh Allow integration test rack app to be set with "@app" ivar instead of…
josh authored
224 @app = app
0508318 If IntegrationSession is initialized with an objects that responds to…
Carlhuda authored
225
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
226 reset!
227 end
228
e306ca3 @pixeltrix Refactor the handling of default_url_options in integration tests
pixeltrix authored
229 def url_options
230 @url_options ||= default_url_options.dup.tap do |url_options|
231 url_options.reverse_merge!(controller.url_options) if controller
232
1ae9f05 @tenderlove routed applications will respond to these methods
tenderlove authored
233 if @app.respond_to?(:routes)
e306ca3 @pixeltrix Refactor the handling of default_url_options in integration tests
pixeltrix authored
234 url_options.reverse_merge!(@app.routes.default_url_options)
235 end
236
237 url_options.reverse_merge!(:host => host, :protocol => https? ? "https" : "http")
238 end
0508318 If IntegrationSession is initialized with an objects that responds to…
Carlhuda authored
239 end
240
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
241 # Resets the instance. This can be used to reset the state information
242 # in an existing session instance, so it can be used from a clean-slate
243 # condition.
244 #
245 # session.reset!
246 def reset!
247 @https = false
248 @controller = @request = @response = nil
570c54c @josh Fix cookie access in integration tests with other host names
josh authored
249 @_mock_session = nil
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
250 @request_count = 0
e306ca3 @pixeltrix Refactor the handling of default_url_options in integration tests
pixeltrix authored
251 @url_options = nil
d1c957d @jeremy Integration tests: alias xhr to xml_http_request and add a request_me…
jeremy authored
252
0029d5e @brynary Integrating Rack::MockSession (from Rack::Test)
brynary authored
253 self.host = DEFAULT_HOST
fe94ba1 @dhh Added access to remote_addr in integration tests (closes #4266) [Chad…
dhh authored
254 self.remote_addr = "127.0.0.1"
ebec9d4 @josh Make integration test runner more Rack friendly and clean out old CGI…
josh authored
255 self.accept = "text/xml,application/xml,application/xhtml+xml," +
256 "text/html;q=0.9,text/plain;q=0.8,image/png," +
257 "*/*;q=0.5"
0fbe683 @jamis more integration tweaks
jamis authored
258
0eacdcf @jeremy Use a consistent load path to avoid double requires. Fix some scatter…
jeremy authored
259 unless defined? @named_routes_configured
0fbe683 @jamis more integration tweaks
jamis authored
260 # the helpers are made protected by default--we make them public for
261 # easier access during testing and troubleshooting.
262 @named_routes_configured = true
263 end
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
264 end
265
266 # Specify whether or not the session should mimic a secure HTTPS request.
267 #
268 # session.https!
269 # session.https!(false)
ebec9d4 @josh Make integration test runner more Rack friendly and clean out old CGI…
josh authored
270 def https!(flag = true)
d1c957d @jeremy Integration tests: alias xhr to xml_http_request and add a request_me…
jeremy authored
271 @https = flag
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
272 end
273
b1b9a0a @laurocaetano Typos. return -> returns. [ci skip]
laurocaetano authored
274 # Returns +true+ if the session is mimicking a secure HTTPS request.
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
275 #
276 # if session.https?
277 # ...
278 # end
279 def https?
280 @https
281 end
282
283 # Set the host name to use in the next request.
284 #
9326222 @dhh Use example.com as standard (closes #4413) [anna]
dhh authored
285 # session.host! "www.example.com"
831a234 @tenderlove just use alias
tenderlove authored
286 alias :host! :host=
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
287
288 private
570c54c @josh Fix cookie access in integration tests with other host names
josh authored
289 def _mock_session
290 @_mock_session ||= Rack::MockSession.new(@app, host)
291 end
0029d5e @brynary Integrating Rack::MockSession (from Rack::Test)
brynary authored
292
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
293 def process_with_kwargs(http_method, path, *args)
e260975 @eileencodes Use `args` instead of `*args` in `kwargs_request?` method
eileencodes authored
294 if kwarg_request?(args)
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
295 process(http_method, path, *args)
296 else
f6b01c1 @eileencodes Use `any?` rather than `present?` to check args
eileencodes authored
297 non_kwarg_request_warning if args.any?
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
298 process(http_method, path, { params: args[0], headers: args[1] })
299 end
300 end
301
b19999f @kirs Migrating xhr methods to keyword arguments syntax
kirs authored
302 REQUEST_KWARGS = %i(params headers env xhr)
e260975 @eileencodes Use `args` instead of `*args` in `kwargs_request?` method
eileencodes authored
303 def kwarg_request?(args)
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
304 args[0].respond_to?(:keys) && args[0].keys.any? { |k| REQUEST_KWARGS.include?(k) }
305 end
306
307 def non_kwarg_request_warning
308 ActiveSupport::Deprecation.warn(<<-MSG.strip_heredoc)
899e10f @tgxworld Correct module name in deprecation message.
tgxworld authored
309 ActionDispatch::IntegrationTest HTTP request methods will accept only
aca4c82 @tgxworld Improve deprecation message.
tgxworld authored
310 the following keyword arguments in future Rails versions:
311 #{REQUEST_KWARGS.join(', ')}
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
312
313 Examples:
314
315 get '/profile',
316 params: { id: 1 },
317 headers: { 'X-Extra-Header' => '123' },
6213332 @arthurnn Add missing comma
arthurnn authored
318 env: { 'action_dispatch.custom' => 'custom' },
aca4c82 @tgxworld Improve deprecation message.
tgxworld authored
319 xhr: true
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
320 MSG
321 end
322
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
323 # Performs the actual request.
b19999f @kirs Migrating xhr methods to keyword arguments syntax
kirs authored
324 def process(method, path, params: nil, headers: nil, env: nil, xhr: false)
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
325 if path =~ %r{://}
326 location = URI.parse(path)
327 https! URI::HTTPS === location if location.scheme
b28fc68 @pixeltrix Ensure port is set when passed via the process method
pixeltrix authored
328 host! "#{location.host}:#{location.port}" if location.host
9bac470 @josh Group integration test helpers and delegate other helpers to request …
josh authored
329 path = location.query ? "#{location.path}?#{location.query}" : location.path
330 end
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
331
29f13be @spastorino port is appended twice to HTTP_HOST when host already has the port
spastorino authored
332 hostname, port = host.split(':')
de9b338 @tenderlove fixing bug with rails use of rack-test
tenderlove authored
333
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
334 request_env = {
00d1a57 @josh Start moving TestRequest and TestResponse into ActionDispatch
josh authored
335 :method => method,
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
336 :params => params,
ebec9d4 @josh Make integration test runner more Rack friendly and clean out old CGI…
josh authored
337
29f13be @spastorino port is appended twice to HTTP_HOST when host already has the port
spastorino authored
338 "SERVER_NAME" => hostname,
56de4e9 @spastorino Fix the precedence issue here
spastorino authored
339 "SERVER_PORT" => port || (https? ? "443" : "80"),
ebec9d4 @josh Make integration test runner more Rack friendly and clean out old CGI…
josh authored
340 "HTTPS" => https? ? "on" : "off",
341 "rack.url_scheme" => https? ? "https" : "http",
342
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
343 "REQUEST_URI" => path,
29f13be @spastorino port is appended twice to HTTP_HOST when host already has the port
spastorino authored
344 "HTTP_HOST" => host,
fe94ba1 @dhh Added access to remote_addr in integration tests (closes #4266) [Chad…
dhh authored
345 "REMOTE_ADDR" => remote_addr,
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
346 "CONTENT_TYPE" => "application/x-www-form-urlencoded",
997e22c @josevalim Add a test which ensures action_dispatch.show_exceptions is properly …
josevalim authored
347 "HTTP_ACCEPT" => accept
dd2ed32 @josh Start to integrate some of the features in Rack::Test.
josh authored
348 }
b19999f @kirs Migrating xhr methods to keyword arguments syntax
kirs authored
349
350 if xhr
351 headers ||= {}
352 headers['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
353 headers['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
354 end
355
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
356 # this modifies the passed request_env directly
357 if headers.present?
358 Http::Headers.new(request_env).merge!(headers)
359 end
360 if env.present?
361 Http::Headers.new(request_env).merge!(env)
362 end
5e5e343 @josh Back off rack 1.1-pre and bundle in the new testing goodies
josh authored
363
570c54c @josh Fix cookie access in integration tests with other host names
josh authored
364 session = Rack::Test::Session.new(_mock_session)
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
365
570c54c @josh Fix cookie access in integration tests with other host names
josh authored
366 # NOTE: rack-test v0.5 doesn't build a default uri correctly
367 # Make sure requested path is always a full uri
baf14ae @kirs Switch to kwargs in ActionController::TestCase and ActionDispatch::In…
kirs authored
368 session.request(build_full_uri(path, request_env), request_env)
6940c0d @josh Unify functional and integration tests cookie helpers
josh authored
369
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
370 @request_count += 1
a79790e @josh rack-test 0.4.2 has rack 1.1.pre goodies, we'll use it instead
josh authored
371 @request = ActionDispatch::Request.new(session.last_request.env)
570c54c @josh Fix cookie access in integration tests with other host names
josh authored
372 response = _mock_session.last_response
f6e293e @jeremy Fix default headers in test responses
jeremy authored
373 @response = ActionDispatch::TestResponse.from_response(response)
6940c0d @josh Unify functional and integration tests cookie helpers
josh authored
374 @html_document = nil
e306ca3 @pixeltrix Refactor the handling of default_url_options in integration tests
pixeltrix authored
375 @url_options = nil
97a178b @jnewland Decorate responses from Rack Middleware and Rails Metal for the purpo…
jnewland authored
376
909443e @josh Expose last controller in rack env["action_controller.instance"]
josh authored
377 @controller = session.last_request.env['action_controller.instance']
378
b19999f @kirs Migrating xhr methods to keyword arguments syntax
kirs authored
379 response.status
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
380 end
4fd144d @tgxworld Form full URI as string to be parsed in Rack::Test.
tgxworld authored
381
382 def build_full_uri(path, env)
383 "#{env['rack.url_scheme']}://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{path}"
384 end
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
385 end
386
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
387 module Runner
0e15f07 Get modules back into integration tests
Carlhuda authored
388 include ActionDispatch::Assertions
389
0acd4a5 @eileencodes Skip url_helpers instead of caching, speed up integration tests
eileencodes authored
390 APP_SESSIONS = {}
391
d5e55e9 @eileencodes Revert "Revert integration test refactoring that caused app test regr…
eileencodes authored
392 attr_reader :app
393
394 def before_setup
395 @app = nil
396 @integration_session = nil
2e4a01b @eileencodes Call super last in before_setup
eileencodes authored
397 super
d5e55e9 @eileencodes Revert "Revert integration test refactoring that caused app test regr…
eileencodes authored
398 end
399
400 def integration_session
401 @integration_session ||= create_session(app)
303567e @tenderlove lazily create the integration session
tenderlove authored
402 end
403
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
404 # Reset the current session. This is useful for testing multiple sessions
405 # in a single test case.
406 def reset!
0acd4a5 @eileencodes Skip url_helpers instead of caching, speed up integration tests
eileencodes authored
407 @integration_session = create_session(app)
408 end
409
410 def create_session(app)
411 klass = APP_SESSIONS[app] ||= Class.new(Integration::Session) {
412 # If the app is a Rails app, make url_helpers available on the session
413 # This makes app.url_for and app.foo_path available in the console
414 if app.respond_to?(:routes)
415 include app.routes.url_helpers
416 include app.routes.mounted_helpers
417 end
418 }
419 klass.new(app)
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
420 end
421
76f5a9a @tgxworld Remove session to allow `with_routing` to be called twice.
tgxworld authored
422 def remove! # :nodoc:
423 @integration_session = nil
424 end
425
c9d75e0 @rafaelfranca Revert "Integration tests support the OPTIONS http method"
rafaelfranca authored
426 %w(get post patch put head delete cookies assigns
71c4ff0 @josh Delegate xhr helper method to integration session
josh authored
427 xml_http_request xhr get_via_redirect post_via_redirect).each do |method|
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
428 define_method(method) do |*args|
c3e8d15 @calvincorreli Fix for assigns(:..) resetting template assertions
calvincorreli authored
429 # reset the html_document variable, except for cookies/assigns calls
430 unless method == 'cookies' || method == 'assigns'
431 @html_document = nil
432 end
433
53b91b1 @miloops Avoid uninitialized variable warning, reuse @integration_session.
miloops authored
434 integration_session.__send__(method, *args).tap do
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
435 copy_session_variables!
436 end
437 end
438 end
439
440 # Open a new session instance. If a block is given, the new session is
441 # yielded to the block before being returned.
442 #
443 # session = open_session do |sess|
444 # sess.extend(CustomAssertions)
445 # end
446 #
447 # By default, a single session is automatically created for you, but you
448 # can use this method to open multiple sessions that ought to be tested
449 # simultaneously.
70312d2 @tgxworld Remove unused parameter.
tgxworld authored
450 def open_session
15c31c7 @wycats open_session can just return the a dup of the current context.
wycats authored
451 dup.tap do |session|
452 yield session if block_given?
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
453 end
454 end
455
456 # Copy the instance variables from the current session instance into the
457 # test instance.
458 def copy_session_variables! #:nodoc:
b03b09d @tenderlove remove meta programming
tenderlove authored
459 @controller = @integration_session.controller
460 @response = @integration_session.response
461 @request = @integration_session.request
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
462 end
463
e306ca3 @pixeltrix Refactor the handling of default_url_options in integration tests
pixeltrix authored
464 def default_url_options
465 integration_session.default_url_options
466 end
8760add Get URL helpers working again in integration tests.
Carlhuda authored
467
e306ca3 @pixeltrix Refactor the handling of default_url_options in integration tests
pixeltrix authored
468 def default_url_options=(options)
469 integration_session.default_url_options = options
8760add Get URL helpers working again in integration tests.
Carlhuda authored
470 end
471
5c86286 @svenfuchs add respond_to? to ActionDispatch::Integration::Runner
svenfuchs authored
472 def respond_to?(method, include_private = false)
da583df @josevalim Remove bazillion warnings from AP suite.
josevalim authored
473 integration_session.respond_to?(method, include_private) || super
5c86286 @svenfuchs add respond_to? to ActionDispatch::Integration::Runner
svenfuchs authored
474 end
475
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
476 # Delegate unhandled messages to the current session instance.
477 def method_missing(sym, *args, &block)
53b91b1 @miloops Avoid uninitialized variable warning, reuse @integration_session.
miloops authored
478 if integration_session.respond_to?(sym)
479 integration_session.__send__(sym, *args, &block).tap do
3de8b44 @oggy Make IntegrationTest::Runner propagate method_missing to ancestors.
oggy authored
480 copy_session_variables!
481 end
482 else
483 super
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
484 end
485 end
486 end
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
487 end
488
07054fe @jfirebaugh Fix grammar, formatting, and cross references
jfirebaugh authored
489 # An integration test spans multiple controllers and actions,
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
490 # tying them all together to ensure they work together as expected. It tests
491 # more completely than either unit or functional tests do, exercising the
492 # entire stack, from the dispatcher to the database.
493 #
591e87f @tilsammans Expanded routing documentation with current best practices
tilsammans authored
494 # At its simplest, you simply extend <tt>IntegrationTest</tt> and write your tests
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
495 # using the get/post methods:
496 #
fe5f660 @dhh Dont encourage __FILE__ bullshit
dhh authored
497 # require "test_helper"
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
498 #
7fc1edd @carlosantoniodasilva Remove deprecated stuff in ActionController
carlosantoniodasilva authored
499 # class ExampleTest < ActionDispatch::IntegrationTest
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
500 # fixtures :people
501 #
502 # def test_login
503 # # get the login page
504 # get "/login"
505 # assert_equal 200, status
506 #
507 # # post the login and follow through to the home page
fbb1185 @y-yagi update integration test example as is not output deprecation warning …
y-yagi authored
508 # post "/login", params: { username: people(:jamis).username,
509 # password: people(:jamis).password }
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
510 # follow_redirect!
511 # assert_equal 200, status
512 # assert_equal "/home", path
513 # end
514 # end
515 #
516 # However, you can also have multiple session instances open per test, and
517 # even extend those instances with assertions and methods to create a very
518 # powerful testing DSL that is specific for your application. You can even
591e87f @tilsammans Expanded routing documentation with current best practices
tilsammans authored
519 # reference any named routes you happen to have defined.
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
520 #
fe5f660 @dhh Dont encourage __FILE__ bullshit
dhh authored
521 # require "test_helper"
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
522 #
7fc1edd @carlosantoniodasilva Remove deprecated stuff in ActionController
carlosantoniodasilva authored
523 # class AdvancedTest < ActionDispatch::IntegrationTest
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
524 # fixtures :people, :rooms
525 #
526 # def test_login_and_speak
527 # jamis, david = login(:jamis), login(:david)
528 # room = rooms(:office)
529 #
530 # jamis.enter(room)
531 # jamis.speak(room, "anybody home?")
532 #
533 # david.enter(room)
534 # david.speak(room, "hello!")
535 # end
536 #
537 # private
538 #
539 # module CustomAssertions
540 # def enter(room)
541 # # reference a named route, for maximum internal consistency!
d20a529 @AvnerCohen 1.9 hash syntax changes to docs
AvnerCohen authored
542 # get(room_url(id: room.id))
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
543 # assert(...)
544 # ...
545 # end
546 #
547 # def speak(room, message)
fbb1185 @y-yagi update integration test example as is not output deprecation warning …
y-yagi authored
548 # post "/say/#{room.id}", xhr: true, params: { message: message }
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
549 # assert(...)
550 # ...
551 # end
552 # end
553 #
554 # def login(who)
555 # open_session do |sess|
556 # sess.extend(CustomAssertions)
557 # who = people(who)
fbb1185 @y-yagi update integration test example as is not output deprecation warning …
y-yagi authored
558 # sess.post "/login", params: { username: who.username,
559 # password: who.password }
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
560 # assert(...)
561 # end
562 # end
563 # end
241ccae @zzak Move longer form example from integration guide to api reference, bel…
zzak authored
564 #
565 # Another longer example would be:
566 #
567 # A simple integration test that exercises multiple controllers:
568 #
569 # require 'test_helper'
570 #
571 # class UserFlowsTest < ActionDispatch::IntegrationTest
572 # test "login and browse site" do
573 # # login via https
574 # https!
575 # get "/login"
576 # assert_response :success
577 #
fbb1185 @y-yagi update integration test example as is not output deprecation warning …
y-yagi authored
578 # post "/login", params: { username: users(:david).username, password: users(:david).password }
579 # follow_redirect!
241ccae @zzak Move longer form example from integration guide to api reference, bel…
zzak authored
580 # assert_equal '/welcome', path
581 # assert_equal 'Welcome david!', flash[:notice]
582 #
583 # https!(false)
584 # get "/articles/all"
585 # assert_response :success
bc1e802 @repinel [ci skip] remove `assigns` from the integration test example in API docs
repinel authored
586 # assert_select 'h1', 'Articles'
241ccae @zzak Move longer form example from integration guide to api reference, bel…
zzak authored
587 # end
588 # end
589 #
590 # As you can see the integration test involves multiple controllers and
591 # exercises the entire stack from database to dispatcher. In addition you can
592 # have multiple session instances open simultaneously in a test and extend
593 # those instances with assertion methods to create a very powerful testing
594 # DSL (domain-specific language) just for your application.
595 #
596 # Here's an example of multiple sessions and custom DSL in an integration test
597 #
598 # require 'test_helper'
599 #
600 # class UserFlowsTest < ActionDispatch::IntegrationTest
601 # test "login and browse site" do
602 # # User david logs in
603 # david = login(:david)
604 # # User guest logs in
605 # guest = login(:guest)
606 #
607 # # Both are now available in different sessions
608 # assert_equal 'Welcome david!', david.flash[:notice]
609 # assert_equal 'Welcome guest!', guest.flash[:notice]
610 #
611 # # User david can browse site
612 # david.browses_site
613 # # User guest can browse site as well
614 # guest.browses_site
615 #
616 # # Continue with other assertions
617 # end
618 #
619 # private
620 #
621 # module CustomDsl
622 # def browses_site
623 # get "/products/all"
624 # assert_response :success
bc1e802 @repinel [ci skip] remove `assigns` from the integration test example in API docs
repinel authored
625 # assert_select 'h1', 'Products'
241ccae @zzak Move longer form example from integration guide to api reference, bel…
zzak authored
626 # end
627 # end
628 #
629 # def login(user)
630 # open_session do |sess|
631 # sess.extend(CustomDsl)
632 # u = users(user)
633 # sess.https!
fbb1185 @y-yagi update integration test example as is not output deprecation warning …
y-yagi authored
634 # sess.post "/login", params: { username: u.username, password: u.password }
241ccae @zzak Move longer form example from integration guide to api reference, bel…
zzak authored
635 # assert_equal '/welcome', sess.path
636 # sess.https!(false)
637 # end
638 # end
639 # end
640 #
641 # Consult the Rails Testing Guide for more.
642
eab7120 @jeremy Performance: integration test benchmarking and profiling. [Jeremy Ke…
jeremy authored
643 class IntegrationTest < ActiveSupport::TestCase
8231460 @jeremy Factor Integration::Runner behavior out of IntegrationTest. Introduce…
jeremy authored
644 include Integration::Runner
0e15f07 Get modules back into integration tests
Carlhuda authored
645 include ActionController::TemplateAssertions
e306ca3 @pixeltrix Refactor the handling of default_url_options in integration tests
pixeltrix authored
646 include ActionDispatch::Routing::UrlFor
14866fa @josh Allow setting a default application for all integration tests
josh authored
647
648 @@app = nil
649
650 def self.app
5f3b9de @lest remove Rails application fallback from AD::IntegrationTest
lest authored
651 @@app || ActionDispatch.test_app
14866fa @josh Allow setting a default application for all integration tests
josh authored
652 end
653
654 def self.app=(app)
655 @@app = app
656 end
657
658 def app
659 super || self.class.app
660 end
e306ca3 @pixeltrix Refactor the handling of default_url_options in integration tests
pixeltrix authored
661
662 def url_options
663 integration_session.url_options
664 end
5ffc36d @kaspth Add document_root_element to ActionDispatch::IntegrationTest so asser…
kaspth authored
665
666 def document_root_element
1b9e85d @rafaelfranca Make sure assert_select can assert body tag
rafaelfranca authored
667 html_document.root
5ffc36d @kaspth Add document_root_element to ActionDispatch::IntegrationTest so asser…
kaspth authored
668 end
9507f5d @jamis Add ActionController::IntegrationTest to allow high-level testing of …
jamis authored
669 end
0ee1cb2 @jeremy Ruby 1.9 compat, consistent load paths
jeremy authored
670 end
Something went wrong with that request. Please try again.