##// END OF EJS Templates
Reset current user before helpers tests....
Jean-Philippe Lang -
r15849:9d747d6811ed
parent child
Show More
@@ -1,401 +1,404
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 if ENV["COVERAGE"]
19 19 require 'simplecov'
20 20 require File.expand_path(File.dirname(__FILE__) + "/coverage/html_formatter")
21 21 SimpleCov.formatter = Redmine::Coverage::HtmlFormatter
22 22 SimpleCov.start 'rails'
23 23 end
24 24
25 25 $redmine_test_ldap_server = ENV['REDMINE_TEST_LDAP_SERVER'] || '127.0.0.1'
26 26
27 27 ENV["RAILS_ENV"] = "test"
28 28 require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
29 29 require 'rails/test_help'
30 30 require Rails.root.join('test', 'mocks', 'open_id_authentication_mock.rb').to_s
31 31
32 32 require File.expand_path(File.dirname(__FILE__) + '/object_helpers')
33 33 include ObjectHelpers
34 34
35 35 require 'net/ldap'
36 36 require 'mocha/setup'
37 37
38 38 Redmine::SudoMode.disable!
39 39
40 40 class ActionView::TestCase
41 41 helper :application
42 42 include ApplicationHelper
43 43 end
44 44
45 45 class ActiveSupport::TestCase
46 46 include ActionDispatch::TestProcess
47 47
48 48 self.use_transactional_fixtures = true
49 49 self.use_instantiated_fixtures = false
50 50
51 51 def uploaded_test_file(name, mime)
52 52 fixture_file_upload("files/#{name}", mime, true)
53 53 end
54 54
55 55 # Mock out a file
56 56 def self.mock_file
57 57 file = 'a_file.png'
58 58 file.stubs(:size).returns(32)
59 59 file.stubs(:original_filename).returns('a_file.png')
60 60 file.stubs(:content_type).returns('image/png')
61 61 file.stubs(:read).returns(false)
62 62 file
63 63 end
64 64
65 65 def mock_file
66 66 self.class.mock_file
67 67 end
68 68
69 69 def mock_file_with_options(options={})
70 70 file = ''
71 71 file.stubs(:size).returns(32)
72 72 original_filename = options[:original_filename] || nil
73 73 file.stubs(:original_filename).returns(original_filename)
74 74 content_type = options[:content_type] || nil
75 75 file.stubs(:content_type).returns(content_type)
76 76 file.stubs(:read).returns(false)
77 77 file
78 78 end
79 79
80 80 # Use a temporary directory for attachment related tests
81 81 def set_tmp_attachments_directory
82 82 Dir.mkdir "#{Rails.root}/tmp/test" unless File.directory?("#{Rails.root}/tmp/test")
83 83 unless File.directory?("#{Rails.root}/tmp/test/attachments")
84 84 Dir.mkdir "#{Rails.root}/tmp/test/attachments"
85 85 end
86 86 Attachment.storage_path = "#{Rails.root}/tmp/test/attachments"
87 87 end
88 88
89 89 def set_fixtures_attachments_directory
90 90 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
91 91 end
92 92
93 93 def with_settings(options, &block)
94 94 saved_settings = options.keys.inject({}) do |h, k|
95 95 h[k] = case Setting[k]
96 96 when Symbol, false, true, nil
97 97 Setting[k]
98 98 else
99 99 Setting[k].dup
100 100 end
101 101 h
102 102 end
103 103 options.each {|k, v| Setting[k] = v}
104 104 yield
105 105 ensure
106 106 saved_settings.each {|k, v| Setting[k] = v} if saved_settings
107 107 end
108 108
109 109 # Yields the block with user as the current user
110 110 def with_current_user(user, &block)
111 111 saved_user = User.current
112 112 User.current = user
113 113 yield
114 114 ensure
115 115 User.current = saved_user
116 116 end
117 117
118 118 def with_locale(locale, &block)
119 119 saved_localed = ::I18n.locale
120 120 ::I18n.locale = locale
121 121 yield
122 122 ensure
123 123 ::I18n.locale = saved_localed
124 124 end
125 125
126 126 def self.ldap_configured?
127 127 @test_ldap = Net::LDAP.new(:host => $redmine_test_ldap_server, :port => 389)
128 128 return @test_ldap.bind
129 129 rescue Exception => e
130 130 # LDAP is not listening
131 131 return nil
132 132 end
133 133
134 134 def self.convert_installed?
135 135 Redmine::Thumbnail.convert_available?
136 136 end
137 137
138 138 def convert_installed?
139 139 self.class.convert_installed?
140 140 end
141 141
142 142 # Returns the path to the test +vendor+ repository
143 143 def self.repository_path(vendor)
144 144 path = Rails.root.join("tmp/test/#{vendor.downcase}_repository").to_s
145 145 # Unlike ruby, JRuby returns Rails.root with backslashes under Windows
146 146 path.tr("\\", "/")
147 147 end
148 148
149 149 # Returns the url of the subversion test repository
150 150 def self.subversion_repository_url
151 151 path = repository_path('subversion')
152 152 path = '/' + path unless path.starts_with?('/')
153 153 "file://#{path}"
154 154 end
155 155
156 156 # Returns true if the +vendor+ test repository is configured
157 157 def self.repository_configured?(vendor)
158 158 File.directory?(repository_path(vendor))
159 159 end
160 160
161 161 def repository_path_hash(arr)
162 162 hs = {}
163 163 hs[:path] = arr.join("/")
164 164 hs[:param] = arr.join("/")
165 165 hs
166 166 end
167 167
168 168 def sqlite?
169 169 ActiveRecord::Base.connection.adapter_name =~ /sqlite/i
170 170 end
171 171
172 172 def mysql?
173 173 ActiveRecord::Base.connection.adapter_name =~ /mysql/i
174 174 end
175 175
176 176 def postgresql?
177 177 ActiveRecord::Base.connection.adapter_name =~ /postgresql/i
178 178 end
179 179
180 180 def quoted_date(date)
181 181 date = Date.parse(date) if date.is_a?(String)
182 182 ActiveRecord::Base.connection.quoted_date(date)
183 183 end
184 184
185 185 # Asserts that a new record for the given class is created
186 186 # and returns it
187 187 def new_record(klass, &block)
188 188 new_records(klass, 1, &block).first
189 189 end
190 190
191 191 # Asserts that count new records for the given class are created
192 192 # and returns them as an array order by object id
193 193 def new_records(klass, count, &block)
194 194 assert_difference "#{klass}.count", count do
195 195 yield
196 196 end
197 197 klass.order(:id => :desc).limit(count).to_a.reverse
198 198 end
199 199
200 200 def assert_save(object)
201 201 saved = object.save
202 202 message = "#{object.class} could not be saved"
203 203 errors = object.errors.full_messages.map {|m| "- #{m}"}
204 204 message << ":\n#{errors.join("\n")}" if errors.any?
205 205 assert_equal true, saved, message
206 206 end
207 207
208 208 def assert_select_error(arg)
209 209 assert_select '#errorExplanation', :text => arg
210 210 end
211 211
212 212 def assert_include(expected, s, message=nil)
213 213 assert s.include?(expected), (message || "\"#{expected}\" not found in \"#{s}\"")
214 214 end
215 215
216 216 def assert_not_include(expected, s, message=nil)
217 217 assert !s.include?(expected), (message || "\"#{expected}\" found in \"#{s}\"")
218 218 end
219 219
220 220 def assert_select_in(text, *args, &block)
221 221 d = Nokogiri::HTML(CGI::unescapeHTML(String.new(text))).root
222 222 assert_select(d, *args, &block)
223 223 end
224 224
225 225 def assert_select_email(*args, &block)
226 226 email = ActionMailer::Base.deliveries.last
227 227 assert_not_nil email
228 228 html_body = email.parts.detect {|part| part.content_type.include?('text/html')}.try(&:body)
229 229 assert_not_nil html_body
230 230 assert_select_in html_body.encoded, *args, &block
231 231 end
232 232
233 233 def assert_mail_body_match(expected, mail, message=nil)
234 234 if expected.is_a?(String)
235 235 assert_include expected, mail_body(mail), message
236 236 else
237 237 assert_match expected, mail_body(mail), message
238 238 end
239 239 end
240 240
241 241 def assert_mail_body_no_match(expected, mail, message=nil)
242 242 if expected.is_a?(String)
243 243 assert_not_include expected, mail_body(mail), message
244 244 else
245 245 assert_no_match expected, mail_body(mail), message
246 246 end
247 247 end
248 248
249 249 def mail_body(mail)
250 250 mail.parts.first.body.encoded
251 251 end
252 252
253 253 # Returns the lft value for a new root issue
254 254 def new_issue_lft
255 255 1
256 256 end
257 257 end
258 258
259 259 module Redmine
260 260 class RoutingTest < ActionDispatch::IntegrationTest
261 261 def should_route(arg)
262 262 arg = arg.dup
263 263 request = arg.keys.detect {|key| key.is_a?(String)}
264 264 raise ArgumentError unless request
265 265 options = arg.slice!(request)
266 266
267 267 raise ArgumentError unless request =~ /\A(GET|POST|PUT|PATCH|DELETE)\s+(.+)\z/
268 268 method, path = $1.downcase.to_sym, $2
269 269
270 270 raise ArgumentError unless arg.values.first =~ /\A(.+)#(.+)\z/
271 271 controller, action = $1, $2
272 272
273 273 assert_routing(
274 274 {:method => method, :path => path},
275 275 options.merge(:controller => controller, :action => action)
276 276 )
277 277 end
278 278 end
279 279
280 280 class HelperTest < ActionView::TestCase
281
281 def setup
282 super
283 User.current = nil
284 end
282 285 end
283 286
284 287 class ControllerTest < ActionController::TestCase
285 288 # Returns the issues that are displayed in the list in the same order
286 289 def issues_in_list
287 290 ids = css_select('tr.issue td.id').map(&:text).map(&:to_i)
288 291 Issue.where(:id => ids).sort_by {|issue| ids.index(issue.id)}
289 292 end
290 293
291 294 # Return the columns that are displayed in the list
292 295 def columns_in_issues_list
293 296 css_select('table.issues thead th:not(.checkbox)').map(&:text)
294 297 end
295 298
296 299 # Verifies that the query filters match the expected filters
297 300 def assert_query_filters(expected_filters)
298 301 response.body =~ /initFilters\(\);\s*((addFilter\(.+\);\s*)*)/
299 302 filter_init = $1.to_s
300 303
301 304 expected_filters.each do |field, operator, values|
302 305 s = "addFilter(#{field.to_json}, #{operator.to_json}, #{Array(values).to_json});"
303 306 assert_include s, filter_init
304 307 end
305 308 assert_equal expected_filters.size, filter_init.scan("addFilter").size, "filters counts don't match"
306 309 end
307 310
308 311 def process(method, path, parameters={}, session={}, flash={})
309 312 if parameters.key?(:params) || parameters.key?(:session)
310 313 raise ArgumentError if session.present?
311 314 super method, path, parameters[:params], parameters[:session], parameters.except(:params, :session)
312 315 else
313 316 super
314 317 end
315 318 end
316 319 end
317 320
318 321 class IntegrationTest < ActionDispatch::IntegrationTest
319 322 def log_user(login, password)
320 323 User.anonymous
321 324 get "/login"
322 325 assert_nil session[:user_id]
323 326 assert_response :success
324 327
325 328 post "/login", :username => login, :password => password
326 329 assert_equal login, User.find(session[:user_id]).login
327 330 end
328 331
329 332 def credentials(user, password=nil)
330 333 {'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)}
331 334 end
332 335 end
333 336
334 337 module ApiTest
335 338 API_FORMATS = %w(json xml).freeze
336 339
337 340 # Base class for API tests
338 341 class Base < Redmine::IntegrationTest
339 342 def setup
340 343 Setting.rest_api_enabled = '1'
341 344 end
342 345
343 346 def teardown
344 347 Setting.rest_api_enabled = '0'
345 348 end
346 349
347 350 # Uploads content using the XML API and returns the attachment token
348 351 def xml_upload(content, credentials)
349 352 upload('xml', content, credentials)
350 353 end
351 354
352 355 # Uploads content using the JSON API and returns the attachment token
353 356 def json_upload(content, credentials)
354 357 upload('json', content, credentials)
355 358 end
356 359
357 360 def upload(format, content, credentials)
358 361 set_tmp_attachments_directory
359 362 assert_difference 'Attachment.count' do
360 363 post "/uploads.#{format}", content, {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials)
361 364 assert_response :created
362 365 end
363 366 data = response_data
364 367 assert_kind_of Hash, data['upload']
365 368 token = data['upload']['token']
366 369 assert_not_nil token
367 370 token
368 371 end
369 372
370 373 # Parses the response body based on its content type
371 374 def response_data
372 375 unless response.content_type.to_s =~ /^application\/(.+)/
373 376 raise "Unexpected response type: #{response.content_type}"
374 377 end
375 378 format = $1
376 379 case format
377 380 when 'xml'
378 381 Hash.from_xml(response.body)
379 382 when 'json'
380 383 ActiveSupport::JSON.decode(response.body)
381 384 else
382 385 raise "Unknown response format: #{format}"
383 386 end
384 387 end
385 388 end
386 389
387 390 class Routing < Redmine::RoutingTest
388 391 def should_route(arg)
389 392 arg = arg.dup
390 393 request = arg.keys.detect {|key| key.is_a?(String)}
391 394 raise ArgumentError unless request
392 395 options = arg.slice!(request)
393 396
394 397 API_FORMATS.each do |format|
395 398 format_request = request.sub /$/, ".#{format}"
396 399 super options.merge(format_request => arg[request], :format => format)
397 400 end
398 401 end
399 402 end
400 403 end
401 404 end
@@ -1,102 +1,103
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class ActivitiesHelperTest < Redmine::HelperTest
21 21 include ActivitiesHelper
22 22 include Redmine::I18n
23 23
24 24 class MockEvent
25 25 attr_reader :event_datetime, :event_group, :name
26 26
27 27 def initialize(group=nil)
28 28 @@count ||= 0
29 29 @name = "e#{@@count}"
30 30 @event_datetime = Time.now + @@count.hours
31 31 @event_group = group || self
32 32 @@count += 1
33 33 end
34 34
35 35 def self.clear
36 36 @@count = 0
37 37 end
38 38 end
39 39
40 40 def setup
41 super
41 42 MockEvent.clear
42 43 end
43 44
44 45 def test_sort_activity_events_should_sort_by_datetime
45 46 events = []
46 47 events << MockEvent.new
47 48 events << MockEvent.new
48 49 events << MockEvent.new
49 50
50 51 assert_equal [
51 52 ['e2', false],
52 53 ['e1', false],
53 54 ['e0', false]
54 55 ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
55 56 end
56 57
57 58 def test_sort_activity_events_should_group_events
58 59 events = []
59 60 events << MockEvent.new
60 61 events << MockEvent.new(events[0])
61 62 events << MockEvent.new(events[0])
62 63
63 64 assert_equal [
64 65 ['e2', false],
65 66 ['e1', true],
66 67 ['e0', true]
67 68 ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
68 69 end
69 70
70 71 def test_sort_activity_events_with_group_not_in_set_should_group_events
71 72 e = MockEvent.new
72 73 events = []
73 74 events << MockEvent.new(e)
74 75 events << MockEvent.new(e)
75 76
76 77 assert_equal [
77 78 ['e2', false],
78 79 ['e1', true]
79 80 ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
80 81 end
81 82
82 83 def test_sort_activity_events_should_sort_by_datetime_and_group
83 84 events = []
84 85 events << MockEvent.new
85 86 events << MockEvent.new
86 87 events << MockEvent.new
87 88 events << MockEvent.new(events[1])
88 89 events << MockEvent.new(events[2])
89 90 events << MockEvent.new
90 91 events << MockEvent.new(events[2])
91 92
92 93 assert_equal [
93 94 ['e6', false],
94 95 ['e4', true],
95 96 ['e2', true],
96 97 ['e5', false],
97 98 ['e3', false],
98 99 ['e1', true],
99 100 ['e0', false]
100 101 ], sort_activity_events(events).map {|event, grouped| [event.name, grouped]}
101 102 end
102 103 end
@@ -1,339 +1,338
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class IssuesHelperTest < Redmine::HelperTest
21 21 include Redmine::I18n
22 22 include IssuesHelper
23 23 include CustomFieldsHelper
24 24 include ERB::Util
25 25 include Rails.application.routes.url_helpers
26 26
27 27 fixtures :projects, :trackers, :issue_statuses, :issues,
28 28 :enumerations, :users, :issue_categories,
29 29 :projects_trackers,
30 30 :roles,
31 31 :member_roles,
32 32 :members,
33 33 :enabled_modules,
34 34 :custom_fields,
35 35 :attachments,
36 36 :versions
37 37
38 38 def setup
39 39 super
40 40 set_language_if_valid('en')
41 User.current = nil
42 41 end
43 42
44 43 def test_issue_heading
45 44 assert_equal "Bug #1", issue_heading(Issue.find(1))
46 45 end
47 46
48 47 def test_issues_destroy_confirmation_message_with_one_root_issue
49 48 assert_equal l(:text_issues_destroy_confirmation),
50 49 issues_destroy_confirmation_message(Issue.find(1))
51 50 end
52 51
53 52 def test_issues_destroy_confirmation_message_with_an_arrayt_of_root_issues
54 53 assert_equal l(:text_issues_destroy_confirmation),
55 54 issues_destroy_confirmation_message(Issue.find([1, 2]))
56 55 end
57 56
58 57 def test_issues_destroy_confirmation_message_with_one_parent_issue
59 58 Issue.find(2).update! :parent_issue_id => 1
60 59 assert_equal l(:text_issues_destroy_confirmation) + "\n" +
61 60 l(:text_issues_destroy_descendants_confirmation, :count => 1),
62 61 issues_destroy_confirmation_message(Issue.find(1))
63 62 end
64 63
65 64 def test_issues_destroy_confirmation_message_with_one_parent_issue_and_its_child
66 65 Issue.find(2).update! :parent_issue_id => 1
67 66 assert_equal l(:text_issues_destroy_confirmation),
68 67 issues_destroy_confirmation_message(Issue.find([1, 2]))
69 68 end
70 69
71 70 def test_issues_destroy_confirmation_message_with_issues_that_share_descendants
72 71 root = Issue.generate!
73 72 child = Issue.generate!(:parent_issue_id => root.id)
74 73 Issue.generate!(:parent_issue_id => child.id)
75 74
76 75 assert_equal l(:text_issues_destroy_confirmation) + "\n" +
77 76 l(:text_issues_destroy_descendants_confirmation, :count => 1),
78 77 issues_destroy_confirmation_message([root.reload, child.reload])
79 78 end
80 79
81 80 test 'show_detail with no_html should show a changing attribute' do
82 81 detail = JournalDetail.new(:property => 'attr', :old_value => '40',
83 82 :value => '100', :prop_key => 'done_ratio')
84 83 assert_equal "% Done changed from 40 to 100", show_detail(detail, true)
85 84 end
86 85
87 86 test 'show_detail with no_html should show a new attribute' do
88 87 detail = JournalDetail.new(:property => 'attr', :old_value => nil,
89 88 :value => '100', :prop_key => 'done_ratio')
90 89 assert_equal "% Done set to 100", show_detail(detail, true)
91 90 end
92 91
93 92 test 'show_detail with no_html should show a deleted attribute' do
94 93 detail = JournalDetail.new(:property => 'attr', :old_value => '50',
95 94 :value => nil, :prop_key => 'done_ratio')
96 95 assert_equal "% Done deleted (50)", show_detail(detail, true)
97 96 end
98 97
99 98 test 'show_detail with html should show a changing attribute with HTML highlights' do
100 99 detail = JournalDetail.new(:property => 'attr', :old_value => '40',
101 100 :value => '100', :prop_key => 'done_ratio')
102 101 html = show_detail(detail, false)
103 102 assert_include '<strong>% Done</strong>', html
104 103 assert_include '<i>40</i>', html
105 104 assert_include '<i>100</i>', html
106 105 end
107 106
108 107 test 'show_detail with html should show a new attribute with HTML highlights' do
109 108 detail = JournalDetail.new(:property => 'attr', :old_value => nil,
110 109 :value => '100', :prop_key => 'done_ratio')
111 110 html = show_detail(detail, false)
112 111 assert_include '<strong>% Done</strong>', html
113 112 assert_include '<i>100</i>', html
114 113 end
115 114
116 115 test 'show_detail with html should show a deleted attribute with HTML highlights' do
117 116 detail = JournalDetail.new(:property => 'attr', :old_value => '50',
118 117 :value => nil, :prop_key => 'done_ratio')
119 118 html = show_detail(detail, false)
120 119 assert_include '<strong>% Done</strong>', html
121 120 assert_include '<del><i>50</i></del>', html
122 121 end
123 122
124 123 test 'show_detail with a start_date attribute should format the dates' do
125 124 detail = JournalDetail.new(
126 125 :property => 'attr',
127 126 :old_value => '2010-01-01',
128 127 :value => '2010-01-31',
129 128 :prop_key => 'start_date'
130 129 )
131 130 with_settings :date_format => '%m/%d/%Y' do
132 131 assert_match "01/31/2010", show_detail(detail, true)
133 132 assert_match "01/01/2010", show_detail(detail, true)
134 133 end
135 134 end
136 135
137 136 test 'show_detail with a due_date attribute should format the dates' do
138 137 detail = JournalDetail.new(
139 138 :property => 'attr',
140 139 :old_value => '2010-01-01',
141 140 :value => '2010-01-31',
142 141 :prop_key => 'due_date'
143 142 )
144 143 with_settings :date_format => '%m/%d/%Y' do
145 144 assert_match "01/31/2010", show_detail(detail, true)
146 145 assert_match "01/01/2010", show_detail(detail, true)
147 146 end
148 147 end
149 148
150 149 test 'show_detail should show old and new values with a project attribute' do
151 150 detail = JournalDetail.new(:property => 'attr', :prop_key => 'project_id',
152 151 :old_value => 1, :value => 2)
153 152 assert_match 'eCookbook', show_detail(detail, true)
154 153 assert_match 'OnlineStore', show_detail(detail, true)
155 154 end
156 155
157 156 test 'show_detail should show old and new values with a issue status attribute' do
158 157 detail = JournalDetail.new(:property => 'attr', :prop_key => 'status_id',
159 158 :old_value => 1, :value => 2)
160 159 assert_match 'New', show_detail(detail, true)
161 160 assert_match 'Assigned', show_detail(detail, true)
162 161 end
163 162
164 163 test 'show_detail should show old and new values with a tracker attribute' do
165 164 detail = JournalDetail.new(:property => 'attr', :prop_key => 'tracker_id',
166 165 :old_value => 1, :value => 2)
167 166 assert_match 'Bug', show_detail(detail, true)
168 167 assert_match 'Feature request', show_detail(detail, true)
169 168 end
170 169
171 170 test 'show_detail should show old and new values with a assigned to attribute' do
172 171 detail = JournalDetail.new(:property => 'attr', :prop_key => 'assigned_to_id',
173 172 :old_value => 1, :value => 2)
174 173 assert_match 'Redmine Admin', show_detail(detail, true)
175 174 assert_match 'John Smith', show_detail(detail, true)
176 175 end
177 176
178 177 test 'show_detail should show old and new values with a priority attribute' do
179 178 detail = JournalDetail.new(:property => 'attr', :prop_key => 'priority_id',
180 179 :old_value => 4, :value => 5)
181 180 assert_match 'Low', show_detail(detail, true)
182 181 assert_match 'Normal', show_detail(detail, true)
183 182 end
184 183
185 184 test 'show_detail should show old and new values with a category attribute' do
186 185 detail = JournalDetail.new(:property => 'attr', :prop_key => 'category_id',
187 186 :old_value => 1, :value => 2)
188 187 assert_match 'Printing', show_detail(detail, true)
189 188 assert_match 'Recipes', show_detail(detail, true)
190 189 end
191 190
192 191 test 'show_detail should show old and new values with a fixed version attribute' do
193 192 detail = JournalDetail.new(:property => 'attr', :prop_key => 'fixed_version_id',
194 193 :old_value => 1, :value => 2)
195 194 assert_match '0.1', show_detail(detail, true)
196 195 assert_match '1.0', show_detail(detail, true)
197 196 end
198 197
199 198 test 'show_detail should show old and new values with a estimated hours attribute' do
200 199 detail = JournalDetail.new(:property => 'attr', :prop_key => 'estimated_hours',
201 200 :old_value => '5', :value => '6.3')
202 201 assert_match '5.00', show_detail(detail, true)
203 202 assert_match '6.30', show_detail(detail, true)
204 203 end
205 204
206 205 test 'show_detail should not show values with a description attribute' do
207 206 detail = JournalDetail.new(:property => 'attr', :prop_key => 'description',
208 207 :old_value => 'Foo', :value => 'Bar')
209 208 assert_equal 'Description updated', show_detail(detail, true)
210 209 end
211 210
212 211 test 'show_detail should show old and new values with a custom field' do
213 212 detail = JournalDetail.new(:property => 'cf', :prop_key => '1',
214 213 :old_value => 'MySQL', :value => 'PostgreSQL')
215 214 assert_equal 'Database changed from MySQL to PostgreSQL', show_detail(detail, true)
216 215 end
217 216
218 217 test 'show_detail should not show values with a long text custom field' do
219 218 field = IssueCustomField.create!(:name => "Long field", :field_format => 'text')
220 219 detail = JournalDetail.new(:property => 'cf', :prop_key => field.id,
221 220 :old_value => 'Foo', :value => 'Bar')
222 221 assert_equal 'Long field updated', show_detail(detail, true)
223 222 end
224 223
225 224 test 'show_detail should show added file' do
226 225 detail = JournalDetail.new(:property => 'attachment', :prop_key => '1',
227 226 :old_value => nil, :value => 'error281.txt')
228 227 assert_match 'error281.txt', show_detail(detail, true)
229 228 end
230 229
231 230 test 'show_detail should show removed file' do
232 231 detail = JournalDetail.new(:property => 'attachment', :prop_key => '1',
233 232 :old_value => 'error281.txt', :value => nil)
234 233 assert_match 'error281.txt', show_detail(detail, true)
235 234 end
236 235
237 236 def test_show_detail_relation_added
238 237 detail = JournalDetail.new(:property => 'relation',
239 238 :prop_key => 'precedes',
240 239 :value => 1)
241 240 assert_equal "Precedes Bug #1: Cannot print recipes added", show_detail(detail, true)
242 241 str = link_to("Bug #1", "/issues/1", :class => Issue.find(1).css_classes)
243 242 assert_equal "<strong>Precedes</strong> <i>#{str}: Cannot print recipes</i> added",
244 243 show_detail(detail, false)
245 244 end
246 245
247 246 def test_show_detail_relation_added_with_inexistant_issue
248 247 inexistant_issue_number = 9999
249 248 assert_nil Issue.find_by_id(inexistant_issue_number)
250 249 detail = JournalDetail.new(:property => 'relation',
251 250 :prop_key => 'precedes',
252 251 :value => inexistant_issue_number)
253 252 assert_equal "Precedes Issue ##{inexistant_issue_number} added", show_detail(detail, true)
254 253 assert_equal "<strong>Precedes</strong> <i>Issue ##{inexistant_issue_number}</i> added", show_detail(detail, false)
255 254 end
256 255
257 256 def test_show_detail_relation_added_should_not_disclose_issue_that_is_not_visible
258 257 issue = Issue.generate!(:is_private => true)
259 258 detail = JournalDetail.new(:property => 'relation',
260 259 :prop_key => 'precedes',
261 260 :value => issue.id)
262 261
263 262 assert_equal "Precedes Issue ##{issue.id} added", show_detail(detail, true)
264 263 assert_equal "<strong>Precedes</strong> <i>Issue ##{issue.id}</i> added", show_detail(detail, false)
265 264 end
266 265
267 266 def test_show_detail_relation_deleted
268 267 detail = JournalDetail.new(:property => 'relation',
269 268 :prop_key => 'precedes',
270 269 :old_value => 1)
271 270 assert_equal "Precedes deleted (Bug #1: Cannot print recipes)", show_detail(detail, true)
272 271 str = link_to("Bug #1",
273 272 "/issues/1",
274 273 :class => Issue.find(1).css_classes)
275 274 assert_equal "<strong>Precedes</strong> deleted (<i>#{str}: Cannot print recipes</i>)",
276 275 show_detail(detail, false)
277 276 end
278 277
279 278 def test_show_detail_relation_deleted_with_inexistant_issue
280 279 inexistant_issue_number = 9999
281 280 assert_nil Issue.find_by_id(inexistant_issue_number)
282 281 detail = JournalDetail.new(:property => 'relation',
283 282 :prop_key => 'precedes',
284 283 :old_value => inexistant_issue_number)
285 284 assert_equal "Precedes deleted (Issue #9999)", show_detail(detail, true)
286 285 assert_equal "<strong>Precedes</strong> deleted (<i>Issue #9999</i>)", show_detail(detail, false)
287 286 end
288 287
289 288 def test_show_detail_relation_deleted_should_not_disclose_issue_that_is_not_visible
290 289 issue = Issue.generate!(:is_private => true)
291 290 detail = JournalDetail.new(:property => 'relation',
292 291 :prop_key => 'precedes',
293 292 :old_value => issue.id)
294 293
295 294 assert_equal "Precedes deleted (Issue ##{issue.id})", show_detail(detail, true)
296 295 assert_equal "<strong>Precedes</strong> deleted (<i>Issue ##{issue.id}</i>)", show_detail(detail, false)
297 296 end
298 297
299 298 def test_details_to_strings_with_multiple_values_removed_from_custom_field
300 299 field = IssueCustomField.generate!(:name => 'User', :field_format => 'user', :multiple => true)
301 300 details = []
302 301 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => '1', :value => nil)
303 302 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => '3', :value => nil)
304 303
305 304 assert_equal ["User deleted (Dave Lopper, Redmine Admin)"], details_to_strings(details, true)
306 305 assert_equal ["<strong>User</strong> deleted (<del><i>Dave Lopper, Redmine Admin</i></del>)"], details_to_strings(details, false)
307 306 end
308 307
309 308 def test_details_to_strings_with_multiple_values_added_to_custom_field
310 309 field = IssueCustomField.generate!(:name => 'User', :field_format => 'user', :multiple => true)
311 310 details = []
312 311 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => nil, :value => '1')
313 312 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => nil, :value => '3')
314 313
315 314 assert_equal ["User Dave Lopper, Redmine Admin added"], details_to_strings(details, true)
316 315 assert_equal ["<strong>User</strong> <i>Dave Lopper, Redmine Admin</i> added"], details_to_strings(details, false)
317 316 end
318 317
319 318 def test_details_to_strings_with_multiple_values_added_and_removed_from_custom_field
320 319 field = IssueCustomField.generate!(:name => 'User', :field_format => 'user', :multiple => true)
321 320 details = []
322 321 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => nil, :value => '1')
323 322 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => '2', :value => nil)
324 323 details << JournalDetail.new(:property => 'cf', :prop_key => field.id.to_s, :old_value => '3', :value => nil)
325 324
326 325 assert_equal [
327 326 "User Redmine Admin added",
328 327 "User deleted (Dave Lopper, John Smith)"
329 328 ], details_to_strings(details, true)
330 329 assert_equal [
331 330 "<strong>User</strong> <i>Redmine Admin</i> added",
332 331 "<strong>User</strong> deleted (<del><i>Dave Lopper, John Smith</i></del>)"
333 332 ], details_to_strings(details, false)
334 333 end
335 334
336 335 def test_find_name_by_reflection_should_return_nil_for_missing_record
337 336 assert_nil find_name_by_reflection('status', 99)
338 337 end
339 338 end
@@ -1,85 +1,84
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class ProjectsHelperTest < Redmine::HelperTest
21 21 include ApplicationHelper
22 22 include ProjectsHelper
23 23 include Redmine::I18n
24 24 include ERB::Util
25 25 include Rails.application.routes.url_helpers
26 26
27 27 fixtures :projects, :trackers, :issue_statuses, :issues,
28 28 :enumerations, :users, :issue_categories,
29 29 :versions,
30 30 :projects_trackers,
31 31 :member_roles,
32 32 :members,
33 33 :groups_users,
34 34 :enabled_modules
35 35
36 36 def setup
37 37 super
38 38 set_language_if_valid('en')
39 User.current = nil
40 39 end
41 40
42 41 def test_link_to_version_within_project
43 42 @project = Project.find(2)
44 43 User.current = User.find(1)
45 44 assert_equal '<a title="07/01/2006" href="/versions/5">Alpha</a>', link_to_version(Version.find(5))
46 45 end
47 46
48 47 def test_link_to_version
49 48 User.current = User.find(1)
50 49 assert_equal '<a title="07/01/2006" href="/versions/5">OnlineStore - Alpha</a>', link_to_version(Version.find(5))
51 50 end
52 51
53 52 def test_link_to_version_without_effective_date
54 53 User.current = User.find(1)
55 54 version = Version.find(5)
56 55 version.effective_date = nil
57 56 assert_equal '<a href="/versions/5">OnlineStore - Alpha</a>', link_to_version(version)
58 57 end
59 58
60 59 def test_link_to_private_version
61 60 assert_equal 'OnlineStore - Alpha', link_to_version(Version.find(5))
62 61 end
63 62
64 63 def test_link_to_version_invalid_version
65 64 assert_equal '', link_to_version(Object)
66 65 end
67 66
68 67 def test_format_version_name_within_project
69 68 @project = Project.find(1)
70 69 assert_equal "0.1", format_version_name(Version.find(1))
71 70 end
72 71
73 72 def test_format_version_name
74 73 assert_equal "eCookbook - 0.1", format_version_name(Version.find(1))
75 74 end
76 75
77 76 def test_format_version_name_for_system_version
78 77 assert_equal "OnlineStore - Systemwide visible version", format_version_name(Version.find(7))
79 78 end
80 79
81 80 def test_version_options_for_select_with_no_versions
82 81 assert_equal '', version_options_for_select([])
83 82 assert_equal '', version_options_for_select([], Version.find(1))
84 83 end
85 84 end
@@ -1,109 +1,110
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class SortHelperTest < Redmine::HelperTest
21 21 include SortHelper
22 22 include Redmine::I18n
23 23 include ERB::Util
24 24
25 25 def setup
26 super
26 27 @session = nil
27 28 @sort_param = nil
28 29 end
29 30
30 31 def test_default_sort_clause_with_array
31 32 sort_init 'attr1', 'desc'
32 33 sort_update(['attr1', 'attr2'])
33 34
34 35 assert_equal ['attr1 DESC'], sort_clause
35 36 end
36 37
37 38 def test_default_sort_clause_with_hash
38 39 sort_init 'attr1', 'desc'
39 40 sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
40 41
41 42 assert_equal ['table1.attr1 DESC'], sort_clause
42 43 end
43 44
44 45 def test_default_sort_clause_with_multiple_columns
45 46 sort_init 'attr1', 'desc'
46 47 sort_update({'attr1' => ['table1.attr1', 'table1.attr2'], 'attr2' => 'table2.attr2'})
47 48
48 49 assert_equal ['table1.attr1 DESC', 'table1.attr2 DESC'], sort_clause
49 50 end
50 51
51 52 def test_params_sort
52 53 @sort_param = 'attr1,attr2:desc'
53 54
54 55 sort_init 'attr1', 'desc'
55 56 sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
56 57
57 58 assert_equal ['table1.attr1 ASC', 'table2.attr2 DESC'], sort_clause
58 59 assert_equal 'attr1,attr2:desc', @session['foo_bar_sort']
59 60 end
60 61
61 62 def test_invalid_params_sort
62 63 @sort_param = 'invalid_key'
63 64
64 65 sort_init 'attr1', 'desc'
65 66 sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
66 67
67 68 assert_equal ['table1.attr1 DESC'], sort_clause
68 69 assert_equal 'attr1:desc', @session['foo_bar_sort']
69 70 end
70 71
71 72 def test_invalid_order_params_sort
72 73 @sort_param = 'attr1:foo:bar,attr2'
73 74
74 75 sort_init 'attr1', 'desc'
75 76 sort_update({'attr1' => 'table1.attr1', 'attr2' => 'table2.attr2'})
76 77
77 78 assert_equal ['table1.attr1 ASC', 'table2.attr2 ASC'], sort_clause
78 79 assert_equal 'attr1,attr2', @session['foo_bar_sort']
79 80 end
80 81
81 82 def test_sort_css_without_params_should_use_default_sort
82 83 sort_init 'attr1', 'desc'
83 84 sort_update(['attr1', 'attr2'])
84 85
85 86 assert_equal 'sort-by-attr1 sort-desc', sort_css_classes
86 87 end
87 88
88 89 def test_sort_css_should_use_params
89 90 @sort_param = 'attr2,attr1'
90 91 sort_init 'attr1', 'desc'
91 92 sort_update(['attr1', 'attr2'])
92 93
93 94 assert_equal 'sort-by-attr2 sort-asc', sort_css_classes
94 95 end
95 96
96 97 def test_sort_css_should_dasherize_sort_name
97 98 sort_init 'foo_bar'
98 99 sort_update(['foo_bar'])
99 100
100 101 assert_equal 'sort-by-foo-bar sort-asc', sort_css_classes
101 102 end
102 103
103 104 private
104 105
105 106 def controller_name; 'foo'; end
106 107 def action_name; 'bar'; end
107 108 def params; {:sort => @sort_param}; end
108 109 def session; @session ||= {}; end
109 110 end
@@ -1,58 +1,54
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class TimelogHelperTest < Redmine::HelperTest
21 21 include TimelogHelper
22 22 include Redmine::I18n
23 23 include ActionView::Helpers::TextHelper
24 24 include ActionView::Helpers::DateHelper
25 25 include ERB::Util
26 26
27 27 fixtures :projects, :roles, :enabled_modules, :users,
28 28 :repositories, :changesets,
29 29 :trackers, :issue_statuses, :issues, :versions, :documents,
30 30 :wikis, :wiki_pages, :wiki_contents,
31 31 :boards, :messages,
32 32 :attachments,
33 33 :enumerations
34 34
35 def setup
36 super
37 end
38
39 35 def test_activities_collection_for_select_options_should_return_array_of_activity_names_and_ids
40 36 activities = activity_collection_for_select_options
41 37 assert activities.include?(["Design", 9])
42 38 assert activities.include?(["Development", 10])
43 39 end
44 40
45 41 def test_activities_collection_for_select_options_should_not_include_inactive_activities
46 42 activities = activity_collection_for_select_options
47 43 assert !activities.include?(["Inactive Activity", 14])
48 44 end
49 45
50 46 def test_activities_collection_for_select_options_should_use_the_projects_override
51 47 project = Project.find(1)
52 48 override_activity = TimeEntryActivity.create!({:name => "Design override", :parent => TimeEntryActivity.find_by_name("Design"), :project => project})
53 49
54 50 activities = activity_collection_for_select_options(nil, project)
55 51 assert !activities.include?(["Design", 9]), "System activity found in: " + activities.inspect
56 52 assert activities.include?(["Design override", override_activity.id]), "Override activity not found in: " + activities.inspect
57 53 end
58 54 end
@@ -1,74 +1,73
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class WatchersHelperTest < Redmine::HelperTest
21 21 include WatchersHelper
22 22 include Redmine::I18n
23 23 include Rails.application.routes.url_helpers
24 24
25 25 fixtures :users, :issues
26 26
27 27 def setup
28 28 super
29 29 set_language_if_valid('en')
30 User.current = nil
31 30 end
32 31
33 32 test '#watcher_link with a non-watched object' do
34 33 expected = link_to(
35 34 "Watch",
36 35 "/watchers/watch?object_id=1&object_type=issue",
37 36 :remote => true, :method => 'post', :class => "issue-1-watcher icon icon-fav-off"
38 37 )
39 38 assert_equal expected, watcher_link(Issue.find(1), User.find(1))
40 39 end
41 40
42 41 test '#watcher_link with a single objet array' do
43 42 expected = link_to(
44 43 "Watch",
45 44 "/watchers/watch?object_id=1&object_type=issue",
46 45 :remote => true, :method => 'post', :class => "issue-1-watcher icon icon-fav-off"
47 46 )
48 47 assert_equal expected, watcher_link([Issue.find(1)], User.find(1))
49 48 end
50 49
51 50 test '#watcher_link with a multiple objets array' do
52 51 expected = link_to(
53 52 "Watch",
54 53 "/watchers/watch?object_id%5B%5D=1&object_id%5B%5D=3&object_type=issue",
55 54 :remote => true, :method => 'post', :class => "issue-bulk-watcher icon icon-fav-off"
56 55 )
57 56 assert_equal expected, watcher_link([Issue.find(1), Issue.find(3)], User.find(1))
58 57 end
59 58
60 59 def test_watcher_link_with_nil_should_return_empty_string
61 60 assert_equal '', watcher_link(nil, User.find(1))
62 61 end
63 62
64 63 test '#watcher_link with a watched object' do
65 64 Watcher.create!(:watchable => Issue.find(1), :user => User.find(1))
66 65
67 66 expected = link_to(
68 67 "Unwatch",
69 68 "/watchers/watch?object_id=1&object_type=issue",
70 69 :remote => true, :method => 'delete', :class => "issue-1-watcher icon icon-fav"
71 70 )
72 71 assert_equal expected, watcher_link(Issue.find(1), User.find(1))
73 72 end
74 73 end
General Comments 0
You need to be logged in to leave comments. Login now