Mercurial > hg > soundsoftware-site
comparison .svn/pristine/29/29e8e11e7b7fba04b2ca11546151e862eaeb8161.svn-base @ 1517:dffacf8a6908 redmine-2.5
Update to Redmine SVN revision 13367 on 2.5-stable branch
author | Chris Cannam |
---|---|
date | Tue, 09 Sep 2014 09:29:00 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1516:b450a9d58aed | 1517:dffacf8a6908 |
---|---|
1 # encoding: utf-8 | |
2 # | |
3 # Redmine - project management software | |
4 # Copyright (C) 2006-2014 Jean-Philippe Lang | |
5 # | |
6 # This program is free software; you can redistribute it and/or | |
7 # modify it under the terms of the GNU General Public License | |
8 # as published by the Free Software Foundation; either version 2 | |
9 # of the License, or (at your option) any later version. | |
10 # | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU General Public License for more details. | |
15 # | |
16 # You should have received a copy of the GNU General Public License | |
17 # along with this program; if not, write to the Free Software | |
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 | |
20 require File.expand_path('../../test_helper', __FILE__) | |
21 | |
22 class ChangesetTest < ActiveSupport::TestCase | |
23 fixtures :projects, :repositories, | |
24 :issues, :issue_statuses, :issue_categories, | |
25 :changesets, :changes, | |
26 :enumerations, | |
27 :custom_fields, :custom_values, | |
28 :users, :members, :member_roles, :trackers, | |
29 :enabled_modules, :roles | |
30 | |
31 def test_ref_keywords_any | |
32 ActionMailer::Base.deliveries.clear | |
33 Setting.commit_ref_keywords = '*' | |
34 Setting.commit_update_keywords = [{'keywords' => 'fixes , closes', 'status_id' => '5', 'done_ratio' => '90'}] | |
35 | |
36 c = Changeset.new(:repository => Project.find(1).repository, | |
37 :committed_on => Time.now, | |
38 :comments => 'New commit (#2). Fixes #1', | |
39 :revision => '12345') | |
40 assert c.save | |
41 assert_equal [1, 2], c.issue_ids.sort | |
42 fixed = Issue.find(1) | |
43 assert fixed.closed? | |
44 assert_equal 90, fixed.done_ratio | |
45 assert_equal 1, ActionMailer::Base.deliveries.size | |
46 end | |
47 | |
48 def test_ref_keywords | |
49 Setting.commit_ref_keywords = 'refs' | |
50 Setting.commit_update_keywords = '' | |
51 c = Changeset.new(:repository => Project.find(1).repository, | |
52 :committed_on => Time.now, | |
53 :comments => 'Ignores #2. Refs #1', | |
54 :revision => '12345') | |
55 assert c.save | |
56 assert_equal [1], c.issue_ids.sort | |
57 end | |
58 | |
59 def test_ref_keywords_any_only | |
60 Setting.commit_ref_keywords = '*' | |
61 Setting.commit_update_keywords = '' | |
62 c = Changeset.new(:repository => Project.find(1).repository, | |
63 :committed_on => Time.now, | |
64 :comments => 'Ignores #2. Refs #1', | |
65 :revision => '12345') | |
66 assert c.save | |
67 assert_equal [1, 2], c.issue_ids.sort | |
68 end | |
69 | |
70 def test_ref_keywords_any_with_timelog | |
71 Setting.commit_ref_keywords = '*' | |
72 Setting.commit_logtime_enabled = '1' | |
73 | |
74 { | |
75 '2' => 2.0, | |
76 '2h' => 2.0, | |
77 '2hours' => 2.0, | |
78 '15m' => 0.25, | |
79 '15min' => 0.25, | |
80 '3h15' => 3.25, | |
81 '3h15m' => 3.25, | |
82 '3h15min' => 3.25, | |
83 '3:15' => 3.25, | |
84 '3.25' => 3.25, | |
85 '3.25h' => 3.25, | |
86 '3,25' => 3.25, | |
87 '3,25h' => 3.25, | |
88 }.each do |syntax, expected_hours| | |
89 c = Changeset.new(:repository => Project.find(1).repository, | |
90 :committed_on => 24.hours.ago, | |
91 :comments => "Worked on this issue #1 @#{syntax}", | |
92 :revision => '520', | |
93 :user => User.find(2)) | |
94 assert_difference 'TimeEntry.count' do | |
95 c.scan_comment_for_issue_ids | |
96 end | |
97 assert_equal [1], c.issue_ids.sort | |
98 | |
99 time = TimeEntry.order('id desc').first | |
100 assert_equal 1, time.issue_id | |
101 assert_equal 1, time.project_id | |
102 assert_equal 2, time.user_id | |
103 assert_equal expected_hours, time.hours, | |
104 "@#{syntax} should be logged as #{expected_hours} hours but was #{time.hours}" | |
105 assert_equal Date.yesterday, time.spent_on | |
106 assert time.activity.is_default? | |
107 assert time.comments.include?('r520'), | |
108 "r520 was expected in time_entry comments: #{time.comments}" | |
109 end | |
110 end | |
111 | |
112 def test_ref_keywords_closing_with_timelog | |
113 Setting.commit_ref_keywords = '*' | |
114 Setting.commit_update_keywords = [{'keywords' => 'fixes , closes', | |
115 'status_id' => IssueStatus.where(:is_closed => true).first.id.to_s}] | |
116 Setting.commit_logtime_enabled = '1' | |
117 | |
118 c = Changeset.new(:repository => Project.find(1).repository, | |
119 :committed_on => Time.now, | |
120 :comments => 'This is a comment. Fixes #1 @4.5, #2 @1', | |
121 :user => User.find(2)) | |
122 assert_difference 'TimeEntry.count', 2 do | |
123 c.scan_comment_for_issue_ids | |
124 end | |
125 | |
126 assert_equal [1, 2], c.issue_ids.sort | |
127 assert Issue.find(1).closed? | |
128 assert Issue.find(2).closed? | |
129 | |
130 times = TimeEntry.order('id desc').limit(2) | |
131 assert_equal [1, 2], times.collect(&:issue_id).sort | |
132 end | |
133 | |
134 def test_ref_keywords_any_line_start | |
135 Setting.commit_ref_keywords = '*' | |
136 c = Changeset.new(:repository => Project.find(1).repository, | |
137 :committed_on => Time.now, | |
138 :comments => '#1 is the reason of this commit', | |
139 :revision => '12345') | |
140 assert c.save | |
141 assert_equal [1], c.issue_ids.sort | |
142 end | |
143 | |
144 def test_ref_keywords_allow_brackets_around_a_issue_number | |
145 Setting.commit_ref_keywords = '*' | |
146 c = Changeset.new(:repository => Project.find(1).repository, | |
147 :committed_on => Time.now, | |
148 :comments => '[#1] Worked on this issue', | |
149 :revision => '12345') | |
150 assert c.save | |
151 assert_equal [1], c.issue_ids.sort | |
152 end | |
153 | |
154 def test_ref_keywords_allow_brackets_around_multiple_issue_numbers | |
155 Setting.commit_ref_keywords = '*' | |
156 c = Changeset.new(:repository => Project.find(1).repository, | |
157 :committed_on => Time.now, | |
158 :comments => '[#1 #2, #3] Worked on these', | |
159 :revision => '12345') | |
160 assert c.save | |
161 assert_equal [1,2,3], c.issue_ids.sort | |
162 end | |
163 | |
164 def test_update_keywords_with_multiple_rules | |
165 with_settings :commit_update_keywords => [ | |
166 {'keywords' => 'fixes, closes', 'status_id' => '5'}, | |
167 {'keywords' => 'resolves', 'status_id' => '3'} | |
168 ] do | |
169 | |
170 issue1 = Issue.generate! | |
171 issue2 = Issue.generate! | |
172 Changeset.generate!(:comments => "Closes ##{issue1.id}\nResolves ##{issue2.id}") | |
173 assert_equal 5, issue1.reload.status_id | |
174 assert_equal 3, issue2.reload.status_id | |
175 end | |
176 end | |
177 | |
178 def test_update_keywords_with_multiple_rules_should_match_tracker | |
179 with_settings :commit_update_keywords => [ | |
180 {'keywords' => 'fixes', 'status_id' => '5', 'if_tracker_id' => '2'}, | |
181 {'keywords' => 'fixes', 'status_id' => '3', 'if_tracker_id' => ''} | |
182 ] do | |
183 | |
184 issue1 = Issue.generate!(:tracker_id => 2) | |
185 issue2 = Issue.generate! | |
186 Changeset.generate!(:comments => "Fixes ##{issue1.id}, ##{issue2.id}") | |
187 assert_equal 5, issue1.reload.status_id | |
188 assert_equal 3, issue2.reload.status_id | |
189 end | |
190 end | |
191 | |
192 def test_update_keywords_with_multiple_rules_and_no_match | |
193 with_settings :commit_update_keywords => [ | |
194 {'keywords' => 'fixes', 'status_id' => '5', 'if_tracker_id' => '2'}, | |
195 {'keywords' => 'fixes', 'status_id' => '3', 'if_tracker_id' => '3'} | |
196 ] do | |
197 | |
198 issue1 = Issue.generate!(:tracker_id => 2) | |
199 issue2 = Issue.generate! | |
200 Changeset.generate!(:comments => "Fixes ##{issue1.id}, ##{issue2.id}") | |
201 assert_equal 5, issue1.reload.status_id | |
202 assert_equal 1, issue2.reload.status_id # no updates | |
203 end | |
204 end | |
205 | |
206 def test_commit_referencing_a_subproject_issue | |
207 c = Changeset.new(:repository => Project.find(1).repository, | |
208 :committed_on => Time.now, | |
209 :comments => 'refs #5, a subproject issue', | |
210 :revision => '12345') | |
211 assert c.save | |
212 assert_equal [5], c.issue_ids.sort | |
213 assert c.issues.first.project != c.project | |
214 end | |
215 | |
216 def test_commit_closing_a_subproject_issue | |
217 with_settings :commit_update_keywords => [{'keywords' => 'closes', 'status_id' => '5'}], | |
218 :default_language => 'en' do | |
219 issue = Issue.find(5) | |
220 assert !issue.closed? | |
221 assert_difference 'Journal.count' do | |
222 c = Changeset.new(:repository => Project.find(1).repository, | |
223 :committed_on => Time.now, | |
224 :comments => 'closes #5, a subproject issue', | |
225 :revision => '12345') | |
226 assert c.save | |
227 end | |
228 assert issue.reload.closed? | |
229 journal = Journal.order('id DESC').first | |
230 assert_equal issue, journal.issue | |
231 assert_include "Applied in changeset ecookbook:r12345.", journal.notes | |
232 end | |
233 end | |
234 | |
235 def test_commit_referencing_a_parent_project_issue | |
236 # repository of child project | |
237 r = Repository::Subversion.create!( | |
238 :project => Project.find(3), | |
239 :url => 'svn://localhost/test') | |
240 c = Changeset.new(:repository => r, | |
241 :committed_on => Time.now, | |
242 :comments => 'refs #2, an issue of a parent project', | |
243 :revision => '12345') | |
244 assert c.save | |
245 assert_equal [2], c.issue_ids.sort | |
246 assert c.issues.first.project != c.project | |
247 end | |
248 | |
249 def test_commit_referencing_a_project_with_commit_cross_project_ref_disabled | |
250 r = Repository::Subversion.create!( | |
251 :project => Project.find(3), | |
252 :url => 'svn://localhost/test') | |
253 with_settings :commit_cross_project_ref => '0' do | |
254 c = Changeset.new(:repository => r, | |
255 :committed_on => Time.now, | |
256 :comments => 'refs #4, an issue of a different project', | |
257 :revision => '12345') | |
258 assert c.save | |
259 assert_equal [], c.issue_ids | |
260 end | |
261 end | |
262 | |
263 def test_commit_referencing_a_project_with_commit_cross_project_ref_enabled | |
264 r = Repository::Subversion.create!( | |
265 :project => Project.find(3), | |
266 :url => 'svn://localhost/test') | |
267 with_settings :commit_cross_project_ref => '1' do | |
268 c = Changeset.new(:repository => r, | |
269 :committed_on => Time.now, | |
270 :comments => 'refs #4, an issue of a different project', | |
271 :revision => '12345') | |
272 assert c.save | |
273 assert_equal [4], c.issue_ids | |
274 end | |
275 end | |
276 | |
277 def test_old_commits_should_not_update_issues_nor_log_time | |
278 Setting.commit_ref_keywords = '*' | |
279 Setting.commit_update_keywords = {'fixes , closes' => {'status_id' => '5', 'done_ratio' => '90'}} | |
280 Setting.commit_logtime_enabled = '1' | |
281 | |
282 repository = Project.find(1).repository | |
283 repository.created_on = Time.now | |
284 repository.save! | |
285 | |
286 c = Changeset.new(:repository => repository, | |
287 :committed_on => 1.month.ago, | |
288 :comments => 'New commit (#2). Fixes #1 @1h', | |
289 :revision => '12345') | |
290 assert_no_difference 'TimeEntry.count' do | |
291 assert c.save | |
292 end | |
293 assert_equal [1, 2], c.issue_ids.sort | |
294 issue = Issue.find(1) | |
295 assert_equal 1, issue.status_id | |
296 assert_equal 0, issue.done_ratio | |
297 end | |
298 | |
299 def test_text_tag_revision | |
300 c = Changeset.new(:revision => '520') | |
301 assert_equal 'r520', c.text_tag | |
302 end | |
303 | |
304 def test_text_tag_revision_with_same_project | |
305 c = Changeset.new(:revision => '520', :repository => Project.find(1).repository) | |
306 assert_equal 'r520', c.text_tag(Project.find(1)) | |
307 end | |
308 | |
309 def test_text_tag_revision_with_different_project | |
310 c = Changeset.new(:revision => '520', :repository => Project.find(1).repository) | |
311 assert_equal 'ecookbook:r520', c.text_tag(Project.find(2)) | |
312 end | |
313 | |
314 def test_text_tag_revision_with_repository_identifier | |
315 r = Repository::Subversion.create!( | |
316 :project_id => 1, | |
317 :url => 'svn://localhost/test', | |
318 :identifier => 'documents') | |
319 c = Changeset.new(:revision => '520', :repository => r) | |
320 assert_equal 'documents|r520', c.text_tag | |
321 assert_equal 'ecookbook:documents|r520', c.text_tag(Project.find(2)) | |
322 end | |
323 | |
324 def test_text_tag_hash | |
325 c = Changeset.new( | |
326 :scmid => '7234cb2750b63f47bff735edc50a1c0a433c2518', | |
327 :revision => '7234cb2750b63f47bff735edc50a1c0a433c2518') | |
328 assert_equal 'commit:7234cb2750b63f47bff735edc50a1c0a433c2518', c.text_tag | |
329 end | |
330 | |
331 def test_text_tag_hash_with_same_project | |
332 c = Changeset.new(:revision => '7234cb27', :scmid => '7234cb27', :repository => Project.find(1).repository) | |
333 assert_equal 'commit:7234cb27', c.text_tag(Project.find(1)) | |
334 end | |
335 | |
336 def test_text_tag_hash_with_different_project | |
337 c = Changeset.new(:revision => '7234cb27', :scmid => '7234cb27', :repository => Project.find(1).repository) | |
338 assert_equal 'ecookbook:commit:7234cb27', c.text_tag(Project.find(2)) | |
339 end | |
340 | |
341 def test_text_tag_hash_all_number | |
342 c = Changeset.new(:scmid => '0123456789', :revision => '0123456789') | |
343 assert_equal 'commit:0123456789', c.text_tag | |
344 end | |
345 | |
346 def test_text_tag_hash_with_repository_identifier | |
347 r = Repository::Subversion.new( | |
348 :project_id => 1, | |
349 :url => 'svn://localhost/test', | |
350 :identifier => 'documents') | |
351 c = Changeset.new(:revision => '7234cb27', :scmid => '7234cb27', :repository => r) | |
352 assert_equal 'commit:documents|7234cb27', c.text_tag | |
353 assert_equal 'ecookbook:commit:documents|7234cb27', c.text_tag(Project.find(2)) | |
354 end | |
355 | |
356 def test_previous | |
357 changeset = Changeset.find_by_revision('3') | |
358 assert_equal Changeset.find_by_revision('2'), changeset.previous | |
359 end | |
360 | |
361 def test_previous_nil | |
362 changeset = Changeset.find_by_revision('1') | |
363 assert_nil changeset.previous | |
364 end | |
365 | |
366 def test_next | |
367 changeset = Changeset.find_by_revision('2') | |
368 assert_equal Changeset.find_by_revision('3'), changeset.next | |
369 end | |
370 | |
371 def test_next_nil | |
372 changeset = Changeset.find_by_revision('10') | |
373 assert_nil changeset.next | |
374 end | |
375 | |
376 def test_comments_should_be_converted_to_utf8 | |
377 proj = Project.find(3) | |
378 # str = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt") | |
379 str = "Texte encod\xe9 en ISO-8859-1." | |
380 str.force_encoding("ASCII-8BIT") if str.respond_to?(:force_encoding) | |
381 r = Repository::Bazaar.create!( | |
382 :project => proj, | |
383 :url => '/tmp/test/bazaar', | |
384 :log_encoding => 'ISO-8859-1' ) | |
385 assert r | |
386 c = Changeset.new(:repository => r, | |
387 :committed_on => Time.now, | |
388 :revision => '123', | |
389 :scmid => '12345', | |
390 :comments => str) | |
391 assert( c.save ) | |
392 str_utf8 = "Texte encod\xc3\xa9 en ISO-8859-1." | |
393 str_utf8.force_encoding("UTF-8") if str_utf8.respond_to?(:force_encoding) | |
394 assert_equal str_utf8, c.comments | |
395 end | |
396 | |
397 def test_invalid_utf8_sequences_in_comments_should_be_replaced_latin1 | |
398 proj = Project.find(3) | |
399 # str = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt") | |
400 str1 = "Texte encod\xe9 en ISO-8859-1." | |
401 str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test" | |
402 str1.force_encoding("UTF-8") if str1.respond_to?(:force_encoding) | |
403 str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding) | |
404 r = Repository::Bazaar.create!( | |
405 :project => proj, | |
406 :url => '/tmp/test/bazaar', | |
407 :log_encoding => 'UTF-8' ) | |
408 assert r | |
409 c = Changeset.new(:repository => r, | |
410 :committed_on => Time.now, | |
411 :revision => '123', | |
412 :scmid => '12345', | |
413 :comments => str1, | |
414 :committer => str2) | |
415 assert( c.save ) | |
416 assert_equal "Texte encod? en ISO-8859-1.", c.comments | |
417 assert_equal "?a?b?c?d?e test", c.committer | |
418 end | |
419 | |
420 def test_invalid_utf8_sequences_in_comments_should_be_replaced_ja_jis | |
421 proj = Project.find(3) | |
422 str = "test\xb5\xfetest\xb5\xfe" | |
423 if str.respond_to?(:force_encoding) | |
424 str.force_encoding('ASCII-8BIT') | |
425 end | |
426 r = Repository::Bazaar.create!( | |
427 :project => proj, | |
428 :url => '/tmp/test/bazaar', | |
429 :log_encoding => 'ISO-2022-JP' ) | |
430 assert r | |
431 c = Changeset.new(:repository => r, | |
432 :committed_on => Time.now, | |
433 :revision => '123', | |
434 :scmid => '12345', | |
435 :comments => str) | |
436 assert( c.save ) | |
437 assert_equal "test??test??", c.comments | |
438 end | |
439 | |
440 def test_comments_should_be_converted_all_latin1_to_utf8 | |
441 s1 = "\xC2\x80" | |
442 s2 = "\xc3\x82\xc2\x80" | |
443 s4 = s2.dup | |
444 if s1.respond_to?(:force_encoding) | |
445 s3 = s1.dup | |
446 s1.force_encoding('ASCII-8BIT') | |
447 s2.force_encoding('ASCII-8BIT') | |
448 s3.force_encoding('ISO-8859-1') | |
449 s4.force_encoding('UTF-8') | |
450 assert_equal s3.encode('UTF-8'), s4 | |
451 end | |
452 proj = Project.find(3) | |
453 r = Repository::Bazaar.create!( | |
454 :project => proj, | |
455 :url => '/tmp/test/bazaar', | |
456 :log_encoding => 'ISO-8859-1' ) | |
457 assert r | |
458 c = Changeset.new(:repository => r, | |
459 :committed_on => Time.now, | |
460 :revision => '123', | |
461 :scmid => '12345', | |
462 :comments => s1) | |
463 assert( c.save ) | |
464 assert_equal s4, c.comments | |
465 end | |
466 | |
467 def test_invalid_utf8_sequences_in_paths_should_be_replaced | |
468 proj = Project.find(3) | |
469 str1 = "Texte encod\xe9 en ISO-8859-1" | |
470 str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test" | |
471 str1.force_encoding("UTF-8") if str1.respond_to?(:force_encoding) | |
472 str2.force_encoding("ASCII-8BIT") if str2.respond_to?(:force_encoding) | |
473 r = Repository::Bazaar.create!( | |
474 :project => proj, | |
475 :url => '/tmp/test/bazaar', | |
476 :log_encoding => 'UTF-8' ) | |
477 assert r | |
478 cs = Changeset.new( | |
479 :repository => r, | |
480 :committed_on => Time.now, | |
481 :revision => '123', | |
482 :scmid => '12345', | |
483 :comments => "test") | |
484 assert(cs.save) | |
485 ch = Change.new( | |
486 :changeset => cs, | |
487 :action => "A", | |
488 :path => str1, | |
489 :from_path => str2, | |
490 :from_revision => "345") | |
491 assert(ch.save) | |
492 assert_equal "Texte encod? en ISO-8859-1", ch.path | |
493 assert_equal "?a?b?c?d?e test", ch.from_path | |
494 end | |
495 | |
496 def test_comments_nil | |
497 proj = Project.find(3) | |
498 r = Repository::Bazaar.create!( | |
499 :project => proj, | |
500 :url => '/tmp/test/bazaar', | |
501 :log_encoding => 'ISO-8859-1' ) | |
502 assert r | |
503 c = Changeset.new(:repository => r, | |
504 :committed_on => Time.now, | |
505 :revision => '123', | |
506 :scmid => '12345', | |
507 :comments => nil, | |
508 :committer => nil) | |
509 assert( c.save ) | |
510 assert_equal "", c.comments | |
511 assert_equal nil, c.committer | |
512 if c.comments.respond_to?(:force_encoding) | |
513 assert_equal "UTF-8", c.comments.encoding.to_s | |
514 end | |
515 end | |
516 | |
517 def test_comments_empty | |
518 proj = Project.find(3) | |
519 r = Repository::Bazaar.create!( | |
520 :project => proj, | |
521 :url => '/tmp/test/bazaar', | |
522 :log_encoding => 'ISO-8859-1' ) | |
523 assert r | |
524 c = Changeset.new(:repository => r, | |
525 :committed_on => Time.now, | |
526 :revision => '123', | |
527 :scmid => '12345', | |
528 :comments => "", | |
529 :committer => "") | |
530 assert( c.save ) | |
531 assert_equal "", c.comments | |
532 assert_equal "", c.committer | |
533 if c.comments.respond_to?(:force_encoding) | |
534 assert_equal "UTF-8", c.comments.encoding.to_s | |
535 assert_equal "UTF-8", c.committer.encoding.to_s | |
536 end | |
537 end | |
538 | |
539 def test_comments_should_accept_more_than_64k | |
540 c = Changeset.new(:repository => Repository.first, | |
541 :committed_on => Time.now, | |
542 :revision => '123', | |
543 :scmid => '12345', | |
544 :comments => "a" * 500.kilobyte) | |
545 assert c.save | |
546 c.reload | |
547 assert_equal 500.kilobyte, c.comments.size | |
548 end | |
549 | |
550 def test_identifier | |
551 c = Changeset.find_by_revision('1') | |
552 assert_equal c.revision, c.identifier | |
553 end | |
554 end |