Mercurial > hg > soundsoftware-site
diff test/test_helper.rb @ 1526:404aa68d4227
Merge from live branch
author | Chris Cannam |
---|---|
date | Thu, 11 Sep 2014 12:46:20 +0100 |
parents | fb9a13467253 |
children |
line wrap: on
line diff
--- a/test/test_helper.rb Mon Mar 17 08:57:04 2014 +0000 +++ b/test/test_helper.rb Thu Sep 11 12:46:20 2014 +0100 @@ -1,5 +1,5 @@ # Redmine - project management software -# Copyright (C) 2006-2012 Jean-Philippe Lang +# Copyright (C) 2006-2014 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 @@ -24,31 +24,19 @@ require File.expand_path(File.dirname(__FILE__) + '/object_helpers') include ObjectHelpers +require 'awesome_nested_set/version' + 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... + ESCAPED_CANT = 'can't' + ESCAPED_UCANT = 'Can't' + # Rails 4.0.2 + #ESCAPED_CANT = 'can't' + #ESCAPED_UCANT = 'Can't' def log_user(login, password) User.anonymous @@ -107,7 +95,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 @@ -123,8 +119,16 @@ User.current = saved_user end + def with_locale(locale, &block) + saved_localed = ::I18n.locale + ::I18n.locale = locale + yield + ensure + ::I18n.locale = saved_localed + end + def change_user_password(login, new_password) - user = User.first(:conditions => {:login => login}) + user = User.where(:login => login).first user.password, user.password_confirmation = new_password, new_password user.save! end @@ -181,8 +185,8 @@ assert s.include?(expected), (message || "\"#{expected}\" not found in \"#{s}\"") end - def assert_not_include(expected, s) - assert !s.include?(expected), "\"#{expected}\" found in \"#{s}\"" + def assert_not_include(expected, s, message=nil) + assert !s.include?(expected), (message || "\"#{expected}\" found in \"#{s}\"") end def assert_select_in(text, *args, &block) @@ -190,19 +194,19 @@ assert_select(d, *args, &block) end - def assert_mail_body_match(expected, mail) + def assert_mail_body_match(expected, mail, message=nil) if expected.is_a?(String) - assert_include expected, mail_body(mail) + assert_include expected, mail_body(mail), message else - assert_match expected, mail_body(mail) + assert_match expected, mail_body(mail), message end end - def assert_mail_body_no_match(expected, mail) + def assert_mail_body_no_match(expected, mail, message=nil) if expected.is_a?(String) - assert_not_include expected, mail_body(mail) + assert_not_include expected, mail_body(mail), message else - assert_no_match expected, mail_body(mail) + assert_no_match expected, mail_body(mail), message end end @@ -210,285 +214,281 @@ mail.parts.first.body.encoded end - # Shoulda macros - def self.should_render_404 - should_respond_with :not_found - should_render_template 'common/error' + # awesome_nested_set new node lft and rgt value changed this refactor revision. + # https://github.com/collectiveidea/awesome_nested_set/commit/199fca9bb938e40200cd90714dc69247ef017c61 + # The reason of behavior change is that "self.class.base_class.unscoped" was added to this line. + # https://github.com/collectiveidea/awesome_nested_set/commit/199fca9bb9#diff-f61b59a5e6319024e211b0ffdd0e4ef1R273 + # It seems correct behavior because of this line comment. + # https://github.com/collectiveidea/awesome_nested_set/blame/199fca9bb9/lib/awesome_nested_set/model.rb#L278 + def new_issue_lft + ::AwesomeNestedSet::VERSION > "2.1.6" ? Issue.maximum(:rgt) + 1 : 1 end +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