Feature #4052 » 091018-cross-project_redmine_links-tests.patch
app/helpers/application_helper.rb (working copy) | ||
---|---|---|
29 | 29 |
def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter |
30 | 30 | |
31 | 31 |
# Return true if user is authorized for controller/action, otherwise false |
32 |
def authorize_for(controller, action) |
|
33 |
User.current.allowed_to?({:controller => controller, :action => action}, @project)
|
|
32 |
def authorize_for(controller, action, project = @project)
|
|
33 |
User.current.allowed_to?({:controller => controller, :action => action}, project) |
|
34 | 34 |
end |
35 | 35 | |
36 | 36 |
# Display a link if user is authorized |
... | ... | |
443 | 443 |
# #52 -> Link to issue #52 |
444 | 444 |
# Changesets: |
445 | 445 |
# r52 -> Link to revision 52 |
446 |
# project:r52 -> Link to revision 52 of an other project, using project name or identifier |
|
446 | 447 |
# commit:a85130f -> Link to scmid starting with a85130f |
448 |
# project:commit:a85130f -> Link to scmid starting with a85130f of an other project, using project name or identifier |
|
449 |
# If your project name contains spaces, use quotation marks : |
|
450 |
# "My Project":r52 |
|
451 |
# "My Project":commit:a85130f |
|
447 | 452 |
# Documents: |
448 | 453 |
# document#17 -> Link to document with id 17 |
449 | 454 |
# document:Greetings -> Link to the document with title "Greetings" |
... | ... | |
455 | 460 |
# Attachments: |
456 | 461 |
# attachment:file.zip -> Link to the attachment of the current object named file.zip |
457 | 462 |
# Source files: |
463 |
# ["Link alternate display title"=][project:]source:some/path[/file][@52][#L120] |
|
464 |
# ["Link alternate display title"=][project:]export:some/path/file[@52] |
|
458 | 465 |
# source:some/file -> Link to the file located at /some/file in the project's repository |
459 | 466 |
# source:some/file@52 -> Link to the file's revision 52 |
460 | 467 |
# source:some/file#L120 -> Link to line 120 of the file |
468 |
# "click here"=source:some/file#L120 -> Link to line 120 of the file |
|
469 |
# "click here"=wizbang:source:some/file#L120 -> Link to line 120 of the file in the repo for the wizbang project |
|
461 | 470 |
# source:some/file@52#L120 -> Link to line 120 of the file's revision 52 |
462 | 471 |
# export:some/file -> Force the download of the file |
472 |
# "Download This File"=export:some/file -> Force the download of the file |
|
473 |
# "Download This File"=myproject:export:some/file -> Force the download of the file in repository for myproject project |
|
463 | 474 |
# Forum messages: |
464 | 475 |
# message#1218 -> Link to message with id 1218 |
465 |
text = text.gsub(%r{([\s\(,\-\>]|^)(!)?(attachment|document|version|commit|source|export|message)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|,|\s|<|$)}) do |m|
|
|
466 |
leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
|
|
476 |
text = text.gsub(%r{([\s\(,\-\>]|^)(!)?(\"[^\"\n]+\"=)?(attachment|document|version|(\"[^:<>\r\n\b]+\":|[^:<>\s\r\n\b]+:)?(commit|source|export)|message)?((#|(\"[^:<>\r\n\b]+\":|[^:<>\s\r\n\b]+:)?(r))(\d+)|(:)([^"\s<>][^:\s\r\n\b<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|,|\s|<|$)}) do |m|
|
|
477 |
leading, esc, linktitle, prefix, sep, revproj, oid = $1, $2, $3, $6 || $3, $12 || $10 || $8, $5 || $9, $11 || $13
|
|
467 | 478 |
link = nil |
468 | 479 |
if esc.nil? |
469 | 480 |
if prefix.nil? && sep == 'r' |
470 |
if project && (changeset = project.changesets.find_by_revision(oid)) |
|
471 |
link = link_to("r#{oid}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => oid}, |
|
472 |
:class => 'changeset', |
|
473 |
:title => truncate_single_line(changeset.comments, :length => 100)) |
|
481 |
if revproj.nil? |
|
482 |
if project && (changeset = project.changesets.find_by_revision(oid)) |
|
483 |
link = link_to("r#{oid}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => oid}, |
|
484 |
:class => 'changeset', |
|
485 |
:title => truncate_single_line(changeset.comments, :length => 100)) |
|
486 |
end |
|
487 |
else |
|
488 |
revproj.gsub!(/[\:"]/,'') |
|
489 |
link_project = Project.find_by_name(h(revproj)) || Project.find_by_identifier(h(revproj)) |
|
490 |
if link_project && (changeset = link_project.changesets.find_by_revision(oid)) |
|
491 |
title = truncate_single_line(changeset.comments, :length => 100) if authorize_for('repositories', 'revision', link_project) |
|
492 |
link = link_to h("#{revproj}:r#{oid}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => link_project, :rev => oid}, |
|
493 |
:class => 'changeset', |
|
494 |
:title => title |
|
495 |
end |
|
474 | 496 |
end |
475 | 497 |
elsif sep == '#' |
476 | 498 |
oid = oid.to_i |
... | ... | |
518 | 540 |
:class => 'version' |
519 | 541 |
end |
520 | 542 |
when 'commit' |
521 |
if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"])) |
|
522 |
link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision}, |
|
523 |
:class => 'changeset', |
|
524 |
:title => truncate_single_line(changeset.comments, :length => 100) |
|
543 |
if revproj.nil? |
|
544 |
if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"])) |
|
545 |
link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision}, |
|
546 |
:class => 'changeset', |
|
547 |
:title => truncate_single_line(changeset.comments, :length => 100) |
|
548 |
end |
|
549 |
else |
|
550 |
revproj.gsub!(/[\:"]/,'') |
|
551 |
link_project = Project.find_by_name(h(revproj)) || Project.find_by_identifier(h(revproj)) |
|
552 |
if link_project && (changeset = link_project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"])) |
|
553 |
title = truncate_single_line(changeset.comments, :length => 100) if authorize_for('repositories', 'revision', link_project) |
|
554 |
link = link_to h("#{revproj}:#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => link_project, :rev => changeset.revision}, |
|
555 |
:class => 'changeset', |
|
556 |
:title => title |
|
557 |
end |
|
525 | 558 |
end |
526 | 559 |
when 'source', 'export' |
527 |
if project && project.repository |
|
560 |
if revproj.nil? |
|
561 |
link_project = project |
|
562 |
else |
|
563 |
revproj.gsub!(/[\:"]/,'') |
|
564 |
link_project = Project.find_by_name(h(revproj)) || Project.find_by_identifier(h(revproj)) |
|
565 |
end |
|
566 |
if link_project && link_project.repository |
|
528 | 567 |
name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$} |
529 | 568 |
path, rev, anchor = $1, $3, $5 |
530 |
link = link_to h("#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project, |
|
569 |
link_title = linktitle ? linktitle.gsub!(/[\"=]/,'') : (link_project != project ? "#{revproj}:" : "") + "#{prefix}:#{name}" |
|
570 |
link = link_to h(link_title), {:only_path => only_path, :controller => 'repositories', :action => 'entry', :id => link_project, |
|
531 | 571 |
:path => to_path_param(path), |
532 | 572 |
:rev => rev, |
533 | 573 |
:anchor => anchor, |
... | ... | |
542 | 582 |
end |
543 | 583 |
end |
544 | 584 |
end |
545 |
leading + (link || "#{prefix}#{sep}#{oid}") |
|
585 |
leading + (link || (revproj ? "#{revproj}:" : "") + "#{prefix}#{sep}#{oid}")
|
|
546 | 586 |
end |
547 | 587 | |
548 | 588 |
text |
public/help/wiki_syntax.html (working copy) | ||
---|---|---|
52 | 52 |
<tr><th><img src="../images/jstoolbar/bt_link.png" style="border: 1px solid #bbb;" alt="Link to a Wiki page" /></th><td>[[Wiki page]]</td><td><a href="#">Wiki page</a></td></tr> |
53 | 53 |
<tr><th></th><td>Issue #12</td><td>Issue <a href="#">#12</a></td></tr> |
54 | 54 |
<tr><th></th><td>Revision r43</td><td>Revision <a href="#">r43</a></td></tr> |
55 |
<tr><th></th><td>myproj:r43</td><td><a href="#">myproj:r43</a></td></tr> |
|
55 | 56 |
<tr><th></th><td>commit:f30e13e43</td><td><a href="#">f30e13e4</a></td></tr> |
57 |
<tr><th></th><td>proj:commit:f30e13e43</td><td><a href="#">proj:f30e13e4</a></td></tr> |
|
56 | 58 |
<tr><th></th><td>source:some/file</td><td><a href="#">source:some/file</a></td></tr> |
59 |
<tr><th></th><td>proj:source:some/file</td><td><a href="#">proj:source:some/file</a></td></tr> |
|
60 |
<tr><th></th><td>"File Src"=source:some/file</td><td><a href="#">File Src</a></td></tr> |
|
61 |
<tr><th></th><td>"Download"=proj:export:some/file</td><td><a href="#">Download</a></td></tr> |
|
57 | 62 | |
58 | 63 |
<tr><th colspan="3">Inline images</th></tr> |
59 | 64 |
<tr><th><img src="../images/jstoolbar/bt_img.png" style="border: 1px solid #bbb;" alt="Image" /></th><td>!<em>image_url</em>!</td><td></td></tr> |
public/help/wiki_syntax_detailed.html (working copy) | ||
---|---|---|
49 | 49 |
<li>Link to a changeset with a non-numeric hash: <strong>commit:c6f4d0fd</strong> (displays c6f4d0fd). Added in <a href="/repositories/revision/1?rev=1236" class="changeset" title="Merged Git support branch (r1200 to r1226).">r1236</a>.</li> |
50 | 50 |
</ul> |
51 | 51 |
|
52 |
<p>You can also link to changesets of an other project repository:</p> |
|
53 |
|
|
54 |
<ul> |
|
55 |
<li>Link to a changeset of SandBox project: <strong>sandbox:r758</strong> (displays <a href="/repositories/revision/1?rev=758" class="changeset" title="Search engine now only searches objects the user is allowed to view.">sandbox:r758</a>)</li> |
|
56 |
<li>Link to a changeset of SandBox project with a non-numeric hash: <strong>sandbox:commit:c6f4d0fd</strong> (displays sandbox:c6f4d0fd).</li> |
|
57 |
<li>If your project name contains spaces, use quotation marks : <strong>"My Project":r758</strong> or <strong>"My Project":commit:c6f4d0fd</strong></li> |
|
58 |
</ul> |
|
59 |
|
|
52 | 60 |
<p>Wiki links:</p> |
53 | 61 |
|
54 | 62 |
<ul> |
... | ... | |
97 | 105 |
<ul> |
98 | 106 |
<li>Repository files |
99 | 107 |
<ul> |
108 |
<li><strong>["Link display title"=][project:]source:some/path[/file][@52][#L120]</strong> -- Link to the file located at /some/file in the project's repository</li> |
|
109 |
<li><strong>["Link alternate display title"=][project:]export:some/path/file[@52]</strong> -- Link to the file located at /some/file in the project's repository</li> |
|
100 | 110 |
<li><strong>source:some/file</strong> -- Link to the file located at /some/file in the project's repository</li> |
101 | 111 |
<li><strong>source:some/file@52</strong> -- Link to the file's revision 52</li> |
102 | 112 |
<li><strong>source:some/file#L120</strong> -- Link to line 120 of the file</li> |
113 |
<li><strong>"click here"=source:some/file#L120</strong> -- "click here" Link to line 120 of the file</li> |
|
114 |
<li><strong>"click here"=wizbang:source:some/file#L120</strong> -- Link to line 120 of the file in the repo for the wizbang project</li> |
|
103 | 115 |
<li><strong>source:some/file@52#L120</strong> -- Link to line 120 of the file's revision 52</li> |
104 | 116 |
<li><strong>export:some/file</strong> -- Force the download of the file</li> |
117 |
<li><strong>"Download This File"=export:some/file</strong> -- Force the download of the file</li> |
|
118 |
<li><strong>"Download This File"=myproject:export:some/file</strong> -- Force the download of the file in repository for myproject project</li> |
|
105 | 119 |
</ul></li> |
106 | 120 |
</ul> |
107 | 121 |
|
test/fixtures/changes.yml (working copy) | ||
---|---|---|
20 | 20 |
path: /test/some/path/in/the/repo |
21 | 21 |
from_path: |
22 | 22 |
from_revision: |
23 |
changes_009: |
|
24 |
id: 9 |
|
25 |
changeset_id: 108 |
|
26 |
action: M |
|
27 |
path: /test/some/path/in/the/repo |
|
28 |
from_path: |
|
29 |
from_revision: |
|
30 |
changes_0010: |
|
31 |
id: 10 |
|
32 |
changeset_id: 109 |
|
33 |
action: M |
|
34 |
path: /test/some/path/in/the/repo |
|
35 |
from_path: |
|
36 |
from_revision: |
|
23 | 37 |
|
test/fixtures/changesets.yml (working copy) | ||
---|---|---|
81 | 81 |
user_id: 3 |
82 | 82 |
repository_id: 10 |
83 | 83 |
committer: dlopper |
84 |
changesets_009: |
|
85 |
commit_date: 2007-04-11 |
|
86 |
committed_on: 2007-04-11 15:14:44 +02:00 |
|
87 |
revision: 1 |
|
88 |
id: 108 |
|
89 |
comments: My very first commit |
|
90 |
repository_id: 12 |
|
91 |
committer: dlopper |
|
92 |
user_id: 3 |
|
93 |
changesets_010: |
|
94 |
commit_date: 2007-04-12 |
|
95 |
committed_on: 2007-04-12 15:14:44 +02:00 |
|
96 |
revision: 2 |
|
97 |
id: 109 |
|
98 |
comments: 'This commit fixes #5' |
|
99 |
repository_id: 12 |
|
100 |
committer: dlopper |
|
101 |
user_id: 3 |
|
84 | 102 |
|
test/fixtures/repositories.yml (working copy) | ||
---|---|---|
15 | 15 |
password: "" |
16 | 16 |
login: "" |
17 | 17 |
type: Subversion |
18 |
|
|
19 |
repositories_003: |
|
20 |
project_id: 3 |
|
21 |
url: svn://localhost/test |
|
22 |
id: 12 |
|
23 |
root_url: svn://localhost |
|
24 |
password: "" |
|
25 |
login: "" |
|
26 |
type: Subversion |
test/unit/helpers/application_helper_test.rb (working copy) | ||
---|---|---|
31 | 31 | |
32 | 32 |
def setup |
33 | 33 |
super |
34 |
@admin = User.find(1) |
|
35 |
@jsmith = User.find(2) |
|
36 |
@dlopper = User.find(3) |
|
34 | 37 |
end |
35 | 38 |
|
36 | 39 |
def test_auto_links |
... | ... | |
126 | 129 |
:class => 'changeset', :title => 'My very first commit') |
127 | 130 |
changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2}, |
128 | 131 |
:class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3') |
129 |
|
|
132 | ||
133 |
changeset_link_other_project_id = link_to('subproject1:r1', {:controller => 'repositories', :action => 'revision', :id => 'subproject1', :rev => 1}, |
|
134 |
:class => 'changeset', :title => 'My very first commit') |
|
135 | ||
136 |
changeset_link_other_project_name = link_to('eCookbook Subproject 1:r2', {:controller => 'repositories', :action => 'revision', :id => 'subproject1', :rev => 2}, |
|
137 |
:class => 'changeset', :title => 'This commit fixes #5') |
|
138 | ||
130 | 139 |
document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1}, |
131 | 140 |
:class => 'document') |
132 | 141 |
|
... | ... | |
146 | 155 |
'r1.' => "#{changeset_link}.", |
147 | 156 |
'r1, r2' => "#{changeset_link}, #{changeset_link2}", |
148 | 157 |
'r1,r2' => "#{changeset_link},#{changeset_link2}", |
158 |
'subproject1:r1' => "#{changeset_link_other_project_id}", |
|
159 |
'subproject1:r1.' => "#{changeset_link_other_project_id}.", |
|
160 |
'subproject1:r1,"eCookbook Subproject 1":r2' => "#{changeset_link_other_project_id},#{changeset_link_other_project_name}", |
|
149 | 161 |
# documents |
150 | 162 |
'document#1' => document_link, |
151 | 163 |
'document:"Test document"' => document_link, |
... | ... | |
184 | 196 |
"http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>', |
185 | 197 |
} |
186 | 198 |
@project = Project.find(1) |
199 |
User.current = @admin |
|
200 |
|
|
187 | 201 |
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } |
202 | ||
203 |
User.current = nil |
|
188 | 204 |
end |
189 | 205 |
|
190 | 206 |
def test_wiki_links |
... | ... | |
277 | 293 |
} |
278 | 294 |
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } |
279 | 295 |
end |
280 |
|
|
296 | ||
281 | 297 |
def test_wiki_horizontal_rule |
282 | 298 |
assert_equal '<hr />', textilizable('---') |
283 | 299 |
assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---') |