diff test/test_helper.rb @ 1295:622f24f53b42 redmine-2.3

Update to Redmine SVN revision 11972 on 2.3-stable branch
author Chris Cannam
date Fri, 14 Jun 2013 09:02:21 +0100
parents 433d4f72a19b
children 4f746d8966dd
line wrap: on
line diff
--- a/test/test_helper.rb	Fri Jun 14 09:01:12 2013 +0100
+++ b/test/test_helper.rb	Fri Jun 14 09:02:21 2013 +0100
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2012  Jean-Philippe Lang
+# Copyright (C) 2006-2013  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -26,30 +26,10 @@
 
 class ActiveSupport::TestCase
   include ActionDispatch::TestProcess
-  
-  # Transactional fixtures accelerate your tests by wrapping each test method
-  # in a transaction that's rolled back on completion.  This ensures that the
-  # test database remains unchanged so your fixtures don't have to be reloaded
-  # between every test method.  Fewer database queries means faster tests.
-  #
-  # Read Mike Clark's excellent walkthrough at
-  #   http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
-  #
-  # Every Active Record database supports transactions except MyISAM tables
-  # in MySQL.  Turn off transactional fixtures in this case; however, if you
-  # don't care one way or the other, switching from MyISAM to InnoDB tables
-  # is recommended.
+
   self.use_transactional_fixtures = true
-
-  # Instantiated fixtures are slow, but give you @david where otherwise you
-  # would need people(:david).  If you don't want to migrate your existing
-  # test cases which use the @david style and don't mind the speed hit (each
-  # instantiated fixtures translates to a database query per test method),
-  # then set this back to true.
   self.use_instantiated_fixtures  = false
 
-  # Add more helper methods to be used by all tests here...
-
   def log_user(login, password)
     User.anonymous
     get "/login"
@@ -107,7 +87,15 @@
   end
 
   def with_settings(options, &block)
-    saved_settings = options.keys.inject({}) {|h, k| h[k] = Setting[k].is_a?(Symbol) ? Setting[k] : Setting[k].dup; h}
+    saved_settings = options.keys.inject({}) do |h, k|
+      h[k] = case Setting[k]
+        when Symbol, false, true, nil
+          Setting[k]
+        else
+          Setting[k].dup
+        end
+      h
+    end
     options.each {|k, v| Setting[k] = v}
     yield
   ensure
@@ -209,286 +197,272 @@
   def mail_body(mail)
     mail.parts.first.body.encoded
   end
+end
 
-  # Shoulda macros
-  def self.should_render_404
-    should_respond_with :not_found
-    should_render_template 'common/error'
-  end
-
-  def self.should_have_before_filter(expected_method, options = {})
-    should_have_filter('before', expected_method, options)
-  end
-
-  def self.should_have_after_filter(expected_method, options = {})
-    should_have_filter('after', expected_method, options)
-  end
-
-  def self.should_have_filter(filter_type, expected_method, options)
-    description = "have #{filter_type}_filter :#{expected_method}"
-    description << " with #{options.inspect}" unless options.empty?
-
-    should description do
-      klass = "action_controller/filters/#{filter_type}_filter".classify.constantize
-      expected = klass.new(:filter, expected_method.to_sym, options)
-      assert_equal 1, @controller.class.filter_chain.select { |filter|
-        filter.method == expected.method && filter.kind == expected.kind &&
-        filter.options == expected.options && filter.class == expected.class
-      }.size
-    end
-  end
-
-  # Test that a request allows the three types of API authentication
-  #
-  # * HTTP Basic with username and password
-  # * HTTP Basic with an api key for the username
-  # * Key based with the key=X parameter
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_api_authentication(http_method, url, parameters={}, options={})
-    should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters, options)
-    should_allow_http_basic_auth_with_key(http_method, url, parameters, options)
-    should_allow_key_based_auth(http_method, url, parameters, options)
-  end
-
-  # Test that a request allows the username and password for HTTP BASIC
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters={}, options={})
-    success_code = options[:success_code] || :success
-    failure_code = options[:failure_code] || :unauthorized
-
-    context "should allow http basic auth using a username and password for #{http_method} #{url}" do
-      context "with a valid HTTP authentication" do
-        setup do
-          @user = User.generate! do |user|
-            user.admin = true
-            user.password = 'my_password'
+module Redmine
+  module ApiTest
+    # Base class for API tests
+    class Base < ActionDispatch::IntegrationTest
+      # Test that a request allows the three types of API authentication
+      #
+      # * HTTP Basic with username and password
+      # * HTTP Basic with an api key for the username
+      # * Key based with the key=X parameter
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_api_authentication(http_method, url, parameters={}, options={})
+        should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters, options)
+        should_allow_http_basic_auth_with_key(http_method, url, parameters, options)
+        should_allow_key_based_auth(http_method, url, parameters, options)
+      end
+    
+      # Test that a request allows the username and password for HTTP BASIC
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters={}, options={})
+        success_code = options[:success_code] || :success
+        failure_code = options[:failure_code] || :unauthorized
+    
+        context "should allow http basic auth using a username and password for #{http_method} #{url}" do
+          context "with a valid HTTP authentication" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+                user.password = 'my_password'
+              end
+              send(http_method, url, parameters, credentials(@user.login, 'my_password'))
+            end
+    
+            should_respond_with success_code
+            should_respond_with_content_type_based_on_url(url)
+            should "login as the user" do
+              assert_equal @user, User.current
+            end
           end
-          send(http_method, url, parameters, credentials(@user.login, 'my_password'))
-        end
-
-        should_respond_with success_code
-        should_respond_with_content_type_based_on_url(url)
-        should "login as the user" do
-          assert_equal @user, User.current
+    
+          context "with an invalid HTTP authentication" do
+            setup do
+              @user = User.generate!
+              send(http_method, url, parameters, credentials(@user.login, 'wrong_password'))
+            end
+    
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "not login as the user" do
+              assert_equal User.anonymous, User.current
+            end
+          end
+    
+          context "without credentials" do
+            setup do
+              send(http_method, url, parameters)
+            end
+    
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "include_www_authenticate_header" do
+              assert @controller.response.headers.has_key?('WWW-Authenticate')
+            end
+          end
         end
       end
-
-      context "with an invalid HTTP authentication" do
-        setup do
-          @user = User.generate!
-          send(http_method, url, parameters, credentials(@user.login, 'wrong_password'))
-        end
-
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
+    
+      # Test that a request allows the API key with HTTP BASIC
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_http_basic_auth_with_key(http_method, url, parameters={}, options={})
+        success_code = options[:success_code] || :success
+        failure_code = options[:failure_code] || :unauthorized
+    
+        context "should allow http basic auth with a key for #{http_method} #{url}" do
+          context "with a valid HTTP authentication using the API token" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+              end
+              @token = Token.create!(:user => @user, :action => 'api')
+              send(http_method, url, parameters, credentials(@token.value, 'X'))
+            end
+            should_respond_with success_code
+            should_respond_with_content_type_based_on_url(url)
+            should_be_a_valid_response_string_based_on_url(url)
+            should "login as the user" do
+              assert_equal @user, User.current
+            end
+          end
+    
+          context "with an invalid HTTP authentication" do
+            setup do
+              @user = User.generate!
+              @token = Token.create!(:user => @user, :action => 'feeds')
+              send(http_method, url, parameters, credentials(@token.value, 'X'))
+            end
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "not login as the user" do
+              assert_equal User.anonymous, User.current
+            end
+          end
         end
       end
-
-      context "without credentials" do
-        setup do
-          send(http_method, url, parameters)
+    
+      # Test that a request allows full key authentication
+      #
+      # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
+      # @param [String] url the request url, without the key=ZXY parameter
+      # @param [optional, Hash] parameters additional request parameters
+      # @param [optional, Hash] options additional options
+      # @option options [Symbol] :success_code Successful response code (:success)
+      # @option options [Symbol] :failure_code Failure response code (:unauthorized)
+      def self.should_allow_key_based_auth(http_method, url, parameters={}, options={})
+        success_code = options[:success_code] || :success
+        failure_code = options[:failure_code] || :unauthorized
+    
+        context "should allow key based auth using key=X for #{http_method} #{url}" do
+          context "with a valid api token" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+              end
+              @token = Token.create!(:user => @user, :action => 'api')
+              # Simple url parse to add on ?key= or &key=
+              request_url = if url.match(/\?/)
+                              url + "&key=#{@token.value}"
+                            else
+                              url + "?key=#{@token.value}"
+                            end
+              send(http_method, request_url, parameters)
+            end
+            should_respond_with success_code
+            should_respond_with_content_type_based_on_url(url)
+            should_be_a_valid_response_string_based_on_url(url)
+            should "login as the user" do
+              assert_equal @user, User.current
+            end
+          end
+    
+          context "with an invalid api token" do
+            setup do
+              @user = User.generate! do |user|
+                user.admin = true
+              end
+              @token = Token.create!(:user => @user, :action => 'feeds')
+              # Simple url parse to add on ?key= or &key=
+              request_url = if url.match(/\?/)
+                              url + "&key=#{@token.value}"
+                            else
+                              url + "?key=#{@token.value}"
+                            end
+              send(http_method, request_url, parameters)
+            end
+            should_respond_with failure_code
+            should_respond_with_content_type_based_on_url(url)
+            should "not login as the user" do
+              assert_equal User.anonymous, User.current
+            end
+          end
         end
-
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "include_www_authenticate_header" do
-          assert @controller.response.headers.has_key?('WWW-Authenticate')
+    
+        context "should allow key based auth using X-Redmine-API-Key header for #{http_method} #{url}" do
+          setup do
+            @user = User.generate! do |user|
+              user.admin = true
+            end
+            @token = Token.create!(:user => @user, :action => 'api')
+            send(http_method, url, parameters, {'X-Redmine-API-Key' => @token.value.to_s})
+          end
+          should_respond_with success_code
+          should_respond_with_content_type_based_on_url(url)
+          should_be_a_valid_response_string_based_on_url(url)
+          should "login as the user" do
+            assert_equal @user, User.current
+          end
+        end
+      end
+    
+      # Uses should_respond_with_content_type based on what's in the url:
+      #
+      # '/project/issues.xml' => should_respond_with_content_type :xml
+      # '/project/issues.json' => should_respond_with_content_type :json
+      #
+      # @param [String] url Request
+      def self.should_respond_with_content_type_based_on_url(url)
+        case
+        when url.match(/xml/i)
+          should "respond with XML" do
+            assert_equal 'application/xml', @response.content_type
+          end
+        when url.match(/json/i)
+          should "respond with JSON" do
+            assert_equal 'application/json', @response.content_type
+          end
+        else
+          raise "Unknown content type for should_respond_with_content_type_based_on_url: #{url}"
+        end
+      end
+    
+      # Uses the url to assert which format the response should be in
+      #
+      # '/project/issues.xml' => should_be_a_valid_xml_string
+      # '/project/issues.json' => should_be_a_valid_json_string
+      #
+      # @param [String] url Request
+      def self.should_be_a_valid_response_string_based_on_url(url)
+        case
+        when url.match(/xml/i)
+          should_be_a_valid_xml_string
+        when url.match(/json/i)
+          should_be_a_valid_json_string
+        else
+          raise "Unknown content type for should_be_a_valid_response_based_on_url: #{url}"
+        end
+      end
+    
+      # Checks that the response is a valid JSON string
+      def self.should_be_a_valid_json_string
+        should "be a valid JSON string (or empty)" do
+          assert(response.body.blank? || ActiveSupport::JSON.decode(response.body))
+        end
+      end
+    
+      # Checks that the response is a valid XML string
+      def self.should_be_a_valid_xml_string
+        should "be a valid XML string" do
+          assert REXML::Document.new(response.body)
+        end
+      end
+    
+      def self.should_respond_with(status)
+        should "respond with #{status}" do
+          assert_response status
         end
       end
     end
   end
+end
 
-  # Test that a request allows the API key with HTTP BASIC
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_http_basic_auth_with_key(http_method, url, parameters={}, options={})
-    success_code = options[:success_code] || :success
-    failure_code = options[:failure_code] || :unauthorized
-
-    context "should allow http basic auth with a key for #{http_method} #{url}" do
-      context "with a valid HTTP authentication using the API token" do
-        setup do
-          @user = User.generate! do |user|
-            user.admin = true
-          end
-          @token = Token.create!(:user => @user, :action => 'api')
-          send(http_method, url, parameters, credentials(@token.value, 'X'))
-        end
-        should_respond_with success_code
-        should_respond_with_content_type_based_on_url(url)
-        should_be_a_valid_response_string_based_on_url(url)
-        should "login as the user" do
-          assert_equal @user, User.current
-        end
-      end
-
-      context "with an invalid HTTP authentication" do
-        setup do
-          @user = User.generate!
-          @token = Token.create!(:user => @user, :action => 'feeds')
-          send(http_method, url, parameters, credentials(@token.value, 'X'))
-        end
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-    end
-  end
-
-  # Test that a request allows full key authentication
-  #
-  # @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
-  # @param [String] url the request url, without the key=ZXY parameter
-  # @param [optional, Hash] parameters additional request parameters
-  # @param [optional, Hash] options additional options
-  # @option options [Symbol] :success_code Successful response code (:success)
-  # @option options [Symbol] :failure_code Failure response code (:unauthorized)
-  def self.should_allow_key_based_auth(http_method, url, parameters={}, options={})
-    success_code = options[:success_code] || :success
-    failure_code = options[:failure_code] || :unauthorized
-
-    context "should allow key based auth using key=X for #{http_method} #{url}" do
-      context "with a valid api token" do
-        setup do
-          @user = User.generate! do |user|
-            user.admin = true
-          end
-          @token = Token.create!(:user => @user, :action => 'api')
-          # Simple url parse to add on ?key= or &key=
-          request_url = if url.match(/\?/)
-                          url + "&key=#{@token.value}"
-                        else
-                          url + "?key=#{@token.value}"
-                        end
-          send(http_method, request_url, parameters)
-        end
-        should_respond_with success_code
-        should_respond_with_content_type_based_on_url(url)
-        should_be_a_valid_response_string_based_on_url(url)
-        should "login as the user" do
-          assert_equal @user, User.current
-        end
-      end
-
-      context "with an invalid api token" do
-        setup do
-          @user = User.generate! do |user|
-            user.admin = true
-          end
-          @token = Token.create!(:user => @user, :action => 'feeds')
-          # Simple url parse to add on ?key= or &key=
-          request_url = if url.match(/\?/)
-                          url + "&key=#{@token.value}"
-                        else
-                          url + "?key=#{@token.value}"
-                        end
-          send(http_method, request_url, parameters)
-        end
-        should_respond_with failure_code
-        should_respond_with_content_type_based_on_url(url)
-        should "not login as the user" do
-          assert_equal User.anonymous, User.current
-        end
-      end
-    end
-
-    context "should allow key based auth using X-Redmine-API-Key header for #{http_method} #{url}" do
-      setup do
-        @user = User.generate! do |user|
-          user.admin = true
-        end
-        @token = Token.create!(:user => @user, :action => 'api')
-        send(http_method, url, parameters, {'X-Redmine-API-Key' => @token.value.to_s})
-      end
-      should_respond_with success_code
-      should_respond_with_content_type_based_on_url(url)
-      should_be_a_valid_response_string_based_on_url(url)
-      should "login as the user" do
-        assert_equal @user, User.current
-      end
-    end
-  end
-
-  # Uses should_respond_with_content_type based on what's in the url:
-  #
-  # '/project/issues.xml' => should_respond_with_content_type :xml
-  # '/project/issues.json' => should_respond_with_content_type :json
-  #
-  # @param [String] url Request
-  def self.should_respond_with_content_type_based_on_url(url)
-    case
-    when url.match(/xml/i)
-      should "respond with XML" do
-        assert_equal 'application/xml', @response.content_type
-      end
-    when url.match(/json/i)
-      should "respond with JSON" do
-        assert_equal 'application/json', @response.content_type
-      end
-    else
-      raise "Unknown content type for should_respond_with_content_type_based_on_url: #{url}"
-    end
-  end
-
-  # Uses the url to assert which format the response should be in
-  #
-  # '/project/issues.xml' => should_be_a_valid_xml_string
-  # '/project/issues.json' => should_be_a_valid_json_string
-  #
-  # @param [String] url Request
-  def self.should_be_a_valid_response_string_based_on_url(url)
-    case
-    when url.match(/xml/i)
-      should_be_a_valid_xml_string
-    when url.match(/json/i)
-      should_be_a_valid_json_string
-    else
-      raise "Unknown content type for should_be_a_valid_response_based_on_url: #{url}"
-    end
-  end
-
-  # Checks that the response is a valid JSON string
-  def self.should_be_a_valid_json_string
-    should "be a valid JSON string (or empty)" do
-      assert(response.body.blank? || ActiveSupport::JSON.decode(response.body))
-    end
-  end
-
-  # Checks that the response is a valid XML string
-  def self.should_be_a_valid_xml_string
-    should "be a valid XML string" do
-      assert REXML::Document.new(response.body)
-    end
-  end
-
-  def self.should_respond_with(status)
-    should "respond with #{status}" do
-      assert_response status
-    end
+# URL helpers do not work with config.threadsafe!
+# https://github.com/rspec/rspec-rails/issues/476#issuecomment-4705454
+ActionView::TestCase::TestController.instance_eval do
+  helper Rails.application.routes.url_helpers
+end
+ActionView::TestCase::TestController.class_eval do
+  def _routes
+    Rails.application.routes
   end
 end
-
-# Simple module to "namespace" all of the API tests
-module ApiTest
-end