##// END OF EJS Templates
Removed some shoulda context....
Jean-Philippe Lang -
r11634:474c01074638
parent child
Show More
@@ -1,165 +1,139
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2013 Jean-Philippe Lang
2 # Copyright (C) 2006-2013 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 WelcomeControllerTest < ActionController::TestCase
20 class WelcomeControllerTest < ActionController::TestCase
21 fixtures :projects, :news, :users, :members
21 fixtures :projects, :news, :users, :members
22
22
23 def setup
23 def setup
24 User.current = nil
24 User.current = nil
25 end
25 end
26
26
27 def test_index
27 def test_index
28 get :index
28 get :index
29 assert_response :success
29 assert_response :success
30 assert_template 'index'
30 assert_template 'index'
31 assert_not_nil assigns(:news)
31 assert_not_nil assigns(:news)
32 assert_not_nil assigns(:projects)
32 assert_not_nil assigns(:projects)
33 assert !assigns(:projects).include?(Project.where(:is_public => false).first)
33 assert !assigns(:projects).include?(Project.where(:is_public => false).first)
34 end
34 end
35
35
36 def test_browser_language
36 def test_browser_language
37 Setting.default_language = 'en'
37 Setting.default_language = 'en'
38 @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
38 @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
39 get :index
39 get :index
40 assert_equal :fr, @controller.current_language
40 assert_equal :fr, @controller.current_language
41 end
41 end
42
42
43 def test_browser_language_alternate
43 def test_browser_language_alternate
44 Setting.default_language = 'en'
44 Setting.default_language = 'en'
45 @request.env['HTTP_ACCEPT_LANGUAGE'] = 'zh-TW'
45 @request.env['HTTP_ACCEPT_LANGUAGE'] = 'zh-TW'
46 get :index
46 get :index
47 assert_equal :"zh-TW", @controller.current_language
47 assert_equal :"zh-TW", @controller.current_language
48 end
48 end
49
49
50 def test_browser_language_alternate_not_valid
50 def test_browser_language_alternate_not_valid
51 Setting.default_language = 'en'
51 Setting.default_language = 'en'
52 @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr-CA'
52 @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr-CA'
53 get :index
53 get :index
54 assert_equal :fr, @controller.current_language
54 assert_equal :fr, @controller.current_language
55 end
55 end
56
56
57 def test_robots
57 def test_robots
58 get :robots
58 get :robots
59 assert_response :success
59 assert_response :success
60 assert_equal 'text/plain', @response.content_type
60 assert_equal 'text/plain', @response.content_type
61 assert @response.body.match(%r{^Disallow: /projects/ecookbook/issues\r?$})
61 assert @response.body.match(%r{^Disallow: /projects/ecookbook/issues\r?$})
62 end
62 end
63
63
64 def test_warn_on_leaving_unsaved_turn_on
64 def test_warn_on_leaving_unsaved_turn_on
65 user = User.find(2)
65 user = User.find(2)
66 user.pref.warn_on_leaving_unsaved = '1'
66 user.pref.warn_on_leaving_unsaved = '1'
67 user.pref.save!
67 user.pref.save!
68 @request.session[:user_id] = 2
68 @request.session[:user_id] = 2
69
69
70 get :index
70 get :index
71 assert_tag 'script',
71 assert_tag 'script',
72 :attributes => {:type => "text/javascript"},
72 :attributes => {:type => "text/javascript"},
73 :content => %r{warnLeavingUnsaved}
73 :content => %r{warnLeavingUnsaved}
74 end
74 end
75
75
76 def test_warn_on_leaving_unsaved_turn_off
76 def test_warn_on_leaving_unsaved_turn_off
77 user = User.find(2)
77 user = User.find(2)
78 user.pref.warn_on_leaving_unsaved = '0'
78 user.pref.warn_on_leaving_unsaved = '0'
79 user.pref.save!
79 user.pref.save!
80 @request.session[:user_id] = 2
80 @request.session[:user_id] = 2
81
81
82 get :index
82 get :index
83 assert_no_tag 'script',
83 assert_no_tag 'script',
84 :attributes => {:type => "text/javascript"},
84 :attributes => {:type => "text/javascript"},
85 :content => %r{warnLeavingUnsaved}
85 :content => %r{warnLeavingUnsaved}
86 end
86 end
87
87
88 def test_logout_link_should_post
88 def test_logout_link_should_post
89 @request.session[:user_id] = 2
89 @request.session[:user_id] = 2
90
90
91 get :index
91 get :index
92 assert_select 'a[href=/logout][data-method=post]', :text => 'Sign out'
92 assert_select 'a[href=/logout][data-method=post]', :text => 'Sign out'
93 end
93 end
94
94
95 def test_call_hook_mixed_in
95 def test_call_hook_mixed_in
96 assert @controller.respond_to?(:call_hook)
96 assert @controller.respond_to?(:call_hook)
97 end
97 end
98
98
99 def test_project_jump_box_should_escape_names_once
99 def test_project_jump_box_should_escape_names_once
100 Project.find(1).update_attribute :name, 'Foo & Bar'
100 Project.find(1).update_attribute :name, 'Foo & Bar'
101 @request.session[:user_id] = 2
101 @request.session[:user_id] = 2
102
102
103 get :index
103 get :index
104 assert_select "#header select" do
104 assert_select "#header select" do
105 assert_select "option", :text => 'Foo &amp; Bar'
105 assert_select "option", :text => 'Foo &amp; Bar'
106 end
106 end
107 end
107 end
108
108
109 context "test_api_offset_and_limit" do
109 def test_api_offset_and_limit_without_params
110 context "without params" do
110 assert_equal [0, 25], @controller.api_offset_and_limit({})
111 should "return 0, 25" do
111 end
112 assert_equal [0, 25], @controller.api_offset_and_limit({})
113 end
114 end
115
116 context "with limit" do
117 should "return 0, limit" do
118 assert_equal [0, 30], @controller.api_offset_and_limit({:limit => 30})
119 end
120
121 should "not exceed 100" do
122 assert_equal [0, 100], @controller.api_offset_and_limit({:limit => 120})
123 end
124
112
125 should "not be negative" do
113 def test_api_offset_and_limit_with_limit
126 assert_equal [0, 25], @controller.api_offset_and_limit({:limit => -10})
114 assert_equal [0, 30], @controller.api_offset_and_limit({:limit => 30})
127 end
115 assert_equal [0, 100], @controller.api_offset_and_limit({:limit => 120})
128 end
116 assert_equal [0, 25], @controller.api_offset_and_limit({:limit => -10})
117 end
129
118
130 context "with offset" do
119 def test_api_offset_and_limit_with_offset
131 should "return offset, 25" do
120 assert_equal [10, 25], @controller.api_offset_and_limit({:offset => 10})
132 assert_equal [10, 25], @controller.api_offset_and_limit({:offset => 10})
121 assert_equal [0, 25], @controller.api_offset_and_limit({:offset => -10})
133 end
122 end
134
123
135 should "not be negative" do
124 def test_api_offset_and_limit_with_offset_and_limit
136 assert_equal [0, 25], @controller.api_offset_and_limit({:offset => -10})
125 assert_equal [10, 50], @controller.api_offset_and_limit({:offset => 10, :limit => 50})
137 end
126 end
138
127
139 context "and limit" do
128 def test_api_offset_and_limit_with_page
140 should "return offset, limit" do
129 assert_equal [0, 25], @controller.api_offset_and_limit({:page => 1})
141 assert_equal [10, 50], @controller.api_offset_and_limit({:offset => 10, :limit => 50})
130 assert_equal [50, 25], @controller.api_offset_and_limit({:page => 3})
142 end
131 assert_equal [0, 25], @controller.api_offset_and_limit({:page => 0})
143 end
132 assert_equal [0, 25], @controller.api_offset_and_limit({:page => -2})
144 end
133 end
145
134
146 context "with page" do
135 def test_api_offset_and_limit_with_page_and_limit
147 should "return offset, 25" do
136 assert_equal [0, 100], @controller.api_offset_and_limit({:page => 1, :limit => 100})
148 assert_equal [0, 25], @controller.api_offset_and_limit({:page => 1})
137 assert_equal [200, 100], @controller.api_offset_and_limit({:page => 3, :limit => 100})
149 assert_equal [50, 25], @controller.api_offset_and_limit({:page => 3})
150 end
151
152 should "not be negative" do
153 assert_equal [0, 25], @controller.api_offset_and_limit({:page => 0})
154 assert_equal [0, 25], @controller.api_offset_and_limit({:page => -2})
155 end
156
157 context "and limit" do
158 should "return offset, limit" do
159 assert_equal [0, 100], @controller.api_offset_and_limit({:page => 1, :limit => 100})
160 assert_equal [200, 100], @controller.api_offset_and_limit({:page => 3, :limit => 100})
161 end
162 end
163 end
164 end
138 end
165 end
139 end
@@ -1,1219 +1,1213
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2013 Jean-Philippe Lang
4 # Copyright (C) 2006-2013 Jean-Philippe Lang
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
9 # of the License, or (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
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
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.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 require File.expand_path('../../../test_helper', __FILE__)
20 require File.expand_path('../../../test_helper', __FILE__)
21
21
22 class ApplicationHelperTest < ActionView::TestCase
22 class ApplicationHelperTest < ActionView::TestCase
23 include ERB::Util
23 include ERB::Util
24 include Rails.application.routes.url_helpers
24 include Rails.application.routes.url_helpers
25
25
26 fixtures :projects, :roles, :enabled_modules, :users,
26 fixtures :projects, :roles, :enabled_modules, :users,
27 :repositories, :changesets,
27 :repositories, :changesets,
28 :trackers, :issue_statuses, :issues, :versions, :documents,
28 :trackers, :issue_statuses, :issues, :versions, :documents,
29 :wikis, :wiki_pages, :wiki_contents,
29 :wikis, :wiki_pages, :wiki_contents,
30 :boards, :messages, :news,
30 :boards, :messages, :news,
31 :attachments, :enumerations
31 :attachments, :enumerations
32
32
33 def setup
33 def setup
34 super
34 super
35 set_tmp_attachments_directory
35 set_tmp_attachments_directory
36 end
36 end
37
37
38 context "#link_to_if_authorized" do
38 test "#link_to_if_authorized for authorized user should allow using the :controller and :action for the target link" do
39 context "for authorized user" do
39 User.current = User.find_by_login('admin')
40 should "allow using the :controller and :action for the target link" do
41 User.current = User.find_by_login('admin')
42
43 @project = Issue.first.project # Used by helper
44 response = link_to_if_authorized('By controller/actionr',
45 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
46 assert_match /href/, response
47 end
48 end
49
40
50 context "for unauthorized user" do
41 @project = Issue.first.project # Used by helper
51 should "display nothing if user isn't authorized" do
42 response = link_to_if_authorized('By controller/actionr',
52 User.current = User.find_by_login('dlopper')
43 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
53 @project = Project.find('private-child')
44 assert_match /href/, response
54 issue = @project.issues.first
45 end
55 assert !issue.visible?
46
56
47 test "#link_to_if_authorized for unauthorized user should display nothing if user isn't authorized" do
57 response = link_to_if_authorized('Never displayed',
48 User.current = User.find_by_login('dlopper')
58 {:controller => 'issues', :action => 'show', :id => issue})
49 @project = Project.find('private-child')
59 assert_nil response
50 issue = @project.issues.first
60 end
51 assert !issue.visible?
61 end
52
53 response = link_to_if_authorized('Never displayed',
54 {:controller => 'issues', :action => 'show', :id => issue})
55 assert_nil response
62 end
56 end
63
57
64 def test_auto_links
58 def test_auto_links
65 to_test = {
59 to_test = {
66 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
60 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
67 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
61 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
68 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
62 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
69 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
63 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
70 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
64 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
71 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
65 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
72 'http://foo.bar/foo.bar#foo.bar.' => '<a class="external" href="http://foo.bar/foo.bar#foo.bar">http://foo.bar/foo.bar#foo.bar</a>.',
66 'http://foo.bar/foo.bar#foo.bar.' => '<a class="external" href="http://foo.bar/foo.bar#foo.bar">http://foo.bar/foo.bar#foo.bar</a>.',
73 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
67 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
74 '(see inline link : http://www.foo.bar/Test_(foobar))' => '(see inline link : <a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>)',
68 '(see inline link : http://www.foo.bar/Test_(foobar))' => '(see inline link : <a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>)',
75 '(see inline link : http://www.foo.bar/Test)' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>)',
69 '(see inline link : http://www.foo.bar/Test)' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>)',
76 '(see inline link : http://www.foo.bar/Test).' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>).',
70 '(see inline link : http://www.foo.bar/Test).' => '(see inline link : <a class="external" href="http://www.foo.bar/Test">http://www.foo.bar/Test</a>).',
77 '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
71 '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
78 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
72 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
79 '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
73 '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
80 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
74 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
81 'http://foo.bar/page?p=1&t=z&s=' => '<a class="external" href="http://foo.bar/page?p=1&#38;t=z&#38;s=">http://foo.bar/page?p=1&#38;t=z&#38;s=</a>',
75 'http://foo.bar/page?p=1&t=z&s=' => '<a class="external" href="http://foo.bar/page?p=1&#38;t=z&#38;s=">http://foo.bar/page?p=1&#38;t=z&#38;s=</a>',
82 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
76 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
83 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
77 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
84 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
78 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
85 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
79 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
86 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
80 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
87 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
81 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
88 # two exclamation marks
82 # two exclamation marks
89 'http://example.net/path!602815048C7B5C20!302.html' => '<a class="external" href="http://example.net/path!602815048C7B5C20!302.html">http://example.net/path!602815048C7B5C20!302.html</a>',
83 'http://example.net/path!602815048C7B5C20!302.html' => '<a class="external" href="http://example.net/path!602815048C7B5C20!302.html">http://example.net/path!602815048C7B5C20!302.html</a>',
90 # escaping
84 # escaping
91 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo&quot;bar</a>',
85 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo&quot;bar</a>',
92 # wrap in angle brackets
86 # wrap in angle brackets
93 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;',
87 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;',
94 # invalid urls
88 # invalid urls
95 'http://' => 'http://',
89 'http://' => 'http://',
96 'www.' => 'www.',
90 'www.' => 'www.',
97 'test-www.bar.com' => 'test-www.bar.com',
91 'test-www.bar.com' => 'test-www.bar.com',
98 }
92 }
99 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
93 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
100 end
94 end
101
95
102 if 'ruby'.respond_to?(:encoding)
96 if 'ruby'.respond_to?(:encoding)
103 def test_auto_links_with_non_ascii_characters
97 def test_auto_links_with_non_ascii_characters
104 to_test = {
98 to_test = {
105 'http://foo.bar/тСст' => '<a class="external" href="http://foo.bar/тСст">http://foo.bar/тСст</a>'
99 'http://foo.bar/тСст' => '<a class="external" href="http://foo.bar/тСст">http://foo.bar/тСст</a>'
106 }
100 }
107 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
101 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
108 end
102 end
109 else
103 else
110 puts 'Skipping test_auto_links_with_non_ascii_characters, unsupported ruby version'
104 puts 'Skipping test_auto_links_with_non_ascii_characters, unsupported ruby version'
111 end
105 end
112
106
113 def test_auto_mailto
107 def test_auto_mailto
114 to_test = {
108 to_test = {
115 'test@foo.bar' => '<a class="email" href="mailto:test@foo.bar">test@foo.bar</a>',
109 'test@foo.bar' => '<a class="email" href="mailto:test@foo.bar">test@foo.bar</a>',
116 'test@www.foo.bar' => '<a class="email" href="mailto:test@www.foo.bar">test@www.foo.bar</a>',
110 'test@www.foo.bar' => '<a class="email" href="mailto:test@www.foo.bar">test@www.foo.bar</a>',
117 }
111 }
118 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
112 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
119 end
113 end
120
114
121 def test_inline_images
115 def test_inline_images
122 to_test = {
116 to_test = {
123 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
117 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
124 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
118 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
125 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
119 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
126 'with style !{width:100px;height:100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" style="width:100px;height:100px;" alt="" />',
120 'with style !{width:100px;height:100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" style="width:100px;height:100px;" alt="" />',
127 'with title !http://foo.bar/image.jpg(This is a title)!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a title" alt="This is a title" />',
121 'with title !http://foo.bar/image.jpg(This is a title)!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a title" alt="This is a title" />',
128 'with title !http://foo.bar/image.jpg(This is a double-quoted "title")!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a double-quoted &quot;title&quot;" alt="This is a double-quoted &quot;title&quot;" />',
122 'with title !http://foo.bar/image.jpg(This is a double-quoted "title")!' => 'with title <img src="http://foo.bar/image.jpg" title="This is a double-quoted &quot;title&quot;" alt="This is a double-quoted &quot;title&quot;" />',
129 }
123 }
130 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
124 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
131 end
125 end
132
126
133 def test_inline_images_inside_tags
127 def test_inline_images_inside_tags
134 raw = <<-RAW
128 raw = <<-RAW
135 h1. !foo.png! Heading
129 h1. !foo.png! Heading
136
130
137 Centered image:
131 Centered image:
138
132
139 p=. !bar.gif!
133 p=. !bar.gif!
140 RAW
134 RAW
141
135
142 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
136 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
143 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
137 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
144 end
138 end
145
139
146 def test_attached_images
140 def test_attached_images
147 to_test = {
141 to_test = {
148 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
142 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
149 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
143 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" />',
150 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
144 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
151 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
145 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
152 # link image
146 # link image
153 '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" /></a>',
147 '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3/logo.gif" title="This is a logo" alt="This is a logo" /></a>',
154 }
148 }
155 attachments = Attachment.all
149 attachments = Attachment.all
156 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
150 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
157 end
151 end
158
152
159 def test_attached_images_filename_extension
153 def test_attached_images_filename_extension
160 set_tmp_attachments_directory
154 set_tmp_attachments_directory
161 a1 = Attachment.new(
155 a1 = Attachment.new(
162 :container => Issue.find(1),
156 :container => Issue.find(1),
163 :file => mock_file_with_options({:original_filename => "testtest.JPG"}),
157 :file => mock_file_with_options({:original_filename => "testtest.JPG"}),
164 :author => User.find(1))
158 :author => User.find(1))
165 assert a1.save
159 assert a1.save
166 assert_equal "testtest.JPG", a1.filename
160 assert_equal "testtest.JPG", a1.filename
167 assert_equal "image/jpeg", a1.content_type
161 assert_equal "image/jpeg", a1.content_type
168 assert a1.image?
162 assert a1.image?
169
163
170 a2 = Attachment.new(
164 a2 = Attachment.new(
171 :container => Issue.find(1),
165 :container => Issue.find(1),
172 :file => mock_file_with_options({:original_filename => "testtest.jpeg"}),
166 :file => mock_file_with_options({:original_filename => "testtest.jpeg"}),
173 :author => User.find(1))
167 :author => User.find(1))
174 assert a2.save
168 assert a2.save
175 assert_equal "testtest.jpeg", a2.filename
169 assert_equal "testtest.jpeg", a2.filename
176 assert_equal "image/jpeg", a2.content_type
170 assert_equal "image/jpeg", a2.content_type
177 assert a2.image?
171 assert a2.image?
178
172
179 a3 = Attachment.new(
173 a3 = Attachment.new(
180 :container => Issue.find(1),
174 :container => Issue.find(1),
181 :file => mock_file_with_options({:original_filename => "testtest.JPE"}),
175 :file => mock_file_with_options({:original_filename => "testtest.JPE"}),
182 :author => User.find(1))
176 :author => User.find(1))
183 assert a3.save
177 assert a3.save
184 assert_equal "testtest.JPE", a3.filename
178 assert_equal "testtest.JPE", a3.filename
185 assert_equal "image/jpeg", a3.content_type
179 assert_equal "image/jpeg", a3.content_type
186 assert a3.image?
180 assert a3.image?
187
181
188 a4 = Attachment.new(
182 a4 = Attachment.new(
189 :container => Issue.find(1),
183 :container => Issue.find(1),
190 :file => mock_file_with_options({:original_filename => "Testtest.BMP"}),
184 :file => mock_file_with_options({:original_filename => "Testtest.BMP"}),
191 :author => User.find(1))
185 :author => User.find(1))
192 assert a4.save
186 assert a4.save
193 assert_equal "Testtest.BMP", a4.filename
187 assert_equal "Testtest.BMP", a4.filename
194 assert_equal "image/x-ms-bmp", a4.content_type
188 assert_equal "image/x-ms-bmp", a4.content_type
195 assert a4.image?
189 assert a4.image?
196
190
197 to_test = {
191 to_test = {
198 'Inline image: !testtest.jpg!' =>
192 'Inline image: !testtest.jpg!' =>
199 'Inline image: <img src="/attachments/download/' + a1.id.to_s + '/testtest.JPG" alt="" />',
193 'Inline image: <img src="/attachments/download/' + a1.id.to_s + '/testtest.JPG" alt="" />',
200 'Inline image: !testtest.jpeg!' =>
194 'Inline image: !testtest.jpeg!' =>
201 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testtest.jpeg" alt="" />',
195 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testtest.jpeg" alt="" />',
202 'Inline image: !testtest.jpe!' =>
196 'Inline image: !testtest.jpe!' =>
203 'Inline image: <img src="/attachments/download/' + a3.id.to_s + '/testtest.JPE" alt="" />',
197 'Inline image: <img src="/attachments/download/' + a3.id.to_s + '/testtest.JPE" alt="" />',
204 'Inline image: !testtest.bmp!' =>
198 'Inline image: !testtest.bmp!' =>
205 'Inline image: <img src="/attachments/download/' + a4.id.to_s + '/Testtest.BMP" alt="" />',
199 'Inline image: <img src="/attachments/download/' + a4.id.to_s + '/Testtest.BMP" alt="" />',
206 }
200 }
207
201
208 attachments = [a1, a2, a3, a4]
202 attachments = [a1, a2, a3, a4]
209 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
203 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
210 end
204 end
211
205
212 def test_attached_images_should_read_later
206 def test_attached_images_should_read_later
213 set_fixtures_attachments_directory
207 set_fixtures_attachments_directory
214 a1 = Attachment.find(16)
208 a1 = Attachment.find(16)
215 assert_equal "testfile.png", a1.filename
209 assert_equal "testfile.png", a1.filename
216 assert a1.readable?
210 assert a1.readable?
217 assert (! a1.visible?(User.anonymous))
211 assert (! a1.visible?(User.anonymous))
218 assert a1.visible?(User.find(2))
212 assert a1.visible?(User.find(2))
219 a2 = Attachment.find(17)
213 a2 = Attachment.find(17)
220 assert_equal "testfile.PNG", a2.filename
214 assert_equal "testfile.PNG", a2.filename
221 assert a2.readable?
215 assert a2.readable?
222 assert (! a2.visible?(User.anonymous))
216 assert (! a2.visible?(User.anonymous))
223 assert a2.visible?(User.find(2))
217 assert a2.visible?(User.find(2))
224 assert a1.created_on < a2.created_on
218 assert a1.created_on < a2.created_on
225
219
226 to_test = {
220 to_test = {
227 'Inline image: !testfile.png!' =>
221 'Inline image: !testfile.png!' =>
228 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
222 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
229 'Inline image: !Testfile.PNG!' =>
223 'Inline image: !Testfile.PNG!' =>
230 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
224 'Inline image: <img src="/attachments/download/' + a2.id.to_s + '/testfile.PNG" alt="" />',
231 }
225 }
232 attachments = [a1, a2]
226 attachments = [a1, a2]
233 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
227 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
234 set_tmp_attachments_directory
228 set_tmp_attachments_directory
235 end
229 end
236
230
237 def test_textile_external_links
231 def test_textile_external_links
238 to_test = {
232 to_test = {
239 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
233 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
240 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
234 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
241 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
235 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
242 '"link (Link title with "double-quotes")":http://foo.bar' => '<a href="http://foo.bar" title="Link title with &quot;double-quotes&quot;" class="external">link</a>',
236 '"link (Link title with "double-quotes")":http://foo.bar' => '<a href="http://foo.bar" title="Link title with &quot;double-quotes&quot;" class="external">link</a>',
243 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
237 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
244 # no multiline link text
238 # no multiline link text
245 "This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />and another on a second line\":test",
239 "This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />and another on a second line\":test",
246 # mailto link
240 # mailto link
247 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
241 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
248 # two exclamation marks
242 # two exclamation marks
249 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
243 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
250 # escaping
244 # escaping
251 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
245 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
252 }
246 }
253 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
247 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
254 end
248 end
255
249
256 if 'ruby'.respond_to?(:encoding)
250 if 'ruby'.respond_to?(:encoding)
257 def test_textile_external_links_with_non_ascii_characters
251 def test_textile_external_links_with_non_ascii_characters
258 to_test = {
252 to_test = {
259 'This is a "link":http://foo.bar/тСст' => 'This is a <a href="http://foo.bar/тСст" class="external">link</a>'
253 'This is a "link":http://foo.bar/тСст' => 'This is a <a href="http://foo.bar/тСст" class="external">link</a>'
260 }
254 }
261 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
255 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
262 end
256 end
263 else
257 else
264 puts 'Skipping test_textile_external_links_with_non_ascii_characters, unsupported ruby version'
258 puts 'Skipping test_textile_external_links_with_non_ascii_characters, unsupported ruby version'
265 end
259 end
266
260
267 def test_redmine_links
261 def test_redmine_links
268 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
262 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
269 :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
263 :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
270 note_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'},
264 note_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'},
271 :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
265 :class => Issue.find(3).css_classes, :title => 'Error 281 when updating a recipe (New)')
272
266
273 revision_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
267 revision_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
274 :class => 'changeset', :title => 'My very first commit do not escaping #<>&')
268 :class => 'changeset', :title => 'My very first commit do not escaping #<>&')
275 revision_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
269 revision_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
276 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
270 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
277
271
278 changeset_link2 = link_to('691322a8eb01e11fd7',
272 changeset_link2 = link_to('691322a8eb01e11fd7',
279 {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
273 {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
280 :class => 'changeset', :title => 'My very first commit do not escaping #<>&')
274 :class => 'changeset', :title => 'My very first commit do not escaping #<>&')
281
275
282 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
276 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
283 :class => 'document')
277 :class => 'document')
284
278
285 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
279 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
286 :class => 'version')
280 :class => 'version')
287
281
288 board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
282 board_url = {:controller => 'boards', :action => 'show', :id => 2, :project_id => 'ecookbook'}
289
283
290 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
284 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
291
285
292 news_url = {:controller => 'news', :action => 'show', :id => 1}
286 news_url = {:controller => 'news', :action => 'show', :id => 1}
293
287
294 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
288 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
295
289
296 source_url = '/projects/ecookbook/repository/entry/some/file'
290 source_url = '/projects/ecookbook/repository/entry/some/file'
297 source_url_with_rev = '/projects/ecookbook/repository/revisions/52/entry/some/file'
291 source_url_with_rev = '/projects/ecookbook/repository/revisions/52/entry/some/file'
298 source_url_with_ext = '/projects/ecookbook/repository/entry/some/file.ext'
292 source_url_with_ext = '/projects/ecookbook/repository/entry/some/file.ext'
299 source_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/entry/some/file.ext'
293 source_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/entry/some/file.ext'
300 source_url_with_branch = '/projects/ecookbook/repository/revisions/branch/entry/some/file'
294 source_url_with_branch = '/projects/ecookbook/repository/revisions/branch/entry/some/file'
301
295
302 export_url = '/projects/ecookbook/repository/raw/some/file'
296 export_url = '/projects/ecookbook/repository/raw/some/file'
303 export_url_with_rev = '/projects/ecookbook/repository/revisions/52/raw/some/file'
297 export_url_with_rev = '/projects/ecookbook/repository/revisions/52/raw/some/file'
304 export_url_with_ext = '/projects/ecookbook/repository/raw/some/file.ext'
298 export_url_with_ext = '/projects/ecookbook/repository/raw/some/file.ext'
305 export_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/raw/some/file.ext'
299 export_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/raw/some/file.ext'
306 export_url_with_branch = '/projects/ecookbook/repository/revisions/branch/raw/some/file'
300 export_url_with_branch = '/projects/ecookbook/repository/revisions/branch/raw/some/file'
307
301
308 to_test = {
302 to_test = {
309 # tickets
303 # tickets
310 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
304 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
311 # ticket notes
305 # ticket notes
312 '#3-14' => note_link,
306 '#3-14' => note_link,
313 '#3#note-14' => note_link,
307 '#3#note-14' => note_link,
314 # should not ignore leading zero
308 # should not ignore leading zero
315 '#03' => '#03',
309 '#03' => '#03',
316 # changesets
310 # changesets
317 'r1' => revision_link,
311 'r1' => revision_link,
318 'r1.' => "#{revision_link}.",
312 'r1.' => "#{revision_link}.",
319 'r1, r2' => "#{revision_link}, #{revision_link2}",
313 'r1, r2' => "#{revision_link}, #{revision_link2}",
320 'r1,r2' => "#{revision_link},#{revision_link2}",
314 'r1,r2' => "#{revision_link},#{revision_link2}",
321 'commit:691322a8eb01e11fd7' => changeset_link2,
315 'commit:691322a8eb01e11fd7' => changeset_link2,
322 # documents
316 # documents
323 'document#1' => document_link,
317 'document#1' => document_link,
324 'document:"Test document"' => document_link,
318 'document:"Test document"' => document_link,
325 # versions
319 # versions
326 'version#2' => version_link,
320 'version#2' => version_link,
327 'version:1.0' => version_link,
321 'version:1.0' => version_link,
328 'version:"1.0"' => version_link,
322 'version:"1.0"' => version_link,
329 # source
323 # source
330 'source:some/file' => link_to('source:some/file', source_url, :class => 'source'),
324 'source:some/file' => link_to('source:some/file', source_url, :class => 'source'),
331 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
325 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
332 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
326 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
333 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
327 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
334 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
328 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
335 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
329 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
336 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
330 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
337 'source:/some/file@52' => link_to('source:/some/file@52', source_url_with_rev, :class => 'source'),
331 'source:/some/file@52' => link_to('source:/some/file@52', source_url_with_rev, :class => 'source'),
338 'source:/some/file@branch' => link_to('source:/some/file@branch', source_url_with_branch, :class => 'source'),
332 'source:/some/file@branch' => link_to('source:/some/file@branch', source_url_with_branch, :class => 'source'),
339 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_rev_and_ext, :class => 'source'),
333 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_rev_and_ext, :class => 'source'),
340 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url + "#L110", :class => 'source'),
334 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url + "#L110", :class => 'source'),
341 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext + "#L110", :class => 'source'),
335 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext + "#L110", :class => 'source'),
342 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url_with_rev + "#L110", :class => 'source'),
336 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url_with_rev + "#L110", :class => 'source'),
343 # export
337 # export
344 'export:/some/file' => link_to('export:/some/file', export_url, :class => 'source download'),
338 'export:/some/file' => link_to('export:/some/file', export_url, :class => 'source download'),
345 'export:/some/file.ext' => link_to('export:/some/file.ext', export_url_with_ext, :class => 'source download'),
339 'export:/some/file.ext' => link_to('export:/some/file.ext', export_url_with_ext, :class => 'source download'),
346 'export:/some/file@52' => link_to('export:/some/file@52', export_url_with_rev, :class => 'source download'),
340 'export:/some/file@52' => link_to('export:/some/file@52', export_url_with_rev, :class => 'source download'),
347 'export:/some/file.ext@52' => link_to('export:/some/file.ext@52', export_url_with_rev_and_ext, :class => 'source download'),
341 'export:/some/file.ext@52' => link_to('export:/some/file.ext@52', export_url_with_rev_and_ext, :class => 'source download'),
348 'export:/some/file@branch' => link_to('export:/some/file@branch', export_url_with_branch, :class => 'source download'),
342 'export:/some/file@branch' => link_to('export:/some/file@branch', export_url_with_branch, :class => 'source download'),
349 # forum
343 # forum
350 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
344 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
351 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
345 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
352 # message
346 # message
353 'message#4' => link_to('Post 2', message_url, :class => 'message'),
347 'message#4' => link_to('Post 2', message_url, :class => 'message'),
354 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
348 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5', :r => 5), :class => 'message'),
355 # news
349 # news
356 'news#1' => link_to('eCookbook first release !', news_url, :class => 'news'),
350 'news#1' => link_to('eCookbook first release !', news_url, :class => 'news'),
357 'news:"eCookbook first release !"' => link_to('eCookbook first release !', news_url, :class => 'news'),
351 'news:"eCookbook first release !"' => link_to('eCookbook first release !', news_url, :class => 'news'),
358 # project
352 # project
359 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
353 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
360 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
354 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
361 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
355 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
362 # not found
356 # not found
363 '#0123456789' => '#0123456789',
357 '#0123456789' => '#0123456789',
364 # invalid expressions
358 # invalid expressions
365 'source:' => 'source:',
359 'source:' => 'source:',
366 # url hash
360 # url hash
367 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
361 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
368 }
362 }
369 @project = Project.find(1)
363 @project = Project.find(1)
370 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
364 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
371 end
365 end
372
366
373 def test_redmine_links_with_a_different_project_before_current_project
367 def test_redmine_links_with_a_different_project_before_current_project
374 vp1 = Version.generate!(:project_id => 1, :name => '1.4.4')
368 vp1 = Version.generate!(:project_id => 1, :name => '1.4.4')
375 vp3 = Version.generate!(:project_id => 3, :name => '1.4.4')
369 vp3 = Version.generate!(:project_id => 3, :name => '1.4.4')
376
370
377 @project = Project.find(3)
371 @project = Project.find(3)
378 assert_equal %(<p><a href="/versions/#{vp1.id}" class="version">1.4.4</a> <a href="/versions/#{vp3.id}" class="version">1.4.4</a></p>),
372 assert_equal %(<p><a href="/versions/#{vp1.id}" class="version">1.4.4</a> <a href="/versions/#{vp3.id}" class="version">1.4.4</a></p>),
379 textilizable("ecookbook:version:1.4.4 version:1.4.4")
373 textilizable("ecookbook:version:1.4.4 version:1.4.4")
380 end
374 end
381
375
382 def test_escaped_redmine_links_should_not_be_parsed
376 def test_escaped_redmine_links_should_not_be_parsed
383 to_test = [
377 to_test = [
384 '#3.',
378 '#3.',
385 '#3-14.',
379 '#3-14.',
386 '#3#-note14.',
380 '#3#-note14.',
387 'r1',
381 'r1',
388 'document#1',
382 'document#1',
389 'document:"Test document"',
383 'document:"Test document"',
390 'version#2',
384 'version#2',
391 'version:1.0',
385 'version:1.0',
392 'version:"1.0"',
386 'version:"1.0"',
393 'source:/some/file'
387 'source:/some/file'
394 ]
388 ]
395 @project = Project.find(1)
389 @project = Project.find(1)
396 to_test.each { |text| assert_equal "<p>#{text}</p>", textilizable("!" + text), "#{text} failed" }
390 to_test.each { |text| assert_equal "<p>#{text}</p>", textilizable("!" + text), "#{text} failed" }
397 end
391 end
398
392
399 def test_cross_project_redmine_links
393 def test_cross_project_redmine_links
400 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
394 source_link = link_to('ecookbook:source:/some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']},
401 :class => 'source')
395 :class => 'source')
402
396
403 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
397 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
404 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
398 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
405
399
406 to_test = {
400 to_test = {
407 # documents
401 # documents
408 'document:"Test document"' => 'document:"Test document"',
402 'document:"Test document"' => 'document:"Test document"',
409 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
403 'ecookbook:document:"Test document"' => '<a href="/documents/1" class="document">Test document</a>',
410 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
404 'invalid:document:"Test document"' => 'invalid:document:"Test document"',
411 # versions
405 # versions
412 'version:"1.0"' => 'version:"1.0"',
406 'version:"1.0"' => 'version:"1.0"',
413 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
407 'ecookbook:version:"1.0"' => '<a href="/versions/2" class="version">1.0</a>',
414 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
408 'invalid:version:"1.0"' => 'invalid:version:"1.0"',
415 # changeset
409 # changeset
416 'r2' => 'r2',
410 'r2' => 'r2',
417 'ecookbook:r2' => changeset_link,
411 'ecookbook:r2' => changeset_link,
418 'invalid:r2' => 'invalid:r2',
412 'invalid:r2' => 'invalid:r2',
419 # source
413 # source
420 'source:/some/file' => 'source:/some/file',
414 'source:/some/file' => 'source:/some/file',
421 'ecookbook:source:/some/file' => source_link,
415 'ecookbook:source:/some/file' => source_link,
422 'invalid:source:/some/file' => 'invalid:source:/some/file',
416 'invalid:source:/some/file' => 'invalid:source:/some/file',
423 }
417 }
424 @project = Project.find(3)
418 @project = Project.find(3)
425 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
419 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
426 end
420 end
427
421
428 def test_multiple_repositories_redmine_links
422 def test_multiple_repositories_redmine_links
429 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn_repo-1', :url => 'file:///foo/hg')
423 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn_repo-1', :url => 'file:///foo/hg')
430 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
424 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
431 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
425 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
432 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
426 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
433
427
434 changeset_link = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
428 changeset_link = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
435 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
429 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
436 svn_changeset_link = link_to('svn_repo-1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn_repo-1', :rev => 123},
430 svn_changeset_link = link_to('svn_repo-1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn_repo-1', :rev => 123},
437 :class => 'changeset', :title => '')
431 :class => 'changeset', :title => '')
438 hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
432 hg_changeset_link = link_to('hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
439 :class => 'changeset', :title => '')
433 :class => 'changeset', :title => '')
440
434
441 source_link = link_to('source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
435 source_link = link_to('source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
442 hg_source_link = link_to('source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
436 hg_source_link = link_to('source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
443
437
444 to_test = {
438 to_test = {
445 'r2' => changeset_link,
439 'r2' => changeset_link,
446 'svn_repo-1|r123' => svn_changeset_link,
440 'svn_repo-1|r123' => svn_changeset_link,
447 'invalid|r123' => 'invalid|r123',
441 'invalid|r123' => 'invalid|r123',
448 'commit:hg1|abcd' => hg_changeset_link,
442 'commit:hg1|abcd' => hg_changeset_link,
449 'commit:invalid|abcd' => 'commit:invalid|abcd',
443 'commit:invalid|abcd' => 'commit:invalid|abcd',
450 # source
444 # source
451 'source:some/file' => source_link,
445 'source:some/file' => source_link,
452 'source:hg1|some/file' => hg_source_link,
446 'source:hg1|some/file' => hg_source_link,
453 'source:invalid|some/file' => 'source:invalid|some/file',
447 'source:invalid|some/file' => 'source:invalid|some/file',
454 }
448 }
455
449
456 @project = Project.find(1)
450 @project = Project.find(1)
457 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
451 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
458 end
452 end
459
453
460 def test_cross_project_multiple_repositories_redmine_links
454 def test_cross_project_multiple_repositories_redmine_links
461 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
455 svn = Repository::Subversion.create!(:project_id => 1, :identifier => 'svn1', :url => 'file:///foo/hg')
462 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
456 Changeset.create!(:repository => svn, :committed_on => Time.now, :revision => '123')
463 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
457 hg = Repository::Mercurial.create!(:project_id => 1, :identifier => 'hg1', :url => '/foo/hg')
464 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
458 Changeset.create!(:repository => hg, :committed_on => Time.now, :revision => '123', :scmid => 'abcd')
465
459
466 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
460 changeset_link = link_to('ecookbook:r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
467 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
461 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
468 svn_changeset_link = link_to('ecookbook:svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123},
462 svn_changeset_link = link_to('ecookbook:svn1|r123', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'svn1', :rev => 123},
469 :class => 'changeset', :title => '')
463 :class => 'changeset', :title => '')
470 hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
464 hg_changeset_link = link_to('ecookbook:hg1|abcd', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :repository_id => 'hg1', :rev => 'abcd'},
471 :class => 'changeset', :title => '')
465 :class => 'changeset', :title => '')
472
466
473 source_link = link_to('ecookbook:source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
467 source_link = link_to('ecookbook:source:some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}, :class => 'source')
474 hg_source_link = link_to('ecookbook:source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
468 hg_source_link = link_to('ecookbook:source:hg1|some/file', {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :repository_id => 'hg1', :path => ['some', 'file']}, :class => 'source')
475
469
476 to_test = {
470 to_test = {
477 'ecookbook:r2' => changeset_link,
471 'ecookbook:r2' => changeset_link,
478 'ecookbook:svn1|r123' => svn_changeset_link,
472 'ecookbook:svn1|r123' => svn_changeset_link,
479 'ecookbook:invalid|r123' => 'ecookbook:invalid|r123',
473 'ecookbook:invalid|r123' => 'ecookbook:invalid|r123',
480 'ecookbook:commit:hg1|abcd' => hg_changeset_link,
474 'ecookbook:commit:hg1|abcd' => hg_changeset_link,
481 'ecookbook:commit:invalid|abcd' => 'ecookbook:commit:invalid|abcd',
475 'ecookbook:commit:invalid|abcd' => 'ecookbook:commit:invalid|abcd',
482 'invalid:commit:invalid|abcd' => 'invalid:commit:invalid|abcd',
476 'invalid:commit:invalid|abcd' => 'invalid:commit:invalid|abcd',
483 # source
477 # source
484 'ecookbook:source:some/file' => source_link,
478 'ecookbook:source:some/file' => source_link,
485 'ecookbook:source:hg1|some/file' => hg_source_link,
479 'ecookbook:source:hg1|some/file' => hg_source_link,
486 'ecookbook:source:invalid|some/file' => 'ecookbook:source:invalid|some/file',
480 'ecookbook:source:invalid|some/file' => 'ecookbook:source:invalid|some/file',
487 'invalid:source:invalid|some/file' => 'invalid:source:invalid|some/file',
481 'invalid:source:invalid|some/file' => 'invalid:source:invalid|some/file',
488 }
482 }
489
483
490 @project = Project.find(3)
484 @project = Project.find(3)
491 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
485 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
492 end
486 end
493
487
494 def test_redmine_links_git_commit
488 def test_redmine_links_git_commit
495 changeset_link = link_to('abcd',
489 changeset_link = link_to('abcd',
496 {
490 {
497 :controller => 'repositories',
491 :controller => 'repositories',
498 :action => 'revision',
492 :action => 'revision',
499 :id => 'subproject1',
493 :id => 'subproject1',
500 :rev => 'abcd',
494 :rev => 'abcd',
501 },
495 },
502 :class => 'changeset', :title => 'test commit')
496 :class => 'changeset', :title => 'test commit')
503 to_test = {
497 to_test = {
504 'commit:abcd' => changeset_link,
498 'commit:abcd' => changeset_link,
505 }
499 }
506 @project = Project.find(3)
500 @project = Project.find(3)
507 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
501 r = Repository::Git.create!(:project => @project, :url => '/tmp/test/git')
508 assert r
502 assert r
509 c = Changeset.new(:repository => r,
503 c = Changeset.new(:repository => r,
510 :committed_on => Time.now,
504 :committed_on => Time.now,
511 :revision => 'abcd',
505 :revision => 'abcd',
512 :scmid => 'abcd',
506 :scmid => 'abcd',
513 :comments => 'test commit')
507 :comments => 'test commit')
514 assert( c.save )
508 assert( c.save )
515 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
509 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
516 end
510 end
517
511
518 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
512 # TODO: Bazaar commit id contains mail address, so it contains '@' and '_'.
519 def test_redmine_links_darcs_commit
513 def test_redmine_links_darcs_commit
520 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
514 changeset_link = link_to('20080308225258-98289-abcd456efg.gz',
521 {
515 {
522 :controller => 'repositories',
516 :controller => 'repositories',
523 :action => 'revision',
517 :action => 'revision',
524 :id => 'subproject1',
518 :id => 'subproject1',
525 :rev => '123',
519 :rev => '123',
526 },
520 },
527 :class => 'changeset', :title => 'test commit')
521 :class => 'changeset', :title => 'test commit')
528 to_test = {
522 to_test = {
529 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
523 'commit:20080308225258-98289-abcd456efg.gz' => changeset_link,
530 }
524 }
531 @project = Project.find(3)
525 @project = Project.find(3)
532 r = Repository::Darcs.create!(
526 r = Repository::Darcs.create!(
533 :project => @project, :url => '/tmp/test/darcs',
527 :project => @project, :url => '/tmp/test/darcs',
534 :log_encoding => 'UTF-8')
528 :log_encoding => 'UTF-8')
535 assert r
529 assert r
536 c = Changeset.new(:repository => r,
530 c = Changeset.new(:repository => r,
537 :committed_on => Time.now,
531 :committed_on => Time.now,
538 :revision => '123',
532 :revision => '123',
539 :scmid => '20080308225258-98289-abcd456efg.gz',
533 :scmid => '20080308225258-98289-abcd456efg.gz',
540 :comments => 'test commit')
534 :comments => 'test commit')
541 assert( c.save )
535 assert( c.save )
542 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
536 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
543 end
537 end
544
538
545 def test_redmine_links_mercurial_commit
539 def test_redmine_links_mercurial_commit
546 changeset_link_rev = link_to('r123',
540 changeset_link_rev = link_to('r123',
547 {
541 {
548 :controller => 'repositories',
542 :controller => 'repositories',
549 :action => 'revision',
543 :action => 'revision',
550 :id => 'subproject1',
544 :id => 'subproject1',
551 :rev => '123' ,
545 :rev => '123' ,
552 },
546 },
553 :class => 'changeset', :title => 'test commit')
547 :class => 'changeset', :title => 'test commit')
554 changeset_link_commit = link_to('abcd',
548 changeset_link_commit = link_to('abcd',
555 {
549 {
556 :controller => 'repositories',
550 :controller => 'repositories',
557 :action => 'revision',
551 :action => 'revision',
558 :id => 'subproject1',
552 :id => 'subproject1',
559 :rev => 'abcd' ,
553 :rev => 'abcd' ,
560 },
554 },
561 :class => 'changeset', :title => 'test commit')
555 :class => 'changeset', :title => 'test commit')
562 to_test = {
556 to_test = {
563 'r123' => changeset_link_rev,
557 'r123' => changeset_link_rev,
564 'commit:abcd' => changeset_link_commit,
558 'commit:abcd' => changeset_link_commit,
565 }
559 }
566 @project = Project.find(3)
560 @project = Project.find(3)
567 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
561 r = Repository::Mercurial.create!(:project => @project, :url => '/tmp/test')
568 assert r
562 assert r
569 c = Changeset.new(:repository => r,
563 c = Changeset.new(:repository => r,
570 :committed_on => Time.now,
564 :committed_on => Time.now,
571 :revision => '123',
565 :revision => '123',
572 :scmid => 'abcd',
566 :scmid => 'abcd',
573 :comments => 'test commit')
567 :comments => 'test commit')
574 assert( c.save )
568 assert( c.save )
575 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
569 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
576 end
570 end
577
571
578 def test_attachment_links
572 def test_attachment_links
579 to_test = {
573 to_test = {
580 'attachment:error281.txt' => '<a href="/attachments/download/1/error281.txt" class="attachment">error281.txt</a>'
574 'attachment:error281.txt' => '<a href="/attachments/download/1/error281.txt" class="attachment">error281.txt</a>'
581 }
575 }
582 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
576 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
583 end
577 end
584
578
585 def test_attachment_link_should_link_to_latest_attachment
579 def test_attachment_link_should_link_to_latest_attachment
586 set_tmp_attachments_directory
580 set_tmp_attachments_directory
587 a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago)
581 a1 = Attachment.generate!(:filename => "test.txt", :created_on => 1.hour.ago)
588 a2 = Attachment.generate!(:filename => "test.txt")
582 a2 = Attachment.generate!(:filename => "test.txt")
589
583
590 assert_equal %(<p><a href="/attachments/download/#{a2.id}/test.txt" class="attachment">test.txt</a></p>),
584 assert_equal %(<p><a href="/attachments/download/#{a2.id}/test.txt" class="attachment">test.txt</a></p>),
591 textilizable('attachment:test.txt', :attachments => [a1, a2])
585 textilizable('attachment:test.txt', :attachments => [a1, a2])
592 end
586 end
593
587
594 def test_wiki_links
588 def test_wiki_links
595 to_test = {
589 to_test = {
596 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
590 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
597 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
591 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
598 # title content should be formatted
592 # title content should be formatted
599 '[[Another page|With _styled_ *title*]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With <em>styled</em> <strong>title</strong></a>',
593 '[[Another page|With _styled_ *title*]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With <em>styled</em> <strong>title</strong></a>',
600 '[[Another page|With title containing <strong>HTML entities &amp; markups</strong>]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With title containing &lt;strong&gt;HTML entities &amp; markups&lt;/strong&gt;</a>',
594 '[[Another page|With title containing <strong>HTML entities &amp; markups</strong>]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">With title containing &lt;strong&gt;HTML entities &amp; markups&lt;/strong&gt;</a>',
601 # link with anchor
595 # link with anchor
602 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
596 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
603 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
597 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
604 # UTF8 anchor
598 # UTF8 anchor
605 '[[Another_page#ВСст|ВСст]]' => %|<a href="/projects/ecookbook/wiki/Another_page##{CGI.escape 'ВСст'}" class="wiki-page">ВСст</a>|,
599 '[[Another_page#ВСст|ВСст]]' => %|<a href="/projects/ecookbook/wiki/Another_page##{CGI.escape 'ВСст'}" class="wiki-page">ВСст</a>|,
606 # page that doesn't exist
600 # page that doesn't exist
607 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
601 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
608 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
602 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
609 # link to another project wiki
603 # link to another project wiki
610 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
604 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
611 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
605 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
612 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
606 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
613 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
607 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
614 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
608 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
615 # striked through link
609 # striked through link
616 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
610 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
617 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
611 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
618 # escaping
612 # escaping
619 '![[Another page|Page]]' => '[[Another page|Page]]',
613 '![[Another page|Page]]' => '[[Another page|Page]]',
620 # project does not exist
614 # project does not exist
621 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
615 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
622 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
616 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
623 }
617 }
624
618
625 @project = Project.find(1)
619 @project = Project.find(1)
626 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
620 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
627 end
621 end
628
622
629 def test_wiki_links_within_local_file_generation_context
623 def test_wiki_links_within_local_file_generation_context
630
624
631 to_test = {
625 to_test = {
632 # link to a page
626 # link to a page
633 '[[CookBook documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">CookBook documentation</a>',
627 '[[CookBook documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">CookBook documentation</a>',
634 '[[CookBook documentation|documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">documentation</a>',
628 '[[CookBook documentation|documentation]]' => '<a href="CookBook_documentation.html" class="wiki-page">documentation</a>',
635 '[[CookBook documentation#One-section]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">CookBook documentation</a>',
629 '[[CookBook documentation#One-section]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">CookBook documentation</a>',
636 '[[CookBook documentation#One-section|documentation]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">documentation</a>',
630 '[[CookBook documentation#One-section|documentation]]' => '<a href="CookBook_documentation.html#One-section" class="wiki-page">documentation</a>',
637 # page that doesn't exist
631 # page that doesn't exist
638 '[[Unknown page]]' => '<a href="Unknown_page.html" class="wiki-page new">Unknown page</a>',
632 '[[Unknown page]]' => '<a href="Unknown_page.html" class="wiki-page new">Unknown page</a>',
639 '[[Unknown page|404]]' => '<a href="Unknown_page.html" class="wiki-page new">404</a>',
633 '[[Unknown page|404]]' => '<a href="Unknown_page.html" class="wiki-page new">404</a>',
640 '[[Unknown page#anchor]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">Unknown page</a>',
634 '[[Unknown page#anchor]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">Unknown page</a>',
641 '[[Unknown page#anchor|404]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">404</a>',
635 '[[Unknown page#anchor|404]]' => '<a href="Unknown_page.html#anchor" class="wiki-page new">404</a>',
642 }
636 }
643
637
644 @project = Project.find(1)
638 @project = Project.find(1)
645
639
646 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
640 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :local) }
647 end
641 end
648
642
649 def test_wiki_links_within_wiki_page_context
643 def test_wiki_links_within_wiki_page_context
650
644
651 page = WikiPage.find_by_title('Another_page' )
645 page = WikiPage.find_by_title('Another_page' )
652
646
653 to_test = {
647 to_test = {
654 # link to another page
648 # link to another page
655 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
649 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
656 '[[CookBook documentation|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">documentation</a>',
650 '[[CookBook documentation|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">documentation</a>',
657 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
651 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
658 '[[CookBook documentation#One-section|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">documentation</a>',
652 '[[CookBook documentation#One-section|documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">documentation</a>',
659 # link to the current page
653 # link to the current page
660 '[[Another page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Another page</a>',
654 '[[Another page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Another page</a>',
661 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
655 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
662 '[[Another page#anchor]]' => '<a href="#anchor" class="wiki-page">Another page</a>',
656 '[[Another page#anchor]]' => '<a href="#anchor" class="wiki-page">Another page</a>',
663 '[[Another page#anchor|Page]]' => '<a href="#anchor" class="wiki-page">Page</a>',
657 '[[Another page#anchor|Page]]' => '<a href="#anchor" class="wiki-page">Page</a>',
664 # page that doesn't exist
658 # page that doesn't exist
665 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">Unknown page</a>',
659 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">Unknown page</a>',
666 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">404</a>',
660 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page" class="wiki-page new">404</a>',
667 '[[Unknown page#anchor]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">Unknown page</a>',
661 '[[Unknown page#anchor]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">Unknown page</a>',
668 '[[Unknown page#anchor|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">404</a>',
662 '[[Unknown page#anchor|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page?parent=Another_page#anchor" class="wiki-page new">404</a>',
669 }
663 }
670
664
671 @project = Project.find(1)
665 @project = Project.find(1)
672
666
673 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.new( :text => text, :page => page ), :text) }
667 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(WikiContent.new( :text => text, :page => page ), :text) }
674 end
668 end
675
669
676 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
670 def test_wiki_links_anchor_option_should_prepend_page_title_to_href
677
671
678 to_test = {
672 to_test = {
679 # link to a page
673 # link to a page
680 '[[CookBook documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">CookBook documentation</a>',
674 '[[CookBook documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">CookBook documentation</a>',
681 '[[CookBook documentation|documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">documentation</a>',
675 '[[CookBook documentation|documentation]]' => '<a href="#CookBook_documentation" class="wiki-page">documentation</a>',
682 '[[CookBook documentation#One-section]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">CookBook documentation</a>',
676 '[[CookBook documentation#One-section]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">CookBook documentation</a>',
683 '[[CookBook documentation#One-section|documentation]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">documentation</a>',
677 '[[CookBook documentation#One-section|documentation]]' => '<a href="#CookBook_documentation_One-section" class="wiki-page">documentation</a>',
684 # page that doesn't exist
678 # page that doesn't exist
685 '[[Unknown page]]' => '<a href="#Unknown_page" class="wiki-page new">Unknown page</a>',
679 '[[Unknown page]]' => '<a href="#Unknown_page" class="wiki-page new">Unknown page</a>',
686 '[[Unknown page|404]]' => '<a href="#Unknown_page" class="wiki-page new">404</a>',
680 '[[Unknown page|404]]' => '<a href="#Unknown_page" class="wiki-page new">404</a>',
687 '[[Unknown page#anchor]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">Unknown page</a>',
681 '[[Unknown page#anchor]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">Unknown page</a>',
688 '[[Unknown page#anchor|404]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">404</a>',
682 '[[Unknown page#anchor|404]]' => '<a href="#Unknown_page_anchor" class="wiki-page new">404</a>',
689 }
683 }
690
684
691 @project = Project.find(1)
685 @project = Project.find(1)
692
686
693 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
687 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :wiki_links => :anchor) }
694 end
688 end
695
689
696 def test_html_tags
690 def test_html_tags
697 to_test = {
691 to_test = {
698 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
692 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
699 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
693 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
700 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
694 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
701 # do not escape pre/code tags
695 # do not escape pre/code tags
702 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
696 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
703 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
697 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
704 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
698 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
705 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
699 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
706 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
700 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
707 # remove attributes except class
701 # remove attributes except class
708 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
702 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
709 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
703 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
710 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
704 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
711 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
705 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
712 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
706 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
713 # xss
707 # xss
714 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
708 '<pre><code class=""onmouseover="alert(1)">text</code></pre>' => '<pre><code>text</code></pre>',
715 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
709 '<pre class=""onmouseover="alert(1)">text</pre>' => '<pre>text</pre>',
716 }
710 }
717 to_test.each { |text, result| assert_equal result, textilizable(text) }
711 to_test.each { |text, result| assert_equal result, textilizable(text) }
718 end
712 end
719
713
720 def test_allowed_html_tags
714 def test_allowed_html_tags
721 to_test = {
715 to_test = {
722 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
716 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
723 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
717 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
724 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
718 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
725 }
719 }
726 to_test.each { |text, result| assert_equal result, textilizable(text) }
720 to_test.each { |text, result| assert_equal result, textilizable(text) }
727 end
721 end
728
722
729 def test_pre_tags
723 def test_pre_tags
730 raw = <<-RAW
724 raw = <<-RAW
731 Before
725 Before
732
726
733 <pre>
727 <pre>
734 <prepared-statement-cache-size>32</prepared-statement-cache-size>
728 <prepared-statement-cache-size>32</prepared-statement-cache-size>
735 </pre>
729 </pre>
736
730
737 After
731 After
738 RAW
732 RAW
739
733
740 expected = <<-EXPECTED
734 expected = <<-EXPECTED
741 <p>Before</p>
735 <p>Before</p>
742 <pre>
736 <pre>
743 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
737 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
744 </pre>
738 </pre>
745 <p>After</p>
739 <p>After</p>
746 EXPECTED
740 EXPECTED
747
741
748 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
742 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
749 end
743 end
750
744
751 def test_pre_content_should_not_parse_wiki_and_redmine_links
745 def test_pre_content_should_not_parse_wiki_and_redmine_links
752 raw = <<-RAW
746 raw = <<-RAW
753 [[CookBook documentation]]
747 [[CookBook documentation]]
754
748
755 #1
749 #1
756
750
757 <pre>
751 <pre>
758 [[CookBook documentation]]
752 [[CookBook documentation]]
759
753
760 #1
754 #1
761 </pre>
755 </pre>
762 RAW
756 RAW
763
757
764 expected = <<-EXPECTED
758 expected = <<-EXPECTED
765 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
759 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
766 <p><a href="/issues/1" class="#{Issue.find(1).css_classes}" title="Can&#x27;t print recipes (New)">#1</a></p>
760 <p><a href="/issues/1" class="#{Issue.find(1).css_classes}" title="Can&#x27;t print recipes (New)">#1</a></p>
767 <pre>
761 <pre>
768 [[CookBook documentation]]
762 [[CookBook documentation]]
769
763
770 #1
764 #1
771 </pre>
765 </pre>
772 EXPECTED
766 EXPECTED
773
767
774 @project = Project.find(1)
768 @project = Project.find(1)
775 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
769 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
776 end
770 end
777
771
778 def test_non_closing_pre_blocks_should_be_closed
772 def test_non_closing_pre_blocks_should_be_closed
779 raw = <<-RAW
773 raw = <<-RAW
780 <pre><code>
774 <pre><code>
781 RAW
775 RAW
782
776
783 expected = <<-EXPECTED
777 expected = <<-EXPECTED
784 <pre><code>
778 <pre><code>
785 </code></pre>
779 </code></pre>
786 EXPECTED
780 EXPECTED
787
781
788 @project = Project.find(1)
782 @project = Project.find(1)
789 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
783 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
790 end
784 end
791
785
792 def test_syntax_highlight
786 def test_syntax_highlight
793 raw = <<-RAW
787 raw = <<-RAW
794 <pre><code class="ruby">
788 <pre><code class="ruby">
795 # Some ruby code here
789 # Some ruby code here
796 </code></pre>
790 </code></pre>
797 RAW
791 RAW
798
792
799 expected = <<-EXPECTED
793 expected = <<-EXPECTED
800 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="comment"># Some ruby code here</span></span>
794 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="comment"># Some ruby code here</span></span>
801 </code></pre>
795 </code></pre>
802 EXPECTED
796 EXPECTED
803
797
804 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
798 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
805 end
799 end
806
800
807 def test_to_path_param
801 def test_to_path_param
808 assert_equal 'test1/test2', to_path_param('test1/test2')
802 assert_equal 'test1/test2', to_path_param('test1/test2')
809 assert_equal 'test1/test2', to_path_param('/test1/test2/')
803 assert_equal 'test1/test2', to_path_param('/test1/test2/')
810 assert_equal 'test1/test2', to_path_param('//test1/test2/')
804 assert_equal 'test1/test2', to_path_param('//test1/test2/')
811 assert_equal nil, to_path_param('/')
805 assert_equal nil, to_path_param('/')
812 end
806 end
813
807
814 def test_wiki_links_in_tables
808 def test_wiki_links_in_tables
815 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
809 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
816 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
810 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
817 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
811 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
818 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
812 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
819 }
813 }
820 @project = Project.find(1)
814 @project = Project.find(1)
821 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
815 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
822 end
816 end
823
817
824 def test_text_formatting
818 def test_text_formatting
825 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
819 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
826 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
820 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
827 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
821 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
828 'a H *umane* W *eb* T *ext* G *enerator*' => 'a H <strong>umane</strong> W <strong>eb</strong> T <strong>ext</strong> G <strong>enerator</strong>',
822 'a H *umane* W *eb* T *ext* G *enerator*' => 'a H <strong>umane</strong> W <strong>eb</strong> T <strong>ext</strong> G <strong>enerator</strong>',
829 'a *H* umane *W* eb *T* ext *G* enerator' => 'a <strong>H</strong> umane <strong>W</strong> eb <strong>T</strong> ext <strong>G</strong> enerator',
823 'a *H* umane *W* eb *T* ext *G* enerator' => 'a <strong>H</strong> umane <strong>W</strong> eb <strong>T</strong> ext <strong>G</strong> enerator',
830 }
824 }
831 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
825 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
832 end
826 end
833
827
834 def test_wiki_horizontal_rule
828 def test_wiki_horizontal_rule
835 assert_equal '<hr />', textilizable('---')
829 assert_equal '<hr />', textilizable('---')
836 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
830 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
837 end
831 end
838
832
839 def test_footnotes
833 def test_footnotes
840 raw = <<-RAW
834 raw = <<-RAW
841 This is some text[1].
835 This is some text[1].
842
836
843 fn1. This is the foot note
837 fn1. This is the foot note
844 RAW
838 RAW
845
839
846 expected = <<-EXPECTED
840 expected = <<-EXPECTED
847 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
841 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
848 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
842 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
849 EXPECTED
843 EXPECTED
850
844
851 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
845 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
852 end
846 end
853
847
854 def test_headings
848 def test_headings
855 raw = 'h1. Some heading'
849 raw = 'h1. Some heading'
856 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
850 expected = %|<a name="Some-heading"></a>\n<h1 >Some heading<a href="#Some-heading" class="wiki-anchor">&para;</a></h1>|
857
851
858 assert_equal expected, textilizable(raw)
852 assert_equal expected, textilizable(raw)
859 end
853 end
860
854
861 def test_headings_with_special_chars
855 def test_headings_with_special_chars
862 # This test makes sure that the generated anchor names match the expected
856 # This test makes sure that the generated anchor names match the expected
863 # ones even if the heading text contains unconventional characters
857 # ones even if the heading text contains unconventional characters
864 raw = 'h1. Some heading related to version 0.5'
858 raw = 'h1. Some heading related to version 0.5'
865 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
859 anchor = sanitize_anchor_name("Some-heading-related-to-version-0.5")
866 expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
860 expected = %|<a name="#{anchor}"></a>\n<h1 >Some heading related to version 0.5<a href="##{anchor}" class="wiki-anchor">&para;</a></h1>|
867
861
868 assert_equal expected, textilizable(raw)
862 assert_equal expected, textilizable(raw)
869 end
863 end
870
864
871 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
865 def test_headings_in_wiki_single_page_export_should_be_prepended_with_page_title
872 page = WikiPage.new( :title => 'Page Title', :wiki_id => 1 )
866 page = WikiPage.new( :title => 'Page Title', :wiki_id => 1 )
873 content = WikiContent.new( :text => 'h1. Some heading', :page => page )
867 content = WikiContent.new( :text => 'h1. Some heading', :page => page )
874
868
875 expected = %|<a name="Page_Title_Some-heading"></a>\n<h1 >Some heading<a href="#Page_Title_Some-heading" class="wiki-anchor">&para;</a></h1>|
869 expected = %|<a name="Page_Title_Some-heading"></a>\n<h1 >Some heading<a href="#Page_Title_Some-heading" class="wiki-anchor">&para;</a></h1>|
876
870
877 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
871 assert_equal expected, textilizable(content, :text, :wiki_links => :anchor )
878 end
872 end
879
873
880 def test_table_of_content
874 def test_table_of_content
881 raw = <<-RAW
875 raw = <<-RAW
882 {{toc}}
876 {{toc}}
883
877
884 h1. Title
878 h1. Title
885
879
886 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
880 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
887
881
888 h2. Subtitle with a [[Wiki]] link
882 h2. Subtitle with a [[Wiki]] link
889
883
890 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
884 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
891
885
892 h2. Subtitle with [[Wiki|another Wiki]] link
886 h2. Subtitle with [[Wiki|another Wiki]] link
893
887
894 h2. Subtitle with %{color:red}red text%
888 h2. Subtitle with %{color:red}red text%
895
889
896 <pre>
890 <pre>
897 some code
891 some code
898 </pre>
892 </pre>
899
893
900 h3. Subtitle with *some* _modifiers_
894 h3. Subtitle with *some* _modifiers_
901
895
902 h3. Subtitle with @inline code@
896 h3. Subtitle with @inline code@
903
897
904 h1. Another title
898 h1. Another title
905
899
906 h3. An "Internet link":http://www.redmine.org/ inside subtitle
900 h3. An "Internet link":http://www.redmine.org/ inside subtitle
907
901
908 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
902 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
909
903
910 RAW
904 RAW
911
905
912 expected = '<ul class="toc">' +
906 expected = '<ul class="toc">' +
913 '<li><a href="#Title">Title</a>' +
907 '<li><a href="#Title">Title</a>' +
914 '<ul>' +
908 '<ul>' +
915 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
909 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
916 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
910 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
917 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
911 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
918 '<ul>' +
912 '<ul>' +
919 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
913 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
920 '<li><a href="#Subtitle-with-inline-code">Subtitle with inline code</a></li>' +
914 '<li><a href="#Subtitle-with-inline-code">Subtitle with inline code</a></li>' +
921 '</ul>' +
915 '</ul>' +
922 '</li>' +
916 '</li>' +
923 '</ul>' +
917 '</ul>' +
924 '</li>' +
918 '</li>' +
925 '<li><a href="#Another-title">Another title</a>' +
919 '<li><a href="#Another-title">Another title</a>' +
926 '<ul>' +
920 '<ul>' +
927 '<li>' +
921 '<li>' +
928 '<ul>' +
922 '<ul>' +
929 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
923 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
930 '</ul>' +
924 '</ul>' +
931 '</li>' +
925 '</li>' +
932 '<li><a href="#Project-Name">Project Name</a></li>' +
926 '<li><a href="#Project-Name">Project Name</a></li>' +
933 '</ul>' +
927 '</ul>' +
934 '</li>' +
928 '</li>' +
935 '</ul>'
929 '</ul>'
936
930
937 @project = Project.find(1)
931 @project = Project.find(1)
938 assert textilizable(raw).gsub("\n", "").include?(expected)
932 assert textilizable(raw).gsub("\n", "").include?(expected)
939 end
933 end
940
934
941 def test_table_of_content_should_generate_unique_anchors
935 def test_table_of_content_should_generate_unique_anchors
942 raw = <<-RAW
936 raw = <<-RAW
943 {{toc}}
937 {{toc}}
944
938
945 h1. Title
939 h1. Title
946
940
947 h2. Subtitle
941 h2. Subtitle
948
942
949 h2. Subtitle
943 h2. Subtitle
950 RAW
944 RAW
951
945
952 expected = '<ul class="toc">' +
946 expected = '<ul class="toc">' +
953 '<li><a href="#Title">Title</a>' +
947 '<li><a href="#Title">Title</a>' +
954 '<ul>' +
948 '<ul>' +
955 '<li><a href="#Subtitle">Subtitle</a></li>' +
949 '<li><a href="#Subtitle">Subtitle</a></li>' +
956 '<li><a href="#Subtitle-2">Subtitle</a></li>'
950 '<li><a href="#Subtitle-2">Subtitle</a></li>'
957 '</ul>'
951 '</ul>'
958 '</li>' +
952 '</li>' +
959 '</ul>'
953 '</ul>'
960
954
961 @project = Project.find(1)
955 @project = Project.find(1)
962 result = textilizable(raw).gsub("\n", "")
956 result = textilizable(raw).gsub("\n", "")
963 assert_include expected, result
957 assert_include expected, result
964 assert_include '<a name="Subtitle">', result
958 assert_include '<a name="Subtitle">', result
965 assert_include '<a name="Subtitle-2">', result
959 assert_include '<a name="Subtitle-2">', result
966 end
960 end
967
961
968 def test_table_of_content_should_contain_included_page_headings
962 def test_table_of_content_should_contain_included_page_headings
969 raw = <<-RAW
963 raw = <<-RAW
970 {{toc}}
964 {{toc}}
971
965
972 h1. Included
966 h1. Included
973
967
974 {{include(Child_1)}}
968 {{include(Child_1)}}
975 RAW
969 RAW
976
970
977 expected = '<ul class="toc">' +
971 expected = '<ul class="toc">' +
978 '<li><a href="#Included">Included</a></li>' +
972 '<li><a href="#Included">Included</a></li>' +
979 '<li><a href="#Child-page-1">Child page 1</a></li>' +
973 '<li><a href="#Child-page-1">Child page 1</a></li>' +
980 '</ul>'
974 '</ul>'
981
975
982 @project = Project.find(1)
976 @project = Project.find(1)
983 assert textilizable(raw).gsub("\n", "").include?(expected)
977 assert textilizable(raw).gsub("\n", "").include?(expected)
984 end
978 end
985
979
986 def test_section_edit_links
980 def test_section_edit_links
987 raw = <<-RAW
981 raw = <<-RAW
988 h1. Title
982 h1. Title
989
983
990 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
984 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
991
985
992 h2. Subtitle with a [[Wiki]] link
986 h2. Subtitle with a [[Wiki]] link
993
987
994 h2. Subtitle with *some* _modifiers_
988 h2. Subtitle with *some* _modifiers_
995
989
996 h2. Subtitle with @inline code@
990 h2. Subtitle with @inline code@
997
991
998 <pre>
992 <pre>
999 some code
993 some code
1000
994
1001 h2. heading inside pre
995 h2. heading inside pre
1002
996
1003 <h2>html heading inside pre</h2>
997 <h2>html heading inside pre</h2>
1004 </pre>
998 </pre>
1005
999
1006 h2. Subtitle after pre tag
1000 h2. Subtitle after pre tag
1007 RAW
1001 RAW
1008
1002
1009 @project = Project.find(1)
1003 @project = Project.find(1)
1010 set_language_if_valid 'en'
1004 set_language_if_valid 'en'
1011 result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
1005 result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
1012
1006
1013 # heading that contains inline code
1007 # heading that contains inline code
1014 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1008 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1015 '<a href="/projects/1/wiki/Test/edit\?section=4"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1009 '<a href="/projects/1/wiki/Test/edit\?section=4"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1016 '<a name="Subtitle-with-inline-code"></a>' +
1010 '<a name="Subtitle-with-inline-code"></a>' +
1017 '<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">&para;</a></h2>'),
1011 '<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">&para;</a></h2>'),
1018 result
1012 result
1019
1013
1020 # last heading
1014 # last heading
1021 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1015 assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
1022 '<a href="/projects/1/wiki/Test/edit\?section=5"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1016 '<a href="/projects/1/wiki/Test/edit\?section=5"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
1023 '<a name="Subtitle-after-pre-tag"></a>' +
1017 '<a name="Subtitle-after-pre-tag"></a>' +
1024 '<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">&para;</a></h2>'),
1018 '<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">&para;</a></h2>'),
1025 result
1019 result
1026 end
1020 end
1027
1021
1028 def test_default_formatter
1022 def test_default_formatter
1029 with_settings :text_formatting => 'unknown' do
1023 with_settings :text_formatting => 'unknown' do
1030 text = 'a *link*: http://www.example.net/'
1024 text = 'a *link*: http://www.example.net/'
1031 assert_equal '<p>a *link*: <a class="external" href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
1025 assert_equal '<p>a *link*: <a class="external" href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
1032 end
1026 end
1033 end
1027 end
1034
1028
1035 def test_due_date_distance_in_words
1029 def test_due_date_distance_in_words
1036 to_test = { Date.today => 'Due in 0 days',
1030 to_test = { Date.today => 'Due in 0 days',
1037 Date.today + 1 => 'Due in 1 day',
1031 Date.today + 1 => 'Due in 1 day',
1038 Date.today + 100 => 'Due in about 3 months',
1032 Date.today + 100 => 'Due in about 3 months',
1039 Date.today + 20000 => 'Due in over 54 years',
1033 Date.today + 20000 => 'Due in over 54 years',
1040 Date.today - 1 => '1 day late',
1034 Date.today - 1 => '1 day late',
1041 Date.today - 100 => 'about 3 months late',
1035 Date.today - 100 => 'about 3 months late',
1042 Date.today - 20000 => 'over 54 years late',
1036 Date.today - 20000 => 'over 54 years late',
1043 }
1037 }
1044 ::I18n.locale = :en
1038 ::I18n.locale = :en
1045 to_test.each do |date, expected|
1039 to_test.each do |date, expected|
1046 assert_equal expected, due_date_distance_in_words(date)
1040 assert_equal expected, due_date_distance_in_words(date)
1047 end
1041 end
1048 end
1042 end
1049
1043
1050 def test_avatar_enabled
1044 def test_avatar_enabled
1051 with_settings :gravatar_enabled => '1' do
1045 with_settings :gravatar_enabled => '1' do
1052 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1046 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1053 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1047 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
1054 # Default size is 50
1048 # Default size is 50
1055 assert avatar('jsmith <jsmith@somenet.foo>').include?('size=50')
1049 assert avatar('jsmith <jsmith@somenet.foo>').include?('size=50')
1056 assert avatar('jsmith <jsmith@somenet.foo>', :size => 24).include?('size=24')
1050 assert avatar('jsmith <jsmith@somenet.foo>', :size => 24).include?('size=24')
1057 # Non-avatar options should be considered html options
1051 # Non-avatar options should be considered html options
1058 assert avatar('jsmith <jsmith@somenet.foo>', :title => 'John Smith').include?('title="John Smith"')
1052 assert avatar('jsmith <jsmith@somenet.foo>', :title => 'John Smith').include?('title="John Smith"')
1059 # The default class of the img tag should be gravatar
1053 # The default class of the img tag should be gravatar
1060 assert avatar('jsmith <jsmith@somenet.foo>').include?('class="gravatar"')
1054 assert avatar('jsmith <jsmith@somenet.foo>').include?('class="gravatar"')
1061 assert !avatar('jsmith <jsmith@somenet.foo>', :class => 'picture').include?('class="gravatar"')
1055 assert !avatar('jsmith <jsmith@somenet.foo>', :class => 'picture').include?('class="gravatar"')
1062 assert_nil avatar('jsmith')
1056 assert_nil avatar('jsmith')
1063 assert_nil avatar(nil)
1057 assert_nil avatar(nil)
1064 end
1058 end
1065 end
1059 end
1066
1060
1067 def test_avatar_disabled
1061 def test_avatar_disabled
1068 with_settings :gravatar_enabled => '0' do
1062 with_settings :gravatar_enabled => '0' do
1069 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
1063 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
1070 end
1064 end
1071 end
1065 end
1072
1066
1073 def test_link_to_user
1067 def test_link_to_user
1074 user = User.find(2)
1068 user = User.find(2)
1075 assert_equal '<a href="/users/2" class="user active">John Smith</a>', link_to_user(user)
1069 assert_equal '<a href="/users/2" class="user active">John Smith</a>', link_to_user(user)
1076 end
1070 end
1077
1071
1078 def test_link_to_user_should_not_link_to_locked_user
1072 def test_link_to_user_should_not_link_to_locked_user
1079 with_current_user nil do
1073 with_current_user nil do
1080 user = User.find(5)
1074 user = User.find(5)
1081 assert user.locked?
1075 assert user.locked?
1082 assert_equal 'Dave2 Lopper2', link_to_user(user)
1076 assert_equal 'Dave2 Lopper2', link_to_user(user)
1083 end
1077 end
1084 end
1078 end
1085
1079
1086 def test_link_to_user_should_link_to_locked_user_if_current_user_is_admin
1080 def test_link_to_user_should_link_to_locked_user_if_current_user_is_admin
1087 with_current_user User.find(1) do
1081 with_current_user User.find(1) do
1088 user = User.find(5)
1082 user = User.find(5)
1089 assert user.locked?
1083 assert user.locked?
1090 assert_equal '<a href="/users/5" class="user locked">Dave2 Lopper2</a>', link_to_user(user)
1084 assert_equal '<a href="/users/5" class="user locked">Dave2 Lopper2</a>', link_to_user(user)
1091 end
1085 end
1092 end
1086 end
1093
1087
1094 def test_link_to_user_should_not_link_to_anonymous
1088 def test_link_to_user_should_not_link_to_anonymous
1095 user = User.anonymous
1089 user = User.anonymous
1096 assert user.anonymous?
1090 assert user.anonymous?
1097 t = link_to_user(user)
1091 t = link_to_user(user)
1098 assert_equal ::I18n.t(:label_user_anonymous), t
1092 assert_equal ::I18n.t(:label_user_anonymous), t
1099 end
1093 end
1100
1094
1101 def test_link_to_attachment
1095 def test_link_to_attachment
1102 a = Attachment.find(3)
1096 a = Attachment.find(3)
1103 assert_equal '<a href="/attachments/3/logo.gif">logo.gif</a>',
1097 assert_equal '<a href="/attachments/3/logo.gif">logo.gif</a>',
1104 link_to_attachment(a)
1098 link_to_attachment(a)
1105 assert_equal '<a href="/attachments/3/logo.gif">Text</a>',
1099 assert_equal '<a href="/attachments/3/logo.gif">Text</a>',
1106 link_to_attachment(a, :text => 'Text')
1100 link_to_attachment(a, :text => 'Text')
1107 assert_equal '<a href="/attachments/3/logo.gif" class="foo">logo.gif</a>',
1101 assert_equal '<a href="/attachments/3/logo.gif" class="foo">logo.gif</a>',
1108 link_to_attachment(a, :class => 'foo')
1102 link_to_attachment(a, :class => 'foo')
1109 assert_equal '<a href="/attachments/download/3/logo.gif">logo.gif</a>',
1103 assert_equal '<a href="/attachments/download/3/logo.gif">logo.gif</a>',
1110 link_to_attachment(a, :download => true)
1104 link_to_attachment(a, :download => true)
1111 assert_equal '<a href="http://test.host/attachments/3/logo.gif">logo.gif</a>',
1105 assert_equal '<a href="http://test.host/attachments/3/logo.gif">logo.gif</a>',
1112 link_to_attachment(a, :only_path => false)
1106 link_to_attachment(a, :only_path => false)
1113 end
1107 end
1114
1108
1115 def test_thumbnail_tag
1109 def test_thumbnail_tag
1116 a = Attachment.find(3)
1110 a = Attachment.find(3)
1117 assert_equal '<a href="/attachments/3/logo.gif" title="logo.gif"><img alt="3" src="/attachments/thumbnail/3" /></a>',
1111 assert_equal '<a href="/attachments/3/logo.gif" title="logo.gif"><img alt="3" src="/attachments/thumbnail/3" /></a>',
1118 thumbnail_tag(a)
1112 thumbnail_tag(a)
1119 end
1113 end
1120
1114
1121 def test_link_to_project
1115 def test_link_to_project
1122 project = Project.find(1)
1116 project = Project.find(1)
1123 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
1117 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
1124 link_to_project(project)
1118 link_to_project(project)
1125 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
1119 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
1126 link_to_project(project, :action => 'settings')
1120 link_to_project(project, :action => 'settings')
1127 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
1121 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
1128 link_to_project(project, {:only_path => false, :jump => 'blah'})
1122 link_to_project(project, {:only_path => false, :jump => 'blah'})
1129 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
1123 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
1130 link_to_project(project, {:action => 'settings'}, :class => "project")
1124 link_to_project(project, {:action => 'settings'}, :class => "project")
1131 end
1125 end
1132
1126
1133 def test_link_to_project_settings
1127 def test_link_to_project_settings
1134 project = Project.find(1)
1128 project = Project.find(1)
1135 assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project)
1129 assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project)
1136
1130
1137 project.status = Project::STATUS_CLOSED
1131 project.status = Project::STATUS_CLOSED
1138 assert_equal '<a href="/projects/ecookbook">eCookbook</a>', link_to_project_settings(project)
1132 assert_equal '<a href="/projects/ecookbook">eCookbook</a>', link_to_project_settings(project)
1139
1133
1140 project.status = Project::STATUS_ARCHIVED
1134 project.status = Project::STATUS_ARCHIVED
1141 assert_equal 'eCookbook', link_to_project_settings(project)
1135 assert_equal 'eCookbook', link_to_project_settings(project)
1142 end
1136 end
1143
1137
1144 def test_link_to_legacy_project_with_numerical_identifier_should_use_id
1138 def test_link_to_legacy_project_with_numerical_identifier_should_use_id
1145 # numeric identifier are no longer allowed
1139 # numeric identifier are no longer allowed
1146 Project.update_all "identifier=25", "id=1"
1140 Project.update_all "identifier=25", "id=1"
1147
1141
1148 assert_equal '<a href="/projects/1">eCookbook</a>',
1142 assert_equal '<a href="/projects/1">eCookbook</a>',
1149 link_to_project(Project.find(1))
1143 link_to_project(Project.find(1))
1150 end
1144 end
1151
1145
1152 def test_principals_options_for_select_with_users
1146 def test_principals_options_for_select_with_users
1153 User.current = nil
1147 User.current = nil
1154 users = [User.find(2), User.find(4)]
1148 users = [User.find(2), User.find(4)]
1155 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
1149 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
1156 principals_options_for_select(users)
1150 principals_options_for_select(users)
1157 end
1151 end
1158
1152
1159 def test_principals_options_for_select_with_selected
1153 def test_principals_options_for_select_with_selected
1160 User.current = nil
1154 User.current = nil
1161 users = [User.find(2), User.find(4)]
1155 users = [User.find(2), User.find(4)]
1162 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
1156 assert_equal %(<option value="2">John Smith</option><option value="4" selected="selected">Robert Hill</option>),
1163 principals_options_for_select(users, User.find(4))
1157 principals_options_for_select(users, User.find(4))
1164 end
1158 end
1165
1159
1166 def test_principals_options_for_select_with_users_and_groups
1160 def test_principals_options_for_select_with_users_and_groups
1167 User.current = nil
1161 User.current = nil
1168 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
1162 users = [User.find(2), Group.find(11), User.find(4), Group.find(10)]
1169 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
1163 assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>) +
1170 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
1164 %(<optgroup label="Groups"><option value="10">A Team</option><option value="11">B Team</option></optgroup>),
1171 principals_options_for_select(users)
1165 principals_options_for_select(users)
1172 end
1166 end
1173
1167
1174 def test_principals_options_for_select_with_empty_collection
1168 def test_principals_options_for_select_with_empty_collection
1175 assert_equal '', principals_options_for_select([])
1169 assert_equal '', principals_options_for_select([])
1176 end
1170 end
1177
1171
1178 def test_principals_options_for_select_should_include_me_option_when_current_user_is_in_collection
1172 def test_principals_options_for_select_should_include_me_option_when_current_user_is_in_collection
1179 users = [User.find(2), User.find(4)]
1173 users = [User.find(2), User.find(4)]
1180 User.current = User.find(4)
1174 User.current = User.find(4)
1181 assert_include '<option value="4">&lt;&lt; me &gt;&gt;</option>', principals_options_for_select(users)
1175 assert_include '<option value="4">&lt;&lt; me &gt;&gt;</option>', principals_options_for_select(users)
1182 end
1176 end
1183
1177
1184 def test_stylesheet_link_tag_should_pick_the_default_stylesheet
1178 def test_stylesheet_link_tag_should_pick_the_default_stylesheet
1185 assert_match 'href="/stylesheets/styles.css"', stylesheet_link_tag("styles")
1179 assert_match 'href="/stylesheets/styles.css"', stylesheet_link_tag("styles")
1186 end
1180 end
1187
1181
1188 def test_stylesheet_link_tag_for_plugin_should_pick_the_plugin_stylesheet
1182 def test_stylesheet_link_tag_for_plugin_should_pick_the_plugin_stylesheet
1189 assert_match 'href="/plugin_assets/foo/stylesheets/styles.css"', stylesheet_link_tag("styles", :plugin => :foo)
1183 assert_match 'href="/plugin_assets/foo/stylesheets/styles.css"', stylesheet_link_tag("styles", :plugin => :foo)
1190 end
1184 end
1191
1185
1192 def test_image_tag_should_pick_the_default_image
1186 def test_image_tag_should_pick_the_default_image
1193 assert_match 'src="/images/image.png"', image_tag("image.png")
1187 assert_match 'src="/images/image.png"', image_tag("image.png")
1194 end
1188 end
1195
1189
1196 def test_image_tag_should_pick_the_theme_image_if_it_exists
1190 def test_image_tag_should_pick_the_theme_image_if_it_exists
1197 theme = Redmine::Themes.themes.last
1191 theme = Redmine::Themes.themes.last
1198 theme.images << 'image.png'
1192 theme.images << 'image.png'
1199
1193
1200 with_settings :ui_theme => theme.id do
1194 with_settings :ui_theme => theme.id do
1201 assert_match %|src="/themes/#{theme.dir}/images/image.png"|, image_tag("image.png")
1195 assert_match %|src="/themes/#{theme.dir}/images/image.png"|, image_tag("image.png")
1202 assert_match %|src="/images/other.png"|, image_tag("other.png")
1196 assert_match %|src="/images/other.png"|, image_tag("other.png")
1203 end
1197 end
1204 ensure
1198 ensure
1205 theme.images.delete 'image.png'
1199 theme.images.delete 'image.png'
1206 end
1200 end
1207
1201
1208 def test_image_tag_sfor_plugin_should_pick_the_plugin_image
1202 def test_image_tag_sfor_plugin_should_pick_the_plugin_image
1209 assert_match 'src="/plugin_assets/foo/images/image.png"', image_tag("image.png", :plugin => :foo)
1203 assert_match 'src="/plugin_assets/foo/images/image.png"', image_tag("image.png", :plugin => :foo)
1210 end
1204 end
1211
1205
1212 def test_javascript_include_tag_should_pick_the_default_javascript
1206 def test_javascript_include_tag_should_pick_the_default_javascript
1213 assert_match 'src="/javascripts/scripts.js"', javascript_include_tag("scripts")
1207 assert_match 'src="/javascripts/scripts.js"', javascript_include_tag("scripts")
1214 end
1208 end
1215
1209
1216 def test_javascript_include_tag_for_plugin_should_pick_the_plugin_javascript
1210 def test_javascript_include_tag_for_plugin_should_pick_the_plugin_javascript
1217 assert_match 'src="/plugin_assets/foo/javascripts/scripts.js"', javascript_include_tag("scripts", :plugin => :foo)
1211 assert_match 'src="/plugin_assets/foo/javascripts/scripts.js"', javascript_include_tag("scripts", :plugin => :foo)
1218 end
1212 end
1219 end
1213 end
@@ -1,145 +1,129
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2013 Jean-Philippe Lang
2 # Copyright (C) 2006-2013 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 RoleTest < ActiveSupport::TestCase
20 class RoleTest < ActiveSupport::TestCase
21 fixtures :roles, :workflows, :trackers
21 fixtures :roles, :workflows, :trackers
22
22
23 def test_sorted_scope
23 def test_sorted_scope
24 assert_equal Role.all.sort, Role.sorted.all
24 assert_equal Role.all.sort, Role.sorted.all
25 end
25 end
26
26
27 def test_givable_scope
27 def test_givable_scope
28 assert_equal Role.all.reject(&:builtin?).sort, Role.givable.all
28 assert_equal Role.all.reject(&:builtin?).sort, Role.givable.all
29 end
29 end
30
30
31 def test_builtin_scope
31 def test_builtin_scope
32 assert_equal Role.all.select(&:builtin?).sort, Role.builtin(true).all.sort
32 assert_equal Role.all.select(&:builtin?).sort, Role.builtin(true).all.sort
33 assert_equal Role.all.reject(&:builtin?).sort, Role.builtin(false).all.sort
33 assert_equal Role.all.reject(&:builtin?).sort, Role.builtin(false).all.sort
34 end
34 end
35
35
36 def test_copy_from
36 def test_copy_from
37 role = Role.find(1)
37 role = Role.find(1)
38 copy = Role.new.copy_from(role)
38 copy = Role.new.copy_from(role)
39
39
40 assert_nil copy.id
40 assert_nil copy.id
41 assert_equal '', copy.name
41 assert_equal '', copy.name
42 assert_equal role.permissions, copy.permissions
42 assert_equal role.permissions, copy.permissions
43
43
44 copy.name = 'Copy'
44 copy.name = 'Copy'
45 assert copy.save
45 assert copy.save
46 end
46 end
47
47
48 def test_copy_workflows
48 def test_copy_workflows
49 source = Role.find(1)
49 source = Role.find(1)
50 assert_equal 90, source.workflow_rules.size
50 assert_equal 90, source.workflow_rules.size
51
51
52 target = Role.new(:name => 'Target')
52 target = Role.new(:name => 'Target')
53 assert target.save
53 assert target.save
54 target.workflow_rules.copy(source)
54 target.workflow_rules.copy(source)
55 target.reload
55 target.reload
56 assert_equal 90, target.workflow_rules.size
56 assert_equal 90, target.workflow_rules.size
57 end
57 end
58
58
59 def test_permissions_should_be_unserialized_with_its_coder
59 def test_permissions_should_be_unserialized_with_its_coder
60 Role::PermissionsAttributeCoder.expects(:load).once
60 Role::PermissionsAttributeCoder.expects(:load).once
61 Role.find(1).permissions
61 Role.find(1).permissions
62 end
62 end
63
63
64 def test_add_permission
64 def test_add_permission
65 role = Role.find(1)
65 role = Role.find(1)
66 size = role.permissions.size
66 size = role.permissions.size
67 role.add_permission!("apermission", "anotherpermission")
67 role.add_permission!("apermission", "anotherpermission")
68 role.reload
68 role.reload
69 assert role.permissions.include?(:anotherpermission)
69 assert role.permissions.include?(:anotherpermission)
70 assert_equal size + 2, role.permissions.size
70 assert_equal size + 2, role.permissions.size
71 end
71 end
72
72
73 def test_remove_permission
73 def test_remove_permission
74 role = Role.find(1)
74 role = Role.find(1)
75 size = role.permissions.size
75 size = role.permissions.size
76 perm = role.permissions[0..1]
76 perm = role.permissions[0..1]
77 role.remove_permission!(*perm)
77 role.remove_permission!(*perm)
78 role.reload
78 role.reload
79 assert ! role.permissions.include?(perm[0])
79 assert ! role.permissions.include?(perm[0])
80 assert_equal size - 2, role.permissions.size
80 assert_equal size - 2, role.permissions.size
81 end
81 end
82
82
83 def test_name
83 def test_name
84 I18n.locale = 'fr'
84 I18n.locale = 'fr'
85 assert_equal 'Manager', Role.find(1).name
85 assert_equal 'Manager', Role.find(1).name
86 assert_equal 'Anonyme', Role.anonymous.name
86 assert_equal 'Anonyme', Role.anonymous.name
87 assert_equal 'Non membre', Role.non_member.name
87 assert_equal 'Non membre', Role.non_member.name
88 end
88 end
89
89
90 def test_find_all_givable
90 def test_find_all_givable
91 assert_equal Role.all.reject(&:builtin?).sort, Role.find_all_givable
91 assert_equal Role.all.reject(&:builtin?).sort, Role.find_all_givable
92 end
92 end
93
93
94 context "#anonymous" do
94 def test_anonymous_should_return_the_anonymous_role
95 should "return the anonymous role" do
95 assert_no_difference('Role.count') do
96 role = Role.anonymous
96 role = Role.anonymous
97 assert role.builtin?
97 assert role.builtin?
98 assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
98 assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
99 end
99 end
100 end
101
102 def test_anonymous_with_a_missing_anonymous_role_should_return_the_anonymous_role
103 Role.where(:builtin => Role::BUILTIN_ANONYMOUS).delete_all
100
104
101 context "with a missing anonymous role" do
105 assert_difference('Role.count') do
102 setup do
106 role = Role.anonymous
103 Role.delete_all("builtin = #{Role::BUILTIN_ANONYMOUS}")
107 assert role.builtin?
104 end
108 assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
105
106 should "create a new anonymous role" do
107 assert_difference('Role.count') do
108 Role.anonymous
109 end
110 end
111
112 should "return the anonymous role" do
113 role = Role.anonymous
114 assert role.builtin?
115 assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
116 end
117 end
109 end
118 end
110 end
119
111
120 context "#non_member" do
112 def test_non_member_should_return_the_non_member_role
121 should "return the non-member role" do
113 assert_no_difference('Role.count') do
122 role = Role.non_member
114 role = Role.non_member
123 assert role.builtin?
115 assert role.builtin?
124 assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
116 assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
125 end
117 end
118 end
119
120 def test_non_member_with_a_missing_non_member_role_should_return_the_non_member_role
121 Role.where(:builtin => Role::BUILTIN_NON_MEMBER).delete_all
126
122
127 context "with a missing non-member role" do
123 assert_difference('Role.count') do
128 setup do
124 role = Role.non_member
129 Role.delete_all("builtin = #{Role::BUILTIN_NON_MEMBER}")
125 assert role.builtin?
130 end
126 assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
131
132 should "create a new non-member role" do
133 assert_difference('Role.count') do
134 Role.non_member
135 end
136 end
137
138 should "return the non-member role" do
139 role = Role.non_member
140 assert role.builtin?
141 assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
142 end
143 end
127 end
144 end
128 end
145 end
129 end
@@ -1,105 +1,101
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2013 Jean-Philippe Lang
4 # Copyright (C) 2006-2013 Jean-Philippe Lang
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
9 # of the License, or (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
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
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.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 require File.expand_path('../../test_helper', __FILE__)
20 require File.expand_path('../../test_helper', __FILE__)
21
21
22 class WikiTest < ActiveSupport::TestCase
22 class WikiTest < ActiveSupport::TestCase
23 fixtures :projects, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
23 fixtures :projects, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions
24
24
25 def test_create
25 def test_create
26 wiki = Wiki.new(:project => Project.find(2))
26 wiki = Wiki.new(:project => Project.find(2))
27 assert !wiki.save
27 assert !wiki.save
28 assert_equal 1, wiki.errors.count
28 assert_equal 1, wiki.errors.count
29
29
30 wiki.start_page = "Start page"
30 wiki.start_page = "Start page"
31 assert wiki.save
31 assert wiki.save
32 end
32 end
33
33
34 def test_update
34 def test_update
35 @wiki = Wiki.find(1)
35 @wiki = Wiki.find(1)
36 @wiki.start_page = "Another start page"
36 @wiki.start_page = "Another start page"
37 assert @wiki.save
37 assert @wiki.save
38 @wiki.reload
38 @wiki.reload
39 assert_equal "Another start page", @wiki.start_page
39 assert_equal "Another start page", @wiki.start_page
40 end
40 end
41
41
42 def test_find_page_should_not_be_case_sensitive
42 def test_find_page_should_not_be_case_sensitive
43 wiki = Wiki.find(1)
43 wiki = Wiki.find(1)
44 page = WikiPage.find(2)
44 page = WikiPage.find(2)
45
45
46 assert_equal page, wiki.find_page('Another_page')
46 assert_equal page, wiki.find_page('Another_page')
47 assert_equal page, wiki.find_page('Another page')
47 assert_equal page, wiki.find_page('Another page')
48 assert_equal page, wiki.find_page('ANOTHER page')
48 assert_equal page, wiki.find_page('ANOTHER page')
49 end
49 end
50
50
51 def test_find_page_with_cyrillic_characters
51 def test_find_page_with_cyrillic_characters
52 wiki = Wiki.find(1)
52 wiki = Wiki.find(1)
53 page = WikiPage.find(10)
53 page = WikiPage.find(10)
54 assert_equal page, wiki.find_page('Π­Ρ‚ΠΈΠΊΠ°_ΠΌΠ΅Π½Π΅Π΄ΠΆΠΌΠ΅Π½Ρ‚Π°')
54 assert_equal page, wiki.find_page('Π­Ρ‚ΠΈΠΊΠ°_ΠΌΠ΅Π½Π΅Π΄ΠΆΠΌΠ΅Π½Ρ‚Π°')
55 end
55 end
56
56
57 def test_find_page_with_backslashes
57 def test_find_page_with_backslashes
58 wiki = Wiki.find(1)
58 wiki = Wiki.find(1)
59 page = WikiPage.create!(:wiki => wiki, :title => '2009\\02\\09')
59 page = WikiPage.create!(:wiki => wiki, :title => '2009\\02\\09')
60 assert_equal page, wiki.find_page('2009\\02\\09')
60 assert_equal page, wiki.find_page('2009\\02\\09')
61 end
61 end
62
62
63 def test_find_page_without_redirect
63 def test_find_page_without_redirect
64 wiki = Wiki.find(1)
64 wiki = Wiki.find(1)
65 page = wiki.find_page('Another_page')
65 page = wiki.find_page('Another_page')
66 assert_not_nil page
66 assert_not_nil page
67 assert_equal 'Another_page', page.title
67 assert_equal 'Another_page', page.title
68 assert_equal false, wiki.page_found_with_redirect?
68 assert_equal false, wiki.page_found_with_redirect?
69 end
69 end
70
70
71 def test_find_page_with_redirect
71 def test_find_page_with_redirect
72 wiki = Wiki.find(1)
72 wiki = Wiki.find(1)
73 WikiRedirect.create!(:wiki => wiki, :title => 'Old_title', :redirects_to => 'Another_page')
73 WikiRedirect.create!(:wiki => wiki, :title => 'Old_title', :redirects_to => 'Another_page')
74 page = wiki.find_page('Old_title')
74 page = wiki.find_page('Old_title')
75 assert_not_nil page
75 assert_not_nil page
76 assert_equal 'Another_page', page.title
76 assert_equal 'Another_page', page.title
77 assert_equal true, wiki.page_found_with_redirect?
77 assert_equal true, wiki.page_found_with_redirect?
78 end
78 end
79
79
80 def test_titleize
80 def test_titleize
81 ja_test = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88"
81 ja_test = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88"
82 ja_test.force_encoding('UTF-8') if ja_test.respond_to?(:force_encoding)
82 ja_test.force_encoding('UTF-8') if ja_test.respond_to?(:force_encoding)
83 assert_equal 'Page_title_with_CAPITALES', Wiki.titleize('page title with CAPITALES')
83 assert_equal 'Page_title_with_CAPITALES', Wiki.titleize('page title with CAPITALES')
84 assert_equal ja_test, Wiki.titleize(ja_test)
84 assert_equal ja_test, Wiki.titleize(ja_test)
85 end
85 end
86
86
87 context "#sidebar" do
87 def test_sidebar_should_return_nil_if_undefined
88 setup do
88 @wiki = Wiki.find(1)
89 @wiki = Wiki.find(1)
89 assert_nil @wiki.sidebar
90 end
90 end
91
92 should "return nil if undefined" do
93 assert_nil @wiki.sidebar
94 end
95
91
96 should "return a WikiPage if defined" do
92 def test_sidebar_should_return_a_wiki_page_if_defined
97 page = @wiki.pages.new(:title => 'Sidebar')
93 @wiki = Wiki.find(1)
98 page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
94 page = @wiki.pages.new(:title => 'Sidebar')
99 page.save!
95 page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
96 page.save!
100
97
101 assert_kind_of WikiPage, @wiki.sidebar
98 assert_kind_of WikiPage, @wiki.sidebar
102 assert_equal 'Sidebar', @wiki.sidebar.title
99 assert_equal 'Sidebar', @wiki.sidebar.title
103 end
104 end
100 end
105 end
101 end
General Comments 0
You need to be logged in to leave comments. Login now