##// END OF EJS Templates
Test cleanup....
Jean-Philippe Lang -
r13296:78e6717ba70f
parent child
Show More
@@ -1,117 +1,115
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class LayoutTest < ActionDispatch::IntegrationTest
20 class LayoutTest < ActionDispatch::IntegrationTest
21 fixtures :projects, :trackers, :issue_statuses, :issues,
21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 :enumerations, :users, :issue_categories,
22 :enumerations, :users, :issue_categories,
23 :projects_trackers,
23 :projects_trackers,
24 :roles,
24 :roles,
25 :member_roles,
25 :member_roles,
26 :members,
26 :members,
27 :enabled_modules
27 :enabled_modules
28
28
29 test "browsing to a missing page should render the base layout" do
29 test "browsing to a missing page should render the base layout" do
30 get "/users/100000000"
30 get "/users/100000000"
31
31
32 assert_response :not_found
32 assert_response :not_found
33
33
34 # UsersController uses the admin layout by default
34 # UsersController uses the admin layout by default
35 assert_select "#admin-menu", :count => 0
35 assert_select "#admin-menu", :count => 0
36 end
36 end
37
37
38 test "browsing to an unauthorized page should render the base layout" do
38 test "browsing to an unauthorized page should render the base layout" do
39 change_user_password('miscuser9', 'test1234')
39 log_user('jsmith','jsmith')
40
41 log_user('miscuser9','test1234')
42
40
43 get "/admin"
41 get "/admin"
44 assert_response :forbidden
42 assert_response :forbidden
45 assert_select "#admin-menu", :count => 0
43 assert_select "#admin-menu", :count => 0
46 end
44 end
47
45
48 def test_top_menu_and_search_not_visible_when_login_required
46 def test_top_menu_and_search_not_visible_when_login_required
49 with_settings :login_required => '1' do
47 with_settings :login_required => '1' do
50 get '/'
48 get '/'
51 assert_select "#top-menu > ul", 0
49 assert_select "#top-menu > ul", 0
52 assert_select "#quick-search", 0
50 assert_select "#quick-search", 0
53 end
51 end
54 end
52 end
55
53
56 def test_top_menu_and_search_visible_when_login_not_required
54 def test_top_menu_and_search_visible_when_login_not_required
57 with_settings :login_required => '0' do
55 with_settings :login_required => '0' do
58 get '/'
56 get '/'
59 assert_select "#top-menu > ul"
57 assert_select "#top-menu > ul"
60 assert_select "#quick-search"
58 assert_select "#quick-search"
61 end
59 end
62 end
60 end
63
61
64 def test_wiki_formatter_header_tags
62 def test_wiki_formatter_header_tags
65 Role.anonymous.add_permission! :add_issues
63 Role.anonymous.add_permission! :add_issues
66
64
67 get '/projects/ecookbook/issues/new'
65 get '/projects/ecookbook/issues/new'
68 assert_select 'head script[src=?]', '/javascripts/jstoolbar/jstoolbar-textile.min.js'
66 assert_select 'head script[src=?]', '/javascripts/jstoolbar/jstoolbar-textile.min.js'
69 end
67 end
70
68
71 def test_calendar_header_tags
69 def test_calendar_header_tags
72 with_settings :default_language => 'fr' do
70 with_settings :default_language => 'fr' do
73 get '/issues'
71 get '/issues'
74 assert_include "/javascripts/i18n/datepicker-fr.js", response.body
72 assert_include "/javascripts/i18n/datepicker-fr.js", response.body
75 end
73 end
76
74
77 with_settings :default_language => 'en-GB' do
75 with_settings :default_language => 'en-GB' do
78 get '/issues'
76 get '/issues'
79 assert_include "/javascripts/i18n/datepicker-en-GB.js", response.body
77 assert_include "/javascripts/i18n/datepicker-en-GB.js", response.body
80 end
78 end
81
79
82 with_settings :default_language => 'en' do
80 with_settings :default_language => 'en' do
83 get '/issues'
81 get '/issues'
84 assert_not_include "/javascripts/i18n/datepicker", response.body
82 assert_not_include "/javascripts/i18n/datepicker", response.body
85 end
83 end
86
84
87 with_settings :default_language => 'zh' do
85 with_settings :default_language => 'zh' do
88 get '/issues'
86 get '/issues'
89 assert_include "/javascripts/i18n/datepicker-zh-CN.js", response.body
87 assert_include "/javascripts/i18n/datepicker-zh-CN.js", response.body
90 end
88 end
91
89
92 with_settings :default_language => 'zh-TW' do
90 with_settings :default_language => 'zh-TW' do
93 get '/issues'
91 get '/issues'
94 assert_include "/javascripts/i18n/datepicker-zh-TW.js", response.body
92 assert_include "/javascripts/i18n/datepicker-zh-TW.js", response.body
95 end
93 end
96
94
97 with_settings :default_language => 'pt' do
95 with_settings :default_language => 'pt' do
98 get '/issues'
96 get '/issues'
99 assert_include "/javascripts/i18n/datepicker-pt.js", response.body
97 assert_include "/javascripts/i18n/datepicker-pt.js", response.body
100 end
98 end
101
99
102 with_settings :default_language => 'pt-BR' do
100 with_settings :default_language => 'pt-BR' do
103 get '/issues'
101 get '/issues'
104 assert_include "/javascripts/i18n/datepicker-pt-BR.js", response.body
102 assert_include "/javascripts/i18n/datepicker-pt-BR.js", response.body
105 end
103 end
106 end
104 end
107
105
108 def test_search_field_outside_project_should_link_to_global_search
106 def test_search_field_outside_project_should_link_to_global_search
109 get '/'
107 get '/'
110 assert_select 'div#quick-search form[action=/search]'
108 assert_select 'div#quick-search form[action=/search]'
111 end
109 end
112
110
113 def test_search_field_inside_project_should_link_to_project_search
111 def test_search_field_inside_project_should_link_to_project_search
114 get '/projects/ecookbook'
112 get '/projects/ecookbook'
115 assert_select 'div#quick-search form[action=/projects/ecookbook/search]'
113 assert_select 'div#quick-search form[action=/projects/ecookbook/search]'
116 end
114 end
117 end
115 end
@@ -1,289 +1,283
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 ENV["RAILS_ENV"] = "test"
18 ENV["RAILS_ENV"] = "test"
19 require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
19 require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
20 require 'rails/test_help'
20 require 'rails/test_help'
21 require Rails.root.join('test', 'mocks', 'open_id_authentication_mock.rb').to_s
21 require Rails.root.join('test', 'mocks', 'open_id_authentication_mock.rb').to_s
22
22
23 require File.expand_path(File.dirname(__FILE__) + '/object_helpers')
23 require File.expand_path(File.dirname(__FILE__) + '/object_helpers')
24 include ObjectHelpers
24 include ObjectHelpers
25
25
26 require 'awesome_nested_set/version'
26 require 'awesome_nested_set/version'
27 require 'net/ldap'
27 require 'net/ldap'
28
28
29 class ActionView::TestCase
29 class ActionView::TestCase
30 helper :application
30 helper :application
31 include ApplicationHelper
31 include ApplicationHelper
32 end
32 end
33
33
34 class ActiveSupport::TestCase
34 class ActiveSupport::TestCase
35 include ActionDispatch::TestProcess
35 include ActionDispatch::TestProcess
36
36
37 self.use_transactional_fixtures = true
37 self.use_transactional_fixtures = true
38 self.use_instantiated_fixtures = false
38 self.use_instantiated_fixtures = false
39
39
40 #ESCAPED_CANT = 'can&#x27;t'
40 #ESCAPED_CANT = 'can&#x27;t'
41 #ESCAPED_UCANT = 'Can&#x27;t'
41 #ESCAPED_UCANT = 'Can&#x27;t'
42 # Rails 4.0.2
42 # Rails 4.0.2
43 ESCAPED_CANT = 'can&#39;t'
43 ESCAPED_CANT = 'can&#39;t'
44 ESCAPED_UCANT = 'Can&#39;t'
44 ESCAPED_UCANT = 'Can&#39;t'
45
45
46 def log_user(login, password)
46 def log_user(login, password)
47 User.anonymous
47 User.anonymous
48 get "/login"
48 get "/login"
49 assert_equal nil, session[:user_id]
49 assert_equal nil, session[:user_id]
50 assert_response :success
50 assert_response :success
51 assert_template "account/login"
51 assert_template "account/login"
52 post "/login", :username => login, :password => password
52 post "/login", :username => login, :password => password
53 assert_equal login, User.find(session[:user_id]).login
53 assert_equal login, User.find(session[:user_id]).login
54 end
54 end
55
55
56 def uploaded_test_file(name, mime)
56 def uploaded_test_file(name, mime)
57 fixture_file_upload("files/#{name}", mime, true)
57 fixture_file_upload("files/#{name}", mime, true)
58 end
58 end
59
59
60 def credentials(user, password=nil)
60 def credentials(user, password=nil)
61 {'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)}
61 {'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)}
62 end
62 end
63
63
64 # Mock out a file
64 # Mock out a file
65 def self.mock_file
65 def self.mock_file
66 file = 'a_file.png'
66 file = 'a_file.png'
67 file.stubs(:size).returns(32)
67 file.stubs(:size).returns(32)
68 file.stubs(:original_filename).returns('a_file.png')
68 file.stubs(:original_filename).returns('a_file.png')
69 file.stubs(:content_type).returns('image/png')
69 file.stubs(:content_type).returns('image/png')
70 file.stubs(:read).returns(false)
70 file.stubs(:read).returns(false)
71 file
71 file
72 end
72 end
73
73
74 def mock_file
74 def mock_file
75 self.class.mock_file
75 self.class.mock_file
76 end
76 end
77
77
78 def mock_file_with_options(options={})
78 def mock_file_with_options(options={})
79 file = ''
79 file = ''
80 file.stubs(:size).returns(32)
80 file.stubs(:size).returns(32)
81 original_filename = options[:original_filename] || nil
81 original_filename = options[:original_filename] || nil
82 file.stubs(:original_filename).returns(original_filename)
82 file.stubs(:original_filename).returns(original_filename)
83 content_type = options[:content_type] || nil
83 content_type = options[:content_type] || nil
84 file.stubs(:content_type).returns(content_type)
84 file.stubs(:content_type).returns(content_type)
85 file.stubs(:read).returns(false)
85 file.stubs(:read).returns(false)
86 file
86 file
87 end
87 end
88
88
89 # Use a temporary directory for attachment related tests
89 # Use a temporary directory for attachment related tests
90 def set_tmp_attachments_directory
90 def set_tmp_attachments_directory
91 Dir.mkdir "#{Rails.root}/tmp/test" unless File.directory?("#{Rails.root}/tmp/test")
91 Dir.mkdir "#{Rails.root}/tmp/test" unless File.directory?("#{Rails.root}/tmp/test")
92 unless File.directory?("#{Rails.root}/tmp/test/attachments")
92 unless File.directory?("#{Rails.root}/tmp/test/attachments")
93 Dir.mkdir "#{Rails.root}/tmp/test/attachments"
93 Dir.mkdir "#{Rails.root}/tmp/test/attachments"
94 end
94 end
95 Attachment.storage_path = "#{Rails.root}/tmp/test/attachments"
95 Attachment.storage_path = "#{Rails.root}/tmp/test/attachments"
96 end
96 end
97
97
98 def set_fixtures_attachments_directory
98 def set_fixtures_attachments_directory
99 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
99 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
100 end
100 end
101
101
102 def with_settings(options, &block)
102 def with_settings(options, &block)
103 saved_settings = options.keys.inject({}) do |h, k|
103 saved_settings = options.keys.inject({}) do |h, k|
104 h[k] = case Setting[k]
104 h[k] = case Setting[k]
105 when Symbol, false, true, nil
105 when Symbol, false, true, nil
106 Setting[k]
106 Setting[k]
107 else
107 else
108 Setting[k].dup
108 Setting[k].dup
109 end
109 end
110 h
110 h
111 end
111 end
112 options.each {|k, v| Setting[k] = v}
112 options.each {|k, v| Setting[k] = v}
113 yield
113 yield
114 ensure
114 ensure
115 saved_settings.each {|k, v| Setting[k] = v} if saved_settings
115 saved_settings.each {|k, v| Setting[k] = v} if saved_settings
116 end
116 end
117
117
118 # Yields the block with user as the current user
118 # Yields the block with user as the current user
119 def with_current_user(user, &block)
119 def with_current_user(user, &block)
120 saved_user = User.current
120 saved_user = User.current
121 User.current = user
121 User.current = user
122 yield
122 yield
123 ensure
123 ensure
124 User.current = saved_user
124 User.current = saved_user
125 end
125 end
126
126
127 def with_locale(locale, &block)
127 def with_locale(locale, &block)
128 saved_localed = ::I18n.locale
128 saved_localed = ::I18n.locale
129 ::I18n.locale = locale
129 ::I18n.locale = locale
130 yield
130 yield
131 ensure
131 ensure
132 ::I18n.locale = saved_localed
132 ::I18n.locale = saved_localed
133 end
133 end
134
134
135 def change_user_password(login, new_password)
136 user = User.where(:login => login).first
137 user.password, user.password_confirmation = new_password, new_password
138 user.save!
139 end
140
141 def self.ldap_configured?
135 def self.ldap_configured?
142 @test_ldap = Net::LDAP.new(:host => '127.0.0.1', :port => 389)
136 @test_ldap = Net::LDAP.new(:host => '127.0.0.1', :port => 389)
143 return @test_ldap.bind
137 return @test_ldap.bind
144 rescue Exception => e
138 rescue Exception => e
145 # LDAP is not listening
139 # LDAP is not listening
146 return nil
140 return nil
147 end
141 end
148
142
149 def self.convert_installed?
143 def self.convert_installed?
150 Redmine::Thumbnail.convert_available?
144 Redmine::Thumbnail.convert_available?
151 end
145 end
152
146
153 # Returns the path to the test +vendor+ repository
147 # Returns the path to the test +vendor+ repository
154 def self.repository_path(vendor)
148 def self.repository_path(vendor)
155 path = Rails.root.join("tmp/test/#{vendor.downcase}_repository").to_s
149 path = Rails.root.join("tmp/test/#{vendor.downcase}_repository").to_s
156 # Unlike ruby, JRuby returns Rails.root with backslashes under Windows
150 # Unlike ruby, JRuby returns Rails.root with backslashes under Windows
157 path.tr("\\", "/")
151 path.tr("\\", "/")
158 end
152 end
159
153
160 # Returns the url of the subversion test repository
154 # Returns the url of the subversion test repository
161 def self.subversion_repository_url
155 def self.subversion_repository_url
162 path = repository_path('subversion')
156 path = repository_path('subversion')
163 path = '/' + path unless path.starts_with?('/')
157 path = '/' + path unless path.starts_with?('/')
164 "file://#{path}"
158 "file://#{path}"
165 end
159 end
166
160
167 # Returns true if the +vendor+ test repository is configured
161 # Returns true if the +vendor+ test repository is configured
168 def self.repository_configured?(vendor)
162 def self.repository_configured?(vendor)
169 File.directory?(repository_path(vendor))
163 File.directory?(repository_path(vendor))
170 end
164 end
171
165
172 def repository_path_hash(arr)
166 def repository_path_hash(arr)
173 hs = {}
167 hs = {}
174 hs[:path] = arr.join("/")
168 hs[:path] = arr.join("/")
175 hs[:param] = arr.join("/")
169 hs[:param] = arr.join("/")
176 hs
170 hs
177 end
171 end
178
172
179 def assert_save(object)
173 def assert_save(object)
180 saved = object.save
174 saved = object.save
181 message = "#{object.class} could not be saved"
175 message = "#{object.class} could not be saved"
182 errors = object.errors.full_messages.map {|m| "- #{m}"}
176 errors = object.errors.full_messages.map {|m| "- #{m}"}
183 message << ":\n#{errors.join("\n")}" if errors.any?
177 message << ":\n#{errors.join("\n")}" if errors.any?
184 assert_equal true, saved, message
178 assert_equal true, saved, message
185 end
179 end
186
180
187 def assert_select_error(arg)
181 def assert_select_error(arg)
188 assert_select '#errorExplanation', :text => arg
182 assert_select '#errorExplanation', :text => arg
189 end
183 end
190
184
191 def assert_include(expected, s, message=nil)
185 def assert_include(expected, s, message=nil)
192 assert s.include?(expected), (message || "\"#{expected}\" not found in \"#{s}\"")
186 assert s.include?(expected), (message || "\"#{expected}\" not found in \"#{s}\"")
193 end
187 end
194
188
195 def assert_not_include(expected, s, message=nil)
189 def assert_not_include(expected, s, message=nil)
196 assert !s.include?(expected), (message || "\"#{expected}\" found in \"#{s}\"")
190 assert !s.include?(expected), (message || "\"#{expected}\" found in \"#{s}\"")
197 end
191 end
198
192
199 def assert_select_in(text, *args, &block)
193 def assert_select_in(text, *args, &block)
200 d = HTML::Document.new(CGI::unescapeHTML(String.new(text))).root
194 d = HTML::Document.new(CGI::unescapeHTML(String.new(text))).root
201 assert_select(d, *args, &block)
195 assert_select(d, *args, &block)
202 end
196 end
203
197
204 def assert_mail_body_match(expected, mail, message=nil)
198 def assert_mail_body_match(expected, mail, message=nil)
205 if expected.is_a?(String)
199 if expected.is_a?(String)
206 assert_include expected, mail_body(mail), message
200 assert_include expected, mail_body(mail), message
207 else
201 else
208 assert_match expected, mail_body(mail), message
202 assert_match expected, mail_body(mail), message
209 end
203 end
210 end
204 end
211
205
212 def assert_mail_body_no_match(expected, mail, message=nil)
206 def assert_mail_body_no_match(expected, mail, message=nil)
213 if expected.is_a?(String)
207 if expected.is_a?(String)
214 assert_not_include expected, mail_body(mail), message
208 assert_not_include expected, mail_body(mail), message
215 else
209 else
216 assert_no_match expected, mail_body(mail), message
210 assert_no_match expected, mail_body(mail), message
217 end
211 end
218 end
212 end
219
213
220 def mail_body(mail)
214 def mail_body(mail)
221 mail.parts.first.body.encoded
215 mail.parts.first.body.encoded
222 end
216 end
223
217
224 # awesome_nested_set new node lft and rgt value changed this refactor revision.
218 # awesome_nested_set new node lft and rgt value changed this refactor revision.
225 # https://github.com/collectiveidea/awesome_nested_set/commit/199fca9bb938e40200cd90714dc69247ef017c61
219 # https://github.com/collectiveidea/awesome_nested_set/commit/199fca9bb938e40200cd90714dc69247ef017c61
226 # The reason of behavior change is that "self.class.base_class.unscoped" was added to this line.
220 # The reason of behavior change is that "self.class.base_class.unscoped" was added to this line.
227 # https://github.com/collectiveidea/awesome_nested_set/commit/199fca9bb9#diff-f61b59a5e6319024e211b0ffdd0e4ef1R273
221 # https://github.com/collectiveidea/awesome_nested_set/commit/199fca9bb9#diff-f61b59a5e6319024e211b0ffdd0e4ef1R273
228 # It seems correct behavior because of this line comment.
222 # It seems correct behavior because of this line comment.
229 # https://github.com/collectiveidea/awesome_nested_set/blame/199fca9bb9/lib/awesome_nested_set/model.rb#L278
223 # https://github.com/collectiveidea/awesome_nested_set/blame/199fca9bb9/lib/awesome_nested_set/model.rb#L278
230 def new_issue_lft
224 def new_issue_lft
231 # ::AwesomeNestedSet::VERSION > "2.1.6" ? Issue.maximum(:rgt) + 1 : 1
225 # ::AwesomeNestedSet::VERSION > "2.1.6" ? Issue.maximum(:rgt) + 1 : 1
232 Issue.maximum(:rgt) + 1
226 Issue.maximum(:rgt) + 1
233 end
227 end
234 end
228 end
235
229
236 module Redmine
230 module Redmine
237 class RoutingTest < ActionDispatch::IntegrationTest
231 class RoutingTest < ActionDispatch::IntegrationTest
238 def should_route(arg)
232 def should_route(arg)
239 arg = arg.dup
233 arg = arg.dup
240 request = arg.keys.detect {|key| key.is_a?(String)}
234 request = arg.keys.detect {|key| key.is_a?(String)}
241 raise ArgumentError unless request
235 raise ArgumentError unless request
242 options = arg.slice!(request)
236 options = arg.slice!(request)
243
237
244 raise ArgumentError unless request =~ /\A(GET|POST|PUT|PATCH|DELETE)\s+(.+)\z/
238 raise ArgumentError unless request =~ /\A(GET|POST|PUT|PATCH|DELETE)\s+(.+)\z/
245 method, path = $1.downcase.to_sym, $2
239 method, path = $1.downcase.to_sym, $2
246
240
247 raise ArgumentError unless arg.values.first =~ /\A(.+)#(.+)\z/
241 raise ArgumentError unless arg.values.first =~ /\A(.+)#(.+)\z/
248 controller, action = $1, $2
242 controller, action = $1, $2
249
243
250 assert_routing(
244 assert_routing(
251 {:method => method, :path => path},
245 {:method => method, :path => path},
252 options.merge(:controller => controller, :action => action)
246 options.merge(:controller => controller, :action => action)
253 )
247 )
254 end
248 end
255 end
249 end
256
250
257 module ApiTest
251 module ApiTest
258 API_FORMATS = %w(json xml).freeze
252 API_FORMATS = %w(json xml).freeze
259
253
260 # Base class for API tests
254 # Base class for API tests
261 class Base < ActionDispatch::IntegrationTest
255 class Base < ActionDispatch::IntegrationTest
262 end
256 end
263
257
264 class Routing < Redmine::RoutingTest
258 class Routing < Redmine::RoutingTest
265 def should_route(arg)
259 def should_route(arg)
266 arg = arg.dup
260 arg = arg.dup
267 request = arg.keys.detect {|key| key.is_a?(String)}
261 request = arg.keys.detect {|key| key.is_a?(String)}
268 raise ArgumentError unless request
262 raise ArgumentError unless request
269 options = arg.slice!(request)
263 options = arg.slice!(request)
270
264
271 API_FORMATS.each do |format|
265 API_FORMATS.each do |format|
272 format_request = request.sub /$/, ".#{format}"
266 format_request = request.sub /$/, ".#{format}"
273 super options.merge(format_request => arg[request], :format => format)
267 super options.merge(format_request => arg[request], :format => format)
274 end
268 end
275 end
269 end
276 end
270 end
277 end
271 end
278 end
272 end
279
273
280 # URL helpers do not work with config.threadsafe!
274 # URL helpers do not work with config.threadsafe!
281 # https://github.com/rspec/rspec-rails/issues/476#issuecomment-4705454
275 # https://github.com/rspec/rspec-rails/issues/476#issuecomment-4705454
282 ActionView::TestCase::TestController.instance_eval do
276 ActionView::TestCase::TestController.instance_eval do
283 helper Rails.application.routes.url_helpers
277 helper Rails.application.routes.url_helpers
284 end
278 end
285 ActionView::TestCase::TestController.class_eval do
279 ActionView::TestCase::TestController.class_eval do
286 def _routes
280 def _routes
287 Rails.application.routes
281 Rails.application.routes
288 end
282 end
289 end
283 end
General Comments 0
You need to be logged in to leave comments. Login now