diff options
Diffstat (limited to 'actionpack/lib/action_controller/test_case.rb')
-rw-r--r-- | actionpack/lib/action_controller/test_case.rb | 148 |
1 files changed, 46 insertions, 102 deletions
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 3a6bc92b3c..57dd605b51 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -3,11 +3,11 @@ require "active_support/core_ext/hash/conversions" require "active_support/core_ext/object/to_query" require "active_support/core_ext/module/anonymous" require "active_support/core_ext/hash/keys" +require "active_support/testing/constant_lookup" require "action_controller/template_assertions" require "rails-dom-testing" module ActionController - # :stopdoc: class Metal include Testing::Functional end @@ -52,7 +52,7 @@ module ActionController super(env) self.session = session - self.session_options = TestSession::DEFAULT_OPTIONS + self.session_options = TestSession::DEFAULT_OPTIONS.dup @controller_class = controller_class @custom_param_parsers = { xml: lambda { |raw_post| Hash.from_xml(raw_post)["hash"] } @@ -113,8 +113,9 @@ module ActionController end end - set_header "CONTENT_LENGTH", data.length.to_s - set_header "rack.input", StringIO.new(data) + data_stream = StringIO.new(data) + set_header "CONTENT_LENGTH", data_stream.length.to_s + set_header "rack.input", data_stream end fetch_header("PATH_INFO") do |k| @@ -211,10 +212,18 @@ module ActionController end # Superclass for ActionController functional tests. Functional tests allow you to - # test a single controller action per test method. This should not be confused with - # integration tests (see ActionDispatch::IntegrationTest), which are more like - # "stories" that can involve multiple controllers and multiple actions (i.e. multiple - # different HTTP requests). + # test a single controller action per test method. + # + # == Use integration style controller tests over functional style controller tests. + # + # Rails discourages the use of functional tests in favor of integration tests + # (use ActionDispatch::IntegrationTest). + # + # New Rails applications no longer generate functional style controller tests and they should + # only be used for backward compatibility. Integration style controller tests perform actual + # requests, whereas functional style controller tests merely simulate a request. Besides, + # integration tests are as fast as functional tests and provide lot of helpers such as +as+, + # +parsed_body+ for effective testing of controller actions including even API endpoints. # # == Basic example # @@ -345,7 +354,7 @@ module ActionController end def controller_class - if current_controller_class = self._controller_class + if current_controller_class = _controller_class current_controller_class else self.controller_class = determine_default_controller_class(name) @@ -379,56 +388,39 @@ module ActionController # # Note that the request method is not verified. The different methods are # available to make the tests more expressive. - def get(action, *args) - res = process_with_kwargs("GET", action, *args) - cookies.update res.cookies - res + def get(action, **args) + process(action, method: "GET", **args) end # Simulate a POST request with the given parameters and set/volley the response. # See +get+ for more details. - def post(action, *args) - process_with_kwargs("POST", action, *args) + def post(action, **args) + process(action, method: "POST", **args) end # Simulate a PATCH request with the given parameters and set/volley the response. # See +get+ for more details. - def patch(action, *args) - process_with_kwargs("PATCH", action, *args) + def patch(action, **args) + process(action, method: "PATCH", **args) end # Simulate a PUT request with the given parameters and set/volley the response. # See +get+ for more details. - def put(action, *args) - process_with_kwargs("PUT", action, *args) + def put(action, **args) + process(action, method: "PUT", **args) end # Simulate a DELETE request with the given parameters and set/volley the response. # See +get+ for more details. - def delete(action, *args) - process_with_kwargs("DELETE", action, *args) + def delete(action, **args) + process(action, method: "DELETE", **args) end # Simulate a HEAD request with the given parameters and set/volley the response. # See +get+ for more details. - def head(action, *args) - process_with_kwargs("HEAD", action, *args) - end - - def xml_http_request(*args) - ActiveSupport::Deprecation.warn(<<-MSG.strip_heredoc) - xhr and xml_http_request methods are deprecated in favor of - `get :index, xhr: true` and `post :create, xhr: true` - MSG - - @request.env["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" - @request.env["HTTP_ACCEPT"] ||= [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(", ") - __send__(*args).tap do - @request.env.delete "HTTP_X_REQUESTED_WITH" - @request.env.delete "HTTP_ACCEPT" - end + def head(action, **args) + process(action, method: "HEAD", **args) end - alias xhr :xml_http_request # Simulate an HTTP request to +action+ by specifying request method, # parameters and set/volley the response. @@ -442,6 +434,8 @@ module ActionController # - +session+: A hash of parameters to store in the session. This may be +nil+. # - +flash+: A hash of parameters to store in the flash. This may be +nil+. # - +format+: Request format. Defaults to +nil+. Can be string or symbol. + # - +as+: Content type. Defaults to +nil+. Must be a symbol that corresponds + # to a mime type. # # Example calling +create+ action and sending two params: # @@ -458,40 +452,14 @@ module ActionController # respectively which will make tests more expressive. # # Note that the request method is not verified. - def process(action, *args) + def process(action, method: "GET", params: {}, session: nil, body: nil, flash: {}, format: nil, xhr: false, as: nil) check_required_ivars - if kwarg_request?(args) - parameters, session, body, flash, http_method, format, xhr = args[0].values_at(:params, :session, :body, :flash, :method, :format, :xhr) - else - http_method, parameters, session, flash = args - format = nil - - if parameters.is_a?(String) && http_method != "HEAD" - body = parameters - parameters = nil - end - - if parameters || session || flash - non_kwarg_request_warning - end - end - if body @request.set_header "RAW_POST_DATA", body end - if http_method - http_method = http_method.to_s.upcase - else - http_method = "GET" - end - - parameters ||= {} - - if format - parameters[:format] = format - end + http_method = method.to_s.upcase @html_document = nil @@ -507,7 +475,16 @@ module ActionController @request.set_header "REQUEST_METHOD", http_method - parameters = parameters.symbolize_keys + if as + @request.content_type = Mime[as].to_s + format ||= as + end + + parameters = params.symbolize_keys + + if format + parameters[:format] = format + end generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action.to_s)) generated_path = generated_path(generated_extras) @@ -536,12 +513,11 @@ module ActionController @request = @controller.request @response = @controller.response - @request.delete_header "HTTP_COOKIE" - if @request.have_cookie_jar? unless @request.cookie_jar.committed? @request.cookie_jar.write(@response) cookies.update(@request.cookie_jar.instance_variable_get(:@cookies)) + cookies.update(@response.cookies) end end @response.prepare! @@ -613,6 +589,7 @@ module ActionController include ActionDispatch::Assertions class_attribute :_controller_class setup :setup_controller_request_and_response + ActiveSupport.run_load_hooks(:action_controller_test_case, self) end private @@ -626,38 +603,6 @@ module ActionController env end - def process_with_kwargs(http_method, action, *args) - if kwarg_request?(args) - args.first.merge!(method: http_method) - process(action, *args) - else - non_kwarg_request_warning if args.any? - - args = args.unshift(http_method) - process(action, *args) - end - end - - REQUEST_KWARGS = %i(params session flash method body xhr) - def kwarg_request?(args) - args[0].respond_to?(:keys) && ( - (args[0].key?(:format) && args[0].keys.size == 1) || - args[0].keys.any? { |k| REQUEST_KWARGS.include?(k) } - ) - end - - def non_kwarg_request_warning - ActiveSupport::Deprecation.warn(<<-MSG.strip_heredoc) - ActionController::TestCase HTTP request methods will accept only - keyword arguments in future Rails versions. - - Examples: - - get :show, params: { id: 1 }, session: { user_id: 1 } - process :update, method: :post, params: { id: 1 } - MSG - end - def document_root_element html_document.root end @@ -675,5 +620,4 @@ module ActionController include Behavior end - # :startdoc: end |