##// END OF EJS Templates
Use absolute paths in test/**/* requires for Ruby 1.9.2 compatibility. #4050...
Jean-Baptiste Barth -
r4395:17f86d964fe0
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,224 +1,224
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'account_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class AccountController; def rescue_action(e) raise e end; end
23 23
24 24 class AccountControllerTest < ActionController::TestCase
25 25 fixtures :users, :roles
26 26
27 27 def setup
28 28 @controller = AccountController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_login_should_redirect_to_back_url_param
35 35 # request.uri is "test.host" in test environment
36 36 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http%3A%2F%2Ftest.host%2Fissues%2Fshow%2F1'
37 37 assert_redirected_to '/issues/show/1'
38 38 end
39 39
40 40 def test_login_should_not_redirect_to_another_host
41 41 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http%3A%2F%2Ftest.foo%2Ffake'
42 42 assert_redirected_to '/my/page'
43 43 end
44 44
45 45 def test_login_with_wrong_password
46 46 post :login, :username => 'admin', :password => 'bad'
47 47 assert_response :success
48 48 assert_template 'login'
49 49 assert_tag 'div',
50 50 :attributes => { :class => "flash error" },
51 51 :content => /Invalid user or password/
52 52 end
53 53
54 54 if Object.const_defined?(:OpenID)
55 55
56 56 def test_login_with_openid_for_existing_user
57 57 Setting.self_registration = '3'
58 58 Setting.openid = '1'
59 59 existing_user = User.new(:firstname => 'Cool',
60 60 :lastname => 'User',
61 61 :mail => 'user@somedomain.com',
62 62 :identity_url => 'http://openid.example.com/good_user')
63 63 existing_user.login = 'cool_user'
64 64 assert existing_user.save!
65 65
66 66 post :login, :openid_url => existing_user.identity_url
67 67 assert_redirected_to '/my/page'
68 68 end
69 69
70 70 def test_login_with_invalid_openid_provider
71 71 Setting.self_registration = '0'
72 72 Setting.openid = '1'
73 73 post :login, :openid_url => 'http;//openid.example.com/good_user'
74 74 assert_redirected_to home_url
75 75 end
76 76
77 77 def test_login_with_openid_for_existing_non_active_user
78 78 Setting.self_registration = '2'
79 79 Setting.openid = '1'
80 80 existing_user = User.new(:firstname => 'Cool',
81 81 :lastname => 'User',
82 82 :mail => 'user@somedomain.com',
83 83 :identity_url => 'http://openid.example.com/good_user',
84 84 :status => User::STATUS_REGISTERED)
85 85 existing_user.login = 'cool_user'
86 86 assert existing_user.save!
87 87
88 88 post :login, :openid_url => existing_user.identity_url
89 89 assert_redirected_to '/login'
90 90 end
91 91
92 92 def test_login_with_openid_with_new_user_created
93 93 Setting.self_registration = '3'
94 94 Setting.openid = '1'
95 95 post :login, :openid_url => 'http://openid.example.com/good_user'
96 96 assert_redirected_to '/my/account'
97 97 user = User.find_by_login('cool_user')
98 98 assert user
99 99 assert_equal 'Cool', user.firstname
100 100 assert_equal 'User', user.lastname
101 101 end
102 102
103 103 def test_login_with_openid_with_new_user_and_self_registration_off
104 104 Setting.self_registration = '0'
105 105 Setting.openid = '1'
106 106 post :login, :openid_url => 'http://openid.example.com/good_user'
107 107 assert_redirected_to home_url
108 108 user = User.find_by_login('cool_user')
109 109 assert ! user
110 110 end
111 111
112 112 def test_login_with_openid_with_new_user_created_with_email_activation_should_have_a_token
113 113 Setting.self_registration = '1'
114 114 Setting.openid = '1'
115 115 post :login, :openid_url => 'http://openid.example.com/good_user'
116 116 assert_redirected_to '/login'
117 117 user = User.find_by_login('cool_user')
118 118 assert user
119 119
120 120 token = Token.find_by_user_id_and_action(user.id, 'register')
121 121 assert token
122 122 end
123 123
124 124 def test_login_with_openid_with_new_user_created_with_manual_activation
125 125 Setting.self_registration = '2'
126 126 Setting.openid = '1'
127 127 post :login, :openid_url => 'http://openid.example.com/good_user'
128 128 assert_redirected_to '/login'
129 129 user = User.find_by_login('cool_user')
130 130 assert user
131 131 assert_equal User::STATUS_REGISTERED, user.status
132 132 end
133 133
134 134 def test_login_with_openid_with_new_user_with_conflict_should_register
135 135 Setting.self_registration = '3'
136 136 Setting.openid = '1'
137 137 existing_user = User.new(:firstname => 'Cool', :lastname => 'User', :mail => 'user@somedomain.com')
138 138 existing_user.login = 'cool_user'
139 139 assert existing_user.save!
140 140
141 141 post :login, :openid_url => 'http://openid.example.com/good_user'
142 142 assert_response :success
143 143 assert_template 'register'
144 144 assert assigns(:user)
145 145 assert_equal 'http://openid.example.com/good_user', assigns(:user)[:identity_url]
146 146 end
147 147
148 148 def test_setting_openid_should_return_true_when_set_to_true
149 149 Setting.openid = '1'
150 150 assert_equal true, Setting.openid?
151 151 end
152 152
153 153 else
154 154 puts "Skipping openid tests."
155 155 end
156 156
157 157 def test_logout
158 158 @request.session[:user_id] = 2
159 159 get :logout
160 160 assert_redirected_to '/'
161 161 assert_nil @request.session[:user_id]
162 162 end
163 163
164 164 context "GET #register" do
165 165 context "with self registration on" do
166 166 setup do
167 167 Setting.self_registration = '3'
168 168 get :register
169 169 end
170 170
171 171 should_respond_with :success
172 172 should_render_template :register
173 173 should_assign_to :user
174 174 end
175 175
176 176 context "with self registration off" do
177 177 setup do
178 178 Setting.self_registration = '0'
179 179 get :register
180 180 end
181 181
182 182 should_redirect_to('/') { home_url }
183 183 end
184 184 end
185 185
186 186 # See integration/account_test.rb for the full test
187 187 context "POST #register" do
188 188 context "with self registration on automatic" do
189 189 setup do
190 190 Setting.self_registration = '3'
191 191 post :register, :user => {
192 192 :login => 'register',
193 193 :password => 'test',
194 194 :password_confirmation => 'test',
195 195 :firstname => 'John',
196 196 :lastname => 'Doe',
197 197 :mail => 'register@example.com'
198 198 }
199 199 end
200 200
201 201 should_respond_with :redirect
202 202 should_assign_to :user
203 203 should_redirect_to('my page') { {:controller => 'my', :action => 'account'} }
204 204
205 205 should_create_a_new_user { User.last(:conditions => {:login => 'register'}) }
206 206
207 207 should 'set the user status to active' do
208 208 user = User.last(:conditions => {:login => 'register'})
209 209 assert user
210 210 assert_equal User::STATUS_ACTIVE, user.status
211 211 end
212 212 end
213 213
214 214 context "with self registration off" do
215 215 setup do
216 216 Setting.self_registration = '0'
217 217 post :register
218 218 end
219 219
220 220 should_redirect_to('/') { home_url }
221 221 end
222 222 end
223 223
224 224 end
@@ -1,87 +1,87
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class ActivitiesControllerTest < ActionController::TestCase
4 4 fixtures :all
5 5
6 6 def test_project_index
7 7 get :index, :id => 1, :with_subprojects => 0
8 8 assert_response :success
9 9 assert_template 'index'
10 10 assert_not_nil assigns(:events_by_day)
11 11
12 12 assert_tag :tag => "h3",
13 13 :content => /#{2.days.ago.to_date.day}/,
14 14 :sibling => { :tag => "dl",
15 15 :child => { :tag => "dt",
16 16 :attributes => { :class => /issue-edit/ },
17 17 :child => { :tag => "a",
18 18 :content => /(#{IssueStatus.find(2).name})/,
19 19 }
20 20 }
21 21 }
22 22 end
23 23
24 24 def test_previous_project_index
25 25 get :index, :id => 1, :from => 3.days.ago.to_date
26 26 assert_response :success
27 27 assert_template 'index'
28 28 assert_not_nil assigns(:events_by_day)
29 29
30 30 assert_tag :tag => "h3",
31 31 :content => /#{3.day.ago.to_date.day}/,
32 32 :sibling => { :tag => "dl",
33 33 :child => { :tag => "dt",
34 34 :attributes => { :class => /issue/ },
35 35 :child => { :tag => "a",
36 36 :content => /#{Issue.find(1).subject}/,
37 37 }
38 38 }
39 39 }
40 40 end
41 41
42 42 def test_global_index
43 43 get :index
44 44 assert_response :success
45 45 assert_template 'index'
46 46 assert_not_nil assigns(:events_by_day)
47 47
48 48 assert_tag :tag => "h3",
49 49 :content => /#{5.day.ago.to_date.day}/,
50 50 :sibling => { :tag => "dl",
51 51 :child => { :tag => "dt",
52 52 :attributes => { :class => /issue/ },
53 53 :child => { :tag => "a",
54 54 :content => /#{Issue.find(5).subject}/,
55 55 }
56 56 }
57 57 }
58 58 end
59 59
60 60 def test_user_index
61 61 get :index, :user_id => 2
62 62 assert_response :success
63 63 assert_template 'index'
64 64 assert_not_nil assigns(:events_by_day)
65 65
66 66 assert_tag :tag => "h3",
67 67 :content => /#{3.day.ago.to_date.day}/,
68 68 :sibling => { :tag => "dl",
69 69 :child => { :tag => "dt",
70 70 :attributes => { :class => /issue/ },
71 71 :child => { :tag => "a",
72 72 :content => /#{Issue.find(1).subject}/,
73 73 }
74 74 }
75 75 }
76 76 end
77 77
78 78 def test_index_atom_feed
79 79 get :index, :format => 'atom'
80 80 assert_response :success
81 81 assert_template 'common/feed.atom.rxml'
82 82 assert_tag :tag => 'entry', :child => {
83 83 :tag => 'link',
84 84 :attributes => {:href => 'http://test.host/issues/11'}}
85 85 end
86 86
87 87 end
@@ -1,141 +1,141
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'admin_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class AdminController; def rescue_action(e) raise e end; end
23 23
24 24 class AdminControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles
26 26
27 27 def setup
28 28 @controller = AdminController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 @request.session[:user_id] = 1 # admin
33 33 end
34 34
35 35 def test_index
36 36 get :index
37 37 assert_no_tag :tag => 'div',
38 38 :attributes => { :class => /nodata/ }
39 39 end
40 40
41 41 def test_index_with_no_configuration_data
42 42 delete_configuration_data
43 43 get :index
44 44 assert_tag :tag => 'div',
45 45 :attributes => { :class => /nodata/ }
46 46 end
47 47
48 48 def test_projects
49 49 get :projects
50 50 assert_response :success
51 51 assert_template 'projects'
52 52 assert_not_nil assigns(:projects)
53 53 # active projects only
54 54 assert_nil assigns(:projects).detect {|u| !u.active?}
55 55 end
56 56
57 57 def test_projects_with_name_filter
58 58 get :projects, :name => 'store', :status => ''
59 59 assert_response :success
60 60 assert_template 'projects'
61 61 projects = assigns(:projects)
62 62 assert_not_nil projects
63 63 assert_equal 1, projects.size
64 64 assert_equal 'OnlineStore', projects.first.name
65 65 end
66 66
67 67 def test_load_default_configuration_data
68 68 delete_configuration_data
69 69 post :default_configuration, :lang => 'fr'
70 70 assert_response :redirect
71 71 assert_nil flash[:error]
72 72 assert IssueStatus.find_by_name('Nouveau')
73 73 end
74 74
75 75 def test_test_email
76 76 get :test_email
77 77 assert_redirected_to '/settings/edit?tab=notifications'
78 78 mail = ActionMailer::Base.deliveries.last
79 79 assert_kind_of TMail::Mail, mail
80 80 user = User.find(1)
81 81 assert_equal [user.mail], mail.bcc
82 82 end
83 83
84 84 def test_no_plugins
85 85 Redmine::Plugin.clear
86 86
87 87 get :plugins
88 88 assert_response :success
89 89 assert_template 'plugins'
90 90 end
91 91
92 92 def test_plugins
93 93 # Register a few plugins
94 94 Redmine::Plugin.register :foo do
95 95 name 'Foo plugin'
96 96 author 'John Smith'
97 97 description 'This is a test plugin'
98 98 version '0.0.1'
99 99 settings :default => {'sample_setting' => 'value', 'foo'=>'bar'}, :partial => 'foo/settings'
100 100 end
101 101 Redmine::Plugin.register :bar do
102 102 end
103 103
104 104 get :plugins
105 105 assert_response :success
106 106 assert_template 'plugins'
107 107
108 108 assert_tag :td, :child => { :tag => 'span', :content => 'Foo plugin' }
109 109 assert_tag :td, :child => { :tag => 'span', :content => 'Bar' }
110 110 end
111 111
112 112 def test_info
113 113 get :info
114 114 assert_response :success
115 115 assert_template 'info'
116 116 end
117 117
118 118 def test_admin_menu_plugin_extension
119 119 Redmine::MenuManager.map :admin_menu do |menu|
120 120 menu.push :test_admin_menu_plugin_extension, '/foo/bar', :caption => 'Test'
121 121 end
122 122
123 123 get :index
124 124 assert_response :success
125 125 assert_tag :a, :attributes => { :href => '/foo/bar' },
126 126 :content => 'Test'
127 127
128 128 Redmine::MenuManager.map :admin_menu do |menu|
129 129 menu.delete :test_admin_menu_plugin_extension
130 130 end
131 131 end
132 132
133 133 private
134 134
135 135 def delete_configuration_data
136 136 Role.delete_all('builtin = 0')
137 137 Tracker.delete_all
138 138 IssueStatus.delete_all
139 139 Enumeration.delete_all
140 140 end
141 141 end
@@ -1,46 +1,46
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'application_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class ApplicationController; def rescue_action(e) raise e end; end
23 23
24 24 class ApplicationControllerTest < ActionController::TestCase
25 25 include Redmine::I18n
26 26
27 27 def setup
28 28 @controller = ApplicationController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 end
32 32
33 33 # check that all language files are valid
34 34 def test_localization
35 35 lang_files_count = Dir["#{RAILS_ROOT}/config/locales/*.yml"].size
36 36 assert_equal lang_files_count, valid_languages.size
37 37 valid_languages.each do |lang|
38 38 assert set_language_if_valid(lang)
39 39 end
40 40 set_language_if_valid('en')
41 41 end
42 42
43 43 def test_call_hook_mixed_in
44 44 assert @controller.respond_to?(:call_hook)
45 45 end
46 46 end
@@ -1,135 +1,135
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'attachments_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class AttachmentsController; def rescue_action(e) raise e end; end
23 23
24 24
25 25 class AttachmentsControllerTest < ActionController::TestCase
26 26 fixtures :users, :projects, :roles, :members, :member_roles, :enabled_modules, :issues, :trackers, :attachments,
27 27 :versions, :wiki_pages, :wikis, :documents
28 28
29 29 def setup
30 30 @controller = AttachmentsController.new
31 31 @request = ActionController::TestRequest.new
32 32 @response = ActionController::TestResponse.new
33 33 Attachment.storage_path = "#{RAILS_ROOT}/test/fixtures/files"
34 34 User.current = nil
35 35 end
36 36
37 37 def test_show_diff
38 38 get :show, :id => 5
39 39 assert_response :success
40 40 assert_template 'diff'
41 41 assert_equal 'text/html', @response.content_type
42 42 end
43 43
44 44 def test_show_text_file
45 45 get :show, :id => 4
46 46 assert_response :success
47 47 assert_template 'file'
48 48 assert_equal 'text/html', @response.content_type
49 49 end
50 50
51 51 def test_show_text_file_should_send_if_too_big
52 52 Setting.file_max_size_displayed = 512
53 53 Attachment.find(4).update_attribute :filesize, 754.kilobyte
54 54
55 55 get :show, :id => 4
56 56 assert_response :success
57 57 assert_equal 'application/x-ruby', @response.content_type
58 58 end
59 59
60 60 def test_show_other
61 61 get :show, :id => 6
62 62 assert_response :success
63 63 assert_equal 'application/octet-stream', @response.content_type
64 64 end
65 65
66 66 def test_download_text_file
67 67 get :download, :id => 4
68 68 assert_response :success
69 69 assert_equal 'application/x-ruby', @response.content_type
70 70 end
71 71
72 72 def test_download_should_assign_content_type_if_blank
73 73 Attachment.find(4).update_attribute(:content_type, '')
74 74
75 75 get :download, :id => 4
76 76 assert_response :success
77 77 assert_equal 'text/x-ruby', @response.content_type
78 78 end
79 79
80 80 def test_download_missing_file
81 81 get :download, :id => 2
82 82 assert_response 404
83 83 end
84 84
85 85 def test_anonymous_on_private_private
86 86 get :download, :id => 7
87 87 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fdownload%2F7'
88 88 end
89 89
90 90 def test_destroy_issue_attachment
91 91 issue = Issue.find(3)
92 92 @request.session[:user_id] = 2
93 93
94 94 assert_difference 'issue.attachments.count', -1 do
95 95 post :destroy, :id => 1
96 96 end
97 97 # no referrer
98 98 assert_redirected_to '/projects/ecookbook'
99 99 assert_nil Attachment.find_by_id(1)
100 100 j = issue.journals.find(:first, :order => 'created_on DESC')
101 101 assert_equal 'attachment', j.details.first.property
102 102 assert_equal '1', j.details.first.prop_key
103 103 assert_equal 'error281.txt', j.details.first.old_value
104 104 end
105 105
106 106 def test_destroy_wiki_page_attachment
107 107 @request.session[:user_id] = 2
108 108 assert_difference 'Attachment.count', -1 do
109 109 post :destroy, :id => 3
110 110 assert_response 302
111 111 end
112 112 end
113 113
114 114 def test_destroy_project_attachment
115 115 @request.session[:user_id] = 2
116 116 assert_difference 'Attachment.count', -1 do
117 117 post :destroy, :id => 8
118 118 assert_response 302
119 119 end
120 120 end
121 121
122 122 def test_destroy_version_attachment
123 123 @request.session[:user_id] = 2
124 124 assert_difference 'Attachment.count', -1 do
125 125 post :destroy, :id => 9
126 126 assert_response 302
127 127 end
128 128 end
129 129
130 130 def test_destroy_without_permission
131 131 post :destroy, :id => 3
132 132 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Fattachments%2Fdestroy%2F3'
133 133 assert Attachment.find_by_id(3)
134 134 end
135 135 end
@@ -1,83 +1,83
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class AuthSourcesControllerTest < ActionController::TestCase
4 4 fixtures :all
5 5
6 6 def setup
7 7 @request.session[:user_id] = 1
8 8 end
9 9
10 10 context "get :index" do
11 11 setup do
12 12 get :index
13 13 end
14 14
15 15 should_assign_to :auth_sources
16 16 should_assign_to :auth_source_pages
17 17 should_respond_with :success
18 18 should_render_template :index
19 19 end
20 20
21 21 context "get :new" do
22 22 setup do
23 23 get :new
24 24 end
25 25
26 26 should_assign_to :auth_source
27 27 should_respond_with :success
28 28 should_render_template :new
29 29
30 30 should "initilize a new AuthSource" do
31 31 assert_equal AuthSource, assigns(:auth_source).class
32 32 assert assigns(:auth_source).new_record?
33 33 end
34 34 end
35 35
36 36 context "post :create" do
37 37 setup do
38 38 post :create, :auth_source => {:name => 'Test'}
39 39 end
40 40
41 41 should_respond_with :redirect
42 42 should_redirect_to("index") {{:action => 'index'}}
43 43 should_set_the_flash_to /success/i
44 44 end
45 45
46 46 context "get :edit" do
47 47 setup do
48 48 @auth_source = AuthSource.generate!(:name => 'TestEdit')
49 49 get :edit, :id => @auth_source.id
50 50 end
51 51
52 52 should_assign_to(:auth_source) {@auth_source}
53 53 should_respond_with :success
54 54 should_render_template :edit
55 55 end
56 56
57 57 context "post :update" do
58 58 setup do
59 59 @auth_source = AuthSource.generate!(:name => 'TestEdit')
60 60 post :update, :id => @auth_source.id, :auth_source => {:name => 'TestUpdate'}
61 61 end
62 62
63 63 should_respond_with :redirect
64 64 should_redirect_to("index") {{:action => 'index'}}
65 65 should_set_the_flash_to /update/i
66 66 end
67 67
68 68 context "post :destroy" do
69 69 context "without users" do
70 70 setup do
71 71 @auth_source = AuthSource.generate!(:name => 'TestEdit')
72 72 post :destroy, :id => @auth_source.id
73 73 end
74 74
75 75 should_respond_with :redirect
76 76 should_redirect_to("index") {{:action => 'index'}}
77 77 should_set_the_flash_to /deletion/i
78 78
79 79 end
80 80
81 81 should "be tested with users"
82 82 end
83 83 end
@@ -1,34 +1,34
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class AutoCompletesControllerTest < ActionController::TestCase
4 4 fixtures :all
5 5
6 6 def test_issues_should_not_be_case_sensitive
7 7 get :issues, :project_id => 'ecookbook', :q => 'ReCiPe'
8 8 assert_response :success
9 9 assert_not_nil assigns(:issues)
10 10 assert assigns(:issues).detect {|issue| issue.subject.match /recipe/}
11 11 end
12 12
13 13 def test_issues_should_return_issue_with_given_id
14 14 get :issues, :project_id => 'subproject1', :q => '13'
15 15 assert_response :success
16 16 assert_not_nil assigns(:issues)
17 17 assert assigns(:issues).include?(Issue.find(13))
18 18 end
19 19
20 20 def test_auto_complete_with_scope_all_and_cross_project_relations
21 21 Setting.cross_project_issue_relations = '1'
22 22 get :issues, :project_id => 'ecookbook', :q => '13', :scope => 'all'
23 23 assert_response :success
24 24 assert_not_nil assigns(:issues)
25 25 assert assigns(:issues).include?(Issue.find(13))
26 26 end
27 27
28 28 def test_auto_complete_with_scope_all_without_cross_project_relations
29 29 Setting.cross_project_issue_relations = '0'
30 30 get :issues, :project_id => 'ecookbook', :q => '13', :scope => 'all'
31 31 assert_response :success
32 32 assert_equal [], assigns(:issues)
33 33 end
34 34 end
@@ -1,99 +1,99
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'boards_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class BoardsController; def rescue_action(e) raise e end; end
23 23
24 24 class BoardsControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
26 26
27 27 def setup
28 28 @controller = BoardsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_index
35 35 get :index, :project_id => 1
36 36 assert_response :success
37 37 assert_template 'index'
38 38 assert_not_nil assigns(:boards)
39 39 assert_not_nil assigns(:project)
40 40 end
41 41
42 42 def test_index_not_found
43 43 get :index, :project_id => 97
44 44 assert_response 404
45 45 end
46 46
47 47 def test_index_should_show_messages_if_only_one_board
48 48 Project.find(1).boards.slice(1..-1).each(&:destroy)
49 49
50 50 get :index, :project_id => 1
51 51 assert_response :success
52 52 assert_template 'show'
53 53 assert_not_nil assigns(:topics)
54 54 end
55 55
56 56 def test_post_new
57 57 @request.session[:user_id] = 2
58 58 assert_difference 'Board.count' do
59 59 post :new, :project_id => 1, :board => { :name => 'Testing', :description => 'Testing board creation'}
60 60 end
61 61 assert_redirected_to '/projects/ecookbook/settings/boards'
62 62 end
63 63
64 64 def test_show
65 65 get :show, :project_id => 1, :id => 1
66 66 assert_response :success
67 67 assert_template 'show'
68 68 assert_not_nil assigns(:board)
69 69 assert_not_nil assigns(:project)
70 70 assert_not_nil assigns(:topics)
71 71 end
72 72
73 73 def test_show_atom
74 74 get :show, :project_id => 1, :id => 1, :format => 'atom'
75 75 assert_response :success
76 76 assert_template 'common/feed.atom'
77 77 assert_not_nil assigns(:board)
78 78 assert_not_nil assigns(:project)
79 79 assert_not_nil assigns(:messages)
80 80 end
81 81
82 82 def test_post_edit
83 83 @request.session[:user_id] = 2
84 84 assert_no_difference 'Board.count' do
85 85 post :edit, :project_id => 1, :id => 2, :board => { :name => 'Testing', :description => 'Testing board update'}
86 86 end
87 87 assert_redirected_to '/projects/ecookbook/settings/boards'
88 88 assert_equal 'Testing', Board.find(2).name
89 89 end
90 90
91 91 def test_post_destroy
92 92 @request.session[:user_id] = 2
93 93 assert_difference 'Board.count', -1 do
94 94 post :destroy, :project_id => 1, :id => 2
95 95 end
96 96 assert_redirected_to '/projects/ecookbook/settings/boards'
97 97 assert_nil Board.find_by_id(2)
98 98 end
99 99 end
@@ -1,74 +1,74
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class CalendarsControllerTest < ActionController::TestCase
4 4 fixtures :all
5 5
6 6 def test_calendar
7 7 get :show, :project_id => 1
8 8 assert_response :success
9 9 assert_template 'calendar'
10 10 assert_not_nil assigns(:calendar)
11 11 end
12 12
13 13 def test_cross_project_calendar
14 14 get :show
15 15 assert_response :success
16 16 assert_template 'calendar'
17 17 assert_not_nil assigns(:calendar)
18 18 end
19 19
20 20 context "GET :show" do
21 21 should "run custom queries" do
22 22 @query = Query.generate_default!
23 23
24 24 get :show, :query_id => @query.id
25 25 assert_response :success
26 26 end
27 27
28 28 end
29 29
30 30 def test_week_number_calculation
31 31 Setting.start_of_week = 7
32 32
33 33 get :show, :month => '1', :year => '2010'
34 34 assert_response :success
35 35
36 36 assert_tag :tag => 'tr',
37 37 :descendant => {:tag => 'td',
38 38 :attributes => {:class => 'week-number'}, :content => '53'},
39 39 :descendant => {:tag => 'td',
40 40 :attributes => {:class => 'odd'}, :content => '27'},
41 41 :descendant => {:tag => 'td',
42 42 :attributes => {:class => 'even'}, :content => '2'}
43 43
44 44 assert_tag :tag => 'tr',
45 45 :descendant => {:tag => 'td',
46 46 :attributes => {:class => 'week-number'}, :content => '1'},
47 47 :descendant => {:tag => 'td',
48 48 :attributes => {:class => 'odd'}, :content => '3'},
49 49 :descendant => {:tag => 'td',
50 50 :attributes => {:class => 'even'}, :content => '9'}
51 51
52 52
53 53 Setting.start_of_week = 1
54 54 get :show, :month => '1', :year => '2010'
55 55 assert_response :success
56 56
57 57 assert_tag :tag => 'tr',
58 58 :descendant => {:tag => 'td',
59 59 :attributes => {:class => 'week-number'}, :content => '53'},
60 60 :descendant => {:tag => 'td',
61 61 :attributes => {:class => 'even'}, :content => '28'},
62 62 :descendant => {:tag => 'td',
63 63 :attributes => {:class => 'even'}, :content => '3'}
64 64
65 65 assert_tag :tag => 'tr',
66 66 :descendant => {:tag => 'td',
67 67 :attributes => {:class => 'week-number'}, :content => '1'},
68 68 :descendant => {:tag => 'td',
69 69 :attributes => {:class => 'even'}, :content => '4'},
70 70 :descendant => {:tag => 'td',
71 71 :attributes => {:class => 'even'}, :content => '10'}
72 72
73 73 end
74 74 end
@@ -1,57 +1,57
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class CommentsControllerTest < ActionController::TestCase
21 21 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :news, :comments
22 22
23 23 def setup
24 24 User.current = nil
25 25 end
26 26
27 27 def test_add_comment
28 28 @request.session[:user_id] = 2
29 29 post :create, :id => 1, :comment => { :comments => 'This is a test comment' }
30 30 assert_redirected_to '/news/1'
31 31
32 32 comment = News.find(1).comments.find(:first, :order => 'created_on DESC')
33 33 assert_not_nil comment
34 34 assert_equal 'This is a test comment', comment.comments
35 35 assert_equal User.find(2), comment.author
36 36 end
37 37
38 38 def test_empty_comment_should_not_be_added
39 39 @request.session[:user_id] = 2
40 40 assert_no_difference 'Comment.count' do
41 41 post :create, :id => 1, :comment => { :comments => '' }
42 42 assert_response :redirect
43 43 assert_redirected_to '/news/1'
44 44 end
45 45 end
46 46
47 47 def test_destroy_comment
48 48 comments_count = News.find(1).comments.size
49 49 @request.session[:user_id] = 2
50 50 delete :destroy, :id => 1, :comment_id => 2
51 51 assert_redirected_to '/news/1'
52 52 assert_nil Comment.find_by_id(2)
53 53 assert_equal comments_count - 1, News.find(1).comments.size
54 54 end
55 55
56 56
57 57 end
@@ -1,105 +1,105
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class ContextMenusControllerTest < ActionController::TestCase
4 4 fixtures :all
5 5
6 6 def test_context_menu_one_issue
7 7 @request.session[:user_id] = 2
8 8 get :issues, :ids => [1]
9 9 assert_response :success
10 10 assert_template 'context_menu'
11 11 assert_tag :tag => 'a', :content => 'Edit',
12 12 :attributes => { :href => '/issues/1/edit',
13 13 :class => 'icon-edit' }
14 14 assert_tag :tag => 'a', :content => 'Closed',
15 15 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bstatus_id%5D=5',
16 16 :class => '' }
17 17 assert_tag :tag => 'a', :content => 'Immediate',
18 18 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8',
19 19 :class => '' }
20 20 # Versions
21 21 assert_tag :tag => 'a', :content => '2.0',
22 22 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3',
23 23 :class => '' }
24 24 assert_tag :tag => 'a', :content => 'eCookbook Subproject 1 - 2.0',
25 25 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4',
26 26 :class => '' }
27 27
28 28 assert_tag :tag => 'a', :content => 'Dave Lopper',
29 29 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3',
30 30 :class => '' }
31 31 assert_tag :tag => 'a', :content => 'Duplicate',
32 32 :attributes => { :href => '/projects/ecookbook/issues/1/copy',
33 33 :class => 'icon-duplicate' }
34 34 assert_tag :tag => 'a', :content => 'Copy',
35 35 :attributes => { :href => '/issues/move/new?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1',
36 36 :class => 'icon-copy' }
37 37 assert_tag :tag => 'a', :content => 'Move',
38 38 :attributes => { :href => '/issues/move/new?ids%5B%5D=1',
39 39 :class => 'icon-move' }
40 40 assert_tag :tag => 'a', :content => 'Delete',
41 41 :attributes => { :href => '/issues/destroy?ids%5B%5D=1',
42 42 :class => 'icon-del' }
43 43 end
44 44
45 45 def test_context_menu_one_issue_by_anonymous
46 46 get :issues, :ids => [1]
47 47 assert_response :success
48 48 assert_template 'context_menu'
49 49 assert_tag :tag => 'a', :content => 'Delete',
50 50 :attributes => { :href => '#',
51 51 :class => 'icon-del disabled' }
52 52 end
53 53
54 54 def test_context_menu_multiple_issues_of_same_project
55 55 @request.session[:user_id] = 2
56 56 get :issues, :ids => [1, 2]
57 57 assert_response :success
58 58 assert_template 'context_menu'
59 59 assert_tag :tag => 'a', :content => 'Edit',
60 60 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2',
61 61 :class => 'icon-edit' }
62 62 assert_tag :tag => 'a', :content => 'Closed',
63 63 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bstatus_id%5D=5',
64 64 :class => '' }
65 65 assert_tag :tag => 'a', :content => 'Immediate',
66 66 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bpriority_id%5D=8',
67 67 :class => '' }
68 68 assert_tag :tag => 'a', :content => 'Dave Lopper',
69 69 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bassigned_to_id%5D=3',
70 70 :class => '' }
71 71 assert_tag :tag => 'a', :content => 'Copy',
72 72 :attributes => { :href => '/issues/move/new?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1&amp;ids%5B%5D=2',
73 73 :class => 'icon-copy' }
74 74 assert_tag :tag => 'a', :content => 'Move',
75 75 :attributes => { :href => '/issues/move/new?ids%5B%5D=1&amp;ids%5B%5D=2',
76 76 :class => 'icon-move' }
77 77 assert_tag :tag => 'a', :content => 'Delete',
78 78 :attributes => { :href => '/issues/destroy?ids%5B%5D=1&amp;ids%5B%5D=2',
79 79 :class => 'icon-del' }
80 80 end
81 81
82 82 def test_context_menu_multiple_issues_of_different_projects
83 83 @request.session[:user_id] = 2
84 84 get :issues, :ids => [1, 2, 6]
85 85 assert_response :success
86 86 assert_template 'context_menu'
87 87 ids = "ids%5B%5D=1&amp;ids%5B%5D=2&amp;ids%5B%5D=6"
88 88 assert_tag :tag => 'a', :content => 'Edit',
89 89 :attributes => { :href => "/issues/bulk_edit?#{ids}",
90 90 :class => 'icon-edit' }
91 91 assert_tag :tag => 'a', :content => 'Closed',
92 92 :attributes => { :href => "/issues/bulk_edit?#{ids}&amp;issue%5Bstatus_id%5D=5",
93 93 :class => '' }
94 94 assert_tag :tag => 'a', :content => 'Immediate',
95 95 :attributes => { :href => "/issues/bulk_edit?#{ids}&amp;issue%5Bpriority_id%5D=8",
96 96 :class => '' }
97 97 assert_tag :tag => 'a', :content => 'John Smith',
98 98 :attributes => { :href => "/issues/bulk_edit?#{ids}&amp;issue%5Bassigned_to_id%5D=2",
99 99 :class => '' }
100 100 assert_tag :tag => 'a', :content => 'Delete',
101 101 :attributes => { :href => "/issues/destroy?#{ids}",
102 102 :class => 'icon-del' }
103 103 end
104 104
105 105 end
@@ -1,61 +1,61
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'custom_fields_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class CustomFieldsController; def rescue_action(e) raise e end; end
23 23
24 24 class CustomFieldsControllerTest < ActionController::TestCase
25 25 fixtures :custom_fields, :trackers, :users
26 26
27 27 def setup
28 28 @controller = CustomFieldsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 @request.session[:user_id] = 1
32 32 end
33 33
34 34 def test_post_new_list_custom_field
35 35 assert_difference 'CustomField.count' do
36 36 post :new, :type => "IssueCustomField",
37 37 :custom_field => {:name => "test_post_new_list",
38 38 :default_value => "",
39 39 :min_length => "0",
40 40 :searchable => "0",
41 41 :regexp => "",
42 42 :is_for_all => "1",
43 43 :possible_values => "0.1\n0.2\n",
44 44 :max_length => "0",
45 45 :is_filter => "0",
46 46 :is_required =>"0",
47 47 :field_format => "list",
48 48 :tracker_ids => ["1", ""]}
49 49 end
50 50 assert_redirected_to '/custom_fields?tab=IssueCustomField'
51 51 field = IssueCustomField.find_by_name('test_post_new_list')
52 52 assert_not_nil field
53 53 assert_equal ["0.1", "0.2"], field.possible_values
54 54 assert_equal 1, field.trackers.size
55 55 end
56 56
57 57 def test_invalid_custom_field_class_should_redirect_to_list
58 58 get :new, :type => 'UnknownCustomField'
59 59 assert_redirected_to '/custom_fields'
60 60 end
61 61 end
@@ -1,96 +1,96
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'documents_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class DocumentsController; def rescue_action(e) raise e end; end
23 23
24 24 class DocumentsControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :documents, :enumerations
26 26
27 27 def setup
28 28 @controller = DocumentsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_index
35 35 # Sets a default category
36 36 e = Enumeration.find_by_name('Technical documentation')
37 37 e.update_attributes(:is_default => true)
38 38
39 39 get :index, :project_id => 'ecookbook'
40 40 assert_response :success
41 41 assert_template 'index'
42 42 assert_not_nil assigns(:grouped)
43 43
44 44 # Default category selected in the new document form
45 45 assert_tag :select, :attributes => {:name => 'document[category_id]'},
46 46 :child => {:tag => 'option', :attributes => {:selected => 'selected'},
47 47 :content => 'Technical documentation'}
48 48 end
49 49
50 50 def test_index_with_long_description
51 51 # adds a long description to the first document
52 52 doc = documents(:documents_001)
53 53 doc.update_attributes(:description => <<LOREM)
54 54 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut egestas, mi vehicula varius varius, ipsum massa fermentum orci, eget tristique ante sem vel mi. Nulla facilisi. Donec enim libero, luctus ac sagittis sit amet, vehicula sagittis magna. Duis ultrices molestie ante, eget scelerisque sem iaculis vitae. Etiam fermentum mauris vitae metus pharetra condimentum fermentum est pretium. Proin sollicitudin elementum quam quis pharetra. Aenean facilisis nunc quis elit volutpat mollis. Aenean eleifend varius euismod. Ut dolor est, congue eget dapibus eget, elementum eu odio. Integer et lectus neque, nec scelerisque nisi. EndOfLineHere
55 55
56 56 Vestibulum non velit mi. Aliquam scelerisque libero ut nulla fringilla a sollicitudin magna rhoncus. Praesent a nunc lorem, ac porttitor eros. Sed ac diam nec neque interdum adipiscing quis quis justo. Donec arcu nunc, fringilla eu dictum at, venenatis ac sem. Vestibulum quis elit urna, ac mattis sapien. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
57 57 LOREM
58 58
59 59 get :index, :project_id => 'ecookbook'
60 60 assert_response :success
61 61 assert_template 'index'
62 62
63 63 # should only truncate on new lines to avoid breaking wiki formatting
64 64 assert_select '.wiki p', :text => (doc.description.split("\n").first + '...')
65 65 assert_select '.wiki p', :text => Regexp.new(Regexp.escape("EndOfLineHere..."))
66 66 end
67 67
68 68 def test_new_with_one_attachment
69 69 ActionMailer::Base.deliveries.clear
70 70 Setting.notified_events << 'document_added'
71 71 @request.session[:user_id] = 2
72 72 set_tmp_attachments_directory
73 73
74 74 post :new, :project_id => 'ecookbook',
75 75 :document => { :title => 'DocumentsControllerTest#test_post_new',
76 76 :description => 'This is a new document',
77 77 :category_id => 2},
78 78 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
79 79
80 80 assert_redirected_to '/projects/ecookbook/documents'
81 81
82 82 document = Document.find_by_title('DocumentsControllerTest#test_post_new')
83 83 assert_not_nil document
84 84 assert_equal Enumeration.find(2), document.category
85 85 assert_equal 1, document.attachments.size
86 86 assert_equal 'testfile.txt', document.attachments.first.filename
87 87 assert_equal 1, ActionMailer::Base.deliveries.size
88 88 end
89 89
90 90 def test_destroy
91 91 @request.session[:user_id] = 2
92 92 post :destroy, :id => 1
93 93 assert_redirected_to '/projects/ecookbook/documents'
94 94 assert_nil Document.find_by_id(1)
95 95 end
96 96 end
@@ -1,61 +1,61
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'enumerations_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class EnumerationsController; def rescue_action(e) raise e end; end
23 23
24 24 class EnumerationsControllerTest < ActionController::TestCase
25 25 fixtures :enumerations, :issues, :users
26 26
27 27 def setup
28 28 @controller = EnumerationsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 @request.session[:user_id] = 1 # admin
32 32 end
33 33
34 34 def test_index
35 35 get :index
36 36 assert_response :success
37 37 assert_template 'list'
38 38 end
39 39
40 40 def test_destroy_enumeration_not_in_use
41 41 post :destroy, :id => 7
42 42 assert_redirected_to :controller => 'enumerations', :action => 'index'
43 43 assert_nil Enumeration.find_by_id(7)
44 44 end
45 45
46 46 def test_destroy_enumeration_in_use
47 47 post :destroy, :id => 4
48 48 assert_response :success
49 49 assert_template 'destroy'
50 50 assert_not_nil Enumeration.find_by_id(4)
51 51 end
52 52
53 53 def test_destroy_enumeration_in_use_with_reassignment
54 54 issue = Issue.find(:first, :conditions => {:priority_id => 4})
55 55 post :destroy, :id => 4, :reassign_to_id => 6
56 56 assert_redirected_to :controller => 'enumerations', :action => 'index'
57 57 assert_nil Enumeration.find_by_id(4)
58 58 # check that the issue was reassign
59 59 assert_equal 6, issue.reload.priority_id
60 60 end
61 61 end
@@ -1,67 +1,67
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class FilesControllerTest < ActionController::TestCase
4 4 fixtures :all
5 5
6 6 def setup
7 7 @controller = FilesController.new
8 8 @request = ActionController::TestRequest.new
9 9 @response = ActionController::TestResponse.new
10 10 @request.session[:user_id] = nil
11 11 Setting.default_language = 'en'
12 12 end
13 13
14 14 def test_index
15 15 get :index, :project_id => 1
16 16 assert_response :success
17 17 assert_template 'index'
18 18 assert_not_nil assigns(:containers)
19 19
20 20 # file attached to the project
21 21 assert_tag :a, :content => 'project_file.zip',
22 22 :attributes => { :href => '/attachments/download/8/project_file.zip' }
23 23
24 24 # file attached to a project's version
25 25 assert_tag :a, :content => 'version_file.zip',
26 26 :attributes => { :href => '/attachments/download/9/version_file.zip' }
27 27 end
28 28
29 29 def test_create_file
30 30 set_tmp_attachments_directory
31 31 @request.session[:user_id] = 2
32 32 Setting.notified_events = ['file_added']
33 33 ActionMailer::Base.deliveries.clear
34 34
35 35 assert_difference 'Attachment.count' do
36 36 post :create, :project_id => 1, :version_id => '',
37 37 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
38 38 assert_response :redirect
39 39 end
40 40 assert_redirected_to '/projects/ecookbook/files'
41 41 a = Attachment.find(:first, :order => 'created_on DESC')
42 42 assert_equal 'testfile.txt', a.filename
43 43 assert_equal Project.find(1), a.container
44 44
45 45 mail = ActionMailer::Base.deliveries.last
46 46 assert_kind_of TMail::Mail, mail
47 47 assert_equal "[eCookbook] New file", mail.subject
48 48 assert mail.body.include?('testfile.txt')
49 49 end
50 50
51 51 def test_create_version_file
52 52 set_tmp_attachments_directory
53 53 @request.session[:user_id] = 2
54 54 Setting.notified_events = ['file_added']
55 55
56 56 assert_difference 'Attachment.count' do
57 57 post :create, :project_id => 1, :version_id => '2',
58 58 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
59 59 assert_response :redirect
60 60 end
61 61 assert_redirected_to '/projects/ecookbook/files'
62 62 a = Attachment.find(:first, :order => 'created_on DESC')
63 63 assert_equal 'testfile.txt', a.filename
64 64 assert_equal Version.find(2), a.container
65 65 end
66 66
67 67 end
@@ -1,87 +1,87
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class GanttsControllerTest < ActionController::TestCase
4 4 fixtures :all
5 5
6 6 context "#gantt" do
7 7 should "work" do
8 8 i2 = Issue.find(2)
9 9 i2.update_attribute(:due_date, 1.month.from_now)
10 10
11 11 get :show, :project_id => 1
12 12 assert_response :success
13 13 assert_template 'show.html.erb'
14 14 assert_not_nil assigns(:gantt)
15 15 # Issue with start and due dates
16 16 i = Issue.find(1)
17 17 assert_not_nil i.due_date
18 18 assert_select "div a.issue", /##{i.id}/
19 19 # Issue with on a targeted version should not be in the events but loaded in the html
20 20 i = Issue.find(2)
21 21 assert_select "div a.issue", /##{i.id}/
22 22 end
23 23
24 24 should "work without issue due dates" do
25 25 Issue.update_all("due_date = NULL")
26 26
27 27 get :show, :project_id => 1
28 28 assert_response :success
29 29 assert_template 'show.html.erb'
30 30 assert_not_nil assigns(:gantt)
31 31 end
32 32
33 33 should "work without issue and version due dates" do
34 34 Issue.update_all("due_date = NULL")
35 35 Version.update_all("effective_date = NULL")
36 36
37 37 get :show, :project_id => 1
38 38 assert_response :success
39 39 assert_template 'show.html.erb'
40 40 assert_not_nil assigns(:gantt)
41 41 end
42 42
43 43 should "work cross project" do
44 44 get :show
45 45 assert_response :success
46 46 assert_template 'show.html.erb'
47 47 assert_not_nil assigns(:gantt)
48 48 assert_not_nil assigns(:gantt).query
49 49 assert_nil assigns(:gantt).project
50 50 end
51 51
52 52 should "not disclose private projects" do
53 53 get :show
54 54 assert_response :success
55 55 assert_template 'show.html.erb'
56 56
57 57 assert_tag 'a', :content => /eCookbook/
58 58 # Root private project
59 59 assert_no_tag 'a', {:content => /OnlineStore/}
60 60 # Private children of a public project
61 61 assert_no_tag 'a', :content => /Private child of eCookbook/
62 62 end
63 63
64 64 should "export to pdf" do
65 65 get :show, :project_id => 1, :format => 'pdf'
66 66 assert_response :success
67 67 assert_equal 'application/pdf', @response.content_type
68 68 assert @response.body.starts_with?('%PDF')
69 69 assert_not_nil assigns(:gantt)
70 70 end
71 71
72 72 should "export to pdf cross project" do
73 73 get :show, :format => 'pdf'
74 74 assert_response :success
75 75 assert_equal 'application/pdf', @response.content_type
76 76 assert @response.body.starts_with?('%PDF')
77 77 assert_not_nil assigns(:gantt)
78 78 end
79 79
80 80 should "export to png" do
81 81 get :show, :project_id => 1, :format => 'png'
82 82 assert_response :success
83 83 assert_equal 'image/png', @response.content_type
84 84 end if Object.const_defined?(:Magick)
85 85
86 86 end
87 87 end
@@ -1,107 +1,107
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'groups_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class GroupsController; def rescue_action(e) raise e end; end
23 23
24 24 class GroupsControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :members, :member_roles, :groups_users
26 26
27 27 def setup
28 28 @controller = GroupsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 @request.session[:user_id] = 1
33 33 end
34 34
35 35 def test_index
36 36 get :index
37 37 assert_response :success
38 38 assert_template 'index'
39 39 end
40 40
41 41 def test_show
42 42 get :show, :id => 10
43 43 assert_response :success
44 44 assert_template 'show'
45 45 end
46 46
47 47 def test_new
48 48 get :new
49 49 assert_response :success
50 50 assert_template 'new'
51 51 end
52 52
53 53 def test_create
54 54 assert_difference 'Group.count' do
55 55 post :create, :group => {:lastname => 'New group'}
56 56 end
57 57 assert_redirected_to '/groups'
58 58 end
59 59
60 60 def test_edit
61 61 get :edit, :id => 10
62 62 assert_response :success
63 63 assert_template 'edit'
64 64 end
65 65
66 66 def test_update
67 67 post :update, :id => 10
68 68 assert_redirected_to '/groups'
69 69 end
70 70
71 71 def test_destroy
72 72 assert_difference 'Group.count', -1 do
73 73 post :destroy, :id => 10
74 74 end
75 75 assert_redirected_to '/groups'
76 76 end
77 77
78 78 def test_add_users
79 79 assert_difference 'Group.find(10).users.count', 2 do
80 80 post :add_users, :id => 10, :user_ids => ['2', '3']
81 81 end
82 82 end
83 83
84 84 def test_remove_user
85 85 assert_difference 'Group.find(10).users.count', -1 do
86 86 post :remove_user, :id => 10, :user_id => '8'
87 87 end
88 88 end
89 89
90 90 def test_new_membership
91 91 assert_difference 'Group.find(10).members.count' do
92 92 post :edit_membership, :id => 10, :membership => { :project_id => 2, :role_ids => ['1', '2']}
93 93 end
94 94 end
95 95
96 96 def test_edit_membership
97 97 assert_no_difference 'Group.find(10).members.count' do
98 98 post :edit_membership, :id => 10, :membership_id => 6, :membership => { :role_ids => ['1', '3']}
99 99 end
100 100 end
101 101
102 102 def test_destroy_membership
103 103 assert_difference 'Group.find(10).members.count', -1 do
104 104 post :destroy_membership, :id => 10, :membership_id => 6
105 105 end
106 106 end
107 107 end
@@ -1,96 +1,96
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'issue_categories_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class IssueCategoriesController; def rescue_action(e) raise e end; end
23 23
24 24 class IssueCategoriesControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules, :issue_categories
26 26
27 27 def setup
28 28 @controller = IssueCategoriesController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 @request.session[:user_id] = 2
33 33 end
34 34
35 35 def test_get_new
36 36 @request.session[:user_id] = 2 # manager
37 37 get :new, :project_id => '1'
38 38 assert_response :success
39 39 assert_template 'new'
40 40 end
41 41
42 42 def test_post_new
43 43 @request.session[:user_id] = 2 # manager
44 44 assert_difference 'IssueCategory.count' do
45 45 post :new, :project_id => '1', :category => {:name => 'New category'}
46 46 end
47 47 assert_redirected_to '/projects/ecookbook/settings/categories'
48 48 category = IssueCategory.find_by_name('New category')
49 49 assert_not_nil category
50 50 assert_equal 1, category.project_id
51 51 end
52 52
53 53 def test_post_edit
54 54 assert_no_difference 'IssueCategory.count' do
55 55 post :edit, :id => 2, :category => { :name => 'Testing' }
56 56 end
57 57 assert_redirected_to '/projects/ecookbook/settings/categories'
58 58 assert_equal 'Testing', IssueCategory.find(2).name
59 59 end
60 60
61 61 def test_edit_not_found
62 62 post :edit, :id => 97, :category => { :name => 'Testing' }
63 63 assert_response 404
64 64 end
65 65
66 66 def test_destroy_category_not_in_use
67 67 post :destroy, :id => 2
68 68 assert_redirected_to '/projects/ecookbook/settings/categories'
69 69 assert_nil IssueCategory.find_by_id(2)
70 70 end
71 71
72 72 def test_destroy_category_in_use
73 73 post :destroy, :id => 1
74 74 assert_response :success
75 75 assert_template 'destroy'
76 76 assert_not_nil IssueCategory.find_by_id(1)
77 77 end
78 78
79 79 def test_destroy_category_in_use_with_reassignment
80 80 issue = Issue.find(:first, :conditions => {:category_id => 1})
81 81 post :destroy, :id => 1, :todo => 'reassign', :reassign_to_id => 2
82 82 assert_redirected_to '/projects/ecookbook/settings/categories'
83 83 assert_nil IssueCategory.find_by_id(1)
84 84 # check that the issue was reassign
85 85 assert_equal 2, issue.reload.category_id
86 86 end
87 87
88 88 def test_destroy_category_in_use_without_reassignment
89 89 issue = Issue.find(:first, :conditions => {:category_id => 1})
90 90 post :destroy, :id => 1, :todo => 'nullify'
91 91 assert_redirected_to '/projects/ecookbook/settings/categories'
92 92 assert_nil IssueCategory.find_by_id(1)
93 93 # check that the issue category was nullified
94 94 assert_nil issue.reload.category_id
95 95 end
96 96 end
@@ -1,124 +1,124
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class IssueMovesControllerTest < ActionController::TestCase
4 4 fixtures :all
5 5
6 6 def setup
7 7 User.current = nil
8 8 end
9 9
10 10 def test_create_one_issue_to_another_project
11 11 @request.session[:user_id] = 2
12 12 post :create, :id => 1, :new_project_id => 2, :tracker_id => '', :assigned_to_id => '', :status_id => '', :start_date => '', :due_date => ''
13 13 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
14 14 assert_equal 2, Issue.find(1).project_id
15 15 end
16 16
17 17 def test_create_one_issue_to_another_project_should_follow_when_needed
18 18 @request.session[:user_id] = 2
19 19 post :create, :id => 1, :new_project_id => 2, :follow => '1'
20 20 assert_redirected_to '/issues/1'
21 21 end
22 22
23 23 def test_bulk_create_to_another_project
24 24 @request.session[:user_id] = 2
25 25 post :create, :ids => [1, 2], :new_project_id => 2
26 26 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
27 27 # Issues moved to project 2
28 28 assert_equal 2, Issue.find(1).project_id
29 29 assert_equal 2, Issue.find(2).project_id
30 30 # No tracker change
31 31 assert_equal 1, Issue.find(1).tracker_id
32 32 assert_equal 2, Issue.find(2).tracker_id
33 33 end
34 34
35 35 def test_bulk_create_to_another_tracker
36 36 @request.session[:user_id] = 2
37 37 post :create, :ids => [1, 2], :new_tracker_id => 2
38 38 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
39 39 assert_equal 2, Issue.find(1).tracker_id
40 40 assert_equal 2, Issue.find(2).tracker_id
41 41 end
42 42
43 43 context "#create via bulk move" do
44 44 setup do
45 45 @request.session[:user_id] = 2
46 46 end
47 47
48 48 should "allow changing the issue priority" do
49 49 post :create, :ids => [1, 2], :priority_id => 6
50 50
51 51 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
52 52 assert_equal 6, Issue.find(1).priority_id
53 53 assert_equal 6, Issue.find(2).priority_id
54 54
55 55 end
56 56
57 57 should "allow adding a note when moving" do
58 58 post :create, :ids => [1, 2], :notes => 'Moving two issues'
59 59
60 60 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
61 61 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
62 62 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
63 63
64 64 end
65 65
66 66 end
67 67
68 68 def test_bulk_copy_to_another_project
69 69 @request.session[:user_id] = 2
70 70 assert_difference 'Issue.count', 2 do
71 71 assert_no_difference 'Project.find(1).issues.count' do
72 72 post :create, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}
73 73 end
74 74 end
75 75 assert_redirected_to '/projects/ecookbook/issues'
76 76 end
77 77
78 78 context "#create via bulk copy" do
79 79 should "allow not changing the issue's attributes" do
80 80 @request.session[:user_id] = 2
81 81 issue_before_move = Issue.find(1)
82 82 assert_difference 'Issue.count', 1 do
83 83 assert_no_difference 'Project.find(1).issues.count' do
84 84 post :create, :ids => [1], :new_project_id => 2, :copy_options => {:copy => '1'}, :new_tracker_id => '', :assigned_to_id => '', :status_id => '', :start_date => '', :due_date => ''
85 85 end
86 86 end
87 87 issue_after_move = Issue.first(:order => 'id desc', :conditions => {:project_id => 2})
88 88 assert_equal issue_before_move.tracker_id, issue_after_move.tracker_id
89 89 assert_equal issue_before_move.status_id, issue_after_move.status_id
90 90 assert_equal issue_before_move.assigned_to_id, issue_after_move.assigned_to_id
91 91 end
92 92
93 93 should "allow changing the issue's attributes" do
94 94 # Fixes random test failure with Mysql
95 95 # where Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2}) doesn't return the expected results
96 96 Issue.delete_all("project_id=2")
97 97
98 98 @request.session[:user_id] = 2
99 99 assert_difference 'Issue.count', 2 do
100 100 assert_no_difference 'Project.find(1).issues.count' do
101 101 post :create, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}, :new_tracker_id => '', :assigned_to_id => 4, :status_id => 3, :start_date => '2009-12-01', :due_date => '2009-12-31'
102 102 end
103 103 end
104 104
105 105 copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
106 106 assert_equal 2, copied_issues.size
107 107 copied_issues.each do |issue|
108 108 assert_equal 2, issue.project_id, "Project is incorrect"
109 109 assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
110 110 assert_equal 3, issue.status_id, "Status is incorrect"
111 111 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
112 112 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
113 113 end
114 114 end
115 115 end
116 116
117 117 def test_copy_to_another_project_should_follow_when_needed
118 118 @request.session[:user_id] = 2
119 119 post :create, :ids => [1], :new_project_id => 2, :copy_options => {:copy => '1'}, :follow => '1'
120 120 issue = Issue.first(:order => 'id DESC')
121 121 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
122 122 end
123 123
124 124 end
@@ -1,71 +1,71
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2 require 'issue_relations_controller'
3 3
4 4 # Re-raise errors caught by the controller.
5 5 class IssueRelationsController; def rescue_action(e) raise e end; end
6 6
7 7
8 8 class IssueRelationsControllerTest < ActionController::TestCase
9 9 fixtures :projects,
10 10 :users,
11 11 :roles,
12 12 :members,
13 13 :member_roles,
14 14 :issues,
15 15 :issue_statuses,
16 16 :issue_relations,
17 17 :enabled_modules,
18 18 :enumerations,
19 19 :trackers
20 20
21 21 def setup
22 22 @controller = IssueRelationsController.new
23 23 @request = ActionController::TestRequest.new
24 24 @response = ActionController::TestResponse.new
25 25 User.current = nil
26 26 end
27 27
28 28 def test_new
29 29 assert_difference 'IssueRelation.count' do
30 30 @request.session[:user_id] = 3
31 31 post :new, :issue_id => 1,
32 32 :relation => {:issue_to_id => '2', :relation_type => 'relates', :delay => ''}
33 33 end
34 34 end
35 35
36 36 def test_new_should_accept_id_with_hash
37 37 assert_difference 'IssueRelation.count' do
38 38 @request.session[:user_id] = 3
39 39 post :new, :issue_id => 1,
40 40 :relation => {:issue_to_id => '#2', :relation_type => 'relates', :delay => ''}
41 41 end
42 42 end
43 43
44 44 def test_new_should_not_break_with_non_numerical_id
45 45 assert_no_difference 'IssueRelation.count' do
46 46 assert_nothing_raised do
47 47 @request.session[:user_id] = 3
48 48 post :new, :issue_id => 1,
49 49 :relation => {:issue_to_id => 'foo', :relation_type => 'relates', :delay => ''}
50 50 end
51 51 end
52 52 end
53 53
54 54 def test_should_create_relations_with_visible_issues_only
55 55 Setting.cross_project_issue_relations = '1'
56 56 assert_nil Issue.visible(User.find(3)).find_by_id(4)
57 57
58 58 assert_no_difference 'IssueRelation.count' do
59 59 @request.session[:user_id] = 3
60 60 post :new, :issue_id => 1,
61 61 :relation => {:issue_to_id => '4', :relation_type => 'relates', :delay => ''}
62 62 end
63 63 end
64 64
65 65 def test_destroy
66 66 assert_difference 'IssueRelation.count', -1 do
67 67 @request.session[:user_id] = 3
68 68 post :destroy, :id => '2', :issue_id => '3'
69 69 end
70 70 end
71 71 end
@@ -1,95 +1,95
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2 require 'issue_statuses_controller'
3 3
4 4 # Re-raise errors caught by the controller.
5 5 class IssueStatusesController; def rescue_action(e) raise e end; end
6 6
7 7
8 8 class IssueStatusesControllerTest < ActionController::TestCase
9 9 fixtures :issue_statuses, :issues
10 10
11 11 def setup
12 12 @controller = IssueStatusesController.new
13 13 @request = ActionController::TestRequest.new
14 14 @response = ActionController::TestResponse.new
15 15 User.current = nil
16 16 @request.session[:user_id] = 1 # admin
17 17 end
18 18
19 19 def test_index
20 20 get :index
21 21 assert_response :success
22 22 assert_template 'index'
23 23 end
24 24
25 25 def test_new
26 26 get :new
27 27 assert_response :success
28 28 assert_template 'new'
29 29 end
30 30
31 31 def test_create
32 32 assert_difference 'IssueStatus.count' do
33 33 post :create, :issue_status => {:name => 'New status'}
34 34 end
35 35 assert_redirected_to :action => 'index'
36 36 status = IssueStatus.find(:first, :order => 'id DESC')
37 37 assert_equal 'New status', status.name
38 38 end
39 39
40 40 def test_edit
41 41 get :edit, :id => '3'
42 42 assert_response :success
43 43 assert_template 'edit'
44 44 end
45 45
46 46 def test_update
47 47 post :update, :id => '3', :issue_status => {:name => 'Renamed status'}
48 48 assert_redirected_to :action => 'index'
49 49 status = IssueStatus.find(3)
50 50 assert_equal 'Renamed status', status.name
51 51 end
52 52
53 53 def test_destroy
54 54 Issue.delete_all("status_id = 1")
55 55
56 56 assert_difference 'IssueStatus.count', -1 do
57 57 post :destroy, :id => '1'
58 58 end
59 59 assert_redirected_to :action => 'index'
60 60 assert_nil IssueStatus.find_by_id(1)
61 61 end
62 62
63 63 def test_destroy_should_block_if_status_in_use
64 64 assert_not_nil Issue.find_by_status_id(1)
65 65
66 66 assert_no_difference 'IssueStatus.count' do
67 67 post :destroy, :id => '1'
68 68 end
69 69 assert_redirected_to :action => 'index'
70 70 assert_not_nil IssueStatus.find_by_id(1)
71 71 end
72 72
73 73 context "on POST to :update_issue_done_ratio" do
74 74 context "with Setting.issue_done_ratio using the issue_field" do
75 75 setup do
76 76 Setting.issue_done_ratio = 'issue_field'
77 77 post :update_issue_done_ratio
78 78 end
79 79
80 80 should_set_the_flash_to /not updated/
81 81 should_redirect_to('the index') { '/issue_statuses' }
82 82 end
83 83
84 84 context "with Setting.issue_done_ratio using the issue_status" do
85 85 setup do
86 86 Setting.issue_done_ratio = 'issue_status'
87 87 post :update_issue_done_ratio
88 88 end
89 89
90 90 should_set_the_flash_to /Issue done ratios updated/
91 91 should_redirect_to('the index') { '/issue_statuses' }
92 92 end
93 93 end
94 94
95 95 end
@@ -1,1292 +1,1292
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'issues_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class IssuesController; def rescue_action(e) raise e end; end
23 23
24 24 class IssuesControllerTest < ActionController::TestCase
25 25 fixtures :projects,
26 26 :users,
27 27 :roles,
28 28 :members,
29 29 :member_roles,
30 30 :issues,
31 31 :issue_statuses,
32 32 :versions,
33 33 :trackers,
34 34 :projects_trackers,
35 35 :issue_categories,
36 36 :enabled_modules,
37 37 :enumerations,
38 38 :attachments,
39 39 :workflows,
40 40 :custom_fields,
41 41 :custom_values,
42 42 :custom_fields_projects,
43 43 :custom_fields_trackers,
44 44 :time_entries,
45 45 :journals,
46 46 :journal_details,
47 47 :queries
48 48
49 49 def setup
50 50 @controller = IssuesController.new
51 51 @request = ActionController::TestRequest.new
52 52 @response = ActionController::TestResponse.new
53 53 User.current = nil
54 54 end
55 55
56 56 def test_index
57 57 Setting.default_language = 'en'
58 58
59 59 get :index
60 60 assert_response :success
61 61 assert_template 'index.rhtml'
62 62 assert_not_nil assigns(:issues)
63 63 assert_nil assigns(:project)
64 64 assert_tag :tag => 'a', :content => /Can't print recipes/
65 65 assert_tag :tag => 'a', :content => /Subproject issue/
66 66 # private projects hidden
67 67 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
68 68 assert_no_tag :tag => 'a', :content => /Issue on project 2/
69 69 # project column
70 70 assert_tag :tag => 'th', :content => /Project/
71 71 end
72 72
73 73 def test_index_should_not_list_issues_when_module_disabled
74 74 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
75 75 get :index
76 76 assert_response :success
77 77 assert_template 'index.rhtml'
78 78 assert_not_nil assigns(:issues)
79 79 assert_nil assigns(:project)
80 80 assert_no_tag :tag => 'a', :content => /Can't print recipes/
81 81 assert_tag :tag => 'a', :content => /Subproject issue/
82 82 end
83 83
84 84 def test_index_should_not_list_issues_when_module_disabled
85 85 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
86 86 get :index
87 87 assert_response :success
88 88 assert_template 'index.rhtml'
89 89 assert_not_nil assigns(:issues)
90 90 assert_nil assigns(:project)
91 91 assert_no_tag :tag => 'a', :content => /Can't print recipes/
92 92 assert_tag :tag => 'a', :content => /Subproject issue/
93 93 end
94 94
95 95 def test_index_with_project
96 96 Setting.display_subprojects_issues = 0
97 97 get :index, :project_id => 1
98 98 assert_response :success
99 99 assert_template 'index.rhtml'
100 100 assert_not_nil assigns(:issues)
101 101 assert_tag :tag => 'a', :content => /Can't print recipes/
102 102 assert_no_tag :tag => 'a', :content => /Subproject issue/
103 103 end
104 104
105 105 def test_index_with_project_and_subprojects
106 106 Setting.display_subprojects_issues = 1
107 107 get :index, :project_id => 1
108 108 assert_response :success
109 109 assert_template 'index.rhtml'
110 110 assert_not_nil assigns(:issues)
111 111 assert_tag :tag => 'a', :content => /Can't print recipes/
112 112 assert_tag :tag => 'a', :content => /Subproject issue/
113 113 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
114 114 end
115 115
116 116 def test_index_with_project_and_subprojects_should_show_private_subprojects
117 117 @request.session[:user_id] = 2
118 118 Setting.display_subprojects_issues = 1
119 119 get :index, :project_id => 1
120 120 assert_response :success
121 121 assert_template 'index.rhtml'
122 122 assert_not_nil assigns(:issues)
123 123 assert_tag :tag => 'a', :content => /Can't print recipes/
124 124 assert_tag :tag => 'a', :content => /Subproject issue/
125 125 assert_tag :tag => 'a', :content => /Issue of a private subproject/
126 126 end
127 127
128 128 def test_index_with_project_and_default_filter
129 129 get :index, :project_id => 1, :set_filter => 1
130 130 assert_response :success
131 131 assert_template 'index.rhtml'
132 132 assert_not_nil assigns(:issues)
133 133
134 134 query = assigns(:query)
135 135 assert_not_nil query
136 136 # default filter
137 137 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
138 138 end
139 139
140 140 def test_index_with_project_and_filter
141 141 get :index, :project_id => 1, :set_filter => 1,
142 142 :fields => ['tracker_id'],
143 143 :operators => {'tracker_id' => '='},
144 144 :values => {'tracker_id' => ['1']}
145 145 assert_response :success
146 146 assert_template 'index.rhtml'
147 147 assert_not_nil assigns(:issues)
148 148
149 149 query = assigns(:query)
150 150 assert_not_nil query
151 151 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
152 152 end
153 153
154 154 def test_index_with_project_and_empty_filters
155 155 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
156 156 assert_response :success
157 157 assert_template 'index.rhtml'
158 158 assert_not_nil assigns(:issues)
159 159
160 160 query = assigns(:query)
161 161 assert_not_nil query
162 162 # no filter
163 163 assert_equal({}, query.filters)
164 164 end
165 165
166 166 def test_index_with_query
167 167 get :index, :project_id => 1, :query_id => 5
168 168 assert_response :success
169 169 assert_template 'index.rhtml'
170 170 assert_not_nil assigns(:issues)
171 171 assert_nil assigns(:issue_count_by_group)
172 172 end
173 173
174 174 def test_index_with_query_grouped_by_tracker
175 175 get :index, :project_id => 1, :query_id => 6
176 176 assert_response :success
177 177 assert_template 'index.rhtml'
178 178 assert_not_nil assigns(:issues)
179 179 assert_not_nil assigns(:issue_count_by_group)
180 180 end
181 181
182 182 def test_index_with_query_grouped_by_list_custom_field
183 183 get :index, :project_id => 1, :query_id => 9
184 184 assert_response :success
185 185 assert_template 'index.rhtml'
186 186 assert_not_nil assigns(:issues)
187 187 assert_not_nil assigns(:issue_count_by_group)
188 188 end
189 189
190 190 def test_index_sort_by_field_not_included_in_columns
191 191 Setting.issue_list_default_columns = %w(subject author)
192 192 get :index, :sort => 'tracker'
193 193 end
194 194
195 195 def test_index_csv_with_project
196 196 Setting.default_language = 'en'
197 197
198 198 get :index, :format => 'csv'
199 199 assert_response :success
200 200 assert_not_nil assigns(:issues)
201 201 assert_equal 'text/csv', @response.content_type
202 202 assert @response.body.starts_with?("#,")
203 203
204 204 get :index, :project_id => 1, :format => 'csv'
205 205 assert_response :success
206 206 assert_not_nil assigns(:issues)
207 207 assert_equal 'text/csv', @response.content_type
208 208 end
209 209
210 210 def test_index_pdf
211 211 get :index, :format => 'pdf'
212 212 assert_response :success
213 213 assert_not_nil assigns(:issues)
214 214 assert_equal 'application/pdf', @response.content_type
215 215
216 216 get :index, :project_id => 1, :format => 'pdf'
217 217 assert_response :success
218 218 assert_not_nil assigns(:issues)
219 219 assert_equal 'application/pdf', @response.content_type
220 220
221 221 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
222 222 assert_response :success
223 223 assert_not_nil assigns(:issues)
224 224 assert_equal 'application/pdf', @response.content_type
225 225 end
226 226
227 227 def test_index_pdf_with_query_grouped_by_list_custom_field
228 228 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
229 229 assert_response :success
230 230 assert_not_nil assigns(:issues)
231 231 assert_not_nil assigns(:issue_count_by_group)
232 232 assert_equal 'application/pdf', @response.content_type
233 233 end
234 234
235 235 def test_index_sort
236 236 get :index, :sort => 'tracker,id:desc'
237 237 assert_response :success
238 238
239 239 sort_params = @request.session['issues_index_sort']
240 240 assert sort_params.is_a?(String)
241 241 assert_equal 'tracker,id:desc', sort_params
242 242
243 243 issues = assigns(:issues)
244 244 assert_not_nil issues
245 245 assert !issues.empty?
246 246 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
247 247 end
248 248
249 249 def test_index_with_columns
250 250 columns = ['tracker', 'subject', 'assigned_to']
251 251 get :index, :set_filter => 1, :query => { 'column_names' => columns}
252 252 assert_response :success
253 253
254 254 # query should use specified columns
255 255 query = assigns(:query)
256 256 assert_kind_of Query, query
257 257 assert_equal columns, query.column_names.map(&:to_s)
258 258
259 259 # columns should be stored in session
260 260 assert_kind_of Hash, session[:query]
261 261 assert_kind_of Array, session[:query][:column_names]
262 262 assert_equal columns, session[:query][:column_names].map(&:to_s)
263 263 end
264 264
265 265 def test_show_by_anonymous
266 266 get :show, :id => 1
267 267 assert_response :success
268 268 assert_template 'show.rhtml'
269 269 assert_not_nil assigns(:issue)
270 270 assert_equal Issue.find(1), assigns(:issue)
271 271
272 272 # anonymous role is allowed to add a note
273 273 assert_tag :tag => 'form',
274 274 :descendant => { :tag => 'fieldset',
275 275 :child => { :tag => 'legend',
276 276 :content => /Notes/ } }
277 277 end
278 278
279 279 def test_show_by_manager
280 280 @request.session[:user_id] = 2
281 281 get :show, :id => 1
282 282 assert_response :success
283 283
284 284 assert_tag :tag => 'form',
285 285 :descendant => { :tag => 'fieldset',
286 286 :child => { :tag => 'legend',
287 287 :content => /Change properties/ } },
288 288 :descendant => { :tag => 'fieldset',
289 289 :child => { :tag => 'legend',
290 290 :content => /Log time/ } },
291 291 :descendant => { :tag => 'fieldset',
292 292 :child => { :tag => 'legend',
293 293 :content => /Notes/ } }
294 294 end
295 295
296 296 def test_show_should_deny_anonymous_access_without_permission
297 297 Role.anonymous.remove_permission!(:view_issues)
298 298 get :show, :id => 1
299 299 assert_response :redirect
300 300 end
301 301
302 302 def test_show_should_deny_non_member_access_without_permission
303 303 Role.non_member.remove_permission!(:view_issues)
304 304 @request.session[:user_id] = 9
305 305 get :show, :id => 1
306 306 assert_response 403
307 307 end
308 308
309 309 def test_show_should_deny_member_access_without_permission
310 310 Role.find(1).remove_permission!(:view_issues)
311 311 @request.session[:user_id] = 2
312 312 get :show, :id => 1
313 313 assert_response 403
314 314 end
315 315
316 316 def test_show_should_not_disclose_relations_to_invisible_issues
317 317 Setting.cross_project_issue_relations = '1'
318 318 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
319 319 # Relation to a private project issue
320 320 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
321 321
322 322 get :show, :id => 1
323 323 assert_response :success
324 324
325 325 assert_tag :div, :attributes => { :id => 'relations' },
326 326 :descendant => { :tag => 'a', :content => /#2$/ }
327 327 assert_no_tag :div, :attributes => { :id => 'relations' },
328 328 :descendant => { :tag => 'a', :content => /#4$/ }
329 329 end
330 330
331 331 def test_show_atom
332 332 get :show, :id => 2, :format => 'atom'
333 333 assert_response :success
334 334 assert_template 'journals/index.rxml'
335 335 # Inline image
336 336 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
337 337 end
338 338
339 339 def test_show_export_to_pdf
340 340 get :show, :id => 3, :format => 'pdf'
341 341 assert_response :success
342 342 assert_equal 'application/pdf', @response.content_type
343 343 assert @response.body.starts_with?('%PDF')
344 344 assert_not_nil assigns(:issue)
345 345 end
346 346
347 347 def test_get_new
348 348 @request.session[:user_id] = 2
349 349 get :new, :project_id => 1, :tracker_id => 1
350 350 assert_response :success
351 351 assert_template 'new'
352 352
353 353 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
354 354 :value => 'Default string' }
355 355 end
356 356
357 357 def test_get_new_without_tracker_id
358 358 @request.session[:user_id] = 2
359 359 get :new, :project_id => 1
360 360 assert_response :success
361 361 assert_template 'new'
362 362
363 363 issue = assigns(:issue)
364 364 assert_not_nil issue
365 365 assert_equal Project.find(1).trackers.first, issue.tracker
366 366 end
367 367
368 368 def test_get_new_with_no_default_status_should_display_an_error
369 369 @request.session[:user_id] = 2
370 370 IssueStatus.delete_all
371 371
372 372 get :new, :project_id => 1
373 373 assert_response 500
374 374 assert_error_tag :content => /No default issue/
375 375 end
376 376
377 377 def test_get_new_with_no_tracker_should_display_an_error
378 378 @request.session[:user_id] = 2
379 379 Tracker.delete_all
380 380
381 381 get :new, :project_id => 1
382 382 assert_response 500
383 383 assert_error_tag :content => /No tracker/
384 384 end
385 385
386 386 def test_update_new_form
387 387 @request.session[:user_id] = 2
388 388 xhr :post, :new, :project_id => 1,
389 389 :issue => {:tracker_id => 2,
390 390 :subject => 'This is the test_new issue',
391 391 :description => 'This is the description',
392 392 :priority_id => 5}
393 393 assert_response :success
394 394 assert_template 'attributes'
395 395
396 396 issue = assigns(:issue)
397 397 assert_kind_of Issue, issue
398 398 assert_equal 1, issue.project_id
399 399 assert_equal 2, issue.tracker_id
400 400 assert_equal 'This is the test_new issue', issue.subject
401 401 end
402 402
403 403 def test_post_create
404 404 @request.session[:user_id] = 2
405 405 assert_difference 'Issue.count' do
406 406 post :create, :project_id => 1,
407 407 :issue => {:tracker_id => 3,
408 408 :status_id => 2,
409 409 :subject => 'This is the test_new issue',
410 410 :description => 'This is the description',
411 411 :priority_id => 5,
412 412 :start_date => '2010-11-07',
413 413 :estimated_hours => '',
414 414 :custom_field_values => {'2' => 'Value for field 2'}}
415 415 end
416 416 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
417 417
418 418 issue = Issue.find_by_subject('This is the test_new issue')
419 419 assert_not_nil issue
420 420 assert_equal 2, issue.author_id
421 421 assert_equal 3, issue.tracker_id
422 422 assert_equal 2, issue.status_id
423 423 assert_equal Date.parse('2010-11-07'), issue.start_date
424 424 assert_nil issue.estimated_hours
425 425 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
426 426 assert_not_nil v
427 427 assert_equal 'Value for field 2', v.value
428 428 end
429 429
430 430 def test_post_create_without_start_date
431 431 @request.session[:user_id] = 2
432 432 assert_difference 'Issue.count' do
433 433 post :create, :project_id => 1,
434 434 :issue => {:tracker_id => 3,
435 435 :status_id => 2,
436 436 :subject => 'This is the test_new issue',
437 437 :description => 'This is the description',
438 438 :priority_id => 5,
439 439 :start_date => '',
440 440 :estimated_hours => '',
441 441 :custom_field_values => {'2' => 'Value for field 2'}}
442 442 end
443 443 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
444 444
445 445 issue = Issue.find_by_subject('This is the test_new issue')
446 446 assert_not_nil issue
447 447 assert_nil issue.start_date
448 448 end
449 449
450 450 def test_post_create_and_continue
451 451 @request.session[:user_id] = 2
452 452 post :create, :project_id => 1,
453 453 :issue => {:tracker_id => 3,
454 454 :subject => 'This is first issue',
455 455 :priority_id => 5},
456 456 :continue => ''
457 457 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook',
458 458 :issue => {:tracker_id => 3}
459 459 end
460 460
461 461 def test_post_create_without_custom_fields_param
462 462 @request.session[:user_id] = 2
463 463 assert_difference 'Issue.count' do
464 464 post :create, :project_id => 1,
465 465 :issue => {:tracker_id => 1,
466 466 :subject => 'This is the test_new issue',
467 467 :description => 'This is the description',
468 468 :priority_id => 5}
469 469 end
470 470 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
471 471 end
472 472
473 473 def test_post_create_with_required_custom_field_and_without_custom_fields_param
474 474 field = IssueCustomField.find_by_name('Database')
475 475 field.update_attribute(:is_required, true)
476 476
477 477 @request.session[:user_id] = 2
478 478 post :create, :project_id => 1,
479 479 :issue => {:tracker_id => 1,
480 480 :subject => 'This is the test_new issue',
481 481 :description => 'This is the description',
482 482 :priority_id => 5}
483 483 assert_response :success
484 484 assert_template 'new'
485 485 issue = assigns(:issue)
486 486 assert_not_nil issue
487 487 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
488 488 end
489 489
490 490 def test_post_create_with_watchers
491 491 @request.session[:user_id] = 2
492 492 ActionMailer::Base.deliveries.clear
493 493
494 494 assert_difference 'Watcher.count', 2 do
495 495 post :create, :project_id => 1,
496 496 :issue => {:tracker_id => 1,
497 497 :subject => 'This is a new issue with watchers',
498 498 :description => 'This is the description',
499 499 :priority_id => 5,
500 500 :watcher_user_ids => ['2', '3']}
501 501 end
502 502 issue = Issue.find_by_subject('This is a new issue with watchers')
503 503 assert_not_nil issue
504 504 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
505 505
506 506 # Watchers added
507 507 assert_equal [2, 3], issue.watcher_user_ids.sort
508 508 assert issue.watched_by?(User.find(3))
509 509 # Watchers notified
510 510 mail = ActionMailer::Base.deliveries.last
511 511 assert_kind_of TMail::Mail, mail
512 512 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
513 513 end
514 514
515 515 def test_post_create_subissue
516 516 @request.session[:user_id] = 2
517 517
518 518 assert_difference 'Issue.count' do
519 519 post :create, :project_id => 1,
520 520 :issue => {:tracker_id => 1,
521 521 :subject => 'This is a child issue',
522 522 :parent_issue_id => 2}
523 523 end
524 524 issue = Issue.find_by_subject('This is a child issue')
525 525 assert_not_nil issue
526 526 assert_equal Issue.find(2), issue.parent
527 527 end
528 528
529 529 def test_post_create_subissue_with_non_numeric_parent_id
530 530 @request.session[:user_id] = 2
531 531
532 532 assert_difference 'Issue.count' do
533 533 post :create, :project_id => 1,
534 534 :issue => {:tracker_id => 1,
535 535 :subject => 'This is a child issue',
536 536 :parent_issue_id => 'ABC'}
537 537 end
538 538 issue = Issue.find_by_subject('This is a child issue')
539 539 assert_not_nil issue
540 540 assert_nil issue.parent
541 541 end
542 542
543 543 def test_post_create_should_send_a_notification
544 544 ActionMailer::Base.deliveries.clear
545 545 @request.session[:user_id] = 2
546 546 assert_difference 'Issue.count' do
547 547 post :create, :project_id => 1,
548 548 :issue => {:tracker_id => 3,
549 549 :subject => 'This is the test_new issue',
550 550 :description => 'This is the description',
551 551 :priority_id => 5,
552 552 :estimated_hours => '',
553 553 :custom_field_values => {'2' => 'Value for field 2'}}
554 554 end
555 555 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
556 556
557 557 assert_equal 1, ActionMailer::Base.deliveries.size
558 558 end
559 559
560 560 def test_post_create_should_preserve_fields_values_on_validation_failure
561 561 @request.session[:user_id] = 2
562 562 post :create, :project_id => 1,
563 563 :issue => {:tracker_id => 1,
564 564 # empty subject
565 565 :subject => '',
566 566 :description => 'This is a description',
567 567 :priority_id => 6,
568 568 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
569 569 assert_response :success
570 570 assert_template 'new'
571 571
572 572 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
573 573 :content => 'This is a description'
574 574 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
575 575 :child => { :tag => 'option', :attributes => { :selected => 'selected',
576 576 :value => '6' },
577 577 :content => 'High' }
578 578 # Custom fields
579 579 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
580 580 :child => { :tag => 'option', :attributes => { :selected => 'selected',
581 581 :value => 'Oracle' },
582 582 :content => 'Oracle' }
583 583 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
584 584 :value => 'Value for field 2'}
585 585 end
586 586
587 587 def test_post_create_should_ignore_non_safe_attributes
588 588 @request.session[:user_id] = 2
589 589 assert_nothing_raised do
590 590 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
591 591 end
592 592 end
593 593
594 594 context "without workflow privilege" do
595 595 setup do
596 596 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
597 597 Role.anonymous.add_permission! :add_issues, :add_issue_notes
598 598 end
599 599
600 600 context "#new" do
601 601 should "propose default status only" do
602 602 get :new, :project_id => 1
603 603 assert_response :success
604 604 assert_template 'new'
605 605 assert_tag :tag => 'select',
606 606 :attributes => {:name => 'issue[status_id]'},
607 607 :children => {:count => 1},
608 608 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
609 609 end
610 610
611 611 should "accept default status" do
612 612 assert_difference 'Issue.count' do
613 613 post :create, :project_id => 1,
614 614 :issue => {:tracker_id => 1,
615 615 :subject => 'This is an issue',
616 616 :status_id => 1}
617 617 end
618 618 issue = Issue.last(:order => 'id')
619 619 assert_equal IssueStatus.default, issue.status
620 620 end
621 621
622 622 should "accept default status" do
623 623 assert_difference 'Issue.count' do
624 624 post :create, :project_id => 1,
625 625 :issue => {:tracker_id => 1,
626 626 :subject => 'This is an issue',
627 627 :status_id => 1}
628 628 end
629 629 issue = Issue.last(:order => 'id')
630 630 assert_equal IssueStatus.default, issue.status
631 631 end
632 632
633 633 should "ignore unauthorized status" do
634 634 assert_difference 'Issue.count' do
635 635 post :create, :project_id => 1,
636 636 :issue => {:tracker_id => 1,
637 637 :subject => 'This is an issue',
638 638 :status_id => 3}
639 639 end
640 640 issue = Issue.last(:order => 'id')
641 641 assert_equal IssueStatus.default, issue.status
642 642 end
643 643 end
644 644
645 645 context "#update" do
646 646 should "ignore status change" do
647 647 assert_difference 'Journal.count' do
648 648 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
649 649 end
650 650 assert_equal 1, Issue.find(1).status_id
651 651 end
652 652
653 653 should "ignore attributes changes" do
654 654 assert_difference 'Journal.count' do
655 655 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
656 656 end
657 657 issue = Issue.find(1)
658 658 assert_equal "Can't print recipes", issue.subject
659 659 assert_nil issue.assigned_to
660 660 end
661 661 end
662 662 end
663 663
664 664 context "with workflow privilege" do
665 665 setup do
666 666 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
667 667 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
668 668 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
669 669 Role.anonymous.add_permission! :add_issues, :add_issue_notes
670 670 end
671 671
672 672 context "#update" do
673 673 should "accept authorized status" do
674 674 assert_difference 'Journal.count' do
675 675 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
676 676 end
677 677 assert_equal 3, Issue.find(1).status_id
678 678 end
679 679
680 680 should "ignore unauthorized status" do
681 681 assert_difference 'Journal.count' do
682 682 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
683 683 end
684 684 assert_equal 1, Issue.find(1).status_id
685 685 end
686 686
687 687 should "accept authorized attributes changes" do
688 688 assert_difference 'Journal.count' do
689 689 put :update, :id => 1, :notes => 'just trying', :issue => {:assigned_to_id => 2}
690 690 end
691 691 issue = Issue.find(1)
692 692 assert_equal 2, issue.assigned_to_id
693 693 end
694 694
695 695 should "ignore unauthorized attributes changes" do
696 696 assert_difference 'Journal.count' do
697 697 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed'}
698 698 end
699 699 issue = Issue.find(1)
700 700 assert_equal "Can't print recipes", issue.subject
701 701 end
702 702 end
703 703
704 704 context "and :edit_issues permission" do
705 705 setup do
706 706 Role.anonymous.add_permission! :add_issues, :edit_issues
707 707 end
708 708
709 709 should "accept authorized status" do
710 710 assert_difference 'Journal.count' do
711 711 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
712 712 end
713 713 assert_equal 3, Issue.find(1).status_id
714 714 end
715 715
716 716 should "ignore unauthorized status" do
717 717 assert_difference 'Journal.count' do
718 718 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
719 719 end
720 720 assert_equal 1, Issue.find(1).status_id
721 721 end
722 722
723 723 should "accept authorized attributes changes" do
724 724 assert_difference 'Journal.count' do
725 725 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
726 726 end
727 727 issue = Issue.find(1)
728 728 assert_equal "changed", issue.subject
729 729 assert_equal 2, issue.assigned_to_id
730 730 end
731 731 end
732 732 end
733 733
734 734 def test_copy_issue
735 735 @request.session[:user_id] = 2
736 736 get :new, :project_id => 1, :copy_from => 1
737 737 assert_template 'new'
738 738 assert_not_nil assigns(:issue)
739 739 orig = Issue.find(1)
740 740 assert_equal orig.subject, assigns(:issue).subject
741 741 end
742 742
743 743 def test_get_edit
744 744 @request.session[:user_id] = 2
745 745 get :edit, :id => 1
746 746 assert_response :success
747 747 assert_template 'edit'
748 748 assert_not_nil assigns(:issue)
749 749 assert_equal Issue.find(1), assigns(:issue)
750 750 end
751 751
752 752 def test_get_edit_with_params
753 753 @request.session[:user_id] = 2
754 754 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
755 755 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
756 756 assert_response :success
757 757 assert_template 'edit'
758 758
759 759 issue = assigns(:issue)
760 760 assert_not_nil issue
761 761
762 762 assert_equal 5, issue.status_id
763 763 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
764 764 :child => { :tag => 'option',
765 765 :content => 'Closed',
766 766 :attributes => { :selected => 'selected' } }
767 767
768 768 assert_equal 7, issue.priority_id
769 769 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
770 770 :child => { :tag => 'option',
771 771 :content => 'Urgent',
772 772 :attributes => { :selected => 'selected' } }
773 773
774 774 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
775 775 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
776 776 :child => { :tag => 'option',
777 777 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
778 778 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
779 779 end
780 780
781 781 def test_update_edit_form
782 782 @request.session[:user_id] = 2
783 783 xhr :post, :new, :project_id => 1,
784 784 :id => 1,
785 785 :issue => {:tracker_id => 2,
786 786 :subject => 'This is the test_new issue',
787 787 :description => 'This is the description',
788 788 :priority_id => 5}
789 789 assert_response :success
790 790 assert_template 'attributes'
791 791
792 792 issue = assigns(:issue)
793 793 assert_kind_of Issue, issue
794 794 assert_equal 1, issue.id
795 795 assert_equal 1, issue.project_id
796 796 assert_equal 2, issue.tracker_id
797 797 assert_equal 'This is the test_new issue', issue.subject
798 798 end
799 799
800 800 def test_update_using_invalid_http_verbs
801 801 @request.session[:user_id] = 2
802 802 subject = 'Updated by an invalid http verb'
803 803
804 804 get :update, :id => 1, :issue => {:subject => subject}
805 805 assert_not_equal subject, Issue.find(1).subject
806 806
807 807 post :update, :id => 1, :issue => {:subject => subject}
808 808 assert_not_equal subject, Issue.find(1).subject
809 809
810 810 delete :update, :id => 1, :issue => {:subject => subject}
811 811 assert_not_equal subject, Issue.find(1).subject
812 812 end
813 813
814 814 def test_put_update_without_custom_fields_param
815 815 @request.session[:user_id] = 2
816 816 ActionMailer::Base.deliveries.clear
817 817
818 818 issue = Issue.find(1)
819 819 assert_equal '125', issue.custom_value_for(2).value
820 820 old_subject = issue.subject
821 821 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
822 822
823 823 assert_difference('Journal.count') do
824 824 assert_difference('JournalDetail.count', 2) do
825 825 put :update, :id => 1, :issue => {:subject => new_subject,
826 826 :priority_id => '6',
827 827 :category_id => '1' # no change
828 828 }
829 829 end
830 830 end
831 831 assert_redirected_to :action => 'show', :id => '1'
832 832 issue.reload
833 833 assert_equal new_subject, issue.subject
834 834 # Make sure custom fields were not cleared
835 835 assert_equal '125', issue.custom_value_for(2).value
836 836
837 837 mail = ActionMailer::Base.deliveries.last
838 838 assert_kind_of TMail::Mail, mail
839 839 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
840 840 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
841 841 end
842 842
843 843 def test_put_update_with_custom_field_change
844 844 @request.session[:user_id] = 2
845 845 issue = Issue.find(1)
846 846 assert_equal '125', issue.custom_value_for(2).value
847 847
848 848 assert_difference('Journal.count') do
849 849 assert_difference('JournalDetail.count', 3) do
850 850 put :update, :id => 1, :issue => {:subject => 'Custom field change',
851 851 :priority_id => '6',
852 852 :category_id => '1', # no change
853 853 :custom_field_values => { '2' => 'New custom value' }
854 854 }
855 855 end
856 856 end
857 857 assert_redirected_to :action => 'show', :id => '1'
858 858 issue.reload
859 859 assert_equal 'New custom value', issue.custom_value_for(2).value
860 860
861 861 mail = ActionMailer::Base.deliveries.last
862 862 assert_kind_of TMail::Mail, mail
863 863 assert mail.body.include?("Searchable field changed from 125 to New custom value")
864 864 end
865 865
866 866 def test_put_update_with_status_and_assignee_change
867 867 issue = Issue.find(1)
868 868 assert_equal 1, issue.status_id
869 869 @request.session[:user_id] = 2
870 870 assert_difference('TimeEntry.count', 0) do
871 871 put :update,
872 872 :id => 1,
873 873 :issue => { :status_id => 2, :assigned_to_id => 3 },
874 874 :notes => 'Assigned to dlopper',
875 875 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
876 876 end
877 877 assert_redirected_to :action => 'show', :id => '1'
878 878 issue.reload
879 879 assert_equal 2, issue.status_id
880 880 j = Journal.find(:first, :order => 'id DESC')
881 881 assert_equal 'Assigned to dlopper', j.notes
882 882 assert_equal 2, j.details.size
883 883
884 884 mail = ActionMailer::Base.deliveries.last
885 885 assert mail.body.include?("Status changed from New to Assigned")
886 886 # subject should contain the new status
887 887 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
888 888 end
889 889
890 890 def test_put_update_with_note_only
891 891 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
892 892 # anonymous user
893 893 put :update,
894 894 :id => 1,
895 895 :notes => notes
896 896 assert_redirected_to :action => 'show', :id => '1'
897 897 j = Journal.find(:first, :order => 'id DESC')
898 898 assert_equal notes, j.notes
899 899 assert_equal 0, j.details.size
900 900 assert_equal User.anonymous, j.user
901 901
902 902 mail = ActionMailer::Base.deliveries.last
903 903 assert mail.body.include?(notes)
904 904 end
905 905
906 906 def test_put_update_with_note_and_spent_time
907 907 @request.session[:user_id] = 2
908 908 spent_hours_before = Issue.find(1).spent_hours
909 909 assert_difference('TimeEntry.count') do
910 910 put :update,
911 911 :id => 1,
912 912 :notes => '2.5 hours added',
913 913 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
914 914 end
915 915 assert_redirected_to :action => 'show', :id => '1'
916 916
917 917 issue = Issue.find(1)
918 918
919 919 j = Journal.find(:first, :order => 'id DESC')
920 920 assert_equal '2.5 hours added', j.notes
921 921 assert_equal 0, j.details.size
922 922
923 923 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
924 924 assert_not_nil t
925 925 assert_equal 2.5, t.hours
926 926 assert_equal spent_hours_before + 2.5, issue.spent_hours
927 927 end
928 928
929 929 def test_put_update_with_attachment_only
930 930 set_tmp_attachments_directory
931 931
932 932 # Delete all fixtured journals, a race condition can occur causing the wrong
933 933 # journal to get fetched in the next find.
934 934 Journal.delete_all
935 935
936 936 # anonymous user
937 937 put :update,
938 938 :id => 1,
939 939 :notes => '',
940 940 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
941 941 assert_redirected_to :action => 'show', :id => '1'
942 942 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
943 943 assert j.notes.blank?
944 944 assert_equal 1, j.details.size
945 945 assert_equal 'testfile.txt', j.details.first.value
946 946 assert_equal User.anonymous, j.user
947 947
948 948 mail = ActionMailer::Base.deliveries.last
949 949 assert mail.body.include?('testfile.txt')
950 950 end
951 951
952 952 def test_put_update_with_attachment_that_fails_to_save
953 953 set_tmp_attachments_directory
954 954
955 955 # Delete all fixtured journals, a race condition can occur causing the wrong
956 956 # journal to get fetched in the next find.
957 957 Journal.delete_all
958 958
959 959 # Mock out the unsaved attachment
960 960 Attachment.any_instance.stubs(:create).returns(Attachment.new)
961 961
962 962 # anonymous user
963 963 put :update,
964 964 :id => 1,
965 965 :notes => '',
966 966 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
967 967 assert_redirected_to :action => 'show', :id => '1'
968 968 assert_equal '1 file(s) could not be saved.', flash[:warning]
969 969
970 970 end if Object.const_defined?(:Mocha)
971 971
972 972 def test_put_update_with_no_change
973 973 issue = Issue.find(1)
974 974 issue.journals.clear
975 975 ActionMailer::Base.deliveries.clear
976 976
977 977 put :update,
978 978 :id => 1,
979 979 :notes => ''
980 980 assert_redirected_to :action => 'show', :id => '1'
981 981
982 982 issue.reload
983 983 assert issue.journals.empty?
984 984 # No email should be sent
985 985 assert ActionMailer::Base.deliveries.empty?
986 986 end
987 987
988 988 def test_put_update_should_send_a_notification
989 989 @request.session[:user_id] = 2
990 990 ActionMailer::Base.deliveries.clear
991 991 issue = Issue.find(1)
992 992 old_subject = issue.subject
993 993 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
994 994
995 995 put :update, :id => 1, :issue => {:subject => new_subject,
996 996 :priority_id => '6',
997 997 :category_id => '1' # no change
998 998 }
999 999 assert_equal 1, ActionMailer::Base.deliveries.size
1000 1000 end
1001 1001
1002 1002 def test_put_update_with_invalid_spent_time
1003 1003 @request.session[:user_id] = 2
1004 1004 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
1005 1005
1006 1006 assert_no_difference('Journal.count') do
1007 1007 put :update,
1008 1008 :id => 1,
1009 1009 :notes => notes,
1010 1010 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
1011 1011 end
1012 1012 assert_response :success
1013 1013 assert_template 'edit'
1014 1014
1015 1015 assert_tag :textarea, :attributes => { :name => 'notes' },
1016 1016 :content => notes
1017 1017 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
1018 1018 end
1019 1019
1020 1020 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
1021 1021 issue = Issue.find(2)
1022 1022 @request.session[:user_id] = 2
1023 1023
1024 1024 put :update,
1025 1025 :id => issue.id,
1026 1026 :issue => {
1027 1027 :fixed_version_id => 4
1028 1028 }
1029 1029
1030 1030 assert_response :redirect
1031 1031 issue.reload
1032 1032 assert_equal 4, issue.fixed_version_id
1033 1033 assert_not_equal issue.project_id, issue.fixed_version.project_id
1034 1034 end
1035 1035
1036 1036 def test_put_update_should_redirect_back_using_the_back_url_parameter
1037 1037 issue = Issue.find(2)
1038 1038 @request.session[:user_id] = 2
1039 1039
1040 1040 put :update,
1041 1041 :id => issue.id,
1042 1042 :issue => {
1043 1043 :fixed_version_id => 4
1044 1044 },
1045 1045 :back_url => '/issues'
1046 1046
1047 1047 assert_response :redirect
1048 1048 assert_redirected_to '/issues'
1049 1049 end
1050 1050
1051 1051 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
1052 1052 issue = Issue.find(2)
1053 1053 @request.session[:user_id] = 2
1054 1054
1055 1055 put :update,
1056 1056 :id => issue.id,
1057 1057 :issue => {
1058 1058 :fixed_version_id => 4
1059 1059 },
1060 1060 :back_url => 'http://google.com'
1061 1061
1062 1062 assert_response :redirect
1063 1063 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
1064 1064 end
1065 1065
1066 1066 def test_get_bulk_edit
1067 1067 @request.session[:user_id] = 2
1068 1068 get :bulk_edit, :ids => [1, 2]
1069 1069 assert_response :success
1070 1070 assert_template 'bulk_edit'
1071 1071
1072 1072 # Project specific custom field, date type
1073 1073 field = CustomField.find(9)
1074 1074 assert !field.is_for_all?
1075 1075 assert_equal 'date', field.field_format
1076 1076 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
1077 1077
1078 1078 # System wide custom field
1079 1079 assert CustomField.find(1).is_for_all?
1080 1080 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
1081 1081 end
1082 1082
1083 1083 def test_get_bulk_edit_on_different_projects
1084 1084 @request.session[:user_id] = 2
1085 1085 get :bulk_edit, :ids => [1, 2, 6]
1086 1086 assert_response :success
1087 1087 assert_template 'bulk_edit'
1088 1088
1089 1089 # Project specific custom field, date type
1090 1090 field = CustomField.find(9)
1091 1091 assert !field.is_for_all?
1092 1092 assert !field.project_ids.include?(Issue.find(6).project_id)
1093 1093 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
1094 1094 end
1095 1095
1096 1096 def test_bulk_update
1097 1097 @request.session[:user_id] = 2
1098 1098 # update issues priority
1099 1099 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
1100 1100 :issue => {:priority_id => 7,
1101 1101 :assigned_to_id => '',
1102 1102 :custom_field_values => {'2' => ''}}
1103 1103
1104 1104 assert_response 302
1105 1105 # check that the issues were updated
1106 1106 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
1107 1107
1108 1108 issue = Issue.find(1)
1109 1109 journal = issue.journals.find(:first, :order => 'created_on DESC')
1110 1110 assert_equal '125', issue.custom_value_for(2).value
1111 1111 assert_equal 'Bulk editing', journal.notes
1112 1112 assert_equal 1, journal.details.size
1113 1113 end
1114 1114
1115 1115 def test_bulk_update_on_different_projects
1116 1116 @request.session[:user_id] = 2
1117 1117 # update issues priority
1118 1118 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
1119 1119 :issue => {:priority_id => 7,
1120 1120 :assigned_to_id => '',
1121 1121 :custom_field_values => {'2' => ''}}
1122 1122
1123 1123 assert_response 302
1124 1124 # check that the issues were updated
1125 1125 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
1126 1126
1127 1127 issue = Issue.find(1)
1128 1128 journal = issue.journals.find(:first, :order => 'created_on DESC')
1129 1129 assert_equal '125', issue.custom_value_for(2).value
1130 1130 assert_equal 'Bulk editing', journal.notes
1131 1131 assert_equal 1, journal.details.size
1132 1132 end
1133 1133
1134 1134 def test_bulk_update_on_different_projects_without_rights
1135 1135 @request.session[:user_id] = 3
1136 1136 user = User.find(3)
1137 1137 action = { :controller => "issues", :action => "bulk_update" }
1138 1138 assert user.allowed_to?(action, Issue.find(1).project)
1139 1139 assert ! user.allowed_to?(action, Issue.find(6).project)
1140 1140 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
1141 1141 :issue => {:priority_id => 7,
1142 1142 :assigned_to_id => '',
1143 1143 :custom_field_values => {'2' => ''}}
1144 1144 assert_response 403
1145 1145 assert_not_equal "Bulk should fail", Journal.last.notes
1146 1146 end
1147 1147
1148 1148 def test_bullk_update_should_send_a_notification
1149 1149 @request.session[:user_id] = 2
1150 1150 ActionMailer::Base.deliveries.clear
1151 1151 post(:bulk_update,
1152 1152 {
1153 1153 :ids => [1, 2],
1154 1154 :notes => 'Bulk editing',
1155 1155 :issue => {
1156 1156 :priority_id => 7,
1157 1157 :assigned_to_id => '',
1158 1158 :custom_field_values => {'2' => ''}
1159 1159 }
1160 1160 })
1161 1161
1162 1162 assert_response 302
1163 1163 assert_equal 2, ActionMailer::Base.deliveries.size
1164 1164 end
1165 1165
1166 1166 def test_bulk_update_status
1167 1167 @request.session[:user_id] = 2
1168 1168 # update issues priority
1169 1169 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
1170 1170 :issue => {:priority_id => '',
1171 1171 :assigned_to_id => '',
1172 1172 :status_id => '5'}
1173 1173
1174 1174 assert_response 302
1175 1175 issue = Issue.find(1)
1176 1176 assert issue.closed?
1177 1177 end
1178 1178
1179 1179 def test_bulk_update_custom_field
1180 1180 @request.session[:user_id] = 2
1181 1181 # update issues priority
1182 1182 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
1183 1183 :issue => {:priority_id => '',
1184 1184 :assigned_to_id => '',
1185 1185 :custom_field_values => {'2' => '777'}}
1186 1186
1187 1187 assert_response 302
1188 1188
1189 1189 issue = Issue.find(1)
1190 1190 journal = issue.journals.find(:first, :order => 'created_on DESC')
1191 1191 assert_equal '777', issue.custom_value_for(2).value
1192 1192 assert_equal 1, journal.details.size
1193 1193 assert_equal '125', journal.details.first.old_value
1194 1194 assert_equal '777', journal.details.first.value
1195 1195 end
1196 1196
1197 1197 def test_bulk_update_unassign
1198 1198 assert_not_nil Issue.find(2).assigned_to
1199 1199 @request.session[:user_id] = 2
1200 1200 # unassign issues
1201 1201 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
1202 1202 assert_response 302
1203 1203 # check that the issues were updated
1204 1204 assert_nil Issue.find(2).assigned_to
1205 1205 end
1206 1206
1207 1207 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
1208 1208 @request.session[:user_id] = 2
1209 1209
1210 1210 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
1211 1211
1212 1212 assert_response :redirect
1213 1213 issues = Issue.find([1,2])
1214 1214 issues.each do |issue|
1215 1215 assert_equal 4, issue.fixed_version_id
1216 1216 assert_not_equal issue.project_id, issue.fixed_version.project_id
1217 1217 end
1218 1218 end
1219 1219
1220 1220 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
1221 1221 @request.session[:user_id] = 2
1222 1222 post :bulk_update, :ids => [1,2], :back_url => '/issues'
1223 1223
1224 1224 assert_response :redirect
1225 1225 assert_redirected_to '/issues'
1226 1226 end
1227 1227
1228 1228 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
1229 1229 @request.session[:user_id] = 2
1230 1230 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
1231 1231
1232 1232 assert_response :redirect
1233 1233 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
1234 1234 end
1235 1235
1236 1236 def test_destroy_issue_with_no_time_entries
1237 1237 assert_nil TimeEntry.find_by_issue_id(2)
1238 1238 @request.session[:user_id] = 2
1239 1239 post :destroy, :id => 2
1240 1240 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1241 1241 assert_nil Issue.find_by_id(2)
1242 1242 end
1243 1243
1244 1244 def test_destroy_issues_with_time_entries
1245 1245 @request.session[:user_id] = 2
1246 1246 post :destroy, :ids => [1, 3]
1247 1247 assert_response :success
1248 1248 assert_template 'destroy'
1249 1249 assert_not_nil assigns(:hours)
1250 1250 assert Issue.find_by_id(1) && Issue.find_by_id(3)
1251 1251 end
1252 1252
1253 1253 def test_destroy_issues_and_destroy_time_entries
1254 1254 @request.session[:user_id] = 2
1255 1255 post :destroy, :ids => [1, 3], :todo => 'destroy'
1256 1256 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1257 1257 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1258 1258 assert_nil TimeEntry.find_by_id([1, 2])
1259 1259 end
1260 1260
1261 1261 def test_destroy_issues_and_assign_time_entries_to_project
1262 1262 @request.session[:user_id] = 2
1263 1263 post :destroy, :ids => [1, 3], :todo => 'nullify'
1264 1264 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1265 1265 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1266 1266 assert_nil TimeEntry.find(1).issue_id
1267 1267 assert_nil TimeEntry.find(2).issue_id
1268 1268 end
1269 1269
1270 1270 def test_destroy_issues_and_reassign_time_entries_to_another_issue
1271 1271 @request.session[:user_id] = 2
1272 1272 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
1273 1273 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1274 1274 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1275 1275 assert_equal 2, TimeEntry.find(1).issue_id
1276 1276 assert_equal 2, TimeEntry.find(2).issue_id
1277 1277 end
1278 1278
1279 1279 def test_destroy_issues_from_different_projects
1280 1280 @request.session[:user_id] = 2
1281 1281 post :destroy, :ids => [1, 2, 6], :todo => 'destroy'
1282 1282 assert_redirected_to :controller => 'issues', :action => 'index'
1283 1283 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
1284 1284 end
1285 1285
1286 1286 def test_default_search_scope
1287 1287 get :index
1288 1288 assert_tag :div, :attributes => {:id => 'quick-search'},
1289 1289 :child => {:tag => 'form',
1290 1290 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
1291 1291 end
1292 1292 end
@@ -1,83 +1,83
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'issues_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class IssuesController; def rescue_action(e) raise e end; end
23 23
24 24 class IssuesControllerTransactionTest < ActionController::TestCase
25 25 fixtures :projects,
26 26 :users,
27 27 :roles,
28 28 :members,
29 29 :member_roles,
30 30 :issues,
31 31 :issue_statuses,
32 32 :versions,
33 33 :trackers,
34 34 :projects_trackers,
35 35 :issue_categories,
36 36 :enabled_modules,
37 37 :enumerations,
38 38 :attachments,
39 39 :workflows,
40 40 :custom_fields,
41 41 :custom_values,
42 42 :custom_fields_projects,
43 43 :custom_fields_trackers,
44 44 :time_entries,
45 45 :journals,
46 46 :journal_details,
47 47 :queries
48 48
49 49 self.use_transactional_fixtures = false
50 50
51 51 def setup
52 52 @controller = IssuesController.new
53 53 @request = ActionController::TestRequest.new
54 54 @response = ActionController::TestResponse.new
55 55 User.current = nil
56 56 end
57 57
58 58 def test_put_update_stale_issue
59 59 issue = Issue.find(2)
60 60 @request.session[:user_id] = 2
61 61
62 62 assert_no_difference 'Journal.count' do
63 63 assert_no_difference 'TimeEntry.count' do
64 64 assert_no_difference 'Attachment.count' do
65 65 put :update,
66 66 :id => issue.id,
67 67 :issue => {
68 68 :fixed_version_id => 4,
69 69 :lock_version => (issue.lock_version - 1)
70 70 },
71 71 :notes => '',
72 72 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}},
73 73 :time_entry => { :hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first.id }
74 74 end
75 75 end
76 76 end
77 77
78 78 assert_response :success
79 79 assert_template 'edit'
80 80 assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' },
81 81 :content => /Data has been updated by another user/
82 82 end
83 83 end
@@ -1,80 +1,80
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'journals_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class JournalsController; def rescue_action(e) raise e end; end
23 23
24 24 class JournalsControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :members, :member_roles, :roles, :issues, :journals, :journal_details, :enabled_modules
26 26
27 27 def setup
28 28 @controller = JournalsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_index
35 35 get :index, :project_id => 1
36 36 assert_response :success
37 37 assert_not_nil assigns(:journals)
38 38 assert_equal 'application/atom+xml', @response.content_type
39 39 end
40 40
41 41 def test_reply_to_issue
42 42 @request.session[:user_id] = 2
43 43 get :new, :id => 1
44 44 assert_response :success
45 45 assert_select_rjs :show, "update"
46 46 end
47 47
48 48 def test_reply_to_note
49 49 @request.session[:user_id] = 2
50 50 get :new, :id => 1, :journal_id => 2
51 51 assert_response :success
52 52 assert_select_rjs :show, "update"
53 53 end
54 54
55 55 def test_get_edit
56 56 @request.session[:user_id] = 1
57 57 xhr :get, :edit, :id => 2
58 58 assert_response :success
59 59 assert_select_rjs :insert, :after, 'journal-2-notes' do
60 60 assert_select 'form[id=journal-2-form]'
61 61 assert_select 'textarea'
62 62 end
63 63 end
64 64
65 65 def test_post_edit
66 66 @request.session[:user_id] = 1
67 67 xhr :post, :edit, :id => 2, :notes => 'Updated notes'
68 68 assert_response :success
69 69 assert_select_rjs :replace, 'journal-2-notes'
70 70 assert_equal 'Updated notes', Journal.find(2).notes
71 71 end
72 72
73 73 def test_post_edit_with_empty_notes
74 74 @request.session[:user_id] = 1
75 75 xhr :post, :edit, :id => 2, :notes => ''
76 76 assert_response :success
77 77 assert_select_rjs :remove, 'change-2'
78 78 assert_nil Journal.find_by_id(2)
79 79 end
80 80 end
@@ -1,53 +1,53
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'mail_handler_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class MailHandlerController; def rescue_action(e) raise e end; end
23 23
24 24 class MailHandlerControllerTest < ActionController::TestCase
25 25 fixtures :users, :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :issue_statuses, :trackers, :enumerations
26 26
27 27 FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
28 28
29 29 def setup
30 30 @controller = MailHandlerController.new
31 31 @request = ActionController::TestRequest.new
32 32 @response = ActionController::TestResponse.new
33 33 User.current = nil
34 34 end
35 35
36 36 def test_should_create_issue
37 37 # Enable API and set a key
38 38 Setting.mail_handler_api_enabled = 1
39 39 Setting.mail_handler_api_key = 'secret'
40 40
41 41 post :index, :key => 'secret', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
42 42 assert_response 201
43 43 end
44 44
45 45 def test_should_not_allow
46 46 # Disable API
47 47 Setting.mail_handler_api_enabled = 0
48 48 Setting.mail_handler_api_key = 'secret'
49 49
50 50 post :index, :key => 'secret', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
51 51 assert_response 403
52 52 end
53 53 end
@@ -1,109 +1,109
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'members_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class MembersController; def rescue_action(e) raise e end; end
23 23
24 24
25 25 class MembersControllerTest < ActionController::TestCase
26 26 fixtures :projects, :members, :member_roles, :roles, :users
27 27
28 28 def setup
29 29 @controller = MembersController.new
30 30 @request = ActionController::TestRequest.new
31 31 @response = ActionController::TestResponse.new
32 32 User.current = nil
33 33 @request.session[:user_id] = 2
34 34 end
35 35
36 36 def test_create
37 37 assert_difference 'Member.count' do
38 38 post :new, :id => 1, :member => {:role_ids => [1], :user_id => 7}
39 39 end
40 40 assert_redirected_to '/projects/ecookbook/settings/members'
41 41 assert User.find(7).member_of?(Project.find(1))
42 42 end
43 43
44 44 def test_create_multiple
45 45 assert_difference 'Member.count', 3 do
46 46 post :new, :id => 1, :member => {:role_ids => [1], :user_ids => [7, 8, 9]}
47 47 end
48 48 assert_redirected_to '/projects/ecookbook/settings/members'
49 49 assert User.find(7).member_of?(Project.find(1))
50 50 end
51 51
52 52 context "post :new in JS format" do
53 53 context "with successful saves" do
54 54 should "add membership for each user" do
55 55 post :new, :format => "js", :id => 1, :member => {:role_ids => [1], :user_ids => [7, 8, 9]}
56 56
57 57 assert User.find(7).member_of?(Project.find(1))
58 58 assert User.find(8).member_of?(Project.find(1))
59 59 assert User.find(9).member_of?(Project.find(1))
60 60 end
61 61
62 62 should "replace the tab with RJS" do
63 63 post :new, :format => "js", :id => 1, :member => {:role_ids => [1], :user_ids => [7, 8, 9]}
64 64
65 65 assert_select_rjs :replace_html, 'tab-content-members'
66 66 end
67 67
68 68 end
69 69
70 70 context "with a failed save" do
71 71 should "not replace the tab with RJS" do
72 72 post :new, :format => "js", :id => 1, :member => {:role_ids => [], :user_ids => [7, 8, 9]}
73 73
74 74 assert_select '#tab-content-members', 0
75 75 end
76 76
77 77 should "open an error message" do
78 78 post :new, :format => "js", :id => 1, :member => {:role_ids => [], :user_ids => [7, 8, 9]}
79 79
80 80 assert @response.body.match(/alert/i), "Alert message not sent"
81 81 end
82 82 end
83 83
84 84 end
85 85
86 86 def test_edit
87 87 assert_no_difference 'Member.count' do
88 88 post :edit, :id => 2, :member => {:role_ids => [1], :user_id => 3}
89 89 end
90 90 assert_redirected_to '/projects/ecookbook/settings/members'
91 91 end
92 92
93 93 def test_destroy
94 94 assert_difference 'Member.count', -1 do
95 95 post :destroy, :id => 2
96 96 end
97 97 assert_redirected_to '/projects/ecookbook/settings/members'
98 98 assert !User.find(3).member_of?(Project.find(1))
99 99 end
100 100
101 101 def test_autocomplete_for_member
102 102 get :autocomplete_for_member, :id => 1, :q => 'mis'
103 103 assert_response :success
104 104 assert_template 'autocomplete_for_member'
105 105
106 106 assert_tag :label, :content => /User Misc/,
107 107 :child => { :tag => 'input', :attributes => { :name => 'member[user_ids][]', :value => '8' } }
108 108 end
109 109 end
@@ -1,144 +1,144
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'messages_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class MessagesController; def rescue_action(e) raise e end; end
23 23
24 24 class MessagesControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
26 26
27 27 def setup
28 28 @controller = MessagesController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_show
35 35 get :show, :board_id => 1, :id => 1
36 36 assert_response :success
37 37 assert_template 'show'
38 38 assert_not_nil assigns(:board)
39 39 assert_not_nil assigns(:project)
40 40 assert_not_nil assigns(:topic)
41 41 end
42 42
43 43 def test_show_with_pagination
44 44 message = Message.find(1)
45 45 assert_difference 'Message.count', 30 do
46 46 30.times do
47 47 message.children << Message.new(:subject => 'Reply', :content => 'Reply body', :author_id => 2, :board_id => 1)
48 48 end
49 49 end
50 50 get :show, :board_id => 1, :id => 1, :r => message.children.last(:order => 'id').id
51 51 assert_response :success
52 52 assert_template 'show'
53 53 replies = assigns(:replies)
54 54 assert_not_nil replies
55 55 assert !replies.include?(message.children.first(:order => 'id'))
56 56 assert replies.include?(message.children.last(:order => 'id'))
57 57 end
58 58
59 59 def test_show_with_reply_permission
60 60 @request.session[:user_id] = 2
61 61 get :show, :board_id => 1, :id => 1
62 62 assert_response :success
63 63 assert_template 'show'
64 64 assert_tag :div, :attributes => { :id => 'reply' },
65 65 :descendant => { :tag => 'textarea', :attributes => { :id => 'message_content' } }
66 66 end
67 67
68 68 def test_show_message_not_found
69 69 get :show, :board_id => 1, :id => 99999
70 70 assert_response 404
71 71 end
72 72
73 73 def test_get_new
74 74 @request.session[:user_id] = 2
75 75 get :new, :board_id => 1
76 76 assert_response :success
77 77 assert_template 'new'
78 78 end
79 79
80 80 def test_post_new
81 81 @request.session[:user_id] = 2
82 82 ActionMailer::Base.deliveries.clear
83 83 Setting.notified_events = ['message_posted']
84 84
85 85 post :new, :board_id => 1,
86 86 :message => { :subject => 'Test created message',
87 87 :content => 'Message body'}
88 88 message = Message.find_by_subject('Test created message')
89 89 assert_not_nil message
90 90 assert_redirected_to "/boards/1/topics/#{message.to_param}"
91 91 assert_equal 'Message body', message.content
92 92 assert_equal 2, message.author_id
93 93 assert_equal 1, message.board_id
94 94
95 95 mail = ActionMailer::Base.deliveries.last
96 96 assert_kind_of TMail::Mail, mail
97 97 assert_equal "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] Test created message", mail.subject
98 98 assert mail.body.include?('Message body')
99 99 # author
100 100 assert mail.bcc.include?('jsmith@somenet.foo')
101 101 # project member
102 102 assert mail.bcc.include?('dlopper@somenet.foo')
103 103 end
104 104
105 105 def test_get_edit
106 106 @request.session[:user_id] = 2
107 107 get :edit, :board_id => 1, :id => 1
108 108 assert_response :success
109 109 assert_template 'edit'
110 110 end
111 111
112 112 def test_post_edit
113 113 @request.session[:user_id] = 2
114 114 post :edit, :board_id => 1, :id => 1,
115 115 :message => { :subject => 'New subject',
116 116 :content => 'New body'}
117 117 assert_redirected_to '/boards/1/topics/1'
118 118 message = Message.find(1)
119 119 assert_equal 'New subject', message.subject
120 120 assert_equal 'New body', message.content
121 121 end
122 122
123 123 def test_reply
124 124 @request.session[:user_id] = 2
125 125 post :reply, :board_id => 1, :id => 1, :reply => { :content => 'This is a test reply', :subject => 'Test reply' }
126 126 reply = Message.find(:first, :order => 'id DESC')
127 127 assert_redirected_to "/boards/1/topics/1?r=#{reply.id}"
128 128 assert Message.find_by_subject('Test reply')
129 129 end
130 130
131 131 def test_destroy_topic
132 132 @request.session[:user_id] = 2
133 133 post :destroy, :board_id => 1, :id => 1
134 134 assert_redirected_to '/projects/ecookbook/boards/1'
135 135 assert_nil Message.find_by_id(1)
136 136 end
137 137
138 138 def test_quote
139 139 @request.session[:user_id] = 2
140 140 xhr :get, :quote, :board_id => 1, :id => 3
141 141 assert_response :success
142 142 assert_select_rjs :show, 'reply'
143 143 end
144 144 end
@@ -1,207 +1,207
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'my_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class MyController; def rescue_action(e) raise e end; end
23 23
24 24 class MyControllerTest < ActionController::TestCase
25 25 fixtures :users, :user_preferences, :roles, :projects, :issues, :issue_statuses, :trackers, :enumerations, :custom_fields
26 26
27 27 def setup
28 28 @controller = MyController.new
29 29 @request = ActionController::TestRequest.new
30 30 @request.session[:user_id] = 2
31 31 @response = ActionController::TestResponse.new
32 32 end
33 33
34 34 def test_index
35 35 get :index
36 36 assert_response :success
37 37 assert_template 'page'
38 38 end
39 39
40 40 def test_page
41 41 get :page
42 42 assert_response :success
43 43 assert_template 'page'
44 44 end
45 45
46 46 def test_my_account_should_show_editable_custom_fields
47 47 get :account
48 48 assert_response :success
49 49 assert_template 'account'
50 50 assert_equal User.find(2), assigns(:user)
51 51
52 52 assert_tag :input, :attributes => { :name => 'user[custom_field_values][4]'}
53 53 end
54 54
55 55 def test_my_account_should_not_show_non_editable_custom_fields
56 56 UserCustomField.find(4).update_attribute :editable, false
57 57
58 58 get :account
59 59 assert_response :success
60 60 assert_template 'account'
61 61 assert_equal User.find(2), assigns(:user)
62 62
63 63 assert_no_tag :input, :attributes => { :name => 'user[custom_field_values][4]'}
64 64 end
65 65
66 66 def test_update_account
67 67 post :account,
68 68 :user => {
69 69 :firstname => "Joe",
70 70 :login => "root",
71 71 :admin => 1,
72 72 :group_ids => ['10'],
73 73 :custom_field_values => {"4" => "0100562500"}
74 74 }
75 75
76 76 assert_redirected_to '/my/account'
77 77 user = User.find(2)
78 78 assert_equal user, assigns(:user)
79 79 assert_equal "Joe", user.firstname
80 80 assert_equal "jsmith", user.login
81 81 assert_equal "0100562500", user.custom_value_for(4).value
82 82 # ignored
83 83 assert !user.admin?
84 84 assert user.groups.empty?
85 85 end
86 86
87 87 def test_change_password
88 88 get :password
89 89 assert_response :success
90 90 assert_template 'password'
91 91
92 92 # non matching password confirmation
93 93 post :password, :password => 'jsmith',
94 94 :new_password => 'hello',
95 95 :new_password_confirmation => 'hello2'
96 96 assert_response :success
97 97 assert_template 'password'
98 98 assert_tag :tag => "div", :attributes => { :class => "errorExplanation" }
99 99
100 100 # wrong password
101 101 post :password, :password => 'wrongpassword',
102 102 :new_password => 'hello',
103 103 :new_password_confirmation => 'hello'
104 104 assert_response :success
105 105 assert_template 'password'
106 106 assert_equal 'Wrong password', flash[:error]
107 107
108 108 # good password
109 109 post :password, :password => 'jsmith',
110 110 :new_password => 'hello',
111 111 :new_password_confirmation => 'hello'
112 112 assert_redirected_to '/my/account'
113 113 assert User.try_to_login('jsmith', 'hello')
114 114 end
115 115
116 116 def test_page_layout
117 117 get :page_layout
118 118 assert_response :success
119 119 assert_template 'page_layout'
120 120 end
121 121
122 122 def test_add_block
123 123 xhr :post, :add_block, :block => 'issuesreportedbyme'
124 124 assert_response :success
125 125 assert User.find(2).pref[:my_page_layout]['top'].include?('issuesreportedbyme')
126 126 end
127 127
128 128 def test_remove_block
129 129 xhr :post, :remove_block, :block => 'issuesassignedtome'
130 130 assert_response :success
131 131 assert !User.find(2).pref[:my_page_layout].values.flatten.include?('issuesassignedtome')
132 132 end
133 133
134 134 def test_order_blocks
135 135 xhr :post, :order_blocks, :group => 'left', 'list-left' => ['documents', 'calendar', 'latestnews']
136 136 assert_response :success
137 137 assert_equal ['documents', 'calendar', 'latestnews'], User.find(2).pref[:my_page_layout]['left']
138 138 end
139 139
140 140 context "POST to reset_rss_key" do
141 141 context "with an existing rss_token" do
142 142 setup do
143 143 @previous_token_value = User.find(2).rss_key # Will generate one if it's missing
144 144 post :reset_rss_key
145 145 end
146 146
147 147 should "destroy the existing token" do
148 148 assert_not_equal @previous_token_value, User.find(2).rss_key
149 149 end
150 150
151 151 should "create a new token" do
152 152 assert User.find(2).rss_token
153 153 end
154 154
155 155 should_set_the_flash_to /reset/
156 156 should_redirect_to('my account') {'/my/account' }
157 157 end
158 158
159 159 context "with no rss_token" do
160 160 setup do
161 161 assert_nil User.find(2).rss_token
162 162 post :reset_rss_key
163 163 end
164 164
165 165 should "create a new token" do
166 166 assert User.find(2).rss_token
167 167 end
168 168
169 169 should_set_the_flash_to /reset/
170 170 should_redirect_to('my account') {'/my/account' }
171 171 end
172 172 end
173 173
174 174 context "POST to reset_api_key" do
175 175 context "with an existing api_token" do
176 176 setup do
177 177 @previous_token_value = User.find(2).api_key # Will generate one if it's missing
178 178 post :reset_api_key
179 179 end
180 180
181 181 should "destroy the existing token" do
182 182 assert_not_equal @previous_token_value, User.find(2).api_key
183 183 end
184 184
185 185 should "create a new token" do
186 186 assert User.find(2).api_token
187 187 end
188 188
189 189 should_set_the_flash_to /reset/
190 190 should_redirect_to('my account') {'/my/account' }
191 191 end
192 192
193 193 context "with no api_token" do
194 194 setup do
195 195 assert_nil User.find(2).api_token
196 196 post :reset_api_key
197 197 end
198 198
199 199 should "create a new token" do
200 200 assert User.find(2).api_token
201 201 end
202 202
203 203 should_set_the_flash_to /reset/
204 204 should_redirect_to('my account') {'/my/account' }
205 205 end
206 206 end
207 207 end
@@ -1,120 +1,120
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'news_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class NewsController; def rescue_action(e) raise e end; end
23 23
24 24 class NewsControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :news, :comments
26 26
27 27 def setup
28 28 @controller = NewsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_index
35 35 get :index
36 36 assert_response :success
37 37 assert_template 'index'
38 38 assert_not_nil assigns(:newss)
39 39 assert_nil assigns(:project)
40 40 end
41 41
42 42 def test_index_with_project
43 43 get :index, :project_id => 1
44 44 assert_response :success
45 45 assert_template 'index'
46 46 assert_not_nil assigns(:newss)
47 47 end
48 48
49 49 def test_show
50 50 get :show, :id => 1
51 51 assert_response :success
52 52 assert_template 'show'
53 53 assert_tag :tag => 'h2', :content => /eCookbook first release/
54 54 end
55 55
56 56 def test_show_not_found
57 57 get :show, :id => 999
58 58 assert_response 404
59 59 end
60 60
61 61 def test_get_new
62 62 @request.session[:user_id] = 2
63 63 get :new, :project_id => 1
64 64 assert_response :success
65 65 assert_template 'new'
66 66 end
67 67
68 68 def test_post_create
69 69 ActionMailer::Base.deliveries.clear
70 70 Setting.notified_events << 'news_added'
71 71
72 72 @request.session[:user_id] = 2
73 73 post :create, :project_id => 1, :news => { :title => 'NewsControllerTest',
74 74 :description => 'This is the description',
75 75 :summary => '' }
76 76 assert_redirected_to '/projects/ecookbook/news'
77 77
78 78 news = News.find_by_title('NewsControllerTest')
79 79 assert_not_nil news
80 80 assert_equal 'This is the description', news.description
81 81 assert_equal User.find(2), news.author
82 82 assert_equal Project.find(1), news.project
83 83 assert_equal 1, ActionMailer::Base.deliveries.size
84 84 end
85 85
86 86 def test_get_edit
87 87 @request.session[:user_id] = 2
88 88 get :edit, :id => 1
89 89 assert_response :success
90 90 assert_template 'edit'
91 91 end
92 92
93 93 def test_put_update
94 94 @request.session[:user_id] = 2
95 95 put :update, :id => 1, :news => { :description => 'Description changed by test_post_edit' }
96 96 assert_redirected_to '/news/1'
97 97 news = News.find(1)
98 98 assert_equal 'Description changed by test_post_edit', news.description
99 99 end
100 100
101 101 def test_post_create_with_validation_failure
102 102 @request.session[:user_id] = 2
103 103 post :create, :project_id => 1, :news => { :title => '',
104 104 :description => 'This is the description',
105 105 :summary => '' }
106 106 assert_response :success
107 107 assert_template 'new'
108 108 assert_not_nil assigns(:news)
109 109 assert assigns(:news).new_record?
110 110 assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' },
111 111 :content => /1 error/
112 112 end
113 113
114 114 def test_destroy
115 115 @request.session[:user_id] = 2
116 116 delete :destroy, :id => 1
117 117 assert_redirected_to '/projects/ecookbook/news'
118 118 assert_nil News.find_by_id(1)
119 119 end
120 120 end
@@ -1,32 +1,32
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class PreviewsControllerTest < ActionController::TestCase
4 4 fixtures :all
5 5
6 6 def test_preview_new_issue
7 7 @request.session[:user_id] = 2
8 8 post :issue, :project_id => '1', :issue => {:description => 'Foo'}
9 9 assert_response :success
10 10 assert_template 'preview'
11 11 assert_not_nil assigns(:description)
12 12 end
13 13
14 14 def test_preview_issue_notes
15 15 @request.session[:user_id] = 2
16 16 post :issue, :project_id => '1', :id => 1, :issue => {:description => Issue.find(1).description}, :notes => 'Foo'
17 17 assert_response :success
18 18 assert_template 'preview'
19 19 assert_not_nil assigns(:notes)
20 20 end
21 21
22 22 def test_news
23 23 get :news, :project_id => 1,
24 24 :news => {:title => '',
25 25 :description => 'News description',
26 26 :summary => ''}
27 27 assert_response :success
28 28 assert_template 'common/_preview'
29 29 assert_tag :tag => 'fieldset', :attributes => { :class => 'preview' },
30 30 :content => /News description/
31 31 end
32 32 end
@@ -1,189 +1,189
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class ProjectEnumerationsControllerTest < ActionController::TestCase
4 4 fixtures :all
5 5
6 6 def setup
7 7 @request.session[:user_id] = nil
8 8 Setting.default_language = 'en'
9 9 end
10 10
11 11 def test_update_to_override_system_activities
12 12 @request.session[:user_id] = 2 # manager
13 13 billable_field = TimeEntryActivityCustomField.find_by_name("Billable")
14 14
15 15 put :update, :project_id => 1, :enumerations => {
16 16 "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # Design, De-activate
17 17 "10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"}, # Development, Change custom value
18 18 "14"=>{"parent_id"=>"14", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"}, # Inactive Activity, Activate with custom value
19 19 "11"=>{"parent_id"=>"11", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"} # QA, no changes
20 20 }
21 21
22 22 assert_response :redirect
23 23 assert_redirected_to '/projects/ecookbook/settings/activities'
24 24
25 25 # Created project specific activities...
26 26 project = Project.find('ecookbook')
27 27
28 28 # ... Design
29 29 design = project.time_entry_activities.find_by_name("Design")
30 30 assert design, "Project activity not found"
31 31
32 32 assert_equal 9, design.parent_id # Relate to the system activity
33 33 assert_not_equal design.parent.id, design.id # Different records
34 34 assert_equal design.parent.name, design.name # Same name
35 35 assert !design.active?
36 36
37 37 # ... Development
38 38 development = project.time_entry_activities.find_by_name("Development")
39 39 assert development, "Project activity not found"
40 40
41 41 assert_equal 10, development.parent_id # Relate to the system activity
42 42 assert_not_equal development.parent.id, development.id # Different records
43 43 assert_equal development.parent.name, development.name # Same name
44 44 assert development.active?
45 45 assert_equal "0", development.custom_value_for(billable_field).value
46 46
47 47 # ... Inactive Activity
48 48 previously_inactive = project.time_entry_activities.find_by_name("Inactive Activity")
49 49 assert previously_inactive, "Project activity not found"
50 50
51 51 assert_equal 14, previously_inactive.parent_id # Relate to the system activity
52 52 assert_not_equal previously_inactive.parent.id, previously_inactive.id # Different records
53 53 assert_equal previously_inactive.parent.name, previously_inactive.name # Same name
54 54 assert previously_inactive.active?
55 55 assert_equal "1", previously_inactive.custom_value_for(billable_field).value
56 56
57 57 # ... QA
58 58 assert_equal nil, project.time_entry_activities.find_by_name("QA"), "Custom QA activity created when it wasn't modified"
59 59 end
60 60
61 61 def test_update_will_update_project_specific_activities
62 62 @request.session[:user_id] = 2 # manager
63 63
64 64 project_activity = TimeEntryActivity.new({
65 65 :name => 'Project Specific',
66 66 :parent => TimeEntryActivity.find(:first),
67 67 :project => Project.find(1),
68 68 :active => true
69 69 })
70 70 assert project_activity.save
71 71 project_activity_two = TimeEntryActivity.new({
72 72 :name => 'Project Specific Two',
73 73 :parent => TimeEntryActivity.find(:last),
74 74 :project => Project.find(1),
75 75 :active => true
76 76 })
77 77 assert project_activity_two.save
78 78
79 79
80 80 put :update, :project_id => 1, :enumerations => {
81 81 project_activity.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # De-activate
82 82 project_activity_two.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"} # De-activate
83 83 }
84 84
85 85 assert_response :redirect
86 86 assert_redirected_to '/projects/ecookbook/settings/activities'
87 87
88 88 # Created project specific activities...
89 89 project = Project.find('ecookbook')
90 90 assert_equal 2, project.time_entry_activities.count
91 91
92 92 activity_one = project.time_entry_activities.find_by_name(project_activity.name)
93 93 assert activity_one, "Project activity not found"
94 94 assert_equal project_activity.id, activity_one.id
95 95 assert !activity_one.active?
96 96
97 97 activity_two = project.time_entry_activities.find_by_name(project_activity_two.name)
98 98 assert activity_two, "Project activity not found"
99 99 assert_equal project_activity_two.id, activity_two.id
100 100 assert !activity_two.active?
101 101 end
102 102
103 103 def test_update_when_creating_new_activities_will_convert_existing_data
104 104 assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size
105 105
106 106 @request.session[:user_id] = 2 # manager
107 107 put :update, :project_id => 1, :enumerations => {
108 108 "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"} # Design, De-activate
109 109 }
110 110 assert_response :redirect
111 111
112 112 # No more TimeEntries using the system activity
113 113 assert_equal 0, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "Time Entries still assigned to system activities"
114 114 # All TimeEntries using project activity
115 115 project_specific_activity = TimeEntryActivity.find_by_parent_id_and_project_id(9, 1)
116 116 assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(project_specific_activity.id, 1).size, "No Time Entries assigned to the project activity"
117 117 end
118 118
119 119 def test_update_when_creating_new_activities_will_not_convert_existing_data_if_an_exception_is_raised
120 120 # TODO: Need to cause an exception on create but these tests
121 121 # aren't setup for mocking. Just create a record now so the
122 122 # second one is a dupicate
123 123 parent = TimeEntryActivity.find(9)
124 124 TimeEntryActivity.create!({:name => parent.name, :project_id => 1, :position => parent.position, :active => true})
125 125 TimeEntry.create!({:project_id => 1, :hours => 1.0, :user => User.find(1), :issue_id => 3, :activity_id => 10, :spent_on => '2009-01-01'})
126 126
127 127 assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size
128 128 assert_equal 1, TimeEntry.find_all_by_activity_id_and_project_id(10, 1).size
129 129
130 130 @request.session[:user_id] = 2 # manager
131 131 put :update, :project_id => 1, :enumerations => {
132 132 "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # Design
133 133 "10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"} # Development, Change custom value
134 134 }
135 135 assert_response :redirect
136 136
137 137 # TimeEntries shouldn't have been reassigned on the failed record
138 138 assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "Time Entries are not assigned to system activities"
139 139 # TimeEntries shouldn't have been reassigned on the saved record either
140 140 assert_equal 1, TimeEntry.find_all_by_activity_id_and_project_id(10, 1).size, "Time Entries are not assigned to system activities"
141 141 end
142 142
143 143 def test_destroy
144 144 @request.session[:user_id] = 2 # manager
145 145 project_activity = TimeEntryActivity.new({
146 146 :name => 'Project Specific',
147 147 :parent => TimeEntryActivity.find(:first),
148 148 :project => Project.find(1),
149 149 :active => true
150 150 })
151 151 assert project_activity.save
152 152 project_activity_two = TimeEntryActivity.new({
153 153 :name => 'Project Specific Two',
154 154 :parent => TimeEntryActivity.find(:last),
155 155 :project => Project.find(1),
156 156 :active => true
157 157 })
158 158 assert project_activity_two.save
159 159
160 160 delete :destroy, :project_id => 1
161 161 assert_response :redirect
162 162 assert_redirected_to '/projects/ecookbook/settings/activities'
163 163
164 164 assert_nil TimeEntryActivity.find_by_id(project_activity.id)
165 165 assert_nil TimeEntryActivity.find_by_id(project_activity_two.id)
166 166 end
167 167
168 168 def test_destroy_should_reassign_time_entries_back_to_the_system_activity
169 169 @request.session[:user_id] = 2 # manager
170 170 project_activity = TimeEntryActivity.new({
171 171 :name => 'Project Specific Design',
172 172 :parent => TimeEntryActivity.find(9),
173 173 :project => Project.find(1),
174 174 :active => true
175 175 })
176 176 assert project_activity.save
177 177 assert TimeEntry.update_all("activity_id = '#{project_activity.id}'", ["project_id = ? AND activity_id = ?", 1, 9])
178 178 assert 3, TimeEntry.find_all_by_activity_id_and_project_id(project_activity.id, 1).size
179 179
180 180 delete :destroy, :project_id => 1
181 181 assert_response :redirect
182 182 assert_redirected_to '/projects/ecookbook/settings/activities'
183 183
184 184 assert_nil TimeEntryActivity.find_by_id(project_activity.id)
185 185 assert_equal 0, TimeEntry.find_all_by_activity_id_and_project_id(project_activity.id, 1).size, "TimeEntries still assigned to project specific activity"
186 186 assert_equal 3, TimeEntry.find_all_by_activity_id_and_project_id(9, 1).size, "TimeEntries still assigned to project specific activity"
187 187 end
188 188
189 189 end
@@ -1,468 +1,468
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'projects_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class ProjectsController; def rescue_action(e) raise e end; end
23 23
24 24 class ProjectsControllerTest < ActionController::TestCase
25 25 fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
26 26 :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
27 27 :attachments, :custom_fields, :custom_values, :time_entries
28 28
29 29 def setup
30 30 @controller = ProjectsController.new
31 31 @request = ActionController::TestRequest.new
32 32 @response = ActionController::TestResponse.new
33 33 @request.session[:user_id] = nil
34 34 Setting.default_language = 'en'
35 35 end
36 36
37 37 def test_index
38 38 get :index
39 39 assert_response :success
40 40 assert_template 'index'
41 41 assert_not_nil assigns(:projects)
42 42
43 43 assert_tag :ul, :child => {:tag => 'li',
44 44 :descendant => {:tag => 'a', :content => 'eCookbook'},
45 45 :child => { :tag => 'ul',
46 46 :descendant => { :tag => 'a',
47 47 :content => 'Child of private child'
48 48 }
49 49 }
50 50 }
51 51
52 52 assert_no_tag :a, :content => /Private child of eCookbook/
53 53 end
54 54
55 55 def test_index_atom
56 56 get :index, :format => 'atom'
57 57 assert_response :success
58 58 assert_template 'common/feed.atom.rxml'
59 59 assert_select 'feed>title', :text => 'Redmine: Latest projects'
60 60 assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_by(User.current))
61 61 end
62 62
63 63 context "#index" do
64 64 context "by non-admin user with view_time_entries permission" do
65 65 setup do
66 66 @request.session[:user_id] = 3
67 67 end
68 68 should "show overall spent time link" do
69 69 get :index
70 70 assert_template 'index'
71 71 assert_tag :a, :attributes => {:href => '/time_entries'}
72 72 end
73 73 end
74 74
75 75 context "by non-admin user without view_time_entries permission" do
76 76 setup do
77 77 Role.find(2).remove_permission! :view_time_entries
78 78 Role.non_member.remove_permission! :view_time_entries
79 79 Role.anonymous.remove_permission! :view_time_entries
80 80 @request.session[:user_id] = 3
81 81 end
82 82 should "not show overall spent time link" do
83 83 get :index
84 84 assert_template 'index'
85 85 assert_no_tag :a, :attributes => {:href => '/time_entries'}
86 86 end
87 87 end
88 88 end
89 89
90 90 context "#new" do
91 91 context "by admin user" do
92 92 setup do
93 93 @request.session[:user_id] = 1
94 94 end
95 95
96 96 should "accept get" do
97 97 get :new
98 98 assert_response :success
99 99 assert_template 'new'
100 100 end
101 101
102 102 end
103 103
104 104 context "by non-admin user with add_project permission" do
105 105 setup do
106 106 Role.non_member.add_permission! :add_project
107 107 @request.session[:user_id] = 9
108 108 end
109 109
110 110 should "accept get" do
111 111 get :new
112 112 assert_response :success
113 113 assert_template 'new'
114 114 assert_no_tag :select, :attributes => {:name => 'project[parent_id]'}
115 115 end
116 116 end
117 117
118 118 context "by non-admin user with add_subprojects permission" do
119 119 setup do
120 120 Role.find(1).remove_permission! :add_project
121 121 Role.find(1).add_permission! :add_subprojects
122 122 @request.session[:user_id] = 2
123 123 end
124 124
125 125 should "accept get" do
126 126 get :new, :parent_id => 'ecookbook'
127 127 assert_response :success
128 128 assert_template 'new'
129 129 # parent project selected
130 130 assert_tag :select, :attributes => {:name => 'project[parent_id]'},
131 131 :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}}
132 132 # no empty value
133 133 assert_no_tag :select, :attributes => {:name => 'project[parent_id]'},
134 134 :child => {:tag => 'option', :attributes => {:value => ''}}
135 135 end
136 136 end
137 137
138 138 end
139 139
140 140 context "POST :create" do
141 141 context "by admin user" do
142 142 setup do
143 143 @request.session[:user_id] = 1
144 144 end
145 145
146 146 should "create a new project" do
147 147 post :create,
148 148 :project => {
149 149 :name => "blog",
150 150 :description => "weblog",
151 151 :homepage => 'http://weblog',
152 152 :identifier => "blog",
153 153 :is_public => 1,
154 154 :custom_field_values => { '3' => 'Beta' },
155 155 :tracker_ids => ['1', '3']
156 156 }
157 157 assert_redirected_to '/projects/blog/settings'
158 158
159 159 project = Project.find_by_name('blog')
160 160 assert_kind_of Project, project
161 161 assert project.active?
162 162 assert_equal 'weblog', project.description
163 163 assert_equal 'http://weblog', project.homepage
164 164 assert_equal true, project.is_public?
165 165 assert_nil project.parent
166 166 assert_equal 'Beta', project.custom_value_for(3).value
167 167 assert_equal [1, 3], project.trackers.map(&:id).sort
168 168 end
169 169
170 170 should "create a new subproject" do
171 171 post :create, :project => { :name => "blog",
172 172 :description => "weblog",
173 173 :identifier => "blog",
174 174 :is_public => 1,
175 175 :custom_field_values => { '3' => 'Beta' },
176 176 :parent_id => 1
177 177 }
178 178 assert_redirected_to '/projects/blog/settings'
179 179
180 180 project = Project.find_by_name('blog')
181 181 assert_kind_of Project, project
182 182 assert_equal Project.find(1), project.parent
183 183 end
184 184 end
185 185
186 186 context "by non-admin user with add_project permission" do
187 187 setup do
188 188 Role.non_member.add_permission! :add_project
189 189 @request.session[:user_id] = 9
190 190 end
191 191
192 192 should "accept create a Project" do
193 193 post :create, :project => { :name => "blog",
194 194 :description => "weblog",
195 195 :identifier => "blog",
196 196 :is_public => 1,
197 197 :custom_field_values => { '3' => 'Beta' }
198 198 }
199 199
200 200 assert_redirected_to '/projects/blog/settings'
201 201
202 202 project = Project.find_by_name('blog')
203 203 assert_kind_of Project, project
204 204 assert_equal 'weblog', project.description
205 205 assert_equal true, project.is_public?
206 206
207 207 # User should be added as a project member
208 208 assert User.find(9).member_of?(project)
209 209 assert_equal 1, project.members.size
210 210 end
211 211
212 212 should "fail with parent_id" do
213 213 assert_no_difference 'Project.count' do
214 214 post :create, :project => { :name => "blog",
215 215 :description => "weblog",
216 216 :identifier => "blog",
217 217 :is_public => 1,
218 218 :custom_field_values => { '3' => 'Beta' },
219 219 :parent_id => 1
220 220 }
221 221 end
222 222 assert_response :success
223 223 project = assigns(:project)
224 224 assert_kind_of Project, project
225 225 assert_not_nil project.errors.on(:parent_id)
226 226 end
227 227 end
228 228
229 229 context "by non-admin user with add_subprojects permission" do
230 230 setup do
231 231 Role.find(1).remove_permission! :add_project
232 232 Role.find(1).add_permission! :add_subprojects
233 233 @request.session[:user_id] = 2
234 234 end
235 235
236 236 should "create a project with a parent_id" do
237 237 post :create, :project => { :name => "blog",
238 238 :description => "weblog",
239 239 :identifier => "blog",
240 240 :is_public => 1,
241 241 :custom_field_values => { '3' => 'Beta' },
242 242 :parent_id => 1
243 243 }
244 244 assert_redirected_to '/projects/blog/settings'
245 245 project = Project.find_by_name('blog')
246 246 end
247 247
248 248 should "fail without parent_id" do
249 249 assert_no_difference 'Project.count' do
250 250 post :create, :project => { :name => "blog",
251 251 :description => "weblog",
252 252 :identifier => "blog",
253 253 :is_public => 1,
254 254 :custom_field_values => { '3' => 'Beta' }
255 255 }
256 256 end
257 257 assert_response :success
258 258 project = assigns(:project)
259 259 assert_kind_of Project, project
260 260 assert_not_nil project.errors.on(:parent_id)
261 261 end
262 262
263 263 should "fail with unauthorized parent_id" do
264 264 assert !User.find(2).member_of?(Project.find(6))
265 265 assert_no_difference 'Project.count' do
266 266 post :create, :project => { :name => "blog",
267 267 :description => "weblog",
268 268 :identifier => "blog",
269 269 :is_public => 1,
270 270 :custom_field_values => { '3' => 'Beta' },
271 271 :parent_id => 6
272 272 }
273 273 end
274 274 assert_response :success
275 275 project = assigns(:project)
276 276 assert_kind_of Project, project
277 277 assert_not_nil project.errors.on(:parent_id)
278 278 end
279 279 end
280 280 end
281 281
282 282 def test_show_by_id
283 283 get :show, :id => 1
284 284 assert_response :success
285 285 assert_template 'show'
286 286 assert_not_nil assigns(:project)
287 287 end
288 288
289 289 def test_show_by_identifier
290 290 get :show, :id => 'ecookbook'
291 291 assert_response :success
292 292 assert_template 'show'
293 293 assert_not_nil assigns(:project)
294 294 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
295 295
296 296 assert_tag 'li', :content => /Development status/
297 297 end
298 298
299 299 def test_show_should_not_display_hidden_custom_fields
300 300 ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
301 301 get :show, :id => 'ecookbook'
302 302 assert_response :success
303 303 assert_template 'show'
304 304 assert_not_nil assigns(:project)
305 305
306 306 assert_no_tag 'li', :content => /Development status/
307 307 end
308 308
309 309 def test_show_should_not_fail_when_custom_values_are_nil
310 310 project = Project.find_by_identifier('ecookbook')
311 311 project.custom_values.first.update_attribute(:value, nil)
312 312 get :show, :id => 'ecookbook'
313 313 assert_response :success
314 314 assert_template 'show'
315 315 assert_not_nil assigns(:project)
316 316 assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
317 317 end
318 318
319 319 def show_archived_project_should_be_denied
320 320 project = Project.find_by_identifier('ecookbook')
321 321 project.archive!
322 322
323 323 get :show, :id => 'ecookbook'
324 324 assert_response 403
325 325 assert_nil assigns(:project)
326 326 assert_tag :tag => 'p', :content => /archived/
327 327 end
328 328
329 329 def test_private_subprojects_hidden
330 330 get :show, :id => 'ecookbook'
331 331 assert_response :success
332 332 assert_template 'show'
333 333 assert_no_tag :tag => 'a', :content => /Private child/
334 334 end
335 335
336 336 def test_private_subprojects_visible
337 337 @request.session[:user_id] = 2 # manager who is a member of the private subproject
338 338 get :show, :id => 'ecookbook'
339 339 assert_response :success
340 340 assert_template 'show'
341 341 assert_tag :tag => 'a', :content => /Private child/
342 342 end
343 343
344 344 def test_settings
345 345 @request.session[:user_id] = 2 # manager
346 346 get :settings, :id => 1
347 347 assert_response :success
348 348 assert_template 'settings'
349 349 end
350 350
351 351 def test_update
352 352 @request.session[:user_id] = 2 # manager
353 353 post :update, :id => 1, :project => {:name => 'Test changed name',
354 354 :issue_custom_field_ids => ['']}
355 355 assert_redirected_to '/projects/ecookbook/settings'
356 356 project = Project.find(1)
357 357 assert_equal 'Test changed name', project.name
358 358 end
359 359
360 360 def test_get_destroy
361 361 @request.session[:user_id] = 1 # admin
362 362 get :destroy, :id => 1
363 363 assert_response :success
364 364 assert_template 'destroy'
365 365 assert_not_nil Project.find_by_id(1)
366 366 end
367 367
368 368 def test_post_destroy
369 369 @request.session[:user_id] = 1 # admin
370 370 post :destroy, :id => 1, :confirm => 1
371 371 assert_redirected_to '/admin/projects'
372 372 assert_nil Project.find_by_id(1)
373 373 end
374 374
375 375 def test_archive
376 376 @request.session[:user_id] = 1 # admin
377 377 post :archive, :id => 1
378 378 assert_redirected_to '/admin/projects'
379 379 assert !Project.find(1).active?
380 380 end
381 381
382 382 def test_unarchive
383 383 @request.session[:user_id] = 1 # admin
384 384 Project.find(1).archive
385 385 post :unarchive, :id => 1
386 386 assert_redirected_to '/admin/projects'
387 387 assert Project.find(1).active?
388 388 end
389 389
390 390 def test_project_breadcrumbs_should_be_limited_to_3_ancestors
391 391 CustomField.delete_all
392 392 parent = nil
393 393 6.times do |i|
394 394 p = Project.create!(:name => "Breadcrumbs #{i}", :identifier => "breadcrumbs-#{i}")
395 395 p.set_parent!(parent)
396 396 get :show, :id => p
397 397 assert_tag :h1, :parent => { :attributes => {:id => 'header'}},
398 398 :children => { :count => [i, 3].min,
399 399 :only => { :tag => 'a' } }
400 400
401 401 parent = p
402 402 end
403 403 end
404 404
405 405 def test_copy_with_project
406 406 @request.session[:user_id] = 1 # admin
407 407 get :copy, :id => 1
408 408 assert_response :success
409 409 assert_template 'copy'
410 410 assert assigns(:project)
411 411 assert_equal Project.find(1).description, assigns(:project).description
412 412 assert_nil assigns(:project).id
413 413 end
414 414
415 415 def test_copy_without_project
416 416 @request.session[:user_id] = 1 # admin
417 417 get :copy
418 418 assert_response :redirect
419 419 assert_redirected_to :controller => 'admin', :action => 'projects'
420 420 end
421 421
422 422 context "POST :copy" do
423 423 should "TODO: test the rest of the method"
424 424
425 425 should "redirect to the project settings when successful" do
426 426 @request.session[:user_id] = 1 # admin
427 427 post :copy, :id => 1, :project => {:name => 'Copy', :identifier => 'unique-copy'}
428 428 assert_response :redirect
429 429 assert_redirected_to :controller => 'projects', :action => 'settings'
430 430 end
431 431 end
432 432
433 433 def test_jump_should_redirect_to_active_tab
434 434 get :show, :id => 1, :jump => 'issues'
435 435 assert_redirected_to '/projects/ecookbook/issues'
436 436 end
437 437
438 438 def test_jump_should_not_redirect_to_inactive_tab
439 439 get :show, :id => 3, :jump => 'documents'
440 440 assert_response :success
441 441 assert_template 'show'
442 442 end
443 443
444 444 def test_jump_should_not_redirect_to_unknown_tab
445 445 get :show, :id => 3, :jump => 'foobar'
446 446 assert_response :success
447 447 assert_template 'show'
448 448 end
449 449
450 450 # A hook that is manually registered later
451 451 class ProjectBasedTemplate < Redmine::Hook::ViewListener
452 452 def view_layouts_base_html_head(context)
453 453 # Adds a project stylesheet
454 454 stylesheet_link_tag(context[:project].identifier) if context[:project]
455 455 end
456 456 end
457 457 # Don't use this hook now
458 458 Redmine::Hook.clear_listeners
459 459
460 460 def test_hook_response
461 461 Redmine::Hook.add_listener(ProjectBasedTemplate)
462 462 get :show, :id => 1
463 463 assert_tag :tag => 'link', :attributes => {:href => '/stylesheets/ecookbook.css'},
464 464 :parent => {:tag => 'head'}
465 465
466 466 Redmine::Hook.clear_listeners
467 467 end
468 468 end
@@ -1,240 +1,240
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'queries_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class QueriesController; def rescue_action(e) raise e end; end
23 23
24 24 class QueriesControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :members, :member_roles, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :queries
26 26
27 27 def setup
28 28 @controller = QueriesController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_get_new_project_query
35 35 @request.session[:user_id] = 2
36 36 get :new, :project_id => 1
37 37 assert_response :success
38 38 assert_template 'new'
39 39 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
40 40 :name => 'query[is_public]',
41 41 :checked => nil }
42 42 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
43 43 :name => 'query_is_for_all',
44 44 :checked => nil,
45 45 :disabled => nil }
46 46 end
47 47
48 48 def test_get_new_global_query
49 49 @request.session[:user_id] = 2
50 50 get :new
51 51 assert_response :success
52 52 assert_template 'new'
53 53 assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
54 54 :name => 'query[is_public]' }
55 55 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
56 56 :name => 'query_is_for_all',
57 57 :checked => 'checked',
58 58 :disabled => nil }
59 59 end
60 60
61 61 def test_new_project_public_query
62 62 @request.session[:user_id] = 2
63 63 post :new,
64 64 :project_id => 'ecookbook',
65 65 :confirm => '1',
66 66 :default_columns => '1',
67 67 :fields => ["status_id", "assigned_to_id"],
68 68 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
69 69 :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
70 70 :query => {"name" => "test_new_project_public_query", "is_public" => "1"}
71 71
72 72 q = Query.find_by_name('test_new_project_public_query')
73 73 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
74 74 assert q.is_public?
75 75 assert q.has_default_columns?
76 76 assert q.valid?
77 77 end
78 78
79 79 def test_new_project_private_query
80 80 @request.session[:user_id] = 3
81 81 post :new,
82 82 :project_id => 'ecookbook',
83 83 :confirm => '1',
84 84 :default_columns => '1',
85 85 :fields => ["status_id", "assigned_to_id"],
86 86 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
87 87 :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
88 88 :query => {"name" => "test_new_project_private_query", "is_public" => "1"}
89 89
90 90 q = Query.find_by_name('test_new_project_private_query')
91 91 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
92 92 assert !q.is_public?
93 93 assert q.has_default_columns?
94 94 assert q.valid?
95 95 end
96 96
97 97 def test_new_global_private_query_with_custom_columns
98 98 @request.session[:user_id] = 3
99 99 post :new,
100 100 :confirm => '1',
101 101 :fields => ["status_id", "assigned_to_id"],
102 102 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
103 103 :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
104 104 :query => {"name" => "test_new_global_private_query", "is_public" => "1", "column_names" => ["", "tracker", "subject", "priority", "category"]}
105 105
106 106 q = Query.find_by_name('test_new_global_private_query')
107 107 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
108 108 assert !q.is_public?
109 109 assert !q.has_default_columns?
110 110 assert_equal [:tracker, :subject, :priority, :category], q.columns.collect {|c| c.name}
111 111 assert q.valid?
112 112 end
113 113
114 114 def test_new_with_sort
115 115 @request.session[:user_id] = 1
116 116 post :new,
117 117 :confirm => '1',
118 118 :default_columns => '1',
119 119 :operators => {"status_id" => "o"},
120 120 :values => {"status_id" => ["1"]},
121 121 :query => {:name => "test_new_with_sort",
122 122 :is_public => "1",
123 123 :sort_criteria => {"0" => ["due_date", "desc"], "1" => ["tracker", ""]}}
124 124
125 125 query = Query.find_by_name("test_new_with_sort")
126 126 assert_not_nil query
127 127 assert_equal [['due_date', 'desc'], ['tracker', 'asc']], query.sort_criteria
128 128 end
129 129
130 130 def test_get_edit_global_public_query
131 131 @request.session[:user_id] = 1
132 132 get :edit, :id => 4
133 133 assert_response :success
134 134 assert_template 'edit'
135 135 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
136 136 :name => 'query[is_public]',
137 137 :checked => 'checked' }
138 138 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
139 139 :name => 'query_is_for_all',
140 140 :checked => 'checked',
141 141 :disabled => 'disabled' }
142 142 end
143 143
144 144 def test_edit_global_public_query
145 145 @request.session[:user_id] = 1
146 146 post :edit,
147 147 :id => 4,
148 148 :confirm => '1',
149 149 :default_columns => '1',
150 150 :fields => ["status_id", "assigned_to_id"],
151 151 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
152 152 :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
153 153 :query => {"name" => "test_edit_global_public_query", "is_public" => "1"}
154 154
155 155 assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 4
156 156 q = Query.find_by_name('test_edit_global_public_query')
157 157 assert q.is_public?
158 158 assert q.has_default_columns?
159 159 assert q.valid?
160 160 end
161 161
162 162 def test_get_edit_global_private_query
163 163 @request.session[:user_id] = 3
164 164 get :edit, :id => 3
165 165 assert_response :success
166 166 assert_template 'edit'
167 167 assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
168 168 :name => 'query[is_public]' }
169 169 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
170 170 :name => 'query_is_for_all',
171 171 :checked => 'checked',
172 172 :disabled => 'disabled' }
173 173 end
174 174
175 175 def test_edit_global_private_query
176 176 @request.session[:user_id] = 3
177 177 post :edit,
178 178 :id => 3,
179 179 :confirm => '1',
180 180 :default_columns => '1',
181 181 :fields => ["status_id", "assigned_to_id"],
182 182 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
183 183 :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
184 184 :query => {"name" => "test_edit_global_private_query", "is_public" => "1"}
185 185
186 186 assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 3
187 187 q = Query.find_by_name('test_edit_global_private_query')
188 188 assert !q.is_public?
189 189 assert q.has_default_columns?
190 190 assert q.valid?
191 191 end
192 192
193 193 def test_get_edit_project_private_query
194 194 @request.session[:user_id] = 3
195 195 get :edit, :id => 2
196 196 assert_response :success
197 197 assert_template 'edit'
198 198 assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
199 199 :name => 'query[is_public]' }
200 200 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
201 201 :name => 'query_is_for_all',
202 202 :checked => nil,
203 203 :disabled => nil }
204 204 end
205 205
206 206 def test_get_edit_project_public_query
207 207 @request.session[:user_id] = 2
208 208 get :edit, :id => 1
209 209 assert_response :success
210 210 assert_template 'edit'
211 211 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
212 212 :name => 'query[is_public]',
213 213 :checked => 'checked'
214 214 }
215 215 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
216 216 :name => 'query_is_for_all',
217 217 :checked => nil,
218 218 :disabled => 'disabled' }
219 219 end
220 220
221 221 def test_get_edit_sort_criteria
222 222 @request.session[:user_id] = 1
223 223 get :edit, :id => 5
224 224 assert_response :success
225 225 assert_template 'edit'
226 226 assert_tag :tag => 'select', :attributes => { :name => 'query[sort_criteria][0][]' },
227 227 :child => { :tag => 'option', :attributes => { :value => 'priority',
228 228 :selected => 'selected' } }
229 229 assert_tag :tag => 'select', :attributes => { :name => 'query[sort_criteria][0][]' },
230 230 :child => { :tag => 'option', :attributes => { :value => 'desc',
231 231 :selected => 'selected' } }
232 232 end
233 233
234 234 def test_destroy
235 235 @request.session[:user_id] = 2
236 236 post :destroy, :id => 1
237 237 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :set_filter => 1, :query_id => nil
238 238 assert_nil Query.find_by_id(1)
239 239 end
240 240 end
@@ -1,79 +1,79
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'reports_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class ReportsController; def rescue_action(e) raise e end; end
23 23
24 24
25 25 class ReportsControllerTest < ActionController::TestCase
26 26 fixtures :all
27 27
28 28 def setup
29 29 @controller = ReportsController.new
30 30 @request = ActionController::TestRequest.new
31 31 @response = ActionController::TestResponse.new
32 32 User.current = nil
33 33 end
34 34
35 35 context "GET :issue_report without details" do
36 36 setup do
37 37 get :issue_report, :id => 1
38 38 end
39 39
40 40 should_respond_with :success
41 41 should_render_template :issue_report
42 42
43 43 [:issues_by_tracker, :issues_by_version, :issues_by_category, :issues_by_assigned_to,
44 44 :issues_by_author, :issues_by_subproject].each do |ivar|
45 45 should_assign_to ivar
46 46 should "set a value for #{ivar}" do
47 47 assert assigns[ivar.to_s].present?
48 48 end
49 49 end
50 50 end
51 51
52 52 context "GET :issue_report_details" do
53 53 %w(tracker version priority category assigned_to author subproject).each do |detail|
54 54 context "for #{detail}" do
55 55 setup do
56 56 get :issue_report_details, :id => 1, :detail => detail
57 57 end
58 58
59 59 should_respond_with :success
60 60 should_render_template :issue_report_details
61 61 should_assign_to :field
62 62 should_assign_to :rows
63 63 should_assign_to :data
64 64 should_assign_to :report_title
65 65 end
66 66 end
67 67
68 68 context "with an invalid detail" do
69 69 setup do
70 70 get :issue_report_details, :id => 1, :detail => 'invalid'
71 71 end
72 72
73 73 should_respond_with :redirect
74 74 should_redirect_to('the issue report') {{:controller => 'reports', :action => 'issue_report', :id => 'ecookbook'}}
75 75 end
76 76
77 77 end
78 78
79 79 end
@@ -1,137 +1,137
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'repositories_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class RepositoriesController; def rescue_action(e) raise e end; end
23 23
24 24 class RepositoriesBazaarControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles, :members, :member_roles, :repositories, :enabled_modules
26 26
27 27 # No '..' in the repository path
28 28 REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/bazaar_repository'
29 29
30 30 def setup
31 31 @controller = RepositoriesController.new
32 32 @request = ActionController::TestRequest.new
33 33 @response = ActionController::TestResponse.new
34 34 User.current = nil
35 35 Repository::Bazaar.create(:project => Project.find(3), :url => REPOSITORY_PATH)
36 36 end
37 37
38 38 if File.directory?(REPOSITORY_PATH)
39 39 def test_show
40 40 get :show, :id => 3
41 41 assert_response :success
42 42 assert_template 'show'
43 43 assert_not_nil assigns(:entries)
44 44 assert_not_nil assigns(:changesets)
45 45 end
46 46
47 47 def test_browse_root
48 48 get :show, :id => 3
49 49 assert_response :success
50 50 assert_template 'show'
51 51 assert_not_nil assigns(:entries)
52 52 assert_equal 2, assigns(:entries).size
53 53 assert assigns(:entries).detect {|e| e.name == 'directory' && e.kind == 'dir'}
54 54 assert assigns(:entries).detect {|e| e.name == 'doc-mkdir.txt' && e.kind == 'file'}
55 55 end
56 56
57 57 def test_browse_directory
58 58 get :show, :id => 3, :path => ['directory']
59 59 assert_response :success
60 60 assert_template 'show'
61 61 assert_not_nil assigns(:entries)
62 62 assert_equal ['doc-ls.txt', 'document.txt', 'edit.png'], assigns(:entries).collect(&:name)
63 63 entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
64 64 assert_not_nil entry
65 65 assert_equal 'file', entry.kind
66 66 assert_equal 'directory/edit.png', entry.path
67 67 end
68 68
69 69 def test_browse_at_given_revision
70 70 get :show, :id => 3, :path => [], :rev => 3
71 71 assert_response :success
72 72 assert_template 'show'
73 73 assert_not_nil assigns(:entries)
74 74 assert_equal ['directory', 'doc-deleted.txt', 'doc-ls.txt', 'doc-mkdir.txt'], assigns(:entries).collect(&:name)
75 75 end
76 76
77 77 def test_changes
78 78 get :changes, :id => 3, :path => ['doc-mkdir.txt']
79 79 assert_response :success
80 80 assert_template 'changes'
81 81 assert_tag :tag => 'h2', :content => 'doc-mkdir.txt'
82 82 end
83 83
84 84 def test_entry_show
85 85 get :entry, :id => 3, :path => ['directory', 'doc-ls.txt']
86 86 assert_response :success
87 87 assert_template 'entry'
88 88 # Line 19
89 89 assert_tag :tag => 'th',
90 90 :content => /29/,
91 91 :attributes => { :class => /line-num/ },
92 92 :sibling => { :tag => 'td', :content => /Show help message/ }
93 93 end
94 94
95 95 def test_entry_download
96 96 get :entry, :id => 3, :path => ['directory', 'doc-ls.txt'], :format => 'raw'
97 97 assert_response :success
98 98 # File content
99 99 assert @response.body.include?('Show help message')
100 100 end
101 101
102 102 def test_directory_entry
103 103 get :entry, :id => 3, :path => ['directory']
104 104 assert_response :success
105 105 assert_template 'show'
106 106 assert_not_nil assigns(:entry)
107 107 assert_equal 'directory', assigns(:entry).name
108 108 end
109 109
110 110 def test_diff
111 111 # Full diff of changeset 3
112 112 get :diff, :id => 3, :rev => 3
113 113 assert_response :success
114 114 assert_template 'diff'
115 115 # Line 22 removed
116 116 assert_tag :tag => 'th',
117 117 :content => /2/,
118 118 :sibling => { :tag => 'td',
119 119 :attributes => { :class => /diff_in/ },
120 120 :content => /Main purpose/ }
121 121 end
122 122
123 123 def test_annotate
124 124 get :annotate, :id => 3, :path => ['doc-mkdir.txt']
125 125 assert_response :success
126 126 assert_template 'annotate'
127 127 # Line 2, revision 3
128 128 assert_tag :tag => 'th', :content => /2/,
129 129 :sibling => { :tag => 'td', :child => { :tag => 'a', :content => /3/ } },
130 130 :sibling => { :tag => 'td', :content => /jsmith/ },
131 131 :sibling => { :tag => 'td', :content => /Main purpose/ }
132 132 end
133 133 else
134 134 puts "Bazaar test repository NOT FOUND. Skipping functional tests !!!"
135 135 def test_fake; assert true end
136 136 end
137 137 end
@@ -1,105 +1,105
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'repositories_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class RepositoriesController; def rescue_action(e) raise e end; end
23 23
24 24 class RepositoriesControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles, :members, :member_roles, :repositories, :issues, :issue_statuses, :changesets, :changes, :issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
26 26
27 27 def setup
28 28 @controller = RepositoriesController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_revisions
35 35 get :revisions, :id => 1
36 36 assert_response :success
37 37 assert_template 'revisions'
38 38 assert_not_nil assigns(:changesets)
39 39 end
40 40
41 41 def test_revision
42 42 get :revision, :id => 1, :rev => 1
43 43 assert_response :success
44 44 assert_not_nil assigns(:changeset)
45 45 assert_equal "1", assigns(:changeset).revision
46 46 end
47 47
48 48 def test_revision_with_before_nil_and_afer_normal
49 49 get :revision, {:id => 1, :rev => 1}
50 50 assert_response :success
51 51 assert_template 'revision'
52 52 assert_no_tag :tag => "div", :attributes => { :class => "contextual" },
53 53 :child => { :tag => "a", :attributes => { :href => '/projects/ecookbook/repository/revisions/0'}
54 54 }
55 55 assert_tag :tag => "div", :attributes => { :class => "contextual" },
56 56 :child => { :tag => "a", :attributes => { :href => '/projects/ecookbook/repository/revisions/2'}
57 57 }
58 58 end
59 59
60 60 def test_graph_commits_per_month
61 61 get :graph, :id => 1, :graph => 'commits_per_month'
62 62 assert_response :success
63 63 assert_equal 'image/svg+xml', @response.content_type
64 64 end
65 65
66 66 def test_graph_commits_per_author
67 67 get :graph, :id => 1, :graph => 'commits_per_author'
68 68 assert_response :success
69 69 assert_equal 'image/svg+xml', @response.content_type
70 70 end
71 71
72 72 def test_committers
73 73 @request.session[:user_id] = 2
74 74 # add a commit with an unknown user
75 75 Changeset.create!(:repository => Project.find(1).repository, :committer => 'foo', :committed_on => Time.now, :revision => 100, :comments => 'Committed by foo.')
76 76
77 77 get :committers, :id => 1
78 78 assert_response :success
79 79 assert_template 'committers'
80 80
81 81 assert_tag :td, :content => 'dlopper',
82 82 :sibling => { :tag => 'td',
83 83 :child => { :tag => 'select', :attributes => { :name => %r{^committers\[\d+\]\[\]$} },
84 84 :child => { :tag => 'option', :content => 'Dave Lopper',
85 85 :attributes => { :value => '3', :selected => 'selected' }}}}
86 86 assert_tag :td, :content => 'foo',
87 87 :sibling => { :tag => 'td',
88 88 :child => { :tag => 'select', :attributes => { :name => %r{^committers\[\d+\]\[\]$} }}}
89 89 assert_no_tag :td, :content => 'foo',
90 90 :sibling => { :tag => 'td',
91 91 :descendant => { :tag => 'option', :attributes => { :selected => 'selected' }}}
92 92 end
93 93
94 94 def test_map_committers
95 95 @request.session[:user_id] = 2
96 96 # add a commit with an unknown user
97 97 c = Changeset.create!(:repository => Project.find(1).repository, :committer => 'foo', :committed_on => Time.now, :revision => 100, :comments => 'Committed by foo.')
98 98
99 99 assert_no_difference "Changeset.count(:conditions => 'user_id = 3')" do
100 100 post :committers, :id => 1, :committers => { '0' => ['foo', '2'], '1' => ['dlopper', '3']}
101 101 assert_redirected_to '/projects/ecookbook/repository/committers'
102 102 assert_equal User.find(2), c.reload.user
103 103 end
104 104 end
105 105 end
@@ -1,165 +1,165
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'repositories_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class RepositoriesController; def rescue_action(e) raise e end; end
23 23
24 24 class RepositoriesCvsControllerTest < ActionController::TestCase
25 25
26 26 # No '..' in the repository path
27 27 REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/cvs_repository'
28 28 REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
29 29 # CVS module
30 30 MODULE_NAME = 'test'
31 31
32 32 def setup
33 33 @controller = RepositoriesController.new
34 34 @request = ActionController::TestRequest.new
35 35 @response = ActionController::TestResponse.new
36 36 Setting.default_language = 'en'
37 37 User.current = nil
38 38
39 39 @project = Project.find(1)
40 40 @project.repository = Repository::Cvs.create(:root_url => REPOSITORY_PATH,
41 41 :url => MODULE_NAME)
42 42 end
43 43
44 44 if File.directory?(REPOSITORY_PATH)
45 45 def test_show
46 46 get :show, :id => 1
47 47 assert_response :success
48 48 assert_template 'show'
49 49 assert_not_nil assigns(:entries)
50 50 assert_not_nil assigns(:changesets)
51 51 end
52 52
53 53 def test_browse_root
54 54 get :show, :id => 1
55 55 assert_response :success
56 56 assert_template 'show'
57 57 assert_not_nil assigns(:entries)
58 58 assert_equal 3, assigns(:entries).size
59 59
60 60 entry = assigns(:entries).detect {|e| e.name == 'images'}
61 61 assert_equal 'dir', entry.kind
62 62
63 63 entry = assigns(:entries).detect {|e| e.name == 'README'}
64 64 assert_equal 'file', entry.kind
65 65 end
66 66
67 67 def test_browse_directory
68 68 get :show, :id => 1, :path => ['images']
69 69 assert_response :success
70 70 assert_template 'show'
71 71 assert_not_nil assigns(:entries)
72 72 assert_equal ['add.png', 'delete.png', 'edit.png'], assigns(:entries).collect(&:name)
73 73 entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
74 74 assert_not_nil entry
75 75 assert_equal 'file', entry.kind
76 76 assert_equal 'images/edit.png', entry.path
77 77 end
78 78
79 79 def test_browse_at_given_revision
80 80 Project.find(1).repository.fetch_changesets
81 81 get :show, :id => 1, :path => ['images'], :rev => 1
82 82 assert_response :success
83 83 assert_template 'show'
84 84 assert_not_nil assigns(:entries)
85 85 assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name)
86 86 end
87 87
88 88 def test_entry
89 89 get :entry, :id => 1, :path => ['sources', 'watchers_controller.rb']
90 90 assert_response :success
91 91 assert_template 'entry'
92 92 assert_no_tag :tag => 'td', :attributes => { :class => /line-code/},
93 93 :content => /before_filter/
94 94 end
95 95
96 96 def test_entry_at_given_revision
97 97 # changesets must be loaded
98 98 Project.find(1).repository.fetch_changesets
99 99 get :entry, :id => 1, :path => ['sources', 'watchers_controller.rb'], :rev => 2
100 100 assert_response :success
101 101 assert_template 'entry'
102 102 # this line was removed in r3
103 103 assert_tag :tag => 'td', :attributes => { :class => /line-code/},
104 104 :content => /before_filter/
105 105 end
106 106
107 107 def test_entry_not_found
108 108 get :entry, :id => 1, :path => ['sources', 'zzz.c']
109 109 assert_tag :tag => 'p', :attributes => { :id => /errorExplanation/ },
110 110 :content => /The entry or revision was not found in the repository/
111 111 end
112 112
113 113 def test_entry_download
114 114 get :entry, :id => 1, :path => ['sources', 'watchers_controller.rb'], :format => 'raw'
115 115 assert_response :success
116 116 end
117 117
118 118 def test_directory_entry
119 119 get :entry, :id => 1, :path => ['sources']
120 120 assert_response :success
121 121 assert_template 'show'
122 122 assert_not_nil assigns(:entry)
123 123 assert_equal 'sources', assigns(:entry).name
124 124 end
125 125
126 126 def test_diff
127 127 Project.find(1).repository.fetch_changesets
128 128 get :diff, :id => 1, :rev => 3, :type => 'inline'
129 129 assert_response :success
130 130 assert_template 'diff'
131 131 assert_tag :tag => 'td', :attributes => { :class => 'line-code diff_out' },
132 132 :content => /watched.remove_watcher/
133 133 assert_tag :tag => 'td', :attributes => { :class => 'line-code diff_in' },
134 134 :content => /watched.remove_all_watcher/
135 135 end
136 136
137 137 def test_annotate
138 138 Project.find(1).repository.fetch_changesets
139 139 get :annotate, :id => 1, :path => ['sources', 'watchers_controller.rb']
140 140 assert_response :success
141 141 assert_template 'annotate'
142 142 # 1.1 line
143 143 assert_tag :tag => 'th', :attributes => { :class => 'line-num' },
144 144 :content => '18',
145 145 :sibling => { :tag => 'td', :attributes => { :class => 'revision' },
146 146 :content => /1.1/,
147 147 :sibling => { :tag => 'td', :attributes => { :class => 'author' },
148 148 :content => /LANG/
149 149 }
150 150 }
151 151 # 1.2 line
152 152 assert_tag :tag => 'th', :attributes => { :class => 'line-num' },
153 153 :content => '32',
154 154 :sibling => { :tag => 'td', :attributes => { :class => 'revision' },
155 155 :content => /1.2/,
156 156 :sibling => { :tag => 'td', :attributes => { :class => 'author' },
157 157 :content => /LANG/
158 158 }
159 159 }
160 160 end
161 161 else
162 162 puts "CVS test repository NOT FOUND. Skipping functional tests !!!"
163 163 def test_fake; assert true end
164 164 end
165 165 end
@@ -1,103 +1,103
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'repositories_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class RepositoriesController; def rescue_action(e) raise e end; end
23 23
24 24 class RepositoriesDarcsControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles, :members, :member_roles, :repositories, :enabled_modules
26 26
27 27 # No '..' in the repository path
28 28 REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/darcs_repository'
29 29
30 30 def setup
31 31 @controller = RepositoriesController.new
32 32 @request = ActionController::TestRequest.new
33 33 @response = ActionController::TestResponse.new
34 34 User.current = nil
35 35 Repository::Darcs.create(:project => Project.find(3), :url => REPOSITORY_PATH)
36 36 end
37 37
38 38 if File.directory?(REPOSITORY_PATH)
39 39 def test_show
40 40 get :show, :id => 3
41 41 assert_response :success
42 42 assert_template 'show'
43 43 assert_not_nil assigns(:entries)
44 44 assert_not_nil assigns(:changesets)
45 45 end
46 46
47 47 def test_browse_root
48 48 get :show, :id => 3
49 49 assert_response :success
50 50 assert_template 'show'
51 51 assert_not_nil assigns(:entries)
52 52 assert_equal 3, assigns(:entries).size
53 53 assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'}
54 54 assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
55 55 assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'}
56 56 end
57 57
58 58 def test_browse_directory
59 59 get :show, :id => 3, :path => ['images']
60 60 assert_response :success
61 61 assert_template 'show'
62 62 assert_not_nil assigns(:entries)
63 63 assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name)
64 64 entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
65 65 assert_not_nil entry
66 66 assert_equal 'file', entry.kind
67 67 assert_equal 'images/edit.png', entry.path
68 68 end
69 69
70 70 def test_browse_at_given_revision
71 71 Project.find(3).repository.fetch_changesets
72 72 get :show, :id => 3, :path => ['images'], :rev => 1
73 73 assert_response :success
74 74 assert_template 'show'
75 75 assert_not_nil assigns(:entries)
76 76 assert_equal ['delete.png'], assigns(:entries).collect(&:name)
77 77 end
78 78
79 79 def test_changes
80 80 get :changes, :id => 3, :path => ['images', 'edit.png']
81 81 assert_response :success
82 82 assert_template 'changes'
83 83 assert_tag :tag => 'h2', :content => 'edit.png'
84 84 end
85 85
86 86 def test_diff
87 87 Project.find(3).repository.fetch_changesets
88 88 # Full diff of changeset 5
89 89 get :diff, :id => 3, :rev => 5
90 90 assert_response :success
91 91 assert_template 'diff'
92 92 # Line 22 removed
93 93 assert_tag :tag => 'th',
94 94 :content => /22/,
95 95 :sibling => { :tag => 'td',
96 96 :attributes => { :class => /diff_out/ },
97 97 :content => /def remove/ }
98 98 end
99 99 else
100 100 puts "Darcs test repository NOT FOUND. Skipping functional tests !!!"
101 101 def test_fake; assert true end
102 102 end
103 103 end
@@ -1,164 +1,164
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'repositories_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class RepositoriesController; def rescue_action(e) raise e end; end
23 23
24 24 class RepositoriesGitControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles, :members, :member_roles, :repositories, :enabled_modules
26 26
27 27 # No '..' in the repository path
28 28 REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository'
29 29 REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
30 30
31 31 def setup
32 32 @controller = RepositoriesController.new
33 33 @request = ActionController::TestRequest.new
34 34 @response = ActionController::TestResponse.new
35 35 User.current = nil
36 36 Repository::Git.create(:project => Project.find(3), :url => REPOSITORY_PATH)
37 37 end
38 38
39 39 if File.directory?(REPOSITORY_PATH)
40 40 def test_show
41 41 get :show, :id => 3
42 42 assert_response :success
43 43 assert_template 'show'
44 44 assert_not_nil assigns(:entries)
45 45 assert_not_nil assigns(:changesets)
46 46 end
47 47
48 48 def test_browse_root
49 49 get :show, :id => 3
50 50 assert_response :success
51 51 assert_template 'show'
52 52 assert_not_nil assigns(:entries)
53 53 assert_equal 9, assigns(:entries).size
54 54 assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'}
55 55 assert assigns(:entries).detect {|e| e.name == 'this_is_a_really_long_and_verbose_directory_name' && e.kind == 'dir'}
56 56 assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
57 57 assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'}
58 58 assert assigns(:entries).detect {|e| e.name == 'copied_README' && e.kind == 'file'}
59 59 assert assigns(:entries).detect {|e| e.name == 'new_file.txt' && e.kind == 'file'}
60 60 assert assigns(:entries).detect {|e| e.name == 'renamed_test.txt' && e.kind == 'file'}
61 61 assert assigns(:entries).detect {|e| e.name == 'filemane with spaces.txt' && e.kind == 'file'}
62 62 assert assigns(:entries).detect {|e| e.name == ' filename with a leading space.txt ' && e.kind == 'file'}
63 63 end
64 64
65 65 def test_browse_branch
66 66 get :show, :id => 3, :rev => 'test_branch'
67 67 assert_response :success
68 68 assert_template 'show'
69 69 assert_not_nil assigns(:entries)
70 70 assert_equal 4, assigns(:entries).size
71 71 assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'}
72 72 assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
73 73 assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'}
74 74 assert assigns(:entries).detect {|e| e.name == 'test.txt' && e.kind == 'file'}
75 75 end
76 76
77 77 def test_browse_directory
78 78 get :show, :id => 3, :path => ['images']
79 79 assert_response :success
80 80 assert_template 'show'
81 81 assert_not_nil assigns(:entries)
82 82 assert_equal ['edit.png'], assigns(:entries).collect(&:name)
83 83 entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
84 84 assert_not_nil entry
85 85 assert_equal 'file', entry.kind
86 86 assert_equal 'images/edit.png', entry.path
87 87 end
88 88
89 89 def test_browse_at_given_revision
90 90 get :show, :id => 3, :path => ['images'], :rev => '7234cb2750b63f47bff735edc50a1c0a433c2518'
91 91 assert_response :success
92 92 assert_template 'show'
93 93 assert_not_nil assigns(:entries)
94 94 assert_equal ['delete.png'], assigns(:entries).collect(&:name)
95 95 end
96 96
97 97 def test_changes
98 98 get :changes, :id => 3, :path => ['images', 'edit.png']
99 99 assert_response :success
100 100 assert_template 'changes'
101 101 assert_tag :tag => 'h2', :content => 'edit.png'
102 102 end
103 103
104 104 def test_entry_show
105 105 get :entry, :id => 3, :path => ['sources', 'watchers_controller.rb']
106 106 assert_response :success
107 107 assert_template 'entry'
108 108 # Line 19
109 109 assert_tag :tag => 'th',
110 110 :content => /11/,
111 111 :attributes => { :class => /line-num/ },
112 112 :sibling => { :tag => 'td', :content => /WITHOUT ANY WARRANTY/ }
113 113 end
114 114
115 115 def test_entry_download
116 116 get :entry, :id => 3, :path => ['sources', 'watchers_controller.rb'], :format => 'raw'
117 117 assert_response :success
118 118 # File content
119 119 assert @response.body.include?('WITHOUT ANY WARRANTY')
120 120 end
121 121
122 122 def test_directory_entry
123 123 get :entry, :id => 3, :path => ['sources']
124 124 assert_response :success
125 125 assert_template 'show'
126 126 assert_not_nil assigns(:entry)
127 127 assert_equal 'sources', assigns(:entry).name
128 128 end
129 129
130 130 def test_diff
131 131 # Full diff of changeset 2f9c0091
132 132 get :diff, :id => 3, :rev => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
133 133 assert_response :success
134 134 assert_template 'diff'
135 135 # Line 22 removed
136 136 assert_tag :tag => 'th',
137 137 :content => /22/,
138 138 :sibling => { :tag => 'td',
139 139 :attributes => { :class => /diff_out/ },
140 140 :content => /def remove/ }
141 141 end
142 142
143 143 def test_annotate
144 144 get :annotate, :id => 3, :path => ['sources', 'watchers_controller.rb']
145 145 assert_response :success
146 146 assert_template 'annotate'
147 147 # Line 23, changeset 2f9c0091
148 148 assert_tag :tag => 'th', :content => /24/,
149 149 :sibling => { :tag => 'td', :child => { :tag => 'a', :content => /2f9c0091/ } },
150 150 :sibling => { :tag => 'td', :content => /jsmith/ },
151 151 :sibling => { :tag => 'td', :content => /watcher =/ }
152 152 end
153 153
154 154 def test_annotate_binary_file
155 155 get :annotate, :id => 3, :path => ['images', 'edit.png']
156 156 assert_response 500
157 157 assert_tag :tag => 'p', :attributes => { :id => /errorExplanation/ },
158 158 :content => /can not be annotated/
159 159 end
160 160 else
161 161 puts "Git test repository NOT FOUND. Skipping functional tests !!!"
162 162 def test_fake; assert true end
163 163 end
164 164 end
@@ -1,138 +1,138
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'repositories_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class RepositoriesController; def rescue_action(e) raise e end; end
23 23
24 24 class RepositoriesMercurialControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles, :members, :member_roles, :repositories, :enabled_modules
26 26
27 27 # No '..' in the repository path
28 28 REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/mercurial_repository'
29 29
30 30 def setup
31 31 @controller = RepositoriesController.new
32 32 @request = ActionController::TestRequest.new
33 33 @response = ActionController::TestResponse.new
34 34 User.current = nil
35 35 Repository::Mercurial.create(:project => Project.find(3), :url => REPOSITORY_PATH)
36 36 end
37 37
38 38 if File.directory?(REPOSITORY_PATH)
39 39 def test_show
40 40 get :show, :id => 3
41 41 assert_response :success
42 42 assert_template 'show'
43 43 assert_not_nil assigns(:entries)
44 44 assert_not_nil assigns(:changesets)
45 45 end
46 46
47 47 def test_show_root
48 48 get :show, :id => 3
49 49 assert_response :success
50 50 assert_template 'show'
51 51 assert_not_nil assigns(:entries)
52 52 assert_equal 3, assigns(:entries).size
53 53 assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'}
54 54 assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
55 55 assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'}
56 56 end
57 57
58 58 def test_show_directory
59 59 get :show, :id => 3, :path => ['images']
60 60 assert_response :success
61 61 assert_template 'show'
62 62 assert_not_nil assigns(:entries)
63 63 assert_equal ['delete.png', 'edit.png'], assigns(:entries).collect(&:name)
64 64 entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
65 65 assert_not_nil entry
66 66 assert_equal 'file', entry.kind
67 67 assert_equal 'images/edit.png', entry.path
68 68 end
69 69
70 70 def test_show_at_given_revision
71 71 get :show, :id => 3, :path => ['images'], :rev => 0
72 72 assert_response :success
73 73 assert_template 'show'
74 74 assert_not_nil assigns(:entries)
75 75 assert_equal ['delete.png'], assigns(:entries).collect(&:name)
76 76 end
77 77
78 78 def test_changes
79 79 get :changes, :id => 3, :path => ['images', 'edit.png']
80 80 assert_response :success
81 81 assert_template 'changes'
82 82 assert_tag :tag => 'h2', :content => 'edit.png'
83 83 end
84 84
85 85 def test_entry_show
86 86 get :entry, :id => 3, :path => ['sources', 'watchers_controller.rb']
87 87 assert_response :success
88 88 assert_template 'entry'
89 89 # Line 19
90 90 assert_tag :tag => 'th',
91 91 :content => /10/,
92 92 :attributes => { :class => /line-num/ },
93 93 :sibling => { :tag => 'td', :content => /WITHOUT ANY WARRANTY/ }
94 94 end
95 95
96 96 def test_entry_download
97 97 get :entry, :id => 3, :path => ['sources', 'watchers_controller.rb'], :format => 'raw'
98 98 assert_response :success
99 99 # File content
100 100 assert @response.body.include?('WITHOUT ANY WARRANTY')
101 101 end
102 102
103 103 def test_directory_entry
104 104 get :entry, :id => 3, :path => ['sources']
105 105 assert_response :success
106 106 assert_template 'show'
107 107 assert_not_nil assigns(:entry)
108 108 assert_equal 'sources', assigns(:entry).name
109 109 end
110 110
111 111 def test_diff
112 112 # Full diff of changeset 4
113 113 get :diff, :id => 3, :rev => 4
114 114 assert_response :success
115 115 assert_template 'diff'
116 116 # Line 22 removed
117 117 assert_tag :tag => 'th',
118 118 :content => /22/,
119 119 :sibling => { :tag => 'td',
120 120 :attributes => { :class => /diff_out/ },
121 121 :content => /def remove/ }
122 122 end
123 123
124 124 def test_annotate
125 125 get :annotate, :id => 3, :path => ['sources', 'watchers_controller.rb']
126 126 assert_response :success
127 127 assert_template 'annotate'
128 128 # Line 23, revision 4
129 129 assert_tag :tag => 'th', :content => /23/,
130 130 :sibling => { :tag => 'td', :child => { :tag => 'a', :content => /4/ } },
131 131 :sibling => { :tag => 'td', :content => /jsmith/ },
132 132 :sibling => { :tag => 'td', :content => /watcher =/ }
133 133 end
134 134 else
135 135 puts "Mercurial test repository NOT FOUND. Skipping functional tests !!!"
136 136 def test_fake; assert true end
137 137 end
138 138 end
@@ -1,217 +1,217
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'repositories_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class RepositoriesController; def rescue_action(e) raise e end; end
23 23
24 24 class RepositoriesSubversionControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
26 26 :repositories, :issues, :issue_statuses, :changesets, :changes,
27 27 :issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
28 28
29 29 def setup
30 30 @controller = RepositoriesController.new
31 31 @request = ActionController::TestRequest.new
32 32 @response = ActionController::TestResponse.new
33 33 Setting.default_language = 'en'
34 34 User.current = nil
35 35 end
36 36
37 37 if repository_configured?('subversion')
38 38 def test_show
39 39 get :show, :id => 1
40 40 assert_response :success
41 41 assert_template 'show'
42 42 assert_not_nil assigns(:entries)
43 43 assert_not_nil assigns(:changesets)
44 44 end
45 45
46 46 def test_browse_root
47 47 get :show, :id => 1
48 48 assert_response :success
49 49 assert_template 'show'
50 50 assert_not_nil assigns(:entries)
51 51 entry = assigns(:entries).detect {|e| e.name == 'subversion_test'}
52 52 assert_equal 'dir', entry.kind
53 53 end
54 54
55 55 def test_browse_directory
56 56 get :show, :id => 1, :path => ['subversion_test']
57 57 assert_response :success
58 58 assert_template 'show'
59 59 assert_not_nil assigns(:entries)
60 60 assert_equal ['[folder_with_brackets]', 'folder', '.project', 'helloworld.c', 'textfile.txt'], assigns(:entries).collect(&:name)
61 61 entry = assigns(:entries).detect {|e| e.name == 'helloworld.c'}
62 62 assert_equal 'file', entry.kind
63 63 assert_equal 'subversion_test/helloworld.c', entry.path
64 64 assert_tag :a, :content => 'helloworld.c', :attributes => { :class => /text\-x\-c/ }
65 65 end
66 66
67 67 def test_browse_at_given_revision
68 68 get :show, :id => 1, :path => ['subversion_test'], :rev => 4
69 69 assert_response :success
70 70 assert_template 'show'
71 71 assert_not_nil assigns(:entries)
72 72 assert_equal ['folder', '.project', 'helloworld.c', 'helloworld.rb', 'textfile.txt'], assigns(:entries).collect(&:name)
73 73 end
74 74
75 75 def test_file_changes
76 76 get :changes, :id => 1, :path => ['subversion_test', 'folder', 'helloworld.rb' ]
77 77 assert_response :success
78 78 assert_template 'changes'
79 79
80 80 changesets = assigns(:changesets)
81 81 assert_not_nil changesets
82 82 assert_equal %w(6 3 2), changesets.collect(&:revision)
83 83
84 84 # svn properties displayed with svn >= 1.5 only
85 85 if Redmine::Scm::Adapters::SubversionAdapter.client_version_above?([1, 5, 0])
86 86 assert_not_nil assigns(:properties)
87 87 assert_equal 'native', assigns(:properties)['svn:eol-style']
88 88 assert_tag :ul,
89 89 :child => { :tag => 'li',
90 90 :child => { :tag => 'b', :content => 'svn:eol-style' },
91 91 :child => { :tag => 'span', :content => 'native' } }
92 92 end
93 93 end
94 94
95 95 def test_directory_changes
96 96 get :changes, :id => 1, :path => ['subversion_test', 'folder' ]
97 97 assert_response :success
98 98 assert_template 'changes'
99 99
100 100 changesets = assigns(:changesets)
101 101 assert_not_nil changesets
102 102 assert_equal %w(10 9 7 6 5 2), changesets.collect(&:revision)
103 103 end
104 104
105 105 def test_entry
106 106 get :entry, :id => 1, :path => ['subversion_test', 'helloworld.c']
107 107 assert_response :success
108 108 assert_template 'entry'
109 109 end
110 110
111 111 def test_entry_should_send_if_too_big
112 112 # no files in the test repo is larger than 1KB...
113 113 with_settings :file_max_size_displayed => 0 do
114 114 get :entry, :id => 1, :path => ['subversion_test', 'helloworld.c']
115 115 assert_response :success
116 116 assert_template ''
117 117 assert_equal 'attachment; filename="helloworld.c"', @response.headers['Content-Disposition']
118 118 end
119 119 end
120 120
121 121 def test_entry_at_given_revision
122 122 get :entry, :id => 1, :path => ['subversion_test', 'helloworld.rb'], :rev => 2
123 123 assert_response :success
124 124 assert_template 'entry'
125 125 # this line was removed in r3 and file was moved in r6
126 126 assert_tag :tag => 'td', :attributes => { :class => /line-code/},
127 127 :content => /Here's the code/
128 128 end
129 129
130 130 def test_entry_not_found
131 131 get :entry, :id => 1, :path => ['subversion_test', 'zzz.c']
132 132 assert_tag :tag => 'p', :attributes => { :id => /errorExplanation/ },
133 133 :content => /The entry or revision was not found in the repository/
134 134 end
135 135
136 136 def test_entry_download
137 137 get :entry, :id => 1, :path => ['subversion_test', 'helloworld.c'], :format => 'raw'
138 138 assert_response :success
139 139 assert_template ''
140 140 assert_equal 'attachment; filename="helloworld.c"', @response.headers['Content-Disposition']
141 141 end
142 142
143 143 def test_directory_entry
144 144 get :entry, :id => 1, :path => ['subversion_test', 'folder']
145 145 assert_response :success
146 146 assert_template 'show'
147 147 assert_not_nil assigns(:entry)
148 148 assert_equal 'folder', assigns(:entry).name
149 149 end
150 150
151 151 def test_revision
152 152 get :revision, :id => 1, :rev => 2
153 153 assert_response :success
154 154 assert_template 'revision'
155 155 assert_tag :tag => 'ul',
156 156 :child => { :tag => 'li',
157 157 # link to the entry at rev 2
158 158 :child => { :tag => 'a',
159 159 :attributes => {:href => '/projects/ecookbook/repository/revisions/2/entry/test/some/path/in/the/repo'},
160 160 :content => 'repo',
161 161 # link to partial diff
162 162 :sibling => { :tag => 'a',
163 163 :attributes => { :href => '/projects/ecookbook/repository/revisions/2/diff/test/some/path/in/the/repo' }
164 164 }
165 165 }
166 166 }
167 167 end
168 168
169 169 def test_revision_with_repository_pointing_to_a_subdirectory
170 170 r = Project.find(1).repository
171 171 # Changes repository url to a subdirectory
172 172 r.update_attribute :url, (r.url + '/test/some')
173 173
174 174 get :revision, :id => 1, :rev => 2
175 175 assert_response :success
176 176 assert_template 'revision'
177 177 assert_tag :tag => 'ul',
178 178 :child => { :tag => 'li',
179 179 # link to the entry at rev 2
180 180 :child => { :tag => 'a',
181 181 :attributes => {:href => '/projects/ecookbook/repository/revisions/2/entry/path/in/the/repo'},
182 182 :content => 'repo',
183 183 # link to partial diff
184 184 :sibling => { :tag => 'a',
185 185 :attributes => { :href => '/projects/ecookbook/repository/revisions/2/diff/path/in/the/repo' }
186 186 }
187 187 }
188 188 }
189 189 end
190 190
191 191 def test_revision_diff
192 192 get :diff, :id => 1, :rev => 3
193 193 assert_response :success
194 194 assert_template 'diff'
195 195 end
196 196
197 197 def test_directory_diff
198 198 get :diff, :id => 1, :rev => 6, :rev_to => 2, :path => ['subversion_test', 'folder']
199 199 assert_response :success
200 200 assert_template 'diff'
201 201
202 202 diff = assigns(:diff)
203 203 assert_not_nil diff
204 204 # 2 files modified
205 205 assert_equal 2, Redmine::UnifiedDiff.new(diff).size
206 206 end
207 207
208 208 def test_annotate
209 209 get :annotate, :id => 1, :path => ['subversion_test', 'helloworld.c']
210 210 assert_response :success
211 211 assert_template 'annotate'
212 212 end
213 213 else
214 214 puts "Subversion test repository NOT FOUND. Skipping functional tests !!!"
215 215 def test_fake; assert true end
216 216 end
217 217 end
@@ -1,180 +1,180
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'roles_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class RolesController; def rescue_action(e) raise e end; end
23 23
24 24 class RolesControllerTest < ActionController::TestCase
25 25 fixtures :roles, :users, :members, :member_roles, :workflows
26 26
27 27 def setup
28 28 @controller = RolesController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 @request.session[:user_id] = 1 # admin
33 33 end
34 34
35 35 def test_get_index
36 36 get :index
37 37 assert_response :success
38 38 assert_template 'index'
39 39
40 40 assert_not_nil assigns(:roles)
41 41 assert_equal Role.find(:all, :order => 'builtin, position'), assigns(:roles)
42 42
43 43 assert_tag :tag => 'a', :attributes => { :href => '/roles/edit/1' },
44 44 :content => 'Manager'
45 45 end
46 46
47 47 def test_get_new
48 48 get :new
49 49 assert_response :success
50 50 assert_template 'new'
51 51 end
52 52
53 53 def test_post_new_with_validaton_failure
54 54 post :new, :role => {:name => '',
55 55 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
56 56 :assignable => '0'}
57 57
58 58 assert_response :success
59 59 assert_template 'new'
60 60 assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' }
61 61 end
62 62
63 63 def test_post_new_without_workflow_copy
64 64 post :new, :role => {:name => 'RoleWithoutWorkflowCopy',
65 65 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
66 66 :assignable => '0'}
67 67
68 68 assert_redirected_to '/roles'
69 69 role = Role.find_by_name('RoleWithoutWorkflowCopy')
70 70 assert_not_nil role
71 71 assert_equal [:add_issues, :edit_issues, :log_time], role.permissions
72 72 assert !role.assignable?
73 73 end
74 74
75 75 def test_post_new_with_workflow_copy
76 76 post :new, :role => {:name => 'RoleWithWorkflowCopy',
77 77 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
78 78 :assignable => '0'},
79 79 :copy_workflow_from => '1'
80 80
81 81 assert_redirected_to '/roles'
82 82 role = Role.find_by_name('RoleWithWorkflowCopy')
83 83 assert_not_nil role
84 84 assert_equal Role.find(1).workflows.size, role.workflows.size
85 85 end
86 86
87 87 def test_get_edit
88 88 get :edit, :id => 1
89 89 assert_response :success
90 90 assert_template 'edit'
91 91 assert_equal Role.find(1), assigns(:role)
92 92 end
93 93
94 94 def test_post_edit
95 95 post :edit, :id => 1,
96 96 :role => {:name => 'Manager',
97 97 :permissions => ['edit_project', ''],
98 98 :assignable => '0'}
99 99
100 100 assert_redirected_to '/roles'
101 101 role = Role.find(1)
102 102 assert_equal [:edit_project], role.permissions
103 103 end
104 104
105 105 def test_destroy
106 106 r = Role.new(:name => 'ToBeDestroyed', :permissions => [:view_wiki_pages])
107 107 assert r.save
108 108
109 109 post :destroy, :id => r
110 110 assert_redirected_to '/roles'
111 111 assert_nil Role.find_by_id(r.id)
112 112 end
113 113
114 114 def test_destroy_role_in_use
115 115 post :destroy, :id => 1
116 116 assert_redirected_to '/roles'
117 117 assert flash[:error] == 'This role is in use and can not be deleted.'
118 118 assert_not_nil Role.find_by_id(1)
119 119 end
120 120
121 121 def test_get_report
122 122 get :report
123 123 assert_response :success
124 124 assert_template 'report'
125 125
126 126 assert_not_nil assigns(:roles)
127 127 assert_equal Role.find(:all, :order => 'builtin, position'), assigns(:roles)
128 128
129 129 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
130 130 :name => 'permissions[3][]',
131 131 :value => 'add_issues',
132 132 :checked => 'checked' }
133 133
134 134 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
135 135 :name => 'permissions[3][]',
136 136 :value => 'delete_issues',
137 137 :checked => nil }
138 138 end
139 139
140 140 def test_post_report
141 141 post :report, :permissions => { '0' => '', '1' => ['edit_issues'], '3' => ['add_issues', 'delete_issues']}
142 142 assert_redirected_to '/roles'
143 143
144 144 assert_equal [:edit_issues], Role.find(1).permissions
145 145 assert_equal [:add_issues, :delete_issues], Role.find(3).permissions
146 146 assert Role.find(2).permissions.empty?
147 147 end
148 148
149 149 def test_clear_all_permissions
150 150 post :report, :permissions => { '0' => '' }
151 151 assert_redirected_to '/roles'
152 152 assert Role.find(1).permissions.empty?
153 153 end
154 154
155 155 def test_move_highest
156 156 post :edit, :id => 3, :role => {:move_to => 'highest'}
157 157 assert_redirected_to '/roles'
158 158 assert_equal 1, Role.find(3).position
159 159 end
160 160
161 161 def test_move_higher
162 162 position = Role.find(3).position
163 163 post :edit, :id => 3, :role => {:move_to => 'higher'}
164 164 assert_redirected_to '/roles'
165 165 assert_equal position - 1, Role.find(3).position
166 166 end
167 167
168 168 def test_move_lower
169 169 position = Role.find(2).position
170 170 post :edit, :id => 2, :role => {:move_to => 'lower'}
171 171 assert_redirected_to '/roles'
172 172 assert_equal position + 1, Role.find(2).position
173 173 end
174 174
175 175 def test_move_lowest
176 176 post :edit, :id => 2, :role => {:move_to => 'lowest'}
177 177 assert_redirected_to '/roles'
178 178 assert_equal Role.count, Role.find(2).position
179 179 end
180 180 end
@@ -1,147 +1,147
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2 require 'search_controller'
3 3
4 4 # Re-raise errors caught by the controller.
5 5 class SearchController; def rescue_action(e) raise e end; end
6 6
7 7 class SearchControllerTest < ActionController::TestCase
8 8 fixtures :projects, :enabled_modules, :roles, :users, :members, :member_roles,
9 9 :issues, :trackers, :issue_statuses,
10 10 :custom_fields, :custom_values,
11 11 :repositories, :changesets
12 12
13 13 def setup
14 14 @controller = SearchController.new
15 15 @request = ActionController::TestRequest.new
16 16 @response = ActionController::TestResponse.new
17 17 User.current = nil
18 18 end
19 19
20 20 def test_search_for_projects
21 21 get :index
22 22 assert_response :success
23 23 assert_template 'index'
24 24
25 25 get :index, :q => "cook"
26 26 assert_response :success
27 27 assert_template 'index'
28 28 assert assigns(:results).include?(Project.find(1))
29 29 end
30 30
31 31 def test_search_all_projects
32 32 get :index, :q => 'recipe subproject commit', :submit => 'Search'
33 33 assert_response :success
34 34 assert_template 'index'
35 35
36 36 assert assigns(:results).include?(Issue.find(2))
37 37 assert assigns(:results).include?(Issue.find(5))
38 38 assert assigns(:results).include?(Changeset.find(101))
39 39 assert_tag :dt, :attributes => { :class => /issue/ },
40 40 :child => { :tag => 'a', :content => /Add ingredients categories/ },
41 41 :sibling => { :tag => 'dd', :content => /should be classified by categories/ }
42 42
43 43 assert assigns(:results_by_type).is_a?(Hash)
44 44 assert_equal 5, assigns(:results_by_type)['changesets']
45 45 assert_tag :a, :content => 'Changesets (5)'
46 46 end
47 47
48 48 def test_search_issues
49 49 get :index, :q => 'issue', :issues => 1
50 50 assert_response :success
51 51 assert_template 'index'
52 52
53 53 assert assigns(:results).include?(Issue.find(8))
54 54 assert assigns(:results).include?(Issue.find(5))
55 55 assert_tag :dt, :attributes => { :class => /issue closed/ },
56 56 :child => { :tag => 'a', :content => /Closed/ }
57 57 end
58 58
59 59 def test_search_project_and_subprojects
60 60 get :index, :id => 1, :q => 'recipe subproject', :scope => 'subprojects', :submit => 'Search'
61 61 assert_response :success
62 62 assert_template 'index'
63 63 assert assigns(:results).include?(Issue.find(1))
64 64 assert assigns(:results).include?(Issue.find(5))
65 65 end
66 66
67 67 def test_search_without_searchable_custom_fields
68 68 CustomField.update_all "searchable = #{ActiveRecord::Base.connection.quoted_false}"
69 69
70 70 get :index, :id => 1
71 71 assert_response :success
72 72 assert_template 'index'
73 73 assert_not_nil assigns(:project)
74 74
75 75 get :index, :id => 1, :q => "can"
76 76 assert_response :success
77 77 assert_template 'index'
78 78 end
79 79
80 80 def test_search_with_searchable_custom_fields
81 81 get :index, :id => 1, :q => "stringforcustomfield"
82 82 assert_response :success
83 83 results = assigns(:results)
84 84 assert_not_nil results
85 85 assert_equal 1, results.size
86 86 assert results.include?(Issue.find(7))
87 87 end
88 88
89 89 def test_search_all_words
90 90 # 'all words' is on by default
91 91 get :index, :id => 1, :q => 'recipe updating saving'
92 92 results = assigns(:results)
93 93 assert_not_nil results
94 94 assert_equal 1, results.size
95 95 assert results.include?(Issue.find(3))
96 96 end
97 97
98 98 def test_search_one_of_the_words
99 99 get :index, :id => 1, :q => 'recipe updating saving', :submit => 'Search'
100 100 results = assigns(:results)
101 101 assert_not_nil results
102 102 assert_equal 3, results.size
103 103 assert results.include?(Issue.find(3))
104 104 end
105 105
106 106 def test_search_titles_only_without_result
107 107 get :index, :id => 1, :q => 'recipe updating saving', :all_words => '1', :titles_only => '1', :submit => 'Search'
108 108 results = assigns(:results)
109 109 assert_not_nil results
110 110 assert_equal 0, results.size
111 111 end
112 112
113 113 def test_search_titles_only
114 114 get :index, :id => 1, :q => 'recipe', :titles_only => '1', :submit => 'Search'
115 115 results = assigns(:results)
116 116 assert_not_nil results
117 117 assert_equal 2, results.size
118 118 end
119 119
120 120 def test_search_with_invalid_project_id
121 121 get :index, :id => 195, :q => 'recipe'
122 122 assert_response 404
123 123 assert_nil assigns(:results)
124 124 end
125 125
126 126 def test_quick_jump_to_issue
127 127 # issue of a public project
128 128 get :index, :q => "3"
129 129 assert_redirected_to '/issues/3'
130 130
131 131 # issue of a private project
132 132 get :index, :q => "4"
133 133 assert_response :success
134 134 assert_template 'index'
135 135 end
136 136
137 137 def test_large_integer
138 138 get :index, :q => '4615713488'
139 139 assert_response :success
140 140 assert_template 'index'
141 141 end
142 142
143 143 def test_tokens_with_quotes
144 144 get :index, :id => 1, :q => '"good bye" hello "bye bye"'
145 145 assert_equal ["good bye", "hello", "bye bye"], assigns(:tokens)
146 146 end
147 147 end
@@ -1,59 +1,59
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'settings_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class SettingsController; def rescue_action(e) raise e end; end
23 23
24 24 class SettingsControllerTest < ActionController::TestCase
25 25 fixtures :users
26 26
27 27 def setup
28 28 @controller = SettingsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 @request.session[:user_id] = 1 # admin
33 33 end
34 34
35 35 def test_index
36 36 get :index
37 37 assert_response :success
38 38 assert_template 'edit'
39 39 end
40 40
41 41 def test_get_edit
42 42 get :edit
43 43 assert_response :success
44 44 assert_template 'edit'
45 45 end
46 46
47 47 def test_post_edit_notifications
48 48 post :edit, :settings => {:mail_from => 'functional@test.foo',
49 49 :bcc_recipients => '0',
50 50 :notified_events => %w(issue_added issue_updated news_added),
51 51 :emails_footer => 'Test footer'
52 52 }
53 53 assert_redirected_to '/settings/edit'
54 54 assert_equal 'functional@test.foo', Setting.mail_from
55 55 assert !Setting.bcc_recipients?
56 56 assert_equal %w(issue_added issue_updated news_added), Setting.notified_events
57 57 assert_equal 'Test footer', Setting.emails_footer
58 58 end
59 59 end
@@ -1,92 +1,92
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'sys_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class SysController; def rescue_action(e) raise e end; end
23 23
24 24 class SysControllerTest < ActionController::TestCase
25 25 fixtures :projects, :repositories
26 26
27 27 def setup
28 28 @controller = SysController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 Setting.sys_api_enabled = '1'
32 32 Setting.enabled_scm = %w(Subversion Git)
33 33 end
34 34
35 35 def test_projects_with_repository_enabled
36 36 get :projects
37 37 assert_response :success
38 38 assert_equal 'application/xml', @response.content_type
39 39 with_options :tag => 'projects' do |test|
40 40 test.assert_tag :children => { :count => Project.active.has_module(:repository).count }
41 41 end
42 42 end
43 43
44 44 def test_create_project_repository
45 45 assert_nil Project.find(4).repository
46 46
47 47 post :create_project_repository, :id => 4,
48 48 :vendor => 'Subversion',
49 49 :repository => { :url => 'file:///create/project/repository/subproject2'}
50 50 assert_response :created
51 51
52 52 r = Project.find(4).repository
53 53 assert r.is_a?(Repository::Subversion)
54 54 assert_equal 'file:///create/project/repository/subproject2', r.url
55 55 end
56 56
57 57 def test_fetch_changesets
58 58 get :fetch_changesets
59 59 assert_response :success
60 60 end
61 61
62 62 def test_fetch_changesets_one_project
63 63 get :fetch_changesets, :id => 'ecookbook'
64 64 assert_response :success
65 65 end
66 66
67 67 def test_fetch_changesets_unknown_project
68 68 get :fetch_changesets, :id => 'unknown'
69 69 assert_response 404
70 70 end
71 71
72 72 def test_disabled_ws_should_respond_with_403_error
73 73 with_settings :sys_api_enabled => '0' do
74 74 get :projects
75 75 assert_response 403
76 76 end
77 77 end
78 78
79 79 def test_api_key
80 80 with_settings :sys_api_key => 'my_secret_key' do
81 81 get :projects, :key => 'my_secret_key'
82 82 assert_response :success
83 83 end
84 84 end
85 85
86 86 def test_wrong_key_should_respond_with_403_error
87 87 with_settings :sys_api_enabled => 'my_secret_key' do
88 88 get :projects, :key => 'wrong_key'
89 89 assert_response 403
90 90 end
91 91 end
92 92 end
@@ -1,134 +1,134
1 1 # -*- coding: utf-8 -*-
2 require File.dirname(__FILE__) + '/../test_helper'
2 require File.expand_path('../../test_helper', __FILE__)
3 3
4 4 class TimeEntryReportsControllerTest < ActionController::TestCase
5 5 fixtures :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses, :custom_fields, :custom_values
6 6
7 7 def test_report_no_criteria
8 8 get :report, :project_id => 1
9 9 assert_response :success
10 10 assert_template 'report'
11 11 end
12 12
13 13 def test_report_all_projects
14 14 get :report
15 15 assert_response :success
16 16 assert_template 'report'
17 17 end
18 18
19 19 def test_report_all_projects_denied
20 20 r = Role.anonymous
21 21 r.permissions.delete(:view_time_entries)
22 22 r.permissions_will_change!
23 23 r.save
24 24 get :report
25 25 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Ftime_entries%2Freport'
26 26 end
27 27
28 28 def test_report_all_projects_one_criteria
29 29 get :report, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
30 30 assert_response :success
31 31 assert_template 'report'
32 32 assert_not_nil assigns(:total_hours)
33 33 assert_equal "8.65", "%.2f" % assigns(:total_hours)
34 34 end
35 35
36 36 def test_report_all_time
37 37 get :report, :project_id => 1, :criterias => ['project', 'issue']
38 38 assert_response :success
39 39 assert_template 'report'
40 40 assert_not_nil assigns(:total_hours)
41 41 assert_equal "162.90", "%.2f" % assigns(:total_hours)
42 42 end
43 43
44 44 def test_report_all_time_by_day
45 45 get :report, :project_id => 1, :criterias => ['project', 'issue'], :columns => 'day'
46 46 assert_response :success
47 47 assert_template 'report'
48 48 assert_not_nil assigns(:total_hours)
49 49 assert_equal "162.90", "%.2f" % assigns(:total_hours)
50 50 assert_tag :tag => 'th', :content => '2007-03-12'
51 51 end
52 52
53 53 def test_report_one_criteria
54 54 get :report, :project_id => 1, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
55 55 assert_response :success
56 56 assert_template 'report'
57 57 assert_not_nil assigns(:total_hours)
58 58 assert_equal "8.65", "%.2f" % assigns(:total_hours)
59 59 end
60 60
61 61 def test_report_two_criterias
62 62 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
63 63 assert_response :success
64 64 assert_template 'report'
65 65 assert_not_nil assigns(:total_hours)
66 66 assert_equal "162.90", "%.2f" % assigns(:total_hours)
67 67 end
68 68
69 69 def test_report_one_day
70 70 get :report, :project_id => 1, :columns => 'day', :from => "2007-03-23", :to => "2007-03-23", :criterias => ["member", "activity"]
71 71 assert_response :success
72 72 assert_template 'report'
73 73 assert_not_nil assigns(:total_hours)
74 74 assert_equal "4.25", "%.2f" % assigns(:total_hours)
75 75 end
76 76
77 77 def test_report_at_issue_level
78 78 get :report, :project_id => 1, :issue_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
79 79 assert_response :success
80 80 assert_template 'report'
81 81 assert_not_nil assigns(:total_hours)
82 82 assert_equal "154.25", "%.2f" % assigns(:total_hours)
83 83 end
84 84
85 85 def test_report_custom_field_criteria
86 86 get :report, :project_id => 1, :criterias => ['project', 'cf_1', 'cf_7']
87 87 assert_response :success
88 88 assert_template 'report'
89 89 assert_not_nil assigns(:total_hours)
90 90 assert_not_nil assigns(:criterias)
91 91 assert_equal 3, assigns(:criterias).size
92 92 assert_equal "162.90", "%.2f" % assigns(:total_hours)
93 93 # Custom field column
94 94 assert_tag :tag => 'th', :content => 'Database'
95 95 # Custom field row
96 96 assert_tag :tag => 'td', :content => 'MySQL',
97 97 :sibling => { :tag => 'td', :attributes => { :class => 'hours' },
98 98 :child => { :tag => 'span', :attributes => { :class => 'hours hours-int' },
99 99 :content => '1' }}
100 100 # Second custom field column
101 101 assert_tag :tag => 'th', :content => 'Billable'
102 102 end
103 103
104 104 def test_report_one_criteria_no_result
105 105 get :report, :project_id => 1, :columns => 'week', :from => "1998-04-01", :to => "1998-04-30", :criterias => ['project']
106 106 assert_response :success
107 107 assert_template 'report'
108 108 assert_not_nil assigns(:total_hours)
109 109 assert_equal "0.00", "%.2f" % assigns(:total_hours)
110 110 end
111 111
112 112 def test_report_all_projects_csv_export
113 113 get :report, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30", :criterias => ["project", "member", "activity"], :format => "csv"
114 114 assert_response :success
115 115 assert_equal 'text/csv', @response.content_type
116 116 lines = @response.body.chomp.split("\n")
117 117 # Headers
118 118 assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total', lines.first
119 119 # Total row
120 120 assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
121 121 end
122 122
123 123 def test_report_csv_export
124 124 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30", :criterias => ["project", "member", "activity"], :format => "csv"
125 125 assert_response :success
126 126 assert_equal 'text/csv', @response.content_type
127 127 lines = @response.body.chomp.split("\n")
128 128 # Headers
129 129 assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total', lines.first
130 130 # Total row
131 131 assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
132 132 end
133 133
134 134 end
@@ -1,231 +1,231
1 1 # -*- coding: utf-8 -*-
2 2 # redMine - project management software
3 3 # Copyright (C) 2006-2007 Jean-Philippe Lang
4 4 #
5 5 # This program is free software; you can redistribute it and/or
6 6 # modify it under the terms of the GNU General Public License
7 7 # as published by the Free Software Foundation; either version 2
8 8 # of the License, or (at your option) any later version.
9 9 #
10 10 # This program is distributed in the hope that it will be useful,
11 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 # GNU General Public License for more details.
14 14 #
15 15 # You should have received a copy of the GNU General Public License
16 16 # along with this program; if not, write to the Free Software
17 17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 18
19 require File.dirname(__FILE__) + '/../test_helper'
19 require File.expand_path('../../test_helper', __FILE__)
20 20 require 'timelog_controller'
21 21
22 22 # Re-raise errors caught by the controller.
23 23 class TimelogController; def rescue_action(e) raise e end; end
24 24
25 25 class TimelogControllerTest < ActionController::TestCase
26 26 fixtures :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses, :custom_fields, :custom_values
27 27
28 28 def setup
29 29 @controller = TimelogController.new
30 30 @request = ActionController::TestRequest.new
31 31 @response = ActionController::TestResponse.new
32 32 end
33 33
34 34 def test_get_new
35 35 @request.session[:user_id] = 3
36 36 get :new, :project_id => 1
37 37 assert_response :success
38 38 assert_template 'edit'
39 39 # Default activity selected
40 40 assert_tag :tag => 'option', :attributes => { :selected => 'selected' },
41 41 :content => 'Development'
42 42 end
43 43
44 44 def test_get_new_should_only_show_active_time_entry_activities
45 45 @request.session[:user_id] = 3
46 46 get :new, :project_id => 1
47 47 assert_response :success
48 48 assert_template 'edit'
49 49 assert_no_tag :tag => 'option', :content => 'Inactive Activity'
50 50
51 51 end
52 52
53 53 def test_get_edit_existing_time
54 54 @request.session[:user_id] = 2
55 55 get :edit, :id => 2, :project_id => nil
56 56 assert_response :success
57 57 assert_template 'edit'
58 58 # Default activity selected
59 59 assert_tag :tag => 'form', :attributes => { :action => '/projects/ecookbook/time_entries/2' }
60 60 end
61 61
62 62 def test_get_edit_with_an_existing_time_entry_with_inactive_activity
63 63 te = TimeEntry.find(1)
64 64 te.activity = TimeEntryActivity.find_by_name("Inactive Activity")
65 65 te.save!
66 66
67 67 @request.session[:user_id] = 1
68 68 get :edit, :project_id => 1, :id => 1
69 69 assert_response :success
70 70 assert_template 'edit'
71 71 # Blank option since nothing is pre-selected
72 72 assert_tag :tag => 'option', :content => '--- Please select ---'
73 73 end
74 74
75 75 def test_post_create
76 76 # TODO: should POST to issues’ time log instead of project. change form
77 77 # and routing
78 78 @request.session[:user_id] = 3
79 79 post :create, :project_id => 1,
80 80 :time_entry => {:comments => 'Some work on TimelogControllerTest',
81 81 # Not the default activity
82 82 :activity_id => '11',
83 83 :spent_on => '2008-03-14',
84 84 :issue_id => '1',
85 85 :hours => '7.3'}
86 86 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
87 87
88 88 i = Issue.find(1)
89 89 t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
90 90 assert_not_nil t
91 91 assert_equal 11, t.activity_id
92 92 assert_equal 7.3, t.hours
93 93 assert_equal 3, t.user_id
94 94 assert_equal i, t.issue
95 95 assert_equal i.project, t.project
96 96 end
97 97
98 98 def test_update
99 99 entry = TimeEntry.find(1)
100 100 assert_equal 1, entry.issue_id
101 101 assert_equal 2, entry.user_id
102 102
103 103 @request.session[:user_id] = 1
104 104 put :update, :id => 1,
105 105 :time_entry => {:issue_id => '2',
106 106 :hours => '8'}
107 107 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
108 108 entry.reload
109 109
110 110 assert_equal 8, entry.hours
111 111 assert_equal 2, entry.issue_id
112 112 assert_equal 2, entry.user_id
113 113 end
114 114
115 115 def test_destroy
116 116 @request.session[:user_id] = 2
117 117 delete :destroy, :id => 1
118 118 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
119 119 assert_equal I18n.t(:notice_successful_delete), flash[:notice]
120 120 assert_nil TimeEntry.find_by_id(1)
121 121 end
122 122
123 123 def test_destroy_should_fail
124 124 # simulate that this fails (e.g. due to a plugin), see #5700
125 125 TimeEntry.class_eval do
126 126 before_destroy :stop_callback_chain
127 127 def stop_callback_chain ; return false ; end
128 128 end
129 129
130 130 @request.session[:user_id] = 2
131 131 delete :destroy, :id => 1
132 132 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
133 133 assert_equal I18n.t(:notice_unable_delete_time_entry), flash[:error]
134 134 assert_not_nil TimeEntry.find_by_id(1)
135 135
136 136 # remove the simulation
137 137 TimeEntry.before_destroy.reject! {|callback| callback.method == :stop_callback_chain }
138 138 end
139 139
140 140 def test_index_all_projects
141 141 get :index
142 142 assert_response :success
143 143 assert_template 'index'
144 144 assert_not_nil assigns(:total_hours)
145 145 assert_equal "162.90", "%.2f" % assigns(:total_hours)
146 146 end
147 147
148 148 def test_index_at_project_level
149 149 get :index, :project_id => 1
150 150 assert_response :success
151 151 assert_template 'index'
152 152 assert_not_nil assigns(:entries)
153 153 assert_equal 4, assigns(:entries).size
154 154 # project and subproject
155 155 assert_equal [1, 3], assigns(:entries).collect(&:project_id).uniq.sort
156 156 assert_not_nil assigns(:total_hours)
157 157 assert_equal "162.90", "%.2f" % assigns(:total_hours)
158 158 # display all time by default
159 159 assert_equal '2007-03-12'.to_date, assigns(:from)
160 160 assert_equal '2007-04-22'.to_date, assigns(:to)
161 161 end
162 162
163 163 def test_index_at_project_level_with_date_range
164 164 get :index, :project_id => 1, :from => '2007-03-20', :to => '2007-04-30'
165 165 assert_response :success
166 166 assert_template 'index'
167 167 assert_not_nil assigns(:entries)
168 168 assert_equal 3, assigns(:entries).size
169 169 assert_not_nil assigns(:total_hours)
170 170 assert_equal "12.90", "%.2f" % assigns(:total_hours)
171 171 assert_equal '2007-03-20'.to_date, assigns(:from)
172 172 assert_equal '2007-04-30'.to_date, assigns(:to)
173 173 end
174 174
175 175 def test_index_at_project_level_with_period
176 176 get :index, :project_id => 1, :period => '7_days'
177 177 assert_response :success
178 178 assert_template 'index'
179 179 assert_not_nil assigns(:entries)
180 180 assert_not_nil assigns(:total_hours)
181 181 assert_equal Date.today - 7, assigns(:from)
182 182 assert_equal Date.today, assigns(:to)
183 183 end
184 184
185 185 def test_index_one_day
186 186 get :index, :project_id => 1, :from => "2007-03-23", :to => "2007-03-23"
187 187 assert_response :success
188 188 assert_template 'index'
189 189 assert_not_nil assigns(:total_hours)
190 190 assert_equal "4.25", "%.2f" % assigns(:total_hours)
191 191 end
192 192
193 193 def test_index_at_issue_level
194 194 get :index, :issue_id => 1
195 195 assert_response :success
196 196 assert_template 'index'
197 197 assert_not_nil assigns(:entries)
198 198 assert_equal 2, assigns(:entries).size
199 199 assert_not_nil assigns(:total_hours)
200 200 assert_equal 154.25, assigns(:total_hours)
201 201 # display all time based on what's been logged
202 202 assert_equal '2007-03-12'.to_date, assigns(:from)
203 203 assert_equal '2007-04-22'.to_date, assigns(:to)
204 204 end
205 205
206 206 def test_index_atom_feed
207 207 get :index, :project_id => 1, :format => 'atom'
208 208 assert_response :success
209 209 assert_equal 'application/atom+xml', @response.content_type
210 210 assert_not_nil assigns(:items)
211 211 assert assigns(:items).first.is_a?(TimeEntry)
212 212 end
213 213
214 214 def test_index_all_projects_csv_export
215 215 Setting.date_format = '%m/%d/%Y'
216 216 get :index, :format => 'csv'
217 217 assert_response :success
218 218 assert_equal 'text/csv', @response.content_type
219 219 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment\n")
220 220 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\"\n")
221 221 end
222 222
223 223 def test_index_csv_export
224 224 Setting.date_format = '%m/%d/%Y'
225 225 get :index, :project_id => 1, :format => 'csv'
226 226 assert_response :success
227 227 assert_equal 'text/csv', @response.content_type
228 228 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment\n")
229 229 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\"\n")
230 230 end
231 231 end
@@ -1,120 +1,120
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'trackers_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class TrackersController; def rescue_action(e) raise e end; end
23 23
24 24 class TrackersControllerTest < ActionController::TestCase
25 25 fixtures :trackers, :projects, :projects_trackers, :users, :issues, :custom_fields
26 26
27 27 def setup
28 28 @controller = TrackersController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 @request.session[:user_id] = 1 # admin
33 33 end
34 34
35 35 def test_index
36 36 get :index
37 37 assert_response :success
38 38 assert_template 'index'
39 39 end
40 40
41 41 def test_get_new
42 42 get :new
43 43 assert_response :success
44 44 assert_template 'new'
45 45 end
46 46
47 47 def test_post_new
48 48 post :new, :tracker => { :name => 'New tracker', :project_ids => ['1', '', ''], :custom_field_ids => ['1', '6', ''] }
49 49 assert_redirected_to :action => 'index'
50 50 tracker = Tracker.find_by_name('New tracker')
51 51 assert_equal [1], tracker.project_ids.sort
52 52 assert_equal [1, 6], tracker.custom_field_ids
53 53 assert_equal 0, tracker.workflows.count
54 54 end
55 55
56 56 def test_post_new_with_workflow_copy
57 57 post :new, :tracker => { :name => 'New tracker' }, :copy_workflow_from => 1
58 58 assert_redirected_to :action => 'index'
59 59 tracker = Tracker.find_by_name('New tracker')
60 60 assert_equal 0, tracker.projects.count
61 61 assert_equal Tracker.find(1).workflows.count, tracker.workflows.count
62 62 end
63 63
64 64 def test_get_edit
65 65 Tracker.find(1).project_ids = [1, 3]
66 66
67 67 get :edit, :id => 1
68 68 assert_response :success
69 69 assert_template 'edit'
70 70
71 71 assert_tag :input, :attributes => { :name => 'tracker[project_ids][]',
72 72 :value => '1',
73 73 :checked => 'checked' }
74 74
75 75 assert_tag :input, :attributes => { :name => 'tracker[project_ids][]',
76 76 :value => '2',
77 77 :checked => nil }
78 78
79 79 assert_tag :input, :attributes => { :name => 'tracker[project_ids][]',
80 80 :value => '',
81 81 :type => 'hidden'}
82 82 end
83 83
84 84 def test_post_edit
85 85 post :edit, :id => 1, :tracker => { :name => 'Renamed',
86 86 :project_ids => ['1', '2', ''] }
87 87 assert_redirected_to :action => 'index'
88 88 assert_equal [1, 2], Tracker.find(1).project_ids.sort
89 89 end
90 90
91 91 def test_post_edit_without_projects
92 92 post :edit, :id => 1, :tracker => { :name => 'Renamed',
93 93 :project_ids => [''] }
94 94 assert_redirected_to :action => 'index'
95 95 assert Tracker.find(1).project_ids.empty?
96 96 end
97 97
98 98 def test_move_lower
99 99 tracker = Tracker.find_by_position(1)
100 100 post :edit, :id => 1, :tracker => { :move_to => 'lower' }
101 101 assert_equal 2, tracker.reload.position
102 102 end
103 103
104 104 def test_destroy
105 105 tracker = Tracker.create!(:name => 'Destroyable')
106 106 assert_difference 'Tracker.count', -1 do
107 107 post :destroy, :id => tracker.id
108 108 end
109 109 assert_redirected_to :action => 'index'
110 110 assert_nil flash[:error]
111 111 end
112 112
113 113 def test_destroy_tracker_in_use
114 114 assert_no_difference 'Tracker.count' do
115 115 post :destroy, :id => 1
116 116 end
117 117 assert_redirected_to :action => 'index'
118 118 assert_not_nil flash[:error]
119 119 end
120 120 end
@@ -1,265 +1,265
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'users_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class UsersController; def rescue_action(e) raise e end; end
23 23
24 24 class UsersControllerTest < ActionController::TestCase
25 25 include Redmine::I18n
26 26
27 27 fixtures :users, :projects, :members, :member_roles, :roles, :auth_sources, :custom_fields, :custom_values
28 28
29 29 def setup
30 30 @controller = UsersController.new
31 31 @request = ActionController::TestRequest.new
32 32 @response = ActionController::TestResponse.new
33 33 User.current = nil
34 34 @request.session[:user_id] = 1 # admin
35 35 end
36 36
37 37 def test_index
38 38 get :index
39 39 assert_response :success
40 40 assert_template 'index'
41 41 end
42 42
43 43 def test_index
44 44 get :index
45 45 assert_response :success
46 46 assert_template 'index'
47 47 assert_not_nil assigns(:users)
48 48 # active users only
49 49 assert_nil assigns(:users).detect {|u| !u.active?}
50 50 end
51 51
52 52 def test_index_with_name_filter
53 53 get :index, :name => 'john'
54 54 assert_response :success
55 55 assert_template 'index'
56 56 users = assigns(:users)
57 57 assert_not_nil users
58 58 assert_equal 1, users.size
59 59 assert_equal 'John', users.first.firstname
60 60 end
61 61
62 62 def test_show
63 63 @request.session[:user_id] = nil
64 64 get :show, :id => 2
65 65 assert_response :success
66 66 assert_template 'show'
67 67 assert_not_nil assigns(:user)
68 68
69 69 assert_tag 'li', :content => /Phone number/
70 70 end
71 71
72 72 def test_show_should_not_display_hidden_custom_fields
73 73 @request.session[:user_id] = nil
74 74 UserCustomField.find_by_name('Phone number').update_attribute :visible, false
75 75 get :show, :id => 2
76 76 assert_response :success
77 77 assert_template 'show'
78 78 assert_not_nil assigns(:user)
79 79
80 80 assert_no_tag 'li', :content => /Phone number/
81 81 end
82 82
83 83 def test_show_should_not_fail_when_custom_values_are_nil
84 84 user = User.find(2)
85 85
86 86 # Create a custom field to illustrate the issue
87 87 custom_field = CustomField.create!(:name => 'Testing', :field_format => 'text')
88 88 custom_value = user.custom_values.build(:custom_field => custom_field).save!
89 89
90 90 get :show, :id => 2
91 91 assert_response :success
92 92 end
93 93
94 94 def test_show_inactive
95 95 @request.session[:user_id] = nil
96 96 get :show, :id => 5
97 97 assert_response 404
98 98 end
99 99
100 100 def test_show_should_not_reveal_users_with_no_visible_activity_or_project
101 101 @request.session[:user_id] = nil
102 102 get :show, :id => 9
103 103 assert_response 404
104 104 end
105 105
106 106 def test_show_inactive_by_admin
107 107 @request.session[:user_id] = 1
108 108 get :show, :id => 5
109 109 assert_response 200
110 110 assert_not_nil assigns(:user)
111 111 end
112 112
113 113 def test_show_displays_memberships_based_on_project_visibility
114 114 @request.session[:user_id] = 1
115 115 get :show, :id => 2
116 116 assert_response :success
117 117 memberships = assigns(:memberships)
118 118 assert_not_nil memberships
119 119 project_ids = memberships.map(&:project_id)
120 120 assert project_ids.include?(2) #private project admin can see
121 121 end
122 122
123 123 def test_new
124 124 get :new
125 125
126 126 assert_response :success
127 127 assert_template :new
128 128 assert assigns(:user)
129 129 end
130 130
131 131 def test_create
132 132 Setting.bcc_recipients = '1'
133 133
134 134 assert_difference 'User.count' do
135 135 assert_difference 'ActionMailer::Base.deliveries.size' do
136 136 post :create,
137 137 :user => {
138 138 :firstname => 'John',
139 139 :lastname => 'Doe',
140 140 :login => 'jdoe',
141 141 :password => 'secret',
142 142 :password_confirmation => 'secret',
143 143 :mail => 'jdoe@gmail.com',
144 144 :mail_notification => 'none'
145 145 },
146 146 :send_information => '1'
147 147 end
148 148 end
149 149
150 150 user = User.first(:order => 'id DESC')
151 151 assert_redirected_to :controller => 'users', :action => 'edit', :id => user.id
152 152
153 153 assert_equal 'John', user.firstname
154 154 assert_equal 'Doe', user.lastname
155 155 assert_equal 'jdoe', user.login
156 156 assert_equal 'jdoe@gmail.com', user.mail
157 157 assert_equal 'none', user.mail_notification
158 158 assert user.check_password?('secret')
159 159
160 160 mail = ActionMailer::Base.deliveries.last
161 161 assert_not_nil mail
162 162 assert_equal [user.mail], mail.bcc
163 163 assert mail.body.include?('secret')
164 164 end
165 165
166 166 def test_create_with_failure
167 167 assert_no_difference 'User.count' do
168 168 post :create, :user => {}
169 169 end
170 170
171 171 assert_response :success
172 172 assert_template 'new'
173 173 end
174 174
175 175 def test_edit
176 176 get :edit, :id => 2
177 177
178 178 assert_response :success
179 179 assert_template 'edit'
180 180 assert_equal User.find(2), assigns(:user)
181 181 end
182 182
183 183 def test_update
184 184 ActionMailer::Base.deliveries.clear
185 185 put :update, :id => 2, :user => {:firstname => 'Changed', :mail_notification => 'only_assigned'}, :pref => {:hide_mail => '1', :comments_sorting => 'desc'}
186 186
187 187 user = User.find(2)
188 188 assert_equal 'Changed', user.firstname
189 189 assert_equal 'only_assigned', user.mail_notification
190 190 assert_equal true, user.pref[:hide_mail]
191 191 assert_equal 'desc', user.pref[:comments_sorting]
192 192 assert ActionMailer::Base.deliveries.empty?
193 193 end
194 194
195 195 def test_update_with_failure
196 196 assert_no_difference 'User.count' do
197 197 put :update, :id => 2, :user => {:firstname => ''}
198 198 end
199 199
200 200 assert_response :success
201 201 assert_template 'edit'
202 202 end
203 203
204 204 def test_update_with_group_ids_should_assign_groups
205 205 put :update, :id => 2, :user => {:group_ids => ['10']}
206 206
207 207 user = User.find(2)
208 208 assert_equal [10], user.group_ids
209 209 end
210 210
211 211 def test_update_with_activation_should_send_a_notification
212 212 u = User.new(:firstname => 'Foo', :lastname => 'Bar', :mail => 'foo.bar@somenet.foo', :language => 'fr')
213 213 u.login = 'foo'
214 214 u.status = User::STATUS_REGISTERED
215 215 u.save!
216 216 ActionMailer::Base.deliveries.clear
217 217 Setting.bcc_recipients = '1'
218 218
219 219 put :update, :id => u.id, :user => {:status => User::STATUS_ACTIVE}
220 220 assert u.reload.active?
221 221 mail = ActionMailer::Base.deliveries.last
222 222 assert_not_nil mail
223 223 assert_equal ['foo.bar@somenet.foo'], mail.bcc
224 224 assert mail.body.include?(ll('fr', :notice_account_activated))
225 225 end
226 226
227 227 def test_update_with_password_change_should_send_a_notification
228 228 ActionMailer::Base.deliveries.clear
229 229 Setting.bcc_recipients = '1'
230 230
231 231 put :update, :id => 2, :user => {:password => 'newpass', :password_confirmation => 'newpass'}, :send_information => '1'
232 232 u = User.find(2)
233 233 assert u.check_password?('newpass')
234 234
235 235 mail = ActionMailer::Base.deliveries.last
236 236 assert_not_nil mail
237 237 assert_equal [u.mail], mail.bcc
238 238 assert mail.body.include?('newpass')
239 239 end
240 240
241 241 test "put :update with a password change to an AuthSource user switching to Internal authentication" do
242 242 # Configure as auth source
243 243 u = User.find(2)
244 244 u.auth_source = AuthSource.find(1)
245 245 u.save!
246 246
247 247 put :update, :id => u.id, :user => {:auth_source_id => '', :password => 'newpass'}, :password_confirmation => 'newpass'
248 248
249 249 assert_equal nil, u.reload.auth_source
250 250 assert u.check_password?('newpass')
251 251 end
252 252
253 253 def test_edit_membership
254 254 post :edit_membership, :id => 2, :membership_id => 1,
255 255 :membership => { :role_ids => [2]}
256 256 assert_redirected_to :action => 'edit', :id => '2', :tab => 'memberships'
257 257 assert_equal [2], Member.find(1).role_ids
258 258 end
259 259
260 260 def test_destroy_membership
261 261 post :destroy_membership, :id => 2, :membership_id => 1
262 262 assert_redirected_to :action => 'edit', :id => '2', :tab => 'memberships'
263 263 assert_nil Member.find_by_id(1)
264 264 end
265 265 end
@@ -1,148 +1,148
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'versions_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class VersionsController; def rescue_action(e) raise e end; end
23 23
24 24 class VersionsControllerTest < ActionController::TestCase
25 25 fixtures :projects, :versions, :issues, :users, :roles, :members, :member_roles, :enabled_modules
26 26
27 27 def setup
28 28 @controller = VersionsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_index
35 35 get :index, :project_id => 1
36 36 assert_response :success
37 37 assert_template 'index'
38 38 assert_not_nil assigns(:versions)
39 39 # Version with no date set appears
40 40 assert assigns(:versions).include?(Version.find(3))
41 41 # Completed version doesn't appear
42 42 assert !assigns(:versions).include?(Version.find(1))
43 43 # Context menu on issues
44 44 assert_select "script", :text => Regexp.new(Regexp.escape("new ContextMenu('/issues/context_menu')"))
45 45 end
46 46
47 47 def test_index_with_completed_versions
48 48 get :index, :project_id => 1, :completed => 1
49 49 assert_response :success
50 50 assert_template 'index'
51 51 assert_not_nil assigns(:versions)
52 52 # Version with no date set appears
53 53 assert assigns(:versions).include?(Version.find(3))
54 54 # Completed version appears
55 55 assert assigns(:versions).include?(Version.find(1))
56 56 end
57 57
58 58 def test_index_showing_subprojects_versions
59 59 @subproject_version = Version.generate!(:project => Project.find(3))
60 60 get :index, :project_id => 1, :with_subprojects => 1
61 61 assert_response :success
62 62 assert_template 'index'
63 63 assert_not_nil assigns(:versions)
64 64
65 65 assert assigns(:versions).include?(Version.find(4)), "Shared version not found"
66 66 assert assigns(:versions).include?(@subproject_version), "Subproject version not found"
67 67 end
68 68
69 69 def test_show
70 70 get :show, :id => 2
71 71 assert_response :success
72 72 assert_template 'show'
73 73 assert_not_nil assigns(:version)
74 74
75 75 assert_tag :tag => 'h2', :content => /1.0/
76 76 end
77 77
78 78 def test_create
79 79 @request.session[:user_id] = 2 # manager
80 80 assert_difference 'Version.count' do
81 81 post :create, :project_id => '1', :version => {:name => 'test_add_version'}
82 82 end
83 83 assert_redirected_to '/projects/ecookbook/settings/versions'
84 84 version = Version.find_by_name('test_add_version')
85 85 assert_not_nil version
86 86 assert_equal 1, version.project_id
87 87 end
88 88
89 89 def test_create_from_issue_form
90 90 @request.session[:user_id] = 2 # manager
91 91 assert_difference 'Version.count' do
92 92 xhr :post, :create, :project_id => '1', :version => {:name => 'test_add_version_from_issue_form'}
93 93 end
94 94 assert_response :success
95 95 assert_select_rjs :replace, 'issue_fixed_version_id'
96 96 version = Version.find_by_name('test_add_version_from_issue_form')
97 97 assert_not_nil version
98 98 assert_equal 1, version.project_id
99 99 end
100 100
101 101 def test_get_edit
102 102 @request.session[:user_id] = 2
103 103 get :edit, :id => 2
104 104 assert_response :success
105 105 assert_template 'edit'
106 106 end
107 107
108 108 def test_close_completed
109 109 Version.update_all("status = 'open'")
110 110 @request.session[:user_id] = 2
111 111 put :close_completed, :project_id => 'ecookbook'
112 112 assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
113 113 assert_not_nil Version.find_by_status('closed')
114 114 end
115 115
116 116 def test_post_update
117 117 @request.session[:user_id] = 2
118 118 put :update, :id => 2,
119 119 :version => { :name => 'New version name',
120 120 :effective_date => Date.today.strftime("%Y-%m-%d")}
121 121 assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
122 122 version = Version.find(2)
123 123 assert_equal 'New version name', version.name
124 124 assert_equal Date.today, version.effective_date
125 125 end
126 126
127 127 def test_post_update_with_validation_failure
128 128 @request.session[:user_id] = 2
129 129 put :update, :id => 2,
130 130 :version => { :name => '',
131 131 :effective_date => Date.today.strftime("%Y-%m-%d")}
132 132 assert_response :success
133 133 assert_template 'edit'
134 134 end
135 135
136 136 def test_destroy
137 137 @request.session[:user_id] = 2
138 138 delete :destroy, :id => 3
139 139 assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
140 140 assert_nil Version.find_by_id(3)
141 141 end
142 142
143 143 def test_issue_status_by
144 144 xhr :get, :status_by, :id => 2
145 145 assert_response :success
146 146 assert_template '_issue_counts'
147 147 end
148 148 end
@@ -1,110 +1,110
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'watchers_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class WatchersController; def rescue_action(e) raise e end; end
23 23
24 24 class WatchersControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
26 26 :issues, :trackers, :projects_trackers, :issue_statuses, :enumerations, :watchers
27 27
28 28 def setup
29 29 @controller = WatchersController.new
30 30 @request = ActionController::TestRequest.new
31 31 @response = ActionController::TestResponse.new
32 32 User.current = nil
33 33 end
34 34
35 35 def test_get_watch_should_be_invalid
36 36 @request.session[:user_id] = 3
37 37 get :watch, :object_type => 'issue', :object_id => '1'
38 38 assert_response 405
39 39 end
40 40
41 41 def test_watch
42 42 @request.session[:user_id] = 3
43 43 assert_difference('Watcher.count') do
44 44 xhr :post, :watch, :object_type => 'issue', :object_id => '1'
45 45 assert_response :success
46 46 assert_select_rjs :replace_html, 'watcher'
47 47 end
48 48 assert Issue.find(1).watched_by?(User.find(3))
49 49 end
50 50
51 51 def test_watch_should_be_denied_without_permission
52 52 Role.find(2).remove_permission! :view_issues
53 53 @request.session[:user_id] = 3
54 54 assert_no_difference('Watcher.count') do
55 55 xhr :post, :watch, :object_type => 'issue', :object_id => '1'
56 56 assert_response 403
57 57 end
58 58 end
59 59
60 60 def test_watch_with_multiple_replacements
61 61 @request.session[:user_id] = 3
62 62 assert_difference('Watcher.count') do
63 63 xhr :post, :watch, :object_type => 'issue', :object_id => '1', :replace => ['watch_item_1','watch_item_2']
64 64 assert_response :success
65 65 assert_select_rjs :replace_html, 'watch_item_1'
66 66 assert_select_rjs :replace_html, 'watch_item_2'
67 67 end
68 68 end
69 69
70 70 def test_unwatch
71 71 @request.session[:user_id] = 3
72 72 assert_difference('Watcher.count', -1) do
73 73 xhr :post, :unwatch, :object_type => 'issue', :object_id => '2'
74 74 assert_response :success
75 75 assert_select_rjs :replace_html, 'watcher'
76 76 end
77 77 assert !Issue.find(1).watched_by?(User.find(3))
78 78 end
79 79
80 80 def test_unwatch_with_multiple_replacements
81 81 @request.session[:user_id] = 3
82 82 assert_difference('Watcher.count', -1) do
83 83 xhr :post, :unwatch, :object_type => 'issue', :object_id => '2', :replace => ['watch_item_1', 'watch_item_2']
84 84 assert_response :success
85 85 assert_select_rjs :replace_html, 'watch_item_1'
86 86 assert_select_rjs :replace_html, 'watch_item_2'
87 87 end
88 88 assert !Issue.find(1).watched_by?(User.find(3))
89 89 end
90 90
91 91 def test_new_watcher
92 92 @request.session[:user_id] = 2
93 93 assert_difference('Watcher.count') do
94 94 xhr :post, :new, :object_type => 'issue', :object_id => '2', :watcher => {:user_id => '4'}
95 95 assert_response :success
96 96 assert_select_rjs :replace_html, 'watchers'
97 97 end
98 98 assert Issue.find(2).watched_by?(User.find(4))
99 99 end
100 100
101 101 def test_remove_watcher
102 102 @request.session[:user_id] = 2
103 103 assert_difference('Watcher.count', -1) do
104 104 xhr :post, :destroy, :object_type => 'issue', :object_id => '2', :user_id => '3'
105 105 assert_response :success
106 106 assert_select_rjs :replace_html, 'watchers'
107 107 end
108 108 assert !Issue.find(2).watched_by?(User.find(3))
109 109 end
110 110 end
@@ -1,70 +1,70
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'welcome_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class WelcomeController; def rescue_action(e) raise e end; end
23 23
24 24 class WelcomeControllerTest < ActionController::TestCase
25 25 fixtures :projects, :news
26 26
27 27 def setup
28 28 @controller = WelcomeController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_index
35 35 get :index
36 36 assert_response :success
37 37 assert_template 'index'
38 38 assert_not_nil assigns(:news)
39 39 assert_not_nil assigns(:projects)
40 40 assert !assigns(:projects).include?(Project.find(:first, :conditions => {:is_public => false}))
41 41 end
42 42
43 43 def test_browser_language
44 44 Setting.default_language = 'en'
45 45 @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
46 46 get :index
47 47 assert_equal :fr, @controller.current_language
48 48 end
49 49
50 50 def test_browser_language_alternate
51 51 Setting.default_language = 'en'
52 52 @request.env['HTTP_ACCEPT_LANGUAGE'] = 'zh-TW'
53 53 get :index
54 54 assert_equal :"zh-TW", @controller.current_language
55 55 end
56 56
57 57 def test_browser_language_alternate_not_valid
58 58 Setting.default_language = 'en'
59 59 @request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr-CA'
60 60 get :index
61 61 assert_equal :fr, @controller.current_language
62 62 end
63 63
64 64 def test_robots
65 65 get :robots
66 66 assert_response :success
67 67 assert_equal 'text/plain', @response.content_type
68 68 assert @response.body.match(%r{^Disallow: /projects/ecookbook/issues\r?$})
69 69 end
70 70 end
@@ -1,459 +1,459
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'wiki_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class WikiController; def rescue_action(e) raise e end; end
23 23
24 24 class WikiControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions, :attachments
26 26
27 27 def setup
28 28 @controller = WikiController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_show_start_page
35 35 get :show, :project_id => 'ecookbook'
36 36 assert_response :success
37 37 assert_template 'show'
38 38 assert_tag :tag => 'h1', :content => /CookBook documentation/
39 39
40 40 # child_pages macro
41 41 assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
42 42 :child => { :tag => 'li',
43 43 :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
44 44 :content => 'Page with an inline image' } }
45 45 end
46 46
47 47 def test_show_page_with_name
48 48 get :show, :project_id => 1, :id => 'Another_page'
49 49 assert_response :success
50 50 assert_template 'show'
51 51 assert_tag :tag => 'h1', :content => /Another page/
52 52 # Included page with an inline image
53 53 assert_tag :tag => 'p', :content => /This is an inline image/
54 54 assert_tag :tag => 'img', :attributes => { :src => '/attachments/download/3',
55 55 :alt => 'This is a logo' }
56 56 end
57 57
58 58 def test_show_with_sidebar
59 59 page = Project.find(1).wiki.pages.new(:title => 'Sidebar')
60 60 page.content = WikiContent.new(:text => 'Side bar content for test_show_with_sidebar')
61 61 page.save!
62 62
63 63 get :show, :project_id => 1, :id => 'Another_page'
64 64 assert_response :success
65 65 assert_tag :tag => 'div', :attributes => {:id => 'sidebar'},
66 66 :content => /Side bar content for test_show_with_sidebar/
67 67 end
68 68
69 69 def test_show_unexistent_page_without_edit_right
70 70 get :show, :project_id => 1, :id => 'Unexistent page'
71 71 assert_response 404
72 72 end
73 73
74 74 def test_show_unexistent_page_with_edit_right
75 75 @request.session[:user_id] = 2
76 76 get :show, :project_id => 1, :id => 'Unexistent page'
77 77 assert_response :success
78 78 assert_template 'edit'
79 79 end
80 80
81 81 def test_create_page
82 82 @request.session[:user_id] = 2
83 83 put :update, :project_id => 1,
84 84 :id => 'New page',
85 85 :content => {:comments => 'Created the page',
86 86 :text => "h1. New page\n\nThis is a new page",
87 87 :version => 0}
88 88 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'New_page'
89 89 page = Project.find(1).wiki.find_page('New page')
90 90 assert !page.new_record?
91 91 assert_not_nil page.content
92 92 assert_equal 'Created the page', page.content.comments
93 93 end
94 94
95 95 def test_create_page_with_attachments
96 96 @request.session[:user_id] = 2
97 97 assert_difference 'WikiPage.count' do
98 98 assert_difference 'Attachment.count' do
99 99 put :update, :project_id => 1,
100 100 :id => 'New page',
101 101 :content => {:comments => 'Created the page',
102 102 :text => "h1. New page\n\nThis is a new page",
103 103 :version => 0},
104 104 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
105 105 end
106 106 end
107 107 page = Project.find(1).wiki.find_page('New page')
108 108 assert_equal 1, page.attachments.count
109 109 assert_equal 'testfile.txt', page.attachments.first.filename
110 110 end
111 111
112 112 def test_update_page
113 113 @request.session[:user_id] = 2
114 114 assert_no_difference 'WikiPage.count' do
115 115 assert_no_difference 'WikiContent.count' do
116 116 assert_difference 'WikiContent::Version.count' do
117 117 put :update, :project_id => 1,
118 118 :id => 'Another_page',
119 119 :content => {
120 120 :comments => "my comments",
121 121 :text => "edited",
122 122 :version => 1
123 123 }
124 124 end
125 125 end
126 126 end
127 127 assert_redirected_to '/projects/ecookbook/wiki/Another_page'
128 128
129 129 page = Wiki.find(1).pages.find_by_title('Another_page')
130 130 assert_equal "edited", page.content.text
131 131 assert_equal 2, page.content.version
132 132 assert_equal "my comments", page.content.comments
133 133 end
134 134
135 135 def test_update_page_with_failure
136 136 @request.session[:user_id] = 2
137 137 assert_no_difference 'WikiPage.count' do
138 138 assert_no_difference 'WikiContent.count' do
139 139 assert_no_difference 'WikiContent::Version.count' do
140 140 put :update, :project_id => 1,
141 141 :id => 'Another_page',
142 142 :content => {
143 143 :comments => 'a' * 300, # failure here, comment is too long
144 144 :text => 'edited',
145 145 :version => 1
146 146 }
147 147 end
148 148 end
149 149 end
150 150 assert_response :success
151 151 assert_template 'edit'
152 152
153 153 assert_error_tag :descendant => {:content => /Comment is too long/}
154 154 assert_tag :tag => 'textarea', :attributes => {:id => 'content_text'}, :content => 'edited'
155 155 assert_tag :tag => 'input', :attributes => {:id => 'content_version', :value => '1'}
156 156 end
157 157
158 158 def test_preview
159 159 @request.session[:user_id] = 2
160 160 xhr :post, :preview, :project_id => 1, :id => 'CookBook_documentation',
161 161 :content => { :comments => '',
162 162 :text => 'this is a *previewed text*',
163 163 :version => 3 }
164 164 assert_response :success
165 165 assert_template 'common/_preview'
166 166 assert_tag :tag => 'strong', :content => /previewed text/
167 167 end
168 168
169 169 def test_preview_new_page
170 170 @request.session[:user_id] = 2
171 171 xhr :post, :preview, :project_id => 1, :id => 'New page',
172 172 :content => { :text => 'h1. New page',
173 173 :comments => '',
174 174 :version => 0 }
175 175 assert_response :success
176 176 assert_template 'common/_preview'
177 177 assert_tag :tag => 'h1', :content => /New page/
178 178 end
179 179
180 180 def test_history
181 181 get :history, :project_id => 1, :id => 'CookBook_documentation'
182 182 assert_response :success
183 183 assert_template 'history'
184 184 assert_not_nil assigns(:versions)
185 185 assert_equal 3, assigns(:versions).size
186 186 assert_select "input[type=submit][name=commit]"
187 187 end
188 188
189 189 def test_history_with_one_version
190 190 get :history, :project_id => 1, :id => 'Another_page'
191 191 assert_response :success
192 192 assert_template 'history'
193 193 assert_not_nil assigns(:versions)
194 194 assert_equal 1, assigns(:versions).size
195 195 assert_select "input[type=submit][name=commit]", false
196 196 end
197 197
198 198 def test_diff
199 199 get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => 2, :version_from => 1
200 200 assert_response :success
201 201 assert_template 'diff'
202 202 assert_tag :tag => 'span', :attributes => { :class => 'diff_in'},
203 203 :content => /updated/
204 204 end
205 205
206 206 def test_annotate
207 207 get :annotate, :project_id => 1, :id => 'CookBook_documentation', :version => 2
208 208 assert_response :success
209 209 assert_template 'annotate'
210 210 # Line 1
211 211 assert_tag :tag => 'tr', :child => { :tag => 'th', :attributes => {:class => 'line-num'}, :content => '1' },
212 212 :child => { :tag => 'td', :attributes => {:class => 'author'}, :content => /John Smith/ },
213 213 :child => { :tag => 'td', :content => /h1\. CookBook documentation/ }
214 214 # Line 2
215 215 assert_tag :tag => 'tr', :child => { :tag => 'th', :attributes => {:class => 'line-num'}, :content => '2' },
216 216 :child => { :tag => 'td', :attributes => {:class => 'author'}, :content => /redMine Admin/ },
217 217 :child => { :tag => 'td', :content => /Some updated \[\[documentation\]\] here/ }
218 218 end
219 219
220 220 def test_get_rename
221 221 @request.session[:user_id] = 2
222 222 get :rename, :project_id => 1, :id => 'Another_page'
223 223 assert_response :success
224 224 assert_template 'rename'
225 225 assert_tag 'option',
226 226 :attributes => {:value => ''},
227 227 :content => '',
228 228 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
229 229 assert_no_tag 'option',
230 230 :attributes => {:selected => 'selected'},
231 231 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
232 232 end
233 233
234 234 def test_get_rename_child_page
235 235 @request.session[:user_id] = 2
236 236 get :rename, :project_id => 1, :id => 'Child_1'
237 237 assert_response :success
238 238 assert_template 'rename'
239 239 assert_tag 'option',
240 240 :attributes => {:value => ''},
241 241 :content => '',
242 242 :parent => {:tag => 'select', :attributes => {:name => 'wiki_page[parent_id]'}}
243 243 assert_tag 'option',
244 244 :attributes => {:value => '2', :selected => 'selected'},
245 245 :content => /Another page/,
246 246 :parent => {
247 247 :tag => 'select',
248 248 :attributes => {:name => 'wiki_page[parent_id]'}
249 249 }
250 250 end
251 251
252 252 def test_rename_with_redirect
253 253 @request.session[:user_id] = 2
254 254 post :rename, :project_id => 1, :id => 'Another_page',
255 255 :wiki_page => { :title => 'Another renamed page',
256 256 :redirect_existing_links => 1 }
257 257 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
258 258 wiki = Project.find(1).wiki
259 259 # Check redirects
260 260 assert_not_nil wiki.find_page('Another page')
261 261 assert_nil wiki.find_page('Another page', :with_redirect => false)
262 262 end
263 263
264 264 def test_rename_without_redirect
265 265 @request.session[:user_id] = 2
266 266 post :rename, :project_id => 1, :id => 'Another_page',
267 267 :wiki_page => { :title => 'Another renamed page',
268 268 :redirect_existing_links => "0" }
269 269 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_renamed_page'
270 270 wiki = Project.find(1).wiki
271 271 # Check that there's no redirects
272 272 assert_nil wiki.find_page('Another page')
273 273 end
274 274
275 275 def test_rename_with_parent_assignment
276 276 @request.session[:user_id] = 2
277 277 post :rename, :project_id => 1, :id => 'Another_page',
278 278 :wiki_page => { :title => 'Another page', :redirect_existing_links => "0", :parent_id => '4' }
279 279 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
280 280 assert_equal WikiPage.find(4), WikiPage.find_by_title('Another_page').parent
281 281 end
282 282
283 283 def test_rename_with_parent_unassignment
284 284 @request.session[:user_id] = 2
285 285 post :rename, :project_id => 1, :id => 'Child_1',
286 286 :wiki_page => { :title => 'Child 1', :redirect_existing_links => "0", :parent_id => '' }
287 287 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Child_1'
288 288 assert_nil WikiPage.find_by_title('Child_1').parent
289 289 end
290 290
291 291 def test_destroy_child
292 292 @request.session[:user_id] = 2
293 293 delete :destroy, :project_id => 1, :id => 'Child_1'
294 294 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
295 295 end
296 296
297 297 def test_destroy_parent
298 298 @request.session[:user_id] = 2
299 299 assert_no_difference('WikiPage.count') do
300 300 delete :destroy, :project_id => 1, :id => 'Another_page'
301 301 end
302 302 assert_response :success
303 303 assert_template 'destroy'
304 304 end
305 305
306 306 def test_destroy_parent_with_nullify
307 307 @request.session[:user_id] = 2
308 308 assert_difference('WikiPage.count', -1) do
309 309 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'nullify'
310 310 end
311 311 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
312 312 assert_nil WikiPage.find_by_id(2)
313 313 end
314 314
315 315 def test_destroy_parent_with_cascade
316 316 @request.session[:user_id] = 2
317 317 assert_difference('WikiPage.count', -3) do
318 318 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'destroy'
319 319 end
320 320 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
321 321 assert_nil WikiPage.find_by_id(2)
322 322 assert_nil WikiPage.find_by_id(5)
323 323 end
324 324
325 325 def test_destroy_parent_with_reassign
326 326 @request.session[:user_id] = 2
327 327 assert_difference('WikiPage.count', -1) do
328 328 delete :destroy, :project_id => 1, :id => 'Another_page', :todo => 'reassign', :reassign_to_id => 1
329 329 end
330 330 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
331 331 assert_nil WikiPage.find_by_id(2)
332 332 assert_equal WikiPage.find(1), WikiPage.find_by_id(5).parent
333 333 end
334 334
335 335 def test_index
336 336 get :index, :project_id => 'ecookbook'
337 337 assert_response :success
338 338 assert_template 'index'
339 339 pages = assigns(:pages)
340 340 assert_not_nil pages
341 341 assert_equal Project.find(1).wiki.pages.size, pages.size
342 342
343 343 assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
344 344 :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/CookBook_documentation' },
345 345 :content => 'CookBook documentation' },
346 346 :child => { :tag => 'ul',
347 347 :child => { :tag => 'li',
348 348 :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Page_with_an_inline_image' },
349 349 :content => 'Page with an inline image' } } } },
350 350 :child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/projects/ecookbook/wiki/Another_page' },
351 351 :content => 'Another page' } }
352 352 end
353 353
354 354 context "GET :export" do
355 355 context "with an authorized user to export the wiki" do
356 356 setup do
357 357 @request.session[:user_id] = 2
358 358 get :export, :project_id => 'ecookbook'
359 359 end
360 360
361 361 should_respond_with :success
362 362 should_assign_to :pages
363 363 should_respond_with_content_type "text/html"
364 364 should "export all of the wiki pages to a single html file" do
365 365 assert_select "a[name=?]", "CookBook_documentation"
366 366 assert_select "a[name=?]", "Another_page"
367 367 assert_select "a[name=?]", "Page_with_an_inline_image"
368 368 end
369 369
370 370 end
371 371
372 372 context "with an unauthorized user" do
373 373 setup do
374 374 get :export, :project_id => 'ecookbook'
375 375
376 376 should_respond_with :redirect
377 377 should_redirect_to('wiki index') { {:action => 'show', :project_id => @project, :id => nil} }
378 378 end
379 379 end
380 380 end
381 381
382 382 context "GET :date_index" do
383 383 setup do
384 384 get :date_index, :project_id => 'ecookbook'
385 385 end
386 386
387 387 should_respond_with :success
388 388 should_assign_to :pages
389 389 should_assign_to :pages_by_date
390 390 should_render_template 'wiki/date_index'
391 391
392 392 end
393 393
394 394 def test_not_found
395 395 get :show, :project_id => 999
396 396 assert_response 404
397 397 end
398 398
399 399 def test_protect_page
400 400 page = WikiPage.find_by_wiki_id_and_title(1, 'Another_page')
401 401 assert !page.protected?
402 402 @request.session[:user_id] = 2
403 403 post :protect, :project_id => 1, :id => page.title, :protected => '1'
404 404 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'Another_page'
405 405 assert page.reload.protected?
406 406 end
407 407
408 408 def test_unprotect_page
409 409 page = WikiPage.find_by_wiki_id_and_title(1, 'CookBook_documentation')
410 410 assert page.protected?
411 411 @request.session[:user_id] = 2
412 412 post :protect, :project_id => 1, :id => page.title, :protected => '0'
413 413 assert_redirected_to :action => 'show', :project_id => 'ecookbook', :id => 'CookBook_documentation'
414 414 assert !page.reload.protected?
415 415 end
416 416
417 417 def test_show_page_with_edit_link
418 418 @request.session[:user_id] = 2
419 419 get :show, :project_id => 1
420 420 assert_response :success
421 421 assert_template 'show'
422 422 assert_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
423 423 end
424 424
425 425 def test_show_page_without_edit_link
426 426 @request.session[:user_id] = 4
427 427 get :show, :project_id => 1
428 428 assert_response :success
429 429 assert_template 'show'
430 430 assert_no_tag :tag => 'a', :attributes => { :href => '/projects/1/wiki/CookBook_documentation/edit' }
431 431 end
432 432
433 433 def test_edit_unprotected_page
434 434 # Non members can edit unprotected wiki pages
435 435 @request.session[:user_id] = 4
436 436 get :edit, :project_id => 1, :id => 'Another_page'
437 437 assert_response :success
438 438 assert_template 'edit'
439 439 end
440 440
441 441 def test_edit_protected_page_by_nonmember
442 442 # Non members can't edit protected wiki pages
443 443 @request.session[:user_id] = 4
444 444 get :edit, :project_id => 1, :id => 'CookBook_documentation'
445 445 assert_response 403
446 446 end
447 447
448 448 def test_edit_protected_page_by_member
449 449 @request.session[:user_id] = 2
450 450 get :edit, :project_id => 1, :id => 'CookBook_documentation'
451 451 assert_response :success
452 452 assert_template 'edit'
453 453 end
454 454
455 455 def test_history_of_non_existing_page_should_return_404
456 456 get :history, :project_id => 1, :id => 'Unknown_page'
457 457 assert_response 404
458 458 end
459 459 end
@@ -1,56 +1,56
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'wikis_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class WikisController; def rescue_action(e) raise e end; end
23 23
24 24 class WikisControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :wikis
26 26
27 27 def setup
28 28 @controller = WikisController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_create
35 35 @request.session[:user_id] = 1
36 36 assert_nil Project.find(3).wiki
37 37 post :edit, :id => 3, :wiki => { :start_page => 'Start page' }
38 38 assert_response :success
39 39 wiki = Project.find(3).wiki
40 40 assert_not_nil wiki
41 41 assert_equal 'Start page', wiki.start_page
42 42 end
43 43
44 44 def test_destroy
45 45 @request.session[:user_id] = 1
46 46 post :destroy, :id => 1, :confirm => 1
47 47 assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'ecookbook', :tab => 'wiki'
48 48 assert_nil Project.find(1).wiki
49 49 end
50 50
51 51 def test_not_found
52 52 @request.session[:user_id] = 1
53 53 post :destroy, :id => 999, :confirm => 1
54 54 assert_response 404
55 55 end
56 56 end
@@ -1,158 +1,158
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'workflows_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class WorkflowsController; def rescue_action(e) raise e end; end
23 23
24 24 class WorkflowsControllerTest < ActionController::TestCase
25 25 fixtures :roles, :trackers, :workflows, :users, :issue_statuses
26 26
27 27 def setup
28 28 @controller = WorkflowsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 @request.session[:user_id] = 1 # admin
33 33 end
34 34
35 35 def test_index
36 36 get :index
37 37 assert_response :success
38 38 assert_template 'index'
39 39
40 40 count = Workflow.count(:all, :conditions => 'role_id = 1 AND tracker_id = 2')
41 41 assert_tag :tag => 'a', :content => count.to_s,
42 42 :attributes => { :href => '/workflows/edit?role_id=1&amp;tracker_id=2' }
43 43 end
44 44
45 45 def test_get_edit
46 46 get :edit
47 47 assert_response :success
48 48 assert_template 'edit'
49 49 assert_not_nil assigns(:roles)
50 50 assert_not_nil assigns(:trackers)
51 51 end
52 52
53 53 def test_get_edit_with_role_and_tracker
54 54 Workflow.delete_all
55 55 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
56 56 Workflow.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
57 57
58 58 get :edit, :role_id => 2, :tracker_id => 1
59 59 assert_response :success
60 60 assert_template 'edit'
61 61
62 62 # used status only
63 63 assert_not_nil assigns(:statuses)
64 64 assert_equal [2, 3, 5], assigns(:statuses).collect(&:id)
65 65
66 66 # allowed transitions
67 67 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
68 68 :name => 'issue_status[3][]',
69 69 :value => '5',
70 70 :checked => 'checked' }
71 71 # not allowed
72 72 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
73 73 :name => 'issue_status[3][]',
74 74 :value => '2',
75 75 :checked => nil }
76 76 # unused
77 77 assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
78 78 :name => 'issue_status[4][]' }
79 79 end
80 80
81 81 def test_get_edit_with_role_and_tracker_and_all_statuses
82 82 Workflow.delete_all
83 83
84 84 get :edit, :role_id => 2, :tracker_id => 1, :used_statuses_only => '0'
85 85 assert_response :success
86 86 assert_template 'edit'
87 87
88 88 assert_not_nil assigns(:statuses)
89 89 assert_equal IssueStatus.count, assigns(:statuses).size
90 90
91 91 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
92 92 :name => 'issue_status[1][]',
93 93 :value => '1',
94 94 :checked => nil }
95 95 end
96 96
97 97 def test_post_edit
98 98 post :edit, :role_id => 2, :tracker_id => 1, :issue_status => {'4' => ['5'], '3' => ['1', '2']}
99 99 assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1'
100 100
101 101 assert_equal 3, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
102 102 assert_not_nil Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2})
103 103 assert_nil Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4})
104 104 end
105 105
106 106 def test_clear_workflow
107 107 assert Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2}) > 0
108 108
109 109 post :edit, :role_id => 2, :tracker_id => 1
110 110 assert_equal 0, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
111 111 end
112 112
113 113 def test_get_copy
114 114 get :copy
115 115 assert_response :success
116 116 assert_template 'copy'
117 117 end
118 118
119 119 def test_post_copy_one_to_one
120 120 source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
121 121
122 122 post :copy, :source_tracker_id => '1', :source_role_id => '2',
123 123 :target_tracker_ids => ['3'], :target_role_ids => ['1']
124 124 assert_response 302
125 125 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
126 126 end
127 127
128 128 def test_post_copy_one_to_many
129 129 source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
130 130
131 131 post :copy, :source_tracker_id => '1', :source_role_id => '2',
132 132 :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
133 133 assert_response 302
134 134 assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 1)
135 135 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
136 136 assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 3)
137 137 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 3)
138 138 end
139 139
140 140 def test_post_copy_many_to_many
141 141 source_t2 = status_transitions(:tracker_id => 2, :role_id => 2)
142 142 source_t3 = status_transitions(:tracker_id => 3, :role_id => 2)
143 143
144 144 post :copy, :source_tracker_id => 'any', :source_role_id => '2',
145 145 :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
146 146 assert_response 302
147 147 assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 1)
148 148 assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 1)
149 149 assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 3)
150 150 assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 3)
151 151 end
152 152
153 153 # Returns an array of status transitions that can be compared
154 154 def status_transitions(conditions)
155 155 Workflow.find(:all, :conditions => conditions,
156 156 :order => 'tracker_id, role_id, old_status_id, new_status_id').collect {|w| [w.old_status, w.new_status_id]}
157 157 end
158 158 end
@@ -1,206 +1,206
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../test_helper"
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 begin
21 21 require 'mocha'
22 22 rescue
23 23 # Won't run some tests
24 24 end
25 25
26 26 class AccountTest < ActionController::IntegrationTest
27 27 fixtures :users, :roles
28 28
29 29 # Replace this with your real tests.
30 30 def test_login
31 31 get "my/page"
32 32 assert_redirected_to "/login?back_url=http%3A%2F%2Fwww.example.com%2Fmy%2Fpage"
33 33 log_user('jsmith', 'jsmith')
34 34
35 35 get "my/account"
36 36 assert_response :success
37 37 assert_template "my/account"
38 38 end
39 39
40 40 def test_autologin
41 41 user = User.find(1)
42 42 Setting.autologin = "7"
43 43 Token.delete_all
44 44
45 45 # User logs in with 'autologin' checked
46 46 post '/login', :username => user.login, :password => 'admin', :autologin => 1
47 47 assert_redirected_to '/my/page'
48 48 token = Token.find :first
49 49 assert_not_nil token
50 50 assert_equal user, token.user
51 51 assert_equal 'autologin', token.action
52 52 assert_equal user.id, session[:user_id]
53 53 assert_equal token.value, cookies['autologin']
54 54
55 55 # Session is cleared
56 56 reset!
57 57 User.current = nil
58 58 # Clears user's last login timestamp
59 59 user.update_attribute :last_login_on, nil
60 60 assert_nil user.reload.last_login_on
61 61
62 62 # User comes back with his autologin cookie
63 63 cookies[:autologin] = token.value
64 64 get '/my/page'
65 65 assert_response :success
66 66 assert_template 'my/page'
67 67 assert_equal user.id, session[:user_id]
68 68 assert_not_nil user.reload.last_login_on
69 69 assert user.last_login_on.utc > 10.second.ago.utc
70 70 end
71 71
72 72 def test_lost_password
73 73 Token.delete_all
74 74
75 75 get "account/lost_password"
76 76 assert_response :success
77 77 assert_template "account/lost_password"
78 78
79 79 post "account/lost_password", :mail => 'jSmith@somenet.foo'
80 80 assert_redirected_to "/login"
81 81
82 82 token = Token.find(:first)
83 83 assert_equal 'recovery', token.action
84 84 assert_equal 'jsmith@somenet.foo', token.user.mail
85 85 assert !token.expired?
86 86
87 87 get "account/lost_password", :token => token.value
88 88 assert_response :success
89 89 assert_template "account/password_recovery"
90 90
91 91 post "account/lost_password", :token => token.value, :new_password => 'newpass', :new_password_confirmation => 'newpass'
92 92 assert_redirected_to "/login"
93 93 assert_equal 'Password was successfully updated.', flash[:notice]
94 94
95 95 log_user('jsmith', 'newpass')
96 96 assert_equal 0, Token.count
97 97 end
98 98
99 99 def test_register_with_automatic_activation
100 100 Setting.self_registration = '3'
101 101
102 102 get 'account/register'
103 103 assert_response :success
104 104 assert_template 'account/register'
105 105
106 106 post 'account/register', :user => {:login => "newuser", :language => "en", :firstname => "New", :lastname => "User", :mail => "newuser@foo.bar"},
107 107 :password => "newpass", :password_confirmation => "newpass"
108 108 assert_redirected_to '/my/account'
109 109 follow_redirect!
110 110 assert_response :success
111 111 assert_template 'my/account'
112 112
113 113 user = User.find_by_login('newuser')
114 114 assert_not_nil user
115 115 assert user.active?
116 116 assert_not_nil user.last_login_on
117 117 end
118 118
119 119 def test_register_with_manual_activation
120 120 Setting.self_registration = '2'
121 121
122 122 post 'account/register', :user => {:login => "newuser", :language => "en", :firstname => "New", :lastname => "User", :mail => "newuser@foo.bar"},
123 123 :password => "newpass", :password_confirmation => "newpass"
124 124 assert_redirected_to '/login'
125 125 assert !User.find_by_login('newuser').active?
126 126 end
127 127
128 128 def test_register_with_email_activation
129 129 Setting.self_registration = '1'
130 130 Token.delete_all
131 131
132 132 post 'account/register', :user => {:login => "newuser", :language => "en", :firstname => "New", :lastname => "User", :mail => "newuser@foo.bar"},
133 133 :password => "newpass", :password_confirmation => "newpass"
134 134 assert_redirected_to '/login'
135 135 assert !User.find_by_login('newuser').active?
136 136
137 137 token = Token.find(:first)
138 138 assert_equal 'register', token.action
139 139 assert_equal 'newuser@foo.bar', token.user.mail
140 140 assert !token.expired?
141 141
142 142 get 'account/activate', :token => token.value
143 143 assert_redirected_to '/login'
144 144 log_user('newuser', 'newpass')
145 145 end
146 146
147 147 if Object.const_defined?(:Mocha)
148 148
149 149 def test_onthefly_registration
150 150 # disable registration
151 151 Setting.self_registration = '0'
152 152 AuthSource.expects(:authenticate).returns({:login => 'foo', :firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com', :auth_source_id => 66})
153 153
154 154 post 'account/login', :username => 'foo', :password => 'bar'
155 155 assert_redirected_to '/my/page'
156 156
157 157 user = User.find_by_login('foo')
158 158 assert user.is_a?(User)
159 159 assert_equal 66, user.auth_source_id
160 160 assert user.hashed_password.blank?
161 161 end
162 162
163 163 def test_onthefly_registration_with_invalid_attributes
164 164 # disable registration
165 165 Setting.self_registration = '0'
166 166 AuthSource.expects(:authenticate).returns({:login => 'foo', :lastname => 'Smith', :auth_source_id => 66})
167 167
168 168 post 'account/login', :username => 'foo', :password => 'bar'
169 169 assert_response :success
170 170 assert_template 'account/register'
171 171 assert_tag :input, :attributes => { :name => 'user[firstname]', :value => '' }
172 172 assert_tag :input, :attributes => { :name => 'user[lastname]', :value => 'Smith' }
173 173 assert_no_tag :input, :attributes => { :name => 'user[login]' }
174 174 assert_no_tag :input, :attributes => { :name => 'user[password]' }
175 175
176 176 post 'account/register', :user => {:firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com'}
177 177 assert_redirected_to '/my/account'
178 178
179 179 user = User.find_by_login('foo')
180 180 assert user.is_a?(User)
181 181 assert_equal 66, user.auth_source_id
182 182 assert user.hashed_password.blank?
183 183 end
184 184
185 185 def test_login_and_logout_should_clear_session
186 186 get '/login'
187 187 sid = session[:session_id]
188 188
189 189 post '/login', :username => 'admin', :password => 'admin'
190 190 assert_redirected_to '/my/page'
191 191 assert_not_equal sid, session[:session_id], "login should reset session"
192 192 assert_equal 1, session[:user_id]
193 193 sid = session[:session_id]
194 194
195 195 get '/'
196 196 assert_equal sid, session[:session_id]
197 197
198 198 get '/logout'
199 199 assert_not_equal sid, session[:session_id], "logout should reset session"
200 200 assert_nil session[:user_id]
201 201 end
202 202
203 203 else
204 204 puts 'Mocha is missing. Skipping tests.'
205 205 end
206 206 end
@@ -1,49 +1,49
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../test_helper"
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class AdminTest < ActionController::IntegrationTest
21 21 fixtures :all
22 22
23 23 def test_add_user
24 24 log_user("admin", "admin")
25 25 get "/users/new"
26 26 assert_response :success
27 27 assert_template "users/new"
28 28 post "/users/create", :user => { :login => "psmith", :firstname => "Paul", :lastname => "Smith", :mail => "psmith@somenet.foo", :language => "en", :password => "psmith09", :password_confirmation => "psmith09" }
29 29
30 30 user = User.find_by_login("psmith")
31 31 assert_kind_of User, user
32 32 assert_redirected_to "/users/#{ user.id }/edit"
33 33
34 34 logged_user = User.try_to_login("psmith", "psmith09")
35 35 assert_kind_of User, logged_user
36 36 assert_equal "Paul", logged_user.firstname
37 37
38 38 put "users/#{user.id}", :id => user.id, :user => { :status => User::STATUS_LOCKED }
39 39 assert_redirected_to "/users/#{ user.id }/edit"
40 40 locked_user = User.try_to_login("psmith", "psmith09")
41 41 assert_equal nil, locked_user
42 42 end
43 43
44 44 test "Add a user as an anonymous user should fail" do
45 45 post '/users/create', :user => { :login => 'psmith', :firstname => 'Paul'}, :password => "psmith09", :password_confirmation => "psmith09"
46 46 assert_response :redirect
47 47 assert_redirected_to "/login?back_url=http%3A%2F%2Fwww.example.com%2Fusers"
48 48 end
49 49 end
@@ -1,110 +1,110
1 require "#{File.dirname(__FILE__)}/../../test_helper"
1 require File.expand_path('../../../test_helper', __FILE__)
2 2
3 3 class ApiTest::DisabledRestApiTest < ActionController::IntegrationTest
4 4 fixtures :all
5 5
6 6 def setup
7 7 Setting.rest_api_enabled = '0'
8 8 Setting.login_required = '1'
9 9 end
10 10
11 11 def teardown
12 12 Setting.rest_api_enabled = '1'
13 13 Setting.login_required = '0'
14 14 end
15 15
16 16 # Using the NewsController because it's a simple API.
17 17 context "get /news with the API disabled" do
18 18
19 19 context "in :xml format" do
20 20 context "with a valid api token" do
21 21 setup do
22 22 @user = User.generate_with_protected!
23 23 @token = Token.generate!(:user => @user, :action => 'api')
24 24 get "/news.xml?key=#{@token.value}"
25 25 end
26 26
27 27 should_respond_with :unauthorized
28 28 should_respond_with_content_type :xml
29 29 should "not login as the user" do
30 30 assert_equal User.anonymous, User.current
31 31 end
32 32 end
33 33
34 34 context "with a valid HTTP authentication" do
35 35 setup do
36 36 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
37 37 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
38 38 get "/news.xml", nil, :authorization => @authorization
39 39 end
40 40
41 41 should_respond_with :unauthorized
42 42 should_respond_with_content_type :xml
43 43 should "not login as the user" do
44 44 assert_equal User.anonymous, User.current
45 45 end
46 46 end
47 47
48 48 context "with a valid HTTP authentication using the API token" do
49 49 setup do
50 50 @user = User.generate_with_protected!
51 51 @token = Token.generate!(:user => @user, :action => 'api')
52 52 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
53 53 get "/news.xml", nil, :authorization => @authorization
54 54 end
55 55
56 56 should_respond_with :unauthorized
57 57 should_respond_with_content_type :xml
58 58 should "not login as the user" do
59 59 assert_equal User.anonymous, User.current
60 60 end
61 61 end
62 62 end
63 63
64 64 context "in :json format" do
65 65 context "with a valid api token" do
66 66 setup do
67 67 @user = User.generate_with_protected!
68 68 @token = Token.generate!(:user => @user, :action => 'api')
69 69 get "/news.json?key=#{@token.value}"
70 70 end
71 71
72 72 should_respond_with :unauthorized
73 73 should_respond_with_content_type :json
74 74 should "not login as the user" do
75 75 assert_equal User.anonymous, User.current
76 76 end
77 77 end
78 78
79 79 context "with a valid HTTP authentication" do
80 80 setup do
81 81 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
82 82 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
83 83 get "/news.json", nil, :authorization => @authorization
84 84 end
85 85
86 86 should_respond_with :unauthorized
87 87 should_respond_with_content_type :json
88 88 should "not login as the user" do
89 89 assert_equal User.anonymous, User.current
90 90 end
91 91 end
92 92
93 93 context "with a valid HTTP authentication using the API token" do
94 94 setup do
95 95 @user = User.generate_with_protected!
96 96 @token = Token.generate!(:user => @user, :action => 'api')
97 97 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
98 98 get "/news.json", nil, :authorization => @authorization
99 99 end
100 100
101 101 should_respond_with :unauthorized
102 102 should_respond_with_content_type :json
103 103 should "not login as the user" do
104 104 assert_equal User.anonymous, User.current
105 105 end
106 106 end
107 107
108 108 end
109 109 end
110 110 end
@@ -1,31 +1,31
1 require "#{File.dirname(__FILE__)}/../../test_helper"
1 require File.expand_path('../../../test_helper', __FILE__)
2 2
3 3 class ApiTest::HttpBasicLoginTest < ActionController::IntegrationTest
4 4 fixtures :all
5 5
6 6 def setup
7 7 Setting.rest_api_enabled = '1'
8 8 Setting.login_required = '1'
9 9 end
10 10
11 11 def teardown
12 12 Setting.rest_api_enabled = '0'
13 13 Setting.login_required = '0'
14 14 end
15 15
16 16 # Using the NewsController because it's a simple API.
17 17 context "get /news" do
18 18 setup do
19 19 project = Project.find('onlinestore')
20 20 EnabledModule.create(:project => project, :name => 'news')
21 21 end
22 22
23 23 context "in :xml format" do
24 24 should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.xml")
25 25 end
26 26
27 27 context "in :json format" do
28 28 should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.json")
29 29 end
30 30 end
31 31 end
@@ -1,27 +1,27
1 require "#{File.dirname(__FILE__)}/../../test_helper"
1 require File.expand_path('../../../test_helper', __FILE__)
2 2
3 3 class ApiTest::HttpBasicLoginWithApiTokenTest < ActionController::IntegrationTest
4 4 fixtures :all
5 5
6 6 def setup
7 7 Setting.rest_api_enabled = '1'
8 8 Setting.login_required = '1'
9 9 end
10 10
11 11 def teardown
12 12 Setting.rest_api_enabled = '0'
13 13 Setting.login_required = '0'
14 14 end
15 15
16 16 # Using the NewsController because it's a simple API.
17 17 context "get /news" do
18 18
19 19 context "in :xml format" do
20 20 should_allow_http_basic_auth_with_key(:get, "/news.xml")
21 21 end
22 22
23 23 context "in :json format" do
24 24 should_allow_http_basic_auth_with_key(:get, "/news.json")
25 25 end
26 26 end
27 27 end
@@ -1,521 +1,521
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../../test_helper"
18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class ApiTest::IssuesTest < ActionController::IntegrationTest
21 21 fixtures :projects,
22 22 :users,
23 23 :roles,
24 24 :members,
25 25 :member_roles,
26 26 :issues,
27 27 :issue_statuses,
28 28 :versions,
29 29 :trackers,
30 30 :projects_trackers,
31 31 :issue_categories,
32 32 :enabled_modules,
33 33 :enumerations,
34 34 :attachments,
35 35 :workflows,
36 36 :custom_fields,
37 37 :custom_values,
38 38 :custom_fields_projects,
39 39 :custom_fields_trackers,
40 40 :time_entries,
41 41 :journals,
42 42 :journal_details,
43 43 :queries
44 44
45 45 def setup
46 46 Setting.rest_api_enabled = '1'
47 47 end
48 48
49 49 context "/index.xml" do
50 50 # Use a private project to make sure auth is really working and not just
51 51 # only showing public issues.
52 52 should_allow_api_authentication(:get, "/projects/private-child/issues.xml")
53 53
54 54 should "contain metadata" do
55 55 get '/issues.xml'
56 56
57 57 assert_tag :tag => 'issues',
58 58 :attributes => {
59 59 :type => 'array',
60 60 :total_count => assigns(:issue_count),
61 61 :limit => 25,
62 62 :offset => 0
63 63 }
64 64 end
65 65
66 66 context "with offset and limit" do
67 67 should "use the params" do
68 68 get '/issues.xml?offset=2&limit=3'
69 69
70 70 assert_equal 3, assigns(:limit)
71 71 assert_equal 2, assigns(:offset)
72 72 assert_tag :tag => 'issues', :children => {:count => 3, :only => {:tag => 'issue'}}
73 73 end
74 74 end
75 75
76 76 context "with nometa param" do
77 77 should "not contain metadata" do
78 78 get '/issues.xml?nometa=1'
79 79
80 80 assert_tag :tag => 'issues',
81 81 :attributes => {
82 82 :type => 'array',
83 83 :total_count => nil,
84 84 :limit => nil,
85 85 :offset => nil
86 86 }
87 87 end
88 88 end
89 89
90 90 context "with nometa header" do
91 91 should "not contain metadata" do
92 92 get '/issues.xml', {}, {'X-Redmine-Nometa' => '1'}
93 93
94 94 assert_tag :tag => 'issues',
95 95 :attributes => {
96 96 :type => 'array',
97 97 :total_count => nil,
98 98 :limit => nil,
99 99 :offset => nil
100 100 }
101 101 end
102 102 end
103 103 end
104 104
105 105 context "/index.json" do
106 106 should_allow_api_authentication(:get, "/projects/private-child/issues.json")
107 107 end
108 108
109 109 context "/index.xml with filter" do
110 110 should_allow_api_authentication(:get, "/projects/private-child/issues.xml?status_id=5")
111 111
112 112 should "show only issues with the status_id" do
113 113 get '/issues.xml?status_id=5'
114 114 assert_tag :tag => 'issues',
115 115 :children => { :count => Issue.visible.count(:conditions => {:status_id => 5}),
116 116 :only => { :tag => 'issue' } }
117 117 end
118 118 end
119 119
120 120 context "/index.json with filter" do
121 121 should_allow_api_authentication(:get, "/projects/private-child/issues.json?status_id=5")
122 122
123 123 should "show only issues with the status_id" do
124 124 get '/issues.json?status_id=5'
125 125
126 126 json = ActiveSupport::JSON.decode(response.body)
127 127 status_ids_used = json['issues'].collect {|j| j['status']['id'] }
128 128 assert_equal 3, status_ids_used.length
129 129 assert status_ids_used.all? {|id| id == 5 }
130 130 end
131 131
132 132 end
133 133
134 134 # Issue 6 is on a private project
135 135 context "/issues/6.xml" do
136 136 should_allow_api_authentication(:get, "/issues/6.xml")
137 137 end
138 138
139 139 context "/issues/6.json" do
140 140 should_allow_api_authentication(:get, "/issues/6.json")
141 141 end
142 142
143 143 context "GET /issues/:id" do
144 144 context "with journals" do
145 145 context ".xml" do
146 146 should "display journals" do
147 147 get '/issues/1.xml?include=journals'
148 148
149 149 assert_tag :tag => 'issue',
150 150 :child => {
151 151 :tag => 'journals',
152 152 :attributes => { :type => 'array' },
153 153 :child => {
154 154 :tag => 'journal',
155 155 :attributes => { :id => '1'},
156 156 :child => {
157 157 :tag => 'details',
158 158 :attributes => { :type => 'array' },
159 159 :child => {
160 160 :tag => 'detail',
161 161 :attributes => { :name => 'status_id' },
162 162 :child => {
163 163 :tag => 'old_value',
164 164 :content => '1',
165 165 :sibling => {
166 166 :tag => 'new_value',
167 167 :content => '2'
168 168 }
169 169 }
170 170 }
171 171 }
172 172 }
173 173 }
174 174 end
175 175 end
176 176 end
177 177
178 178 context "with custom fields" do
179 179 context ".xml" do
180 180 should "display custom fields" do
181 181 get '/issues/3.xml'
182 182
183 183 assert_tag :tag => 'issue',
184 184 :child => {
185 185 :tag => 'custom_fields',
186 186 :attributes => { :type => 'array' },
187 187 :child => {
188 188 :tag => 'custom_field',
189 189 :attributes => { :id => '1'},
190 190 :child => {
191 191 :tag => 'value',
192 192 :content => 'MySQL'
193 193 }
194 194 }
195 195 }
196 196
197 197 assert_nothing_raised do
198 198 Hash.from_xml(response.body).to_xml
199 199 end
200 200 end
201 201 end
202 202 end
203 203
204 204 context "with subtasks" do
205 205 setup do
206 206 @c1 = Issue.generate!(:status_id => 1, :subject => "child c1", :tracker_id => 1, :project_id => 1, :parent_issue_id => 1)
207 207 @c2 = Issue.generate!(:status_id => 1, :subject => "child c2", :tracker_id => 1, :project_id => 1, :parent_issue_id => 1)
208 208 @c3 = Issue.generate!(:status_id => 1, :subject => "child c3", :tracker_id => 1, :project_id => 1, :parent_issue_id => @c1.id)
209 209 end
210 210
211 211 context ".xml" do
212 212 should "display children" do
213 213 get '/issues/1.xml?include=children'
214 214
215 215 assert_tag :tag => 'issue',
216 216 :child => {
217 217 :tag => 'children',
218 218 :children => {:count => 2},
219 219 :child => {
220 220 :tag => 'issue',
221 221 :attributes => {:id => @c1.id.to_s},
222 222 :child => {
223 223 :tag => 'subject',
224 224 :content => 'child c1',
225 225 :sibling => {
226 226 :tag => 'children',
227 227 :children => {:count => 1},
228 228 :child => {
229 229 :tag => 'issue',
230 230 :attributes => {:id => @c3.id.to_s}
231 231 }
232 232 }
233 233 }
234 234 }
235 235 }
236 236 end
237 237
238 238 context ".json" do
239 239 should "display children" do
240 240 get '/issues/1.json?include=children'
241 241
242 242 json = ActiveSupport::JSON.decode(response.body)
243 243 assert_equal([
244 244 {
245 245 'id' => @c1.id, 'subject' => 'child c1', 'tracker' => {'id' => 1, 'name' => 'Bug'},
246 246 'children' => [{ 'id' => @c3.id, 'subject' => 'child c3', 'tracker' => {'id' => 1, 'name' => 'Bug'} }]
247 247 },
248 248 { 'id' => @c2.id, 'subject' => 'child c2', 'tracker' => {'id' => 1, 'name' => 'Bug'} }
249 249 ],
250 250 json['issue']['children'])
251 251 end
252 252 end
253 253 end
254 254 end
255 255 end
256 256
257 257 context "POST /issues.xml" do
258 258 should_allow_api_authentication(:post,
259 259 '/issues.xml',
260 260 {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}},
261 261 {:success_code => :created})
262 262
263 263 should "create an issue with the attributes" do
264 264 assert_difference('Issue.count') do
265 265 post '/issues.xml', {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}}, :authorization => credentials('jsmith')
266 266 end
267 267
268 268 issue = Issue.first(:order => 'id DESC')
269 269 assert_equal 1, issue.project_id
270 270 assert_equal 2, issue.tracker_id
271 271 assert_equal 3, issue.status_id
272 272 assert_equal 'API test', issue.subject
273 273
274 274 assert_response :created
275 275 assert_equal 'application/xml', @response.content_type
276 276 assert_tag 'issue', :child => {:tag => 'id', :content => issue.id.to_s}
277 277 end
278 278 end
279 279
280 280 context "POST /issues.xml with failure" do
281 281 should_allow_api_authentication(:post,
282 282 '/issues.xml',
283 283 {:issue => {:project_id => 1}},
284 284 {:success_code => :unprocessable_entity})
285 285
286 286 should "have an errors tag" do
287 287 assert_no_difference('Issue.count') do
288 288 post '/issues.xml', {:issue => {:project_id => 1}}, :authorization => credentials('jsmith')
289 289 end
290 290
291 291 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
292 292 end
293 293 end
294 294
295 295 context "POST /issues.json" do
296 296 should_allow_api_authentication(:post,
297 297 '/issues.json',
298 298 {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}},
299 299 {:success_code => :created})
300 300
301 301 should "create an issue with the attributes" do
302 302 assert_difference('Issue.count') do
303 303 post '/issues.json', {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}}, :authorization => credentials('jsmith')
304 304 end
305 305
306 306 issue = Issue.first(:order => 'id DESC')
307 307 assert_equal 1, issue.project_id
308 308 assert_equal 2, issue.tracker_id
309 309 assert_equal 3, issue.status_id
310 310 assert_equal 'API test', issue.subject
311 311 end
312 312
313 313 end
314 314
315 315 context "POST /issues.json with failure" do
316 316 should_allow_api_authentication(:post,
317 317 '/issues.json',
318 318 {:issue => {:project_id => 1}},
319 319 {:success_code => :unprocessable_entity})
320 320
321 321 should "have an errors element" do
322 322 assert_no_difference('Issue.count') do
323 323 post '/issues.json', {:issue => {:project_id => 1}}, :authorization => credentials('jsmith')
324 324 end
325 325
326 326 json = ActiveSupport::JSON.decode(response.body)
327 327 assert json['errors'].include?(['subject', "can't be blank"])
328 328 end
329 329 end
330 330
331 331 # Issue 6 is on a private project
332 332 context "PUT /issues/6.xml" do
333 333 setup do
334 334 @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}}
335 335 @headers = { :authorization => credentials('jsmith') }
336 336 end
337 337
338 338 should_allow_api_authentication(:put,
339 339 '/issues/6.xml',
340 340 {:issue => {:subject => 'API update', :notes => 'A new note'}},
341 341 {:success_code => :ok})
342 342
343 343 should "not create a new issue" do
344 344 assert_no_difference('Issue.count') do
345 345 put '/issues/6.xml', @parameters, @headers
346 346 end
347 347 end
348 348
349 349 should "create a new journal" do
350 350 assert_difference('Journal.count') do
351 351 put '/issues/6.xml', @parameters, @headers
352 352 end
353 353 end
354 354
355 355 should "add the note to the journal" do
356 356 put '/issues/6.xml', @parameters, @headers
357 357
358 358 journal = Journal.last
359 359 assert_equal "A new note", journal.notes
360 360 end
361 361
362 362 should "update the issue" do
363 363 put '/issues/6.xml', @parameters, @headers
364 364
365 365 issue = Issue.find(6)
366 366 assert_equal "API update", issue.subject
367 367 end
368 368
369 369 end
370 370
371 371 context "PUT /issues/3.xml with custom fields" do
372 372 setup do
373 373 @parameters = {:issue => {:custom_fields => [{'id' => '1', 'value' => 'PostgreSQL' }, {'id' => '2', 'value' => '150'}]}}
374 374 @headers = { :authorization => credentials('jsmith') }
375 375 end
376 376
377 377 should "update custom fields" do
378 378 assert_no_difference('Issue.count') do
379 379 put '/issues/3.xml', @parameters, @headers
380 380 end
381 381
382 382 issue = Issue.find(3)
383 383 assert_equal '150', issue.custom_value_for(2).value
384 384 assert_equal 'PostgreSQL', issue.custom_value_for(1).value
385 385 end
386 386 end
387 387
388 388 context "PUT /issues/6.xml with failed update" do
389 389 setup do
390 390 @parameters = {:issue => {:subject => ''}}
391 391 @headers = { :authorization => credentials('jsmith') }
392 392 end
393 393
394 394 should_allow_api_authentication(:put,
395 395 '/issues/6.xml',
396 396 {:issue => {:subject => ''}}, # Missing subject should fail
397 397 {:success_code => :unprocessable_entity})
398 398
399 399 should "not create a new issue" do
400 400 assert_no_difference('Issue.count') do
401 401 put '/issues/6.xml', @parameters, @headers
402 402 end
403 403 end
404 404
405 405 should "not create a new journal" do
406 406 assert_no_difference('Journal.count') do
407 407 put '/issues/6.xml', @parameters, @headers
408 408 end
409 409 end
410 410
411 411 should "have an errors tag" do
412 412 put '/issues/6.xml', @parameters, @headers
413 413
414 414 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
415 415 end
416 416 end
417 417
418 418 context "PUT /issues/6.json" do
419 419 setup do
420 420 @parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}}
421 421 @headers = { :authorization => credentials('jsmith') }
422 422 end
423 423
424 424 should_allow_api_authentication(:put,
425 425 '/issues/6.json',
426 426 {:issue => {:subject => 'API update', :notes => 'A new note'}},
427 427 {:success_code => :ok})
428 428
429 429 should "not create a new issue" do
430 430 assert_no_difference('Issue.count') do
431 431 put '/issues/6.json', @parameters, @headers
432 432 end
433 433 end
434 434
435 435 should "create a new journal" do
436 436 assert_difference('Journal.count') do
437 437 put '/issues/6.json', @parameters, @headers
438 438 end
439 439 end
440 440
441 441 should "add the note to the journal" do
442 442 put '/issues/6.json', @parameters, @headers
443 443
444 444 journal = Journal.last
445 445 assert_equal "A new note", journal.notes
446 446 end
447 447
448 448 should "update the issue" do
449 449 put '/issues/6.json', @parameters, @headers
450 450
451 451 issue = Issue.find(6)
452 452 assert_equal "API update", issue.subject
453 453 end
454 454
455 455 end
456 456
457 457 context "PUT /issues/6.json with failed update" do
458 458 setup do
459 459 @parameters = {:issue => {:subject => ''}}
460 460 @headers = { :authorization => credentials('jsmith') }
461 461 end
462 462
463 463 should_allow_api_authentication(:put,
464 464 '/issues/6.json',
465 465 {:issue => {:subject => ''}}, # Missing subject should fail
466 466 {:success_code => :unprocessable_entity})
467 467
468 468 should "not create a new issue" do
469 469 assert_no_difference('Issue.count') do
470 470 put '/issues/6.json', @parameters, @headers
471 471 end
472 472 end
473 473
474 474 should "not create a new journal" do
475 475 assert_no_difference('Journal.count') do
476 476 put '/issues/6.json', @parameters, @headers
477 477 end
478 478 end
479 479
480 480 should "have an errors attribute" do
481 481 put '/issues/6.json', @parameters, @headers
482 482
483 483 json = ActiveSupport::JSON.decode(response.body)
484 484 assert json['errors'].include?(['subject', "can't be blank"])
485 485 end
486 486 end
487 487
488 488 context "DELETE /issues/1.xml" do
489 489 should_allow_api_authentication(:delete,
490 490 '/issues/6.xml',
491 491 {},
492 492 {:success_code => :ok})
493 493
494 494 should "delete the issue" do
495 495 assert_difference('Issue.count',-1) do
496 496 delete '/issues/6.xml', {}, :authorization => credentials('jsmith')
497 497 end
498 498
499 499 assert_nil Issue.find_by_id(6)
500 500 end
501 501 end
502 502
503 503 context "DELETE /issues/1.json" do
504 504 should_allow_api_authentication(:delete,
505 505 '/issues/6.json',
506 506 {},
507 507 {:success_code => :ok})
508 508
509 509 should "delete the issue" do
510 510 assert_difference('Issue.count',-1) do
511 511 delete '/issues/6.json', {}, :authorization => credentials('jsmith')
512 512 end
513 513
514 514 assert_nil Issue.find_by_id(6)
515 515 end
516 516 end
517 517
518 518 def credentials(user, password=nil)
519 519 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
520 520 end
521 521 end
@@ -1,94 +1,94
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../../test_helper"
18 require File.expand_path('../../../test_helper', __FILE__)
19 19 require 'pp'
20 20 class ApiTest::NewsTest < ActionController::IntegrationTest
21 21 fixtures :all
22 22
23 23 def setup
24 24 Setting.rest_api_enabled = '1'
25 25 end
26 26
27 27 context "GET /news" do
28 28 context ".xml" do
29 29 should "return news" do
30 30 get '/news.xml'
31 31
32 32 assert_tag :tag => 'news',
33 33 :attributes => {:type => 'array'},
34 34 :child => {
35 35 :tag => 'news',
36 36 :child => {
37 37 :tag => 'id',
38 38 :content => '2'
39 39 }
40 40 }
41 41 end
42 42 end
43 43
44 44 context ".json" do
45 45 should "return news" do
46 46 get '/news.json'
47 47
48 48 json = ActiveSupport::JSON.decode(response.body)
49 49 assert_kind_of Hash, json
50 50 assert_kind_of Array, json['news']
51 51 assert_kind_of Hash, json['news'].first
52 52 assert_equal 2, json['news'].first['id']
53 53 end
54 54 end
55 55 end
56 56
57 57 context "GET /projects/:project_id/news" do
58 58 context ".xml" do
59 59 should_allow_api_authentication(:get, "/projects/onlinestore/news.xml")
60 60
61 61 should "return news" do
62 62 get '/projects/ecookbook/news.xml'
63 63
64 64 assert_tag :tag => 'news',
65 65 :attributes => {:type => 'array'},
66 66 :child => {
67 67 :tag => 'news',
68 68 :child => {
69 69 :tag => 'id',
70 70 :content => '2'
71 71 }
72 72 }
73 73 end
74 74 end
75 75
76 76 context ".json" do
77 77 should_allow_api_authentication(:get, "/projects/onlinestore/news.json")
78 78
79 79 should "return news" do
80 80 get '/projects/ecookbook/news.json'
81 81
82 82 json = ActiveSupport::JSON.decode(response.body)
83 83 assert_kind_of Hash, json
84 84 assert_kind_of Array, json['news']
85 85 assert_kind_of Hash, json['news'].first
86 86 assert_equal 2, json['news'].first['id']
87 87 end
88 88 end
89 89 end
90 90
91 91 def credentials(user, password=nil)
92 92 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
93 93 end
94 94 end
@@ -1,216 +1,216
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../../test_helper"
18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class ApiTest::ProjectsTest < ActionController::IntegrationTest
21 21 fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
22 22 :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
23 23 :attachments, :custom_fields, :custom_values, :time_entries
24 24
25 25 def setup
26 26 Setting.rest_api_enabled = '1'
27 27 end
28 28
29 29 context "GET /projects" do
30 30 context ".xml" do
31 31 should "return projects" do
32 32 get '/projects.xml'
33 33 assert_response :success
34 34 assert_equal 'application/xml', @response.content_type
35 35
36 36 assert_tag :tag => 'projects',
37 37 :child => {:tag => 'project', :child => {:tag => 'id', :content => '1'}}
38 38 end
39 39 end
40 40
41 41 context ".json" do
42 42 should "return projects" do
43 43 get '/projects.json'
44 44 assert_response :success
45 45 assert_equal 'application/json', @response.content_type
46 46
47 47 json = ActiveSupport::JSON.decode(response.body)
48 48 assert_kind_of Hash, json
49 49 assert_kind_of Array, json['projects']
50 50 assert_kind_of Hash, json['projects'].first
51 51 assert json['projects'].first.has_key?('id')
52 52 end
53 53 end
54 54 end
55 55
56 56 context "GET /projects/:id" do
57 57 context ".xml" do
58 58 # TODO: A private project is needed because should_allow_api_authentication
59 59 # actually tests that authentication is *required*, not just allowed
60 60 should_allow_api_authentication(:get, "/projects/2.xml")
61 61
62 62 should "return requested project" do
63 63 get '/projects/1.xml'
64 64 assert_response :success
65 65 assert_equal 'application/xml', @response.content_type
66 66
67 67 assert_tag :tag => 'project',
68 68 :child => {:tag => 'id', :content => '1'}
69 69 assert_tag :tag => 'custom_field',
70 70 :attributes => {:name => 'Development status'}, :content => 'Stable'
71 71 end
72 72
73 73 context "with hidden custom fields" do
74 74 setup do
75 75 ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
76 76 end
77 77
78 78 should "not display hidden custom fields" do
79 79 get '/projects/1.xml'
80 80 assert_response :success
81 81 assert_equal 'application/xml', @response.content_type
82 82
83 83 assert_no_tag 'custom_field',
84 84 :attributes => {:name => 'Development status'}
85 85 end
86 86 end
87 87 end
88 88
89 89 context ".json" do
90 90 should_allow_api_authentication(:get, "/projects/2.json")
91 91
92 92 should "return requested project" do
93 93 get '/projects/1.json'
94 94
95 95 json = ActiveSupport::JSON.decode(response.body)
96 96 assert_kind_of Hash, json
97 97 assert_kind_of Hash, json['project']
98 98 assert_equal 1, json['project']['id']
99 99 end
100 100 end
101 101 end
102 102
103 103 context "POST /projects" do
104 104 context "with valid parameters" do
105 105 setup do
106 106 Setting.default_projects_modules = ['issue_tracking', 'repository']
107 107 @parameters = {:project => {:name => 'API test', :identifier => 'api-test'}}
108 108 end
109 109
110 110 context ".xml" do
111 111 should_allow_api_authentication(:post,
112 112 '/projects.xml',
113 113 {:project => {:name => 'API test', :identifier => 'api-test'}},
114 114 {:success_code => :created})
115 115
116 116
117 117 should "create a project with the attributes" do
118 118 assert_difference('Project.count') do
119 119 post '/projects.xml', @parameters, :authorization => credentials('admin')
120 120 end
121 121
122 122 project = Project.first(:order => 'id DESC')
123 123 assert_equal 'API test', project.name
124 124 assert_equal 'api-test', project.identifier
125 125 assert_equal ['issue_tracking', 'repository'], project.enabled_module_names
126 126
127 127 assert_response :created
128 128 assert_equal 'application/xml', @response.content_type
129 129 assert_tag 'project', :child => {:tag => 'id', :content => project.id.to_s}
130 130 end
131 131 end
132 132 end
133 133
134 134 context "with invalid parameters" do
135 135 setup do
136 136 @parameters = {:project => {:name => 'API test'}}
137 137 end
138 138
139 139 context ".xml" do
140 140 should "return errors" do
141 141 assert_no_difference('Project.count') do
142 142 post '/projects.xml', @parameters, :authorization => credentials('admin')
143 143 end
144 144
145 145 assert_response :unprocessable_entity
146 146 assert_equal 'application/xml', @response.content_type
147 147 assert_tag 'errors', :child => {:tag => 'error', :content => "Identifier can't be blank"}
148 148 end
149 149 end
150 150 end
151 151 end
152 152
153 153 context "PUT /projects/:id" do
154 154 context "with valid parameters" do
155 155 setup do
156 156 @parameters = {:project => {:name => 'API update'}}
157 157 end
158 158
159 159 context ".xml" do
160 160 should_allow_api_authentication(:put,
161 161 '/projects/2.xml',
162 162 {:project => {:name => 'API update'}},
163 163 {:success_code => :ok})
164 164
165 165 should "update the project" do
166 166 assert_no_difference 'Project.count' do
167 167 put '/projects/2.xml', @parameters, :authorization => credentials('jsmith')
168 168 end
169 169 assert_response :ok
170 170 assert_equal 'application/xml', @response.content_type
171 171 project = Project.find(2)
172 172 assert_equal 'API update', project.name
173 173 end
174 174 end
175 175 end
176 176
177 177 context "with invalid parameters" do
178 178 setup do
179 179 @parameters = {:project => {:name => ''}}
180 180 end
181 181
182 182 context ".xml" do
183 183 should "return errors" do
184 184 assert_no_difference('Project.count') do
185 185 put '/projects/2.xml', @parameters, :authorization => credentials('admin')
186 186 end
187 187
188 188 assert_response :unprocessable_entity
189 189 assert_equal 'application/xml', @response.content_type
190 190 assert_tag 'errors', :child => {:tag => 'error', :content => "Name can't be blank"}
191 191 end
192 192 end
193 193 end
194 194 end
195 195
196 196 context "DELETE /projects/:id" do
197 197 context ".xml" do
198 198 should_allow_api_authentication(:delete,
199 199 '/projects/2.xml',
200 200 {},
201 201 {:success_code => :ok})
202 202
203 203 should "delete the project" do
204 204 assert_difference('Project.count',-1) do
205 205 delete '/projects/2.xml', {}, :authorization => credentials('admin')
206 206 end
207 207 assert_response :ok
208 208 assert_nil Project.find_by_id(2)
209 209 end
210 210 end
211 211 end
212 212
213 213 def credentials(user, password=nil)
214 214 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
215 215 end
216 216 end
@@ -1,134 +1,134
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../../test_helper"
18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class ApiTest::TimeEntriesTest < ActionController::IntegrationTest
21 21 fixtures :all
22 22
23 23 def setup
24 24 Setting.rest_api_enabled = '1'
25 25 end
26 26
27 27 context "GET /time_entries.xml" do
28 28 should "return time entries" do
29 29 get '/time_entries.xml', {}, :authorization => credentials('jsmith')
30 30 assert_response :success
31 31 assert_equal 'application/xml', @response.content_type
32 32 assert_tag :tag => 'time_entries',
33 33 :child => {:tag => 'time_entry', :child => {:tag => 'id', :content => '2'}}
34 34 end
35 35 end
36 36
37 37 context "GET /time_entries/2.xml" do
38 38 should "return requested time entry" do
39 39 get '/time_entries/2.xml', {}, :authorization => credentials('jsmith')
40 40 assert_response :success
41 41 assert_equal 'application/xml', @response.content_type
42 42 assert_tag :tag => 'time_entry',
43 43 :child => {:tag => 'id', :content => '2'}
44 44 end
45 45 end
46 46
47 47 context "POST /time_entries.xml" do
48 48 context "with issue_id" do
49 49 should "return create time entry" do
50 50 assert_difference 'TimeEntry.count' do
51 51 post '/time_entries.xml', {:time_entry => {:issue_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}}, :authorization => credentials('jsmith')
52 52 end
53 53 assert_response :created
54 54 assert_equal 'application/xml', @response.content_type
55 55
56 56 entry = TimeEntry.first(:order => 'id DESC')
57 57 assert_equal 'jsmith', entry.user.login
58 58 assert_equal Issue.find(1), entry.issue
59 59 assert_equal Project.find(1), entry.project
60 60 assert_equal Date.parse('2010-12-02'), entry.spent_on
61 61 assert_equal 3.5, entry.hours
62 62 assert_equal TimeEntryActivity.find(11), entry.activity
63 63 end
64 64 end
65 65
66 66 context "with project_id" do
67 67 should "return create time entry" do
68 68 assert_difference 'TimeEntry.count' do
69 69 post '/time_entries.xml', {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}}, :authorization => credentials('jsmith')
70 70 end
71 71 assert_response :created
72 72 assert_equal 'application/xml', @response.content_type
73 73
74 74 entry = TimeEntry.first(:order => 'id DESC')
75 75 assert_equal 'jsmith', entry.user.login
76 76 assert_nil entry.issue
77 77 assert_equal Project.find(1), entry.project
78 78 assert_equal Date.parse('2010-12-02'), entry.spent_on
79 79 assert_equal 3.5, entry.hours
80 80 assert_equal TimeEntryActivity.find(11), entry.activity
81 81 end
82 82 end
83 83
84 84 context "with invalid parameters" do
85 85 should "return errors" do
86 86 assert_no_difference 'TimeEntry.count' do
87 87 post '/time_entries.xml', {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :activity_id => '11'}}, :authorization => credentials('jsmith')
88 88 end
89 89 assert_response :unprocessable_entity
90 90 assert_equal 'application/xml', @response.content_type
91 91
92 92 assert_tag 'errors', :child => {:tag => 'error', :content => "Hours can't be blank"}
93 93 end
94 94 end
95 95 end
96 96
97 97 context "PUT /time_entries/2.xml" do
98 98 context "with valid parameters" do
99 99 should "update time entry" do
100 100 assert_no_difference 'TimeEntry.count' do
101 101 put '/time_entries/2.xml', {:time_entry => {:comments => 'API Update'}}, :authorization => credentials('jsmith')
102 102 end
103 103 assert_response :ok
104 104 assert_equal 'API Update', TimeEntry.find(2).comments
105 105 end
106 106 end
107 107
108 108 context "with invalid parameters" do
109 109 should "return errors" do
110 110 assert_no_difference 'TimeEntry.count' do
111 111 put '/time_entries/2.xml', {:time_entry => {:hours => '', :comments => 'API Update'}}, :authorization => credentials('jsmith')
112 112 end
113 113 assert_response :unprocessable_entity
114 114 assert_equal 'application/xml', @response.content_type
115 115
116 116 assert_tag 'errors', :child => {:tag => 'error', :content => "Hours can't be blank"}
117 117 end
118 118 end
119 119 end
120 120
121 121 context "DELETE /time_entries/2.xml" do
122 122 should "destroy time entry" do
123 123 assert_difference 'TimeEntry.count', -1 do
124 124 delete '/time_entries/2.xml', {}, :authorization => credentials('jsmith')
125 125 end
126 126 assert_response :ok
127 127 assert_nil TimeEntry.find_by_id(2)
128 128 end
129 129 end
130 130
131 131 def credentials(user, password=nil)
132 132 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
133 133 end
134 134 end
@@ -1,26 +1,26
1 require "#{File.dirname(__FILE__)}/../../test_helper"
1 require File.expand_path('../../../test_helper', __FILE__)
2 2
3 3 class ApiTest::TokenAuthenticationTest < ActionController::IntegrationTest
4 4 fixtures :all
5 5
6 6 def setup
7 7 Setting.rest_api_enabled = '1'
8 8 Setting.login_required = '1'
9 9 end
10 10
11 11 def teardown
12 12 Setting.rest_api_enabled = '0'
13 13 Setting.login_required = '0'
14 14 end
15 15
16 16 # Using the NewsController because it's a simple API.
17 17 context "get /news" do
18 18 context "in :xml format" do
19 19 should_allow_key_based_auth(:get, "/news.xml")
20 20 end
21 21
22 22 context "in :json format" do
23 23 should_allow_key_based_auth(:get, "/news.json")
24 24 end
25 25 end
26 26 end
@@ -1,258 +1,258
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../../test_helper"
18 require File.expand_path('../../../test_helper', __FILE__)
19 19 require 'pp'
20 20 class ApiTest::UsersTest < ActionController::IntegrationTest
21 21 fixtures :users
22 22
23 23 def setup
24 24 Setting.rest_api_enabled = '1'
25 25 end
26 26
27 27 context "GET /users" do
28 28 should_allow_api_authentication(:get, "/users.xml")
29 29 should_allow_api_authentication(:get, "/users.json")
30 30 end
31 31
32 32 context "GET /users/2" do
33 33 context ".xml" do
34 34 should "return requested user" do
35 35 get '/users/2.xml'
36 36
37 37 assert_tag :tag => 'user',
38 38 :child => {:tag => 'id', :content => '2'}
39 39 end
40 40 end
41 41
42 42 context ".json" do
43 43 should "return requested user" do
44 44 get '/users/2.json'
45 45
46 46 json = ActiveSupport::JSON.decode(response.body)
47 47 assert_kind_of Hash, json
48 48 assert_kind_of Hash, json['user']
49 49 assert_equal 2, json['user']['id']
50 50 end
51 51 end
52 52 end
53 53
54 54 context "POST /users" do
55 55 context "with valid parameters" do
56 56 setup do
57 57 @parameters = {:user => {:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname', :mail => 'foo@example.net', :password => 'secret', :mail_notification => 'only_assigned'}}
58 58 end
59 59
60 60 context ".xml" do
61 61 should_allow_api_authentication(:post,
62 62 '/users.xml',
63 63 {:user => {:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname', :mail => 'foo@example.net', :password => 'secret'}},
64 64 {:success_code => :created})
65 65
66 66 should "create a user with the attributes" do
67 67 assert_difference('User.count') do
68 68 post '/users.xml', @parameters, :authorization => credentials('admin')
69 69 end
70 70
71 71 user = User.first(:order => 'id DESC')
72 72 assert_equal 'foo', user.login
73 73 assert_equal 'Firstname', user.firstname
74 74 assert_equal 'Lastname', user.lastname
75 75 assert_equal 'foo@example.net', user.mail
76 76 assert_equal 'only_assigned', user.mail_notification
77 77 assert !user.admin?
78 78 assert user.check_password?('secret')
79 79
80 80 assert_response :created
81 81 assert_equal 'application/xml', @response.content_type
82 82 assert_tag 'user', :child => {:tag => 'id', :content => user.id.to_s}
83 83 end
84 84 end
85 85
86 86 context ".json" do
87 87 should_allow_api_authentication(:post,
88 88 '/users.json',
89 89 {:user => {:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname', :mail => 'foo@example.net'}},
90 90 {:success_code => :created})
91 91
92 92 should "create a user with the attributes" do
93 93 assert_difference('User.count') do
94 94 post '/users.json', @parameters, :authorization => credentials('admin')
95 95 end
96 96
97 97 user = User.first(:order => 'id DESC')
98 98 assert_equal 'foo', user.login
99 99 assert_equal 'Firstname', user.firstname
100 100 assert_equal 'Lastname', user.lastname
101 101 assert_equal 'foo@example.net', user.mail
102 102 assert !user.admin?
103 103
104 104 assert_response :created
105 105 assert_equal 'application/json', @response.content_type
106 106 json = ActiveSupport::JSON.decode(response.body)
107 107 assert_kind_of Hash, json
108 108 assert_kind_of Hash, json['user']
109 109 assert_equal user.id, json['user']['id']
110 110 end
111 111 end
112 112 end
113 113
114 114 context "with invalid parameters" do
115 115 setup do
116 116 @parameters = {:user => {:login => 'foo', :lastname => 'Lastname', :mail => 'foo'}}
117 117 end
118 118
119 119 context ".xml" do
120 120 should "return errors" do
121 121 assert_no_difference('User.count') do
122 122 post '/users.xml', @parameters, :authorization => credentials('admin')
123 123 end
124 124
125 125 assert_response :unprocessable_entity
126 126 assert_equal 'application/xml', @response.content_type
127 127 assert_tag 'errors', :child => {:tag => 'error', :content => "Firstname can't be blank"}
128 128 end
129 129 end
130 130
131 131 context ".json" do
132 132 should "return errors" do
133 133 assert_no_difference('User.count') do
134 134 post '/users.json', @parameters, :authorization => credentials('admin')
135 135 end
136 136
137 137 assert_response :unprocessable_entity
138 138 assert_equal 'application/json', @response.content_type
139 139 json = ActiveSupport::JSON.decode(response.body)
140 140 assert_kind_of Hash, json
141 141 assert json.has_key?('errors')
142 142 assert_kind_of Array, json['errors']
143 143 end
144 144 end
145 145 end
146 146 end
147 147
148 148 context "PUT /users/2" do
149 149 context "with valid parameters" do
150 150 setup do
151 151 @parameters = {:user => {:login => 'jsmith', :firstname => 'John', :lastname => 'Renamed', :mail => 'jsmith@somenet.foo'}}
152 152 end
153 153
154 154 context ".xml" do
155 155 should_allow_api_authentication(:put,
156 156 '/users/2.xml',
157 157 {:user => {:login => 'jsmith', :firstname => 'John', :lastname => 'Renamed', :mail => 'jsmith@somenet.foo'}},
158 158 {:success_code => :ok})
159 159
160 160 should "update user with the attributes" do
161 161 assert_no_difference('User.count') do
162 162 put '/users/2.xml', @parameters, :authorization => credentials('admin')
163 163 end
164 164
165 165 user = User.find(2)
166 166 assert_equal 'jsmith', user.login
167 167 assert_equal 'John', user.firstname
168 168 assert_equal 'Renamed', user.lastname
169 169 assert_equal 'jsmith@somenet.foo', user.mail
170 170 assert !user.admin?
171 171
172 172 assert_response :ok
173 173 end
174 174 end
175 175
176 176 context ".json" do
177 177 should_allow_api_authentication(:put,
178 178 '/users/2.json',
179 179 {:user => {:login => 'jsmith', :firstname => 'John', :lastname => 'Renamed', :mail => 'jsmith@somenet.foo'}},
180 180 {:success_code => :ok})
181 181
182 182 should "update user with the attributes" do
183 183 assert_no_difference('User.count') do
184 184 put '/users/2.json', @parameters, :authorization => credentials('admin')
185 185 end
186 186
187 187 user = User.find(2)
188 188 assert_equal 'jsmith', user.login
189 189 assert_equal 'John', user.firstname
190 190 assert_equal 'Renamed', user.lastname
191 191 assert_equal 'jsmith@somenet.foo', user.mail
192 192 assert !user.admin?
193 193
194 194 assert_response :ok
195 195 end
196 196 end
197 197 end
198 198
199 199 context "with invalid parameters" do
200 200 setup do
201 201 @parameters = {:user => {:login => 'jsmith', :firstname => '', :lastname => 'Lastname', :mail => 'foo'}}
202 202 end
203 203
204 204 context ".xml" do
205 205 should "return errors" do
206 206 assert_no_difference('User.count') do
207 207 put '/users/2.xml', @parameters, :authorization => credentials('admin')
208 208 end
209 209
210 210 assert_response :unprocessable_entity
211 211 assert_equal 'application/xml', @response.content_type
212 212 assert_tag 'errors', :child => {:tag => 'error', :content => "Firstname can't be blank"}
213 213 end
214 214 end
215 215
216 216 context ".json" do
217 217 should "return errors" do
218 218 assert_no_difference('User.count') do
219 219 put '/users/2.json', @parameters, :authorization => credentials('admin')
220 220 end
221 221
222 222 assert_response :unprocessable_entity
223 223 assert_equal 'application/json', @response.content_type
224 224 json = ActiveSupport::JSON.decode(response.body)
225 225 assert_kind_of Hash, json
226 226 assert json.has_key?('errors')
227 227 assert_kind_of Array, json['errors']
228 228 end
229 229 end
230 230 end
231 231
232 232 context "DELETE /users/2" do
233 233 context ".xml" do
234 234 should "not be allowed" do
235 235 assert_no_difference('User.count') do
236 236 delete '/users/2.xml'
237 237 end
238 238
239 239 assert_response :method_not_allowed
240 240 end
241 241 end
242 242
243 243 context ".json" do
244 244 should "not be allowed" do
245 245 assert_no_difference('User.count') do
246 246 delete '/users/2.json'
247 247 end
248 248
249 249 assert_response :method_not_allowed
250 250 end
251 251 end
252 252 end
253 253 end
254 254
255 255 def credentials(user, password=nil)
256 256 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
257 257 end
258 258 end
@@ -1,56 +1,56
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../test_helper"
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class ApplicationTest < ActionController::IntegrationTest
21 21 include Redmine::I18n
22 22
23 23 fixtures :all
24 24
25 25 def test_set_localization
26 26 Setting.default_language = 'en'
27 27
28 28 # a french user
29 29 get 'projects', { }, 'Accept-Language' => 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
30 30 assert_response :success
31 31 assert_tag :tag => 'h2', :content => 'Projets'
32 32 assert_equal :fr, current_language
33 33
34 34 # then an italien user
35 35 get 'projects', { }, 'Accept-Language' => 'it;q=0.8,en-us;q=0.5,en;q=0.3'
36 36 assert_response :success
37 37 assert_tag :tag => 'h2', :content => 'Progetti'
38 38 assert_equal :it, current_language
39 39
40 40 # not a supported language: default language should be used
41 41 get 'projects', { }, 'Accept-Language' => 'zz'
42 42 assert_response :success
43 43 assert_tag :tag => 'h2', :content => 'Projects'
44 44 end
45 45
46 46 def test_token_based_access_should_not_start_session
47 47 # issue of a private project
48 48 get 'issues/4.atom'
49 49 assert_response 302
50 50
51 51 rss_key = User.find(2).rss_key
52 52 get "issues/4.atom?key=#{rss_key}"
53 53 assert_response 200
54 54 assert_nil session[:user_id]
55 55 end
56 56 end
@@ -1,129 +1,129
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../test_helper"
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class IssuesTest < ActionController::IntegrationTest
21 21 fixtures :projects,
22 22 :users,
23 23 :roles,
24 24 :members,
25 25 :trackers,
26 26 :projects_trackers,
27 27 :enabled_modules,
28 28 :issue_statuses,
29 29 :issues,
30 30 :enumerations,
31 31 :custom_fields,
32 32 :custom_values,
33 33 :custom_fields_trackers
34 34
35 35 # create an issue
36 36 def test_add_issue
37 37 log_user('jsmith', 'jsmith')
38 38 get 'projects/1/issues/new', :tracker_id => '1'
39 39 assert_response :success
40 40 assert_template 'issues/new'
41 41
42 42 post 'projects/1/issues', :tracker_id => "1",
43 43 :issue => { :start_date => "2006-12-26",
44 44 :priority_id => "4",
45 45 :subject => "new test issue",
46 46 :category_id => "",
47 47 :description => "new issue",
48 48 :done_ratio => "0",
49 49 :due_date => "",
50 50 :assigned_to_id => "" },
51 51 :custom_fields => {'2' => 'Value for field 2'}
52 52 # find created issue
53 53 issue = Issue.find_by_subject("new test issue")
54 54 assert_kind_of Issue, issue
55 55
56 56 # check redirection
57 57 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
58 58 follow_redirect!
59 59 assert_equal issue, assigns(:issue)
60 60
61 61 # check issue attributes
62 62 assert_equal 'jsmith', issue.author.login
63 63 assert_equal 1, issue.project.id
64 64 assert_equal 1, issue.status.id
65 65 end
66 66
67 67 # add then remove 2 attachments to an issue
68 68 def test_issue_attachements
69 69 log_user('jsmith', 'jsmith')
70 70 set_tmp_attachments_directory
71 71
72 72 put 'issues/1',
73 73 :notes => 'Some notes',
74 74 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'This is an attachment'}}
75 75 assert_redirected_to "/issues/1"
76 76
77 77 # make sure attachment was saved
78 78 attachment = Issue.find(1).attachments.find_by_filename("testfile.txt")
79 79 assert_kind_of Attachment, attachment
80 80 assert_equal Issue.find(1), attachment.container
81 81 assert_equal 'This is an attachment', attachment.description
82 82 # verify the size of the attachment stored in db
83 83 #assert_equal file_data_1.length, attachment.filesize
84 84 # verify that the attachment was written to disk
85 85 assert File.exist?(attachment.diskfile)
86 86
87 87 # remove the attachments
88 88 Issue.find(1).attachments.each(&:destroy)
89 89 assert_equal 0, Issue.find(1).attachments.length
90 90 end
91 91
92 92 def test_other_formats_links_on_get_index
93 93 get '/projects/ecookbook/issues'
94 94
95 95 %w(Atom PDF CSV).each do |format|
96 96 assert_tag :a, :content => format,
97 97 :attributes => { :href => "/projects/ecookbook/issues.#{format.downcase}",
98 98 :rel => 'nofollow' }
99 99 end
100 100 end
101 101
102 102 def test_other_formats_links_on_post_index_without_project_id_in_url
103 103 post '/issues', :project_id => 'ecookbook'
104 104
105 105 %w(Atom PDF CSV).each do |format|
106 106 assert_tag :a, :content => format,
107 107 :attributes => { :href => "/projects/ecookbook/issues.#{format.downcase}",
108 108 :rel => 'nofollow' }
109 109 end
110 110 end
111 111
112 112 def test_pagination_links_on_get_index
113 113 Setting.per_page_options = '2'
114 114 get '/projects/ecookbook/issues'
115 115
116 116 assert_tag :a, :content => '2',
117 117 :attributes => { :href => '/projects/ecookbook/issues?page=2' }
118 118
119 119 end
120 120
121 121 def test_pagination_links_on_post_index_without_project_id_in_url
122 122 Setting.per_page_options = '2'
123 123 post '/issues', :project_id => 'ecookbook'
124 124
125 125 assert_tag :a, :content => '2',
126 126 :attributes => { :href => '/projects/ecookbook/issues?page=2' }
127 127
128 128 end
129 129 end
@@ -1,24 +1,24
1 require "#{File.dirname(__FILE__)}/../test_helper"
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class LayoutTest < ActionController::IntegrationTest
4 4 fixtures :all
5 5
6 6 test "browsing to a missing page should render the base layout" do
7 7 get "/users/100000000"
8 8
9 9 assert_response :not_found
10 10
11 11 # UsersController uses the admin layout by default
12 12 assert_select "#admin-menu", :count => 0
13 13 end
14 14
15 15 test "browsing to an unauthorized page should render the base layout" do
16 16 change_user_password('miscuser9', 'test')
17 17
18 18 log_user('miscuser9','test')
19 19
20 20 get "/admin"
21 21 assert_response :forbidden
22 22 assert_select "#admin-menu", :count => 0
23 23 end
24 24 end
@@ -1,70 +1,70
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../../../test_helper"
18 require File.expand_path('../../../../test_helper', __FILE__)
19 19
20 20 class MenuManagerTest < ActionController::IntegrationTest
21 21 include Redmine::I18n
22 22
23 23 fixtures :all
24 24
25 25 def test_project_menu_with_specific_locale
26 26 get 'projects/ecookbook/issues', { }, 'Accept-Language' => 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'
27 27
28 28 assert_tag :div, :attributes => { :id => 'main-menu' },
29 29 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => ll('fr', :label_activity),
30 30 :attributes => { :href => '/projects/ecookbook/activity',
31 31 :class => 'activity' } } }
32 32 assert_tag :div, :attributes => { :id => 'main-menu' },
33 33 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => ll('fr', :label_issue_plural),
34 34 :attributes => { :href => '/projects/ecookbook/issues',
35 35 :class => 'issues selected' } } }
36 36 end
37 37
38 38 def test_project_menu_with_additional_menu_items
39 39 Setting.default_language = 'en'
40 40 assert_no_difference 'Redmine::MenuManager.items(:project_menu).size' do
41 41 Redmine::MenuManager.map :project_menu do |menu|
42 42 menu.push :foo, { :controller => 'projects', :action => 'show' }, :caption => 'Foo'
43 43 menu.push :bar, { :controller => 'projects', :action => 'show' }, :before => :activity
44 44 menu.push :hello, { :controller => 'projects', :action => 'show' }, :caption => Proc.new {|p| p.name.upcase }, :after => :bar
45 45 end
46 46
47 47 get 'projects/ecookbook'
48 48 assert_tag :div, :attributes => { :id => 'main-menu' },
49 49 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Foo',
50 50 :attributes => { :class => 'foo' } } }
51 51
52 52 assert_tag :div, :attributes => { :id => 'main-menu' },
53 53 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Bar',
54 54 :attributes => { :class => 'bar' } },
55 55 :before => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK' } } }
56 56
57 57 assert_tag :div, :attributes => { :id => 'main-menu' },
58 58 :descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK',
59 59 :attributes => { :class => 'hello' } },
60 60 :before => { :tag => 'li', :child => { :tag => 'a', :content => 'Activity' } } }
61 61
62 62 # Remove the menu items
63 63 Redmine::MenuManager.map :project_menu do |menu|
64 64 menu.delete :foo
65 65 menu.delete :bar
66 66 menu.delete :hello
67 67 end
68 68 end
69 69 end
70 70 end
@@ -1,44 +1,44
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../test_helper"
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class ProjectsTest < ActionController::IntegrationTest
21 21 fixtures :projects, :users, :members
22 22
23 23 def test_archive_project
24 24 subproject = Project.find(1).children.first
25 25 log_user("admin", "admin")
26 26 get "admin/projects"
27 27 assert_response :success
28 28 assert_template "admin/projects"
29 29 post "projects/archive", :id => 1
30 30 assert_redirected_to "/admin/projects"
31 31 assert !Project.find(1).active?
32 32
33 33 get 'projects/1'
34 34 assert_response 403
35 35 get "projects/#{subproject.id}"
36 36 assert_response 403
37 37
38 38 post "projects/unarchive", :id => 1
39 39 assert_redirected_to "/admin/projects"
40 40 assert Project.find(1).active?
41 41 get "projects/1"
42 42 assert_response :success
43 43 end
44 44 end
@@ -1,347 +1,347
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require "#{File.dirname(__FILE__)}/../test_helper"
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class RoutingTest < ActionController::IntegrationTest
21 21 context "activities" do
22 22 should_route :get, "/activity", :controller => 'activities', :action => 'index', :id => nil
23 23 should_route :get, "/activity.atom", :controller => 'activities', :action => 'index', :id => nil, :format => 'atom'
24 24 end
25 25
26 26 context "attachments" do
27 27 should_route :get, "/attachments/1", :controller => 'attachments', :action => 'show', :id => '1'
28 28 should_route :get, "/attachments/1/filename.ext", :controller => 'attachments', :action => 'show', :id => '1', :filename => 'filename.ext'
29 29 should_route :get, "/attachments/download/1", :controller => 'attachments', :action => 'download', :id => '1'
30 30 should_route :get, "/attachments/download/1/filename.ext", :controller => 'attachments', :action => 'download', :id => '1', :filename => 'filename.ext'
31 31 end
32 32
33 33 context "boards" do
34 34 should_route :get, "/projects/world_domination/boards", :controller => 'boards', :action => 'index', :project_id => 'world_domination'
35 35 should_route :get, "/projects/world_domination/boards/new", :controller => 'boards', :action => 'new', :project_id => 'world_domination'
36 36 should_route :get, "/projects/world_domination/boards/44", :controller => 'boards', :action => 'show', :project_id => 'world_domination', :id => '44'
37 37 should_route :get, "/projects/world_domination/boards/44.atom", :controller => 'boards', :action => 'show', :project_id => 'world_domination', :id => '44', :format => 'atom'
38 38 should_route :get, "/projects/world_domination/boards/44/edit", :controller => 'boards', :action => 'edit', :project_id => 'world_domination', :id => '44'
39 39
40 40 should_route :post, "/projects/world_domination/boards/new", :controller => 'boards', :action => 'new', :project_id => 'world_domination'
41 41 should_route :post, "/projects/world_domination/boards/44/edit", :controller => 'boards', :action => 'edit', :project_id => 'world_domination', :id => '44'
42 42 should_route :post, "/projects/world_domination/boards/44/destroy", :controller => 'boards', :action => 'destroy', :project_id => 'world_domination', :id => '44'
43 43
44 44 end
45 45
46 46 context "documents" do
47 47 should_route :get, "/projects/567/documents", :controller => 'documents', :action => 'index', :project_id => '567'
48 48 should_route :get, "/projects/567/documents/new", :controller => 'documents', :action => 'new', :project_id => '567'
49 49 should_route :get, "/documents/22", :controller => 'documents', :action => 'show', :id => '22'
50 50 should_route :get, "/documents/22/edit", :controller => 'documents', :action => 'edit', :id => '22'
51 51
52 52 should_route :post, "/projects/567/documents/new", :controller => 'documents', :action => 'new', :project_id => '567'
53 53 should_route :post, "/documents/567/edit", :controller => 'documents', :action => 'edit', :id => '567'
54 54 should_route :post, "/documents/567/destroy", :controller => 'documents', :action => 'destroy', :id => '567'
55 55 end
56 56
57 57 context "issues" do
58 58 # REST actions
59 59 should_route :get, "/issues", :controller => 'issues', :action => 'index'
60 60 should_route :get, "/issues.pdf", :controller => 'issues', :action => 'index', :format => 'pdf'
61 61 should_route :get, "/issues.atom", :controller => 'issues', :action => 'index', :format => 'atom'
62 62 should_route :get, "/issues.xml", :controller => 'issues', :action => 'index', :format => 'xml'
63 63 should_route :get, "/projects/23/issues", :controller => 'issues', :action => 'index', :project_id => '23'
64 64 should_route :get, "/projects/23/issues.pdf", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'pdf'
65 65 should_route :get, "/projects/23/issues.atom", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'atom'
66 66 should_route :get, "/projects/23/issues.xml", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'xml'
67 67 should_route :get, "/issues/64", :controller => 'issues', :action => 'show', :id => '64'
68 68 should_route :get, "/issues/64.pdf", :controller => 'issues', :action => 'show', :id => '64', :format => 'pdf'
69 69 should_route :get, "/issues/64.atom", :controller => 'issues', :action => 'show', :id => '64', :format => 'atom'
70 70 should_route :get, "/issues/64.xml", :controller => 'issues', :action => 'show', :id => '64', :format => 'xml'
71 71
72 72 should_route :get, "/projects/23/issues/new", :controller => 'issues', :action => 'new', :project_id => '23'
73 73 should_route :post, "/projects/23/issues", :controller => 'issues', :action => 'create', :project_id => '23'
74 74 should_route :post, "/issues.xml", :controller => 'issues', :action => 'create', :format => 'xml'
75 75
76 76 should_route :get, "/issues/64/edit", :controller => 'issues', :action => 'edit', :id => '64'
77 77 # TODO: Should use PUT
78 78 should_route :post, "/issues/64/edit", :controller => 'issues', :action => 'edit', :id => '64'
79 79 should_route :put, "/issues/1.xml", :controller => 'issues', :action => 'update', :id => '1', :format => 'xml'
80 80
81 81 # TODO: Should use DELETE
82 82 should_route :post, "/issues/64/destroy", :controller => 'issues', :action => 'destroy', :id => '64'
83 83 should_route :delete, "/issues/1.xml", :controller => 'issues', :action => 'destroy', :id => '1', :format => 'xml'
84 84
85 85 # Extra actions
86 86 should_route :get, "/projects/23/issues/64/copy", :controller => 'issues', :action => 'new', :project_id => '23', :copy_from => '64'
87 87
88 88 should_route :get, "/issues/move/new", :controller => 'issue_moves', :action => 'new'
89 89 should_route :post, "/issues/move", :controller => 'issue_moves', :action => 'create'
90 90
91 91 should_route :post, "/issues/1/quoted", :controller => 'journals', :action => 'new', :id => '1'
92 92
93 93 should_route :get, "/issues/calendar", :controller => 'calendars', :action => 'show'
94 94 should_route :put, "/issues/calendar", :controller => 'calendars', :action => 'update'
95 95 should_route :get, "/projects/project-name/issues/calendar", :controller => 'calendars', :action => 'show', :project_id => 'project-name'
96 96 should_route :put, "/projects/project-name/issues/calendar", :controller => 'calendars', :action => 'update', :project_id => 'project-name'
97 97
98 98 should_route :get, "/issues/gantt", :controller => 'gantts', :action => 'show'
99 99 should_route :put, "/issues/gantt", :controller => 'gantts', :action => 'update'
100 100 should_route :get, "/projects/project-name/issues/gantt", :controller => 'gantts', :action => 'show', :project_id => 'project-name'
101 101 should_route :put, "/projects/project-name/issues/gantt", :controller => 'gantts', :action => 'update', :project_id => 'project-name'
102 102
103 103 should_route :get, "/issues/auto_complete", :controller => 'auto_completes', :action => 'issues'
104 104
105 105 should_route :get, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
106 106 should_route :post, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
107 107 should_route :get, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
108 108 should_route :post, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
109 109
110 110 should_route :get, "/issues/changes", :controller => 'journals', :action => 'index'
111 111
112 112 should_route :get, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_edit'
113 113 should_route :post, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_update'
114 114 end
115 115
116 116 context "issue categories" do
117 117 should_route :get, "/projects/test/issue_categories/new", :controller => 'issue_categories', :action => 'new', :project_id => 'test'
118 118
119 119 should_route :post, "/projects/test/issue_categories/new", :controller => 'issue_categories', :action => 'new', :project_id => 'test'
120 120 end
121 121
122 122 context "issue relations" do
123 123 should_route :post, "/issues/1/relations", :controller => 'issue_relations', :action => 'new', :issue_id => '1'
124 124 should_route :post, "/issues/1/relations/23/destroy", :controller => 'issue_relations', :action => 'destroy', :issue_id => '1', :id => '23'
125 125 end
126 126
127 127 context "issue reports" do
128 128 should_route :get, "/projects/567/issues/report", :controller => 'reports', :action => 'issue_report', :id => '567'
129 129 should_route :get, "/projects/567/issues/report/assigned_to", :controller => 'reports', :action => 'issue_report_details', :id => '567', :detail => 'assigned_to'
130 130 end
131 131
132 132 context "members" do
133 133 should_route :post, "/projects/5234/members/new", :controller => 'members', :action => 'new', :id => '5234'
134 134 end
135 135
136 136 context "messages" do
137 137 should_route :get, "/boards/22/topics/2", :controller => 'messages', :action => 'show', :id => '2', :board_id => '22'
138 138 should_route :get, "/boards/lala/topics/new", :controller => 'messages', :action => 'new', :board_id => 'lala'
139 139 should_route :get, "/boards/lala/topics/22/edit", :controller => 'messages', :action => 'edit', :id => '22', :board_id => 'lala'
140 140
141 141 should_route :post, "/boards/lala/topics/new", :controller => 'messages', :action => 'new', :board_id => 'lala'
142 142 should_route :post, "/boards/lala/topics/22/edit", :controller => 'messages', :action => 'edit', :id => '22', :board_id => 'lala'
143 143 should_route :post, "/boards/22/topics/555/replies", :controller => 'messages', :action => 'reply', :id => '555', :board_id => '22'
144 144 should_route :post, "/boards/22/topics/555/destroy", :controller => 'messages', :action => 'destroy', :id => '555', :board_id => '22'
145 145 end
146 146
147 147 context "news" do
148 148 should_route :get, "/news", :controller => 'news', :action => 'index'
149 149 should_route :get, "/news.atom", :controller => 'news', :action => 'index', :format => 'atom'
150 150 should_route :get, "/news.xml", :controller => 'news', :action => 'index', :format => 'xml'
151 151 should_route :get, "/news.json", :controller => 'news', :action => 'index', :format => 'json'
152 152 should_route :get, "/projects/567/news", :controller => 'news', :action => 'index', :project_id => '567'
153 153 should_route :get, "/projects/567/news.atom", :controller => 'news', :action => 'index', :format => 'atom', :project_id => '567'
154 154 should_route :get, "/projects/567/news.xml", :controller => 'news', :action => 'index', :format => 'xml', :project_id => '567'
155 155 should_route :get, "/projects/567/news.json", :controller => 'news', :action => 'index', :format => 'json', :project_id => '567'
156 156 should_route :get, "/news/2", :controller => 'news', :action => 'show', :id => '2'
157 157 should_route :get, "/projects/567/news/new", :controller => 'news', :action => 'new', :project_id => '567'
158 158 should_route :get, "/news/234", :controller => 'news', :action => 'show', :id => '234'
159 159 should_route :get, "/news/567/edit", :controller => 'news', :action => 'edit', :id => '567'
160 160 should_route :get, "/news/preview", :controller => 'previews', :action => 'news'
161 161
162 162 should_route :post, "/projects/567/news", :controller => 'news', :action => 'create', :project_id => '567'
163 163 should_route :post, "/news/567/comments", :controller => 'comments', :action => 'create', :id => '567'
164 164
165 165 should_route :put, "/news/567", :controller => 'news', :action => 'update', :id => '567'
166 166
167 167 should_route :delete, "/news/567", :controller => 'news', :action => 'destroy', :id => '567'
168 168 should_route :delete, "/news/567/comments/15", :controller => 'comments', :action => 'destroy', :id => '567', :comment_id => '15'
169 169 end
170 170
171 171 context "projects" do
172 172 should_route :get, "/projects", :controller => 'projects', :action => 'index'
173 173 should_route :get, "/projects.atom", :controller => 'projects', :action => 'index', :format => 'atom'
174 174 should_route :get, "/projects.xml", :controller => 'projects', :action => 'index', :format => 'xml'
175 175 should_route :get, "/projects/new", :controller => 'projects', :action => 'new'
176 176 should_route :get, "/projects/test", :controller => 'projects', :action => 'show', :id => 'test'
177 177 should_route :get, "/projects/1.xml", :controller => 'projects', :action => 'show', :id => '1', :format => 'xml'
178 178 should_route :get, "/projects/4223/settings", :controller => 'projects', :action => 'settings', :id => '4223'
179 179 should_route :get, "/projects/4223/settings/members", :controller => 'projects', :action => 'settings', :id => '4223', :tab => 'members'
180 180 should_route :get, "/projects/33/files", :controller => 'files', :action => 'index', :project_id => '33'
181 181 should_route :get, "/projects/33/files/new", :controller => 'files', :action => 'new', :project_id => '33'
182 182 should_route :get, "/projects/33/roadmap", :controller => 'versions', :action => 'index', :project_id => '33'
183 183 should_route :get, "/projects/33/activity", :controller => 'activities', :action => 'index', :id => '33'
184 184 should_route :get, "/projects/33/activity.atom", :controller => 'activities', :action => 'index', :id => '33', :format => 'atom'
185 185
186 186 should_route :post, "/projects", :controller => 'projects', :action => 'create'
187 187 should_route :post, "/projects.xml", :controller => 'projects', :action => 'create', :format => 'xml'
188 188 should_route :post, "/projects/33/files", :controller => 'files', :action => 'create', :project_id => '33'
189 189 should_route :post, "/projects/64/archive", :controller => 'projects', :action => 'archive', :id => '64'
190 190 should_route :post, "/projects/64/unarchive", :controller => 'projects', :action => 'unarchive', :id => '64'
191 191
192 192 should_route :put, "/projects/64/enumerations", :controller => 'project_enumerations', :action => 'update', :project_id => '64'
193 193 should_route :put, "/projects/4223", :controller => 'projects', :action => 'update', :id => '4223'
194 194 should_route :put, "/projects/1.xml", :controller => 'projects', :action => 'update', :id => '1', :format => 'xml'
195 195
196 196 should_route :delete, "/projects/64", :controller => 'projects', :action => 'destroy', :id => '64'
197 197 should_route :delete, "/projects/1.xml", :controller => 'projects', :action => 'destroy', :id => '1', :format => 'xml'
198 198 should_route :delete, "/projects/64/enumerations", :controller => 'project_enumerations', :action => 'destroy', :project_id => '64'
199 199 end
200 200
201 201 context "repositories" do
202 202 should_route :get, "/projects/redmine/repository", :controller => 'repositories', :action => 'show', :id => 'redmine'
203 203 should_route :get, "/projects/redmine/repository/edit", :controller => 'repositories', :action => 'edit', :id => 'redmine'
204 204 should_route :get, "/projects/redmine/repository/revisions", :controller => 'repositories', :action => 'revisions', :id => 'redmine'
205 205 should_route :get, "/projects/redmine/repository/revisions.atom", :controller => 'repositories', :action => 'revisions', :id => 'redmine', :format => 'atom'
206 206 should_route :get, "/projects/redmine/repository/revisions/2457", :controller => 'repositories', :action => 'revision', :id => 'redmine', :rev => '2457'
207 207 should_route :get, "/projects/redmine/repository/revisions/2457/diff", :controller => 'repositories', :action => 'diff', :id => 'redmine', :rev => '2457'
208 208 should_route :get, "/projects/redmine/repository/revisions/2457/diff.diff", :controller => 'repositories', :action => 'diff', :id => 'redmine', :rev => '2457', :format => 'diff'
209 209 should_route :get, "/projects/redmine/repository/diff/path/to/file.c", :controller => 'repositories', :action => 'diff', :id => 'redmine', :path => %w[path to file.c]
210 210 should_route :get, "/projects/redmine/repository/revisions/2/diff/path/to/file.c", :controller => 'repositories', :action => 'diff', :id => 'redmine', :path => %w[path to file.c], :rev => '2'
211 211 should_route :get, "/projects/redmine/repository/browse/path/to/file.c", :controller => 'repositories', :action => 'browse', :id => 'redmine', :path => %w[path to file.c]
212 212 should_route :get, "/projects/redmine/repository/entry/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c]
213 213 should_route :get, "/projects/redmine/repository/revisions/2/entry/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :rev => '2'
214 214 should_route :get, "/projects/redmine/repository/raw/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :format => 'raw'
215 215 should_route :get, "/projects/redmine/repository/revisions/2/raw/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :rev => '2', :format => 'raw'
216 216 should_route :get, "/projects/redmine/repository/annotate/path/to/file.c", :controller => 'repositories', :action => 'annotate', :id => 'redmine', :path => %w[path to file.c]
217 217 should_route :get, "/projects/redmine/repository/changes/path/to/file.c", :controller => 'repositories', :action => 'changes', :id => 'redmine', :path => %w[path to file.c]
218 218 should_route :get, "/projects/redmine/repository/statistics", :controller => 'repositories', :action => 'stats', :id => 'redmine'
219 219
220 220
221 221 should_route :post, "/projects/redmine/repository/edit", :controller => 'repositories', :action => 'edit', :id => 'redmine'
222 222 end
223 223
224 224 context "timelogs (global)" do
225 225 should_route :get, "/time_entries", :controller => 'timelog', :action => 'index'
226 226 should_route :get, "/time_entries.csv", :controller => 'timelog', :action => 'index', :format => 'csv'
227 227 should_route :get, "/time_entries.atom", :controller => 'timelog', :action => 'index', :format => 'atom'
228 228 should_route :get, "/time_entries/new", :controller => 'timelog', :action => 'new'
229 229 should_route :get, "/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22'
230 230
231 231 should_route :post, "/time_entries", :controller => 'timelog', :action => 'create'
232 232
233 233 should_route :put, "/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22'
234 234
235 235 should_route :delete, "/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55'
236 236 end
237 237
238 238 context "timelogs (scoped under project)" do
239 239 should_route :get, "/projects/567/time_entries", :controller => 'timelog', :action => 'index', :project_id => '567'
240 240 should_route :get, "/projects/567/time_entries.csv", :controller => 'timelog', :action => 'index', :project_id => '567', :format => 'csv'
241 241 should_route :get, "/projects/567/time_entries.atom", :controller => 'timelog', :action => 'index', :project_id => '567', :format => 'atom'
242 242 should_route :get, "/projects/567/time_entries/new", :controller => 'timelog', :action => 'new', :project_id => '567'
243 243 should_route :get, "/projects/567/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :project_id => '567'
244 244
245 245 should_route :post, "/projects/567/time_entries", :controller => 'timelog', :action => 'create', :project_id => '567'
246 246
247 247 should_route :put, "/projects/567/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :project_id => '567'
248 248
249 249 should_route :delete, "/projects/567/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :project_id => '567'
250 250 end
251 251
252 252 context "timelogs (scoped under issues)" do
253 253 should_route :get, "/issues/234/time_entries", :controller => 'timelog', :action => 'index', :issue_id => '234'
254 254 should_route :get, "/issues/234/time_entries.csv", :controller => 'timelog', :action => 'index', :issue_id => '234', :format => 'csv'
255 255 should_route :get, "/issues/234/time_entries.atom", :controller => 'timelog', :action => 'index', :issue_id => '234', :format => 'atom'
256 256 should_route :get, "/issues/234/time_entries/new", :controller => 'timelog', :action => 'new', :issue_id => '234'
257 257 should_route :get, "/issues/234/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :issue_id => '234'
258 258
259 259 should_route :post, "/issues/234/time_entries", :controller => 'timelog', :action => 'create', :issue_id => '234'
260 260
261 261 should_route :put, "/issues/234/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :issue_id => '234'
262 262
263 263 should_route :delete, "/issues/234/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :issue_id => '234'
264 264 end
265 265
266 266 context "timelogs (scoped under project and issues)" do
267 267 should_route :get, "/projects/ecookbook/issues/234/time_entries", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook'
268 268 should_route :get, "/projects/ecookbook/issues/234/time_entries.csv", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook', :format => 'csv'
269 269 should_route :get, "/projects/ecookbook/issues/234/time_entries.atom", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook', :format => 'atom'
270 270 should_route :get, "/projects/ecookbook/issues/234/time_entries/new", :controller => 'timelog', :action => 'new', :issue_id => '234', :project_id => 'ecookbook'
271 271 should_route :get, "/projects/ecookbook/issues/234/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :issue_id => '234', :project_id => 'ecookbook'
272 272
273 273 should_route :post, "/projects/ecookbook/issues/234/time_entries", :controller => 'timelog', :action => 'create', :issue_id => '234', :project_id => 'ecookbook'
274 274
275 275 should_route :put, "/projects/ecookbook/issues/234/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :issue_id => '234', :project_id => 'ecookbook'
276 276
277 277 should_route :delete, "/projects/ecookbook/issues/234/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :issue_id => '234', :project_id => 'ecookbook'
278 278 end
279 279
280 280 context "time_entry_reports" do
281 281 should_route :get, "/time_entries/report", :controller => 'time_entry_reports', :action => 'report'
282 282 should_route :get, "/projects/567/time_entries/report", :controller => 'time_entry_reports', :action => 'report', :project_id => '567'
283 283 should_route :get, "/projects/567/time_entries/report.csv", :controller => 'time_entry_reports', :action => 'report', :project_id => '567', :format => 'csv'
284 284 end
285 285
286 286 context "users" do
287 287 should_route :get, "/users", :controller => 'users', :action => 'index'
288 288 should_route :get, "/users/44", :controller => 'users', :action => 'show', :id => '44'
289 289 should_route :get, "/users/new", :controller => 'users', :action => 'new'
290 290 should_route :get, "/users/444/edit", :controller => 'users', :action => 'edit', :id => '444'
291 291 should_route :get, "/users/222/edit/membership", :controller => 'users', :action => 'edit', :id => '222', :tab => 'membership'
292 292
293 293 should_route :post, "/users", :controller => 'users', :action => 'create'
294 294 should_route :post, "/users/123/memberships", :controller => 'users', :action => 'edit_membership', :id => '123'
295 295 should_route :post, "/users/123/memberships/55", :controller => 'users', :action => 'edit_membership', :id => '123', :membership_id => '55'
296 296 should_route :post, "/users/567/memberships/12/destroy", :controller => 'users', :action => 'destroy_membership', :id => '567', :membership_id => '12'
297 297
298 298 should_route :put, "/users/444", :controller => 'users', :action => 'update', :id => '444'
299 299 end
300 300
301 301 # TODO: should they all be scoped under /projects/:project_id ?
302 302 context "versions" do
303 303 should_route :get, "/projects/foo/versions/new", :controller => 'versions', :action => 'new', :project_id => 'foo'
304 304 should_route :get, "/versions/show/1", :controller => 'versions', :action => 'show', :id => '1'
305 305 should_route :get, "/versions/edit/1", :controller => 'versions', :action => 'edit', :id => '1'
306 306
307 307 should_route :post, "/projects/foo/versions", :controller => 'versions', :action => 'create', :project_id => 'foo'
308 308 should_route :post, "/versions/update/1", :controller => 'versions', :action => 'update', :id => '1'
309 309
310 310 should_route :delete, "/versions/destroy/1", :controller => 'versions', :action => 'destroy', :id => '1'
311 311 end
312 312
313 313 context "wiki (singular, project's pages)" do
314 314 should_route :get, "/projects/567/wiki", :controller => 'wiki', :action => 'show', :project_id => '567'
315 315 should_route :get, "/projects/567/wiki/lalala", :controller => 'wiki', :action => 'show', :project_id => '567', :id => 'lalala'
316 316 should_route :get, "/projects/567/wiki/my_page/edit", :controller => 'wiki', :action => 'edit', :project_id => '567', :id => 'my_page'
317 317 should_route :get, "/projects/1/wiki/CookBook_documentation/history", :controller => 'wiki', :action => 'history', :project_id => '1', :id => 'CookBook_documentation'
318 318 should_route :get, "/projects/1/wiki/CookBook_documentation/diff", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation'
319 319 should_route :get, "/projects/1/wiki/CookBook_documentation/diff/2", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation', :version => '2'
320 320 should_route :get, "/projects/1/wiki/CookBook_documentation/diff/2/vs/1", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation', :version => '2', :version_from => '1'
321 321 should_route :get, "/projects/1/wiki/CookBook_documentation/annotate/2", :controller => 'wiki', :action => 'annotate', :project_id => '1', :id => 'CookBook_documentation', :version => '2'
322 322 should_route :get, "/projects/22/wiki/ladida/rename", :controller => 'wiki', :action => 'rename', :project_id => '22', :id => 'ladida'
323 323 should_route :get, "/projects/567/wiki/index", :controller => 'wiki', :action => 'index', :project_id => '567'
324 324 should_route :get, "/projects/567/wiki/date_index", :controller => 'wiki', :action => 'date_index', :project_id => '567'
325 325 should_route :get, "/projects/567/wiki/export", :controller => 'wiki', :action => 'export', :project_id => '567'
326 326
327 327 should_route :post, "/projects/567/wiki/CookBook_documentation/preview", :controller => 'wiki', :action => 'preview', :project_id => '567', :id => 'CookBook_documentation'
328 328 should_route :post, "/projects/22/wiki/ladida/rename", :controller => 'wiki', :action => 'rename', :project_id => '22', :id => 'ladida'
329 329 should_route :post, "/projects/22/wiki/ladida/protect", :controller => 'wiki', :action => 'protect', :project_id => '22', :id => 'ladida'
330 330 should_route :post, "/projects/22/wiki/ladida/add_attachment", :controller => 'wiki', :action => 'add_attachment', :project_id => '22', :id => 'ladida'
331 331
332 332 should_route :put, "/projects/567/wiki/my_page", :controller => 'wiki', :action => 'update', :project_id => '567', :id => 'my_page'
333 333
334 334 should_route :delete, "/projects/22/wiki/ladida", :controller => 'wiki', :action => 'destroy', :project_id => '22', :id => 'ladida'
335 335 end
336 336
337 337 context "wikis (plural, admin setup)" do
338 338 should_route :get, "/projects/ladida/wiki/destroy", :controller => 'wikis', :action => 'destroy', :id => 'ladida'
339 339
340 340 should_route :post, "/projects/ladida/wiki", :controller => 'wikis', :action => 'edit', :id => 'ladida'
341 341 should_route :post, "/projects/ladida/wiki/destroy", :controller => 'wikis', :action => 'destroy', :id => 'ladida'
342 342 end
343 343
344 344 context "administration panel" do
345 345 should_route :get, "/admin/projects", :controller => 'admin', :action => 'projects'
346 346 end
347 347 end
@@ -1,92 +1,92
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class ActivityTest < ActiveSupport::TestCase
21 21 fixtures :projects, :versions, :attachments, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
22 22 :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages
23 23
24 24 def setup
25 25 @project = Project.find(1)
26 26 end
27 27
28 28 def test_activity_without_subprojects
29 29 events = find_events(User.anonymous, :project => @project)
30 30 assert_not_nil events
31 31
32 32 assert events.include?(Issue.find(1))
33 33 assert !events.include?(Issue.find(4))
34 34 # subproject issue
35 35 assert !events.include?(Issue.find(5))
36 36 end
37 37
38 38 def test_activity_with_subprojects
39 39 events = find_events(User.anonymous, :project => @project, :with_subprojects => 1)
40 40 assert_not_nil events
41 41
42 42 assert events.include?(Issue.find(1))
43 43 # subproject issue
44 44 assert events.include?(Issue.find(5))
45 45 end
46 46
47 47 def test_global_activity_anonymous
48 48 events = find_events(User.anonymous)
49 49 assert_not_nil events
50 50
51 51 assert events.include?(Issue.find(1))
52 52 assert events.include?(Message.find(5))
53 53 # Issue of a private project
54 54 assert !events.include?(Issue.find(4))
55 55 end
56 56
57 57 def test_global_activity_logged_user
58 58 events = find_events(User.find(2)) # manager
59 59 assert_not_nil events
60 60
61 61 assert events.include?(Issue.find(1))
62 62 # Issue of a private project the user belongs to
63 63 assert events.include?(Issue.find(4))
64 64 end
65 65
66 66 def test_user_activity
67 67 user = User.find(2)
68 68 events = Redmine::Activity::Fetcher.new(User.anonymous, :author => user).events(nil, nil, :limit => 10)
69 69
70 70 assert(events.size > 0)
71 71 assert(events.size <= 10)
72 72 assert_nil(events.detect {|e| e.event_author != user})
73 73 end
74 74
75 75 def test_files_activity
76 76 f = Redmine::Activity::Fetcher.new(User.anonymous, :project => Project.find(1))
77 77 f.scope = ['files']
78 78 events = f.events
79 79
80 80 assert_kind_of Array, events
81 81 assert events.include?(Attachment.find_by_container_type_and_container_id('Project', 1))
82 82 assert events.include?(Attachment.find_by_container_type_and_container_id('Version', 1))
83 83 assert_equal [Attachment], events.collect(&:class).uniq
84 84 assert_equal %w(Project Version), events.collect(&:container_type).uniq.sort
85 85 end
86 86
87 87 private
88 88
89 89 def find_events(user, options={})
90 90 Redmine::Activity::Fetcher.new(user, options).events(Date.today - 30, Date.today + 1)
91 91 end
92 92 end
@@ -1,85 +1,85
1 1 # encoding: utf-8
2 2 #
3 3 # redMine - project management software
4 4 # Copyright (C) 2006-2007 Jean-Philippe Lang
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; either version 2
9 9 # of the License, or (at your option) any later version.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 19
20 require File.dirname(__FILE__) + '/../test_helper'
20 require File.expand_path('../../test_helper', __FILE__)
21 21
22 22 class AttachmentTest < ActiveSupport::TestCase
23 23 fixtures :issues, :users
24 24
25 25 def setup
26 26 end
27 27
28 28 def test_create
29 29 a = Attachment.new(:container => Issue.find(1),
30 30 :file => uploaded_test_file("testfile.txt", "text/plain"),
31 31 :author => User.find(1))
32 32 assert a.save
33 33 assert_equal 'testfile.txt', a.filename
34 34 assert_equal 59, a.filesize
35 35 assert_equal 'text/plain', a.content_type
36 36 assert_equal 0, a.downloads
37 37 assert_equal Digest::MD5.hexdigest(uploaded_test_file("testfile.txt", "text/plain").read), a.digest
38 38 assert File.exist?(a.diskfile)
39 39 end
40 40
41 41 def test_create_should_auto_assign_content_type
42 42 a = Attachment.new(:container => Issue.find(1),
43 43 :file => uploaded_test_file("testfile.txt", ""),
44 44 :author => User.find(1))
45 45 assert a.save
46 46 assert_equal 'text/plain', a.content_type
47 47 end
48 48
49 49 def test_identical_attachments_at_the_same_time_should_not_overwrite
50 50 a1 = Attachment.create!(:container => Issue.find(1),
51 51 :file => uploaded_test_file("testfile.txt", ""),
52 52 :author => User.find(1))
53 53 a2 = Attachment.create!(:container => Issue.find(1),
54 54 :file => uploaded_test_file("testfile.txt", ""),
55 55 :author => User.find(1))
56 56 assert a1.disk_filename != a2.disk_filename
57 57 end
58 58
59 59 def test_diskfilename
60 60 assert Attachment.disk_filename("test_file.txt") =~ /^\d{12}_test_file.txt$/
61 61 assert_equal 'test_file.txt', Attachment.disk_filename("test_file.txt")[13..-1]
62 62 assert_equal '770c509475505f37c2b8fb6030434d6b.txt', Attachment.disk_filename("test_accentué.txt")[13..-1]
63 63 assert_equal 'f8139524ebb8f32e51976982cd20a85d', Attachment.disk_filename("test_accentué")[13..-1]
64 64 assert_equal 'cbb5b0f30978ba03731d61f9f6d10011', Attachment.disk_filename("test_accentué.ça")[13..-1]
65 65 end
66 66
67 67 context "Attachmnet#attach_files" do
68 68 should "add unsaved files to the object as unsaved attachments" do
69 69 # Max size of 0 to force Attachment creation failures
70 70 with_settings(:attachment_max_size => 0) do
71 71 @project = Project.generate!
72 72 response = Attachment.attach_files(@project, {
73 73 '1' => {'file' => mock_file, 'description' => 'test'},
74 74 '2' => {'file' => mock_file, 'description' => 'test'}
75 75 })
76 76
77 77 assert response[:unsaved].present?
78 78 assert_equal 2, response[:unsaved].length
79 79 assert response[:unsaved].first.new_record?
80 80 assert response[:unsaved].second.new_record?
81 81 assert_equal response[:unsaved], @project.unsaved_attachments
82 82 end
83 83 end
84 84 end
85 85 end
@@ -1,80 +1,80
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class AuthSourceLdapTest < ActiveSupport::TestCase
21 21 fixtures :auth_sources
22 22
23 23 def setup
24 24 end
25 25
26 26 def test_create
27 27 a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName')
28 28 assert a.save
29 29 end
30 30
31 31 def test_should_strip_ldap_attributes
32 32 a = AuthSourceLdap.new(:name => 'My LDAP', :host => 'ldap.example.net', :port => 389, :base_dn => 'dc=example,dc=net', :attr_login => 'sAMAccountName',
33 33 :attr_firstname => 'givenName ')
34 34 assert a.save
35 35 assert_equal 'givenName', a.reload.attr_firstname
36 36 end
37 37
38 38 if ldap_configured?
39 39 context '#authenticate' do
40 40 setup do
41 41 @auth = AuthSourceLdap.find(1)
42 42 end
43 43
44 44 context 'with a valid LDAP user' do
45 45 should 'return the user attributes' do
46 46 attributes = @auth.authenticate('example1','123456')
47 47 assert attributes.is_a?(Hash), "An hash was not returned"
48 48 assert_equal 'Example', attributes[:firstname]
49 49 assert_equal 'One', attributes[:lastname]
50 50 assert_equal 'example1@redmine.org', attributes[:mail]
51 51 assert_equal @auth.id, attributes[:auth_source_id]
52 52 attributes.keys.each do |attribute|
53 53 assert User.new.respond_to?("#{attribute}="), "Unexpected :#{attribute} attribute returned"
54 54 end
55 55 end
56 56 end
57 57
58 58 context 'with an invalid LDAP user' do
59 59 should 'return nil' do
60 60 assert_equal nil, @auth.authenticate('nouser','123456')
61 61 end
62 62 end
63 63
64 64 context 'without a login' do
65 65 should 'return nil' do
66 66 assert_equal nil, @auth.authenticate('','123456')
67 67 end
68 68 end
69 69
70 70 context 'without a password' do
71 71 should 'return nil' do
72 72 assert_equal nil, @auth.authenticate('edavis','')
73 73 end
74 74 end
75 75
76 76 end
77 77 else
78 78 puts '(Test LDAP server not configured)'
79 79 end
80 80 end
@@ -1,35 +1,35
1 require File.dirname(__FILE__) + '/../test_helper'
1 require File.expand_path('../../test_helper', __FILE__)
2 2
3 3 class BoardTest < ActiveSupport::TestCase
4 4 fixtures :projects, :boards, :messages, :attachments, :watchers
5 5
6 6 def setup
7 7 @project = Project.find(1)
8 8 end
9 9
10 10 def test_create
11 11 board = Board.new(:project => @project, :name => 'Test board', :description => 'Test board description')
12 12 assert board.save
13 13 board.reload
14 14 assert_equal 'Test board', board.name
15 15 assert_equal 'Test board description', board.description
16 16 assert_equal @project, board.project
17 17 assert_equal 0, board.topics_count
18 18 assert_equal 0, board.messages_count
19 19 assert_nil board.last_message
20 20 # last position
21 21 assert_equal @project.boards.size, board.position
22 22 end
23 23
24 24 def test_destroy
25 25 board = Board.find(1)
26 26 assert_difference 'Message.count', -6 do
27 27 assert_difference 'Attachment.count', -1 do
28 28 assert_difference 'Watcher.count', -1 do
29 29 assert board.destroy
30 30 end
31 31 end
32 32 end
33 33 assert_equal 0, Message.count(:conditions => {:board_id => 1})
34 34 end
35 35 end
@@ -1,43 +1,43
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class CalendarTest < ActiveSupport::TestCase
21 21
22 22 def test_monthly
23 23 c = Redmine::Helpers::Calendar.new(Date.today, :fr, :month)
24 24 assert_equal [1, 7], [c.startdt.cwday, c.enddt.cwday]
25 25
26 26 c = Redmine::Helpers::Calendar.new('2007-07-14'.to_date, :fr, :month)
27 27 assert_equal ['2007-06-25'.to_date, '2007-08-05'.to_date], [c.startdt, c.enddt]
28 28
29 29 c = Redmine::Helpers::Calendar.new(Date.today, :en, :month)
30 30 assert_equal [7, 6], [c.startdt.cwday, c.enddt.cwday]
31 31 end
32 32
33 33 def test_weekly
34 34 c = Redmine::Helpers::Calendar.new(Date.today, :fr, :week)
35 35 assert_equal [1, 7], [c.startdt.cwday, c.enddt.cwday]
36 36
37 37 c = Redmine::Helpers::Calendar.new('2007-07-14'.to_date, :fr, :week)
38 38 assert_equal ['2007-07-09'.to_date, '2007-07-15'.to_date], [c.startdt, c.enddt]
39 39
40 40 c = Redmine::Helpers::Calendar.new(Date.today, :en, :week)
41 41 assert_equal [7, 6], [c.startdt.cwday, c.enddt.cwday]
42 42 end
43 43 end
@@ -1,221 +1,221
1 1 # encoding: utf-8
2 2 #
3 3 # Redmine - project management software
4 4 # Copyright (C) 2006-2010 Jean-Philippe Lang
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; either version 2
9 9 # of the License, or (at your option) any later version.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 19
20 require File.dirname(__FILE__) + '/../test_helper'
20 require File.expand_path('../../test_helper', __FILE__)
21 21
22 22 class ChangesetTest < ActiveSupport::TestCase
23 23 fixtures :projects, :repositories, :issues, :issue_statuses, :changesets, :changes, :issue_categories, :enumerations, :custom_fields, :custom_values, :users, :members, :member_roles, :trackers
24 24
25 25 def setup
26 26 end
27 27
28 28 def test_ref_keywords_any
29 29 ActionMailer::Base.deliveries.clear
30 30 Setting.commit_fix_status_id = IssueStatus.find(:first, :conditions => ["is_closed = ?", true]).id
31 31 Setting.commit_fix_done_ratio = '90'
32 32 Setting.commit_ref_keywords = '*'
33 33 Setting.commit_fix_keywords = 'fixes , closes'
34 34
35 35 c = Changeset.new(:repository => Project.find(1).repository,
36 36 :committed_on => Time.now,
37 37 :comments => 'New commit (#2). Fixes #1')
38 38 c.scan_comment_for_issue_ids
39 39
40 40 assert_equal [1, 2], c.issue_ids.sort
41 41 fixed = Issue.find(1)
42 42 assert fixed.closed?
43 43 assert_equal 90, fixed.done_ratio
44 44 assert_equal 1, ActionMailer::Base.deliveries.size
45 45 end
46 46
47 47 def test_ref_keywords
48 48 Setting.commit_ref_keywords = 'refs'
49 49 Setting.commit_fix_keywords = ''
50 50
51 51 c = Changeset.new(:repository => Project.find(1).repository,
52 52 :committed_on => Time.now,
53 53 :comments => 'Ignores #2. Refs #1')
54 54 c.scan_comment_for_issue_ids
55 55
56 56 assert_equal [1], c.issue_ids.sort
57 57 end
58 58
59 59 def test_ref_keywords_any_only
60 60 Setting.commit_ref_keywords = '*'
61 61 Setting.commit_fix_keywords = ''
62 62
63 63 c = Changeset.new(:repository => Project.find(1).repository,
64 64 :committed_on => Time.now,
65 65 :comments => 'Ignores #2. Refs #1')
66 66 c.scan_comment_for_issue_ids
67 67
68 68 assert_equal [1, 2], c.issue_ids.sort
69 69 end
70 70
71 71 def test_ref_keywords_any_with_timelog
72 72 Setting.commit_ref_keywords = '*'
73 73 Setting.commit_logtime_enabled = '1'
74 74
75 75 c = Changeset.new(:repository => Project.find(1).repository,
76 76 :committed_on => 24.hours.ago,
77 77 :comments => 'Worked on this issue #1 @2h',
78 78 :revision => '520',
79 79 :user => User.find(2))
80 80 assert_difference 'TimeEntry.count' do
81 81 c.scan_comment_for_issue_ids
82 82 end
83 83 assert_equal [1], c.issue_ids.sort
84 84
85 85 time = TimeEntry.first(:order => 'id desc')
86 86 assert_equal 1, time.issue_id
87 87 assert_equal 1, time.project_id
88 88 assert_equal 2, time.user_id
89 89 assert_equal 2.0, time.hours
90 90 assert_equal Date.yesterday, time.spent_on
91 91 assert time.activity.is_default?
92 92 assert time.comments.include?('r520'), "r520 was expected in time_entry comments: #{time.comments}"
93 93 end
94 94
95 95 def test_ref_keywords_closing_with_timelog
96 96 Setting.commit_fix_status_id = IssueStatus.find(:first, :conditions => ["is_closed = ?", true]).id
97 97 Setting.commit_ref_keywords = '*'
98 98 Setting.commit_fix_keywords = 'fixes , closes'
99 99 Setting.commit_logtime_enabled = '1'
100 100
101 101 c = Changeset.new(:repository => Project.find(1).repository,
102 102 :committed_on => Time.now,
103 103 :comments => 'This is a comment. Fixes #1 @2.5, #2 @1',
104 104 :user => User.find(2))
105 105 assert_difference 'TimeEntry.count', 2 do
106 106 c.scan_comment_for_issue_ids
107 107 end
108 108
109 109 assert_equal [1, 2], c.issue_ids.sort
110 110 assert Issue.find(1).closed?
111 111 assert Issue.find(2).closed?
112 112
113 113 times = TimeEntry.all(:order => 'id desc', :limit => 2)
114 114 assert_equal [1, 2], times.collect(&:issue_id).sort
115 115 end
116 116
117 117 def test_ref_keywords_any_line_start
118 118 Setting.commit_ref_keywords = '*'
119 119
120 120 c = Changeset.new(:repository => Project.find(1).repository,
121 121 :committed_on => Time.now,
122 122 :comments => '#1 is the reason of this commit')
123 123 c.scan_comment_for_issue_ids
124 124
125 125 assert_equal [1], c.issue_ids.sort
126 126 end
127 127
128 128 def test_ref_keywords_allow_brackets_around_a_issue_number
129 129 Setting.commit_ref_keywords = '*'
130 130
131 131 c = Changeset.new(:repository => Project.find(1).repository,
132 132 :committed_on => Time.now,
133 133 :comments => '[#1] Worked on this issue')
134 134 c.scan_comment_for_issue_ids
135 135
136 136 assert_equal [1], c.issue_ids.sort
137 137 end
138 138
139 139 def test_ref_keywords_allow_brackets_around_multiple_issue_numbers
140 140 Setting.commit_ref_keywords = '*'
141 141
142 142 c = Changeset.new(:repository => Project.find(1).repository,
143 143 :committed_on => Time.now,
144 144 :comments => '[#1 #2, #3] Worked on these')
145 145 c.scan_comment_for_issue_ids
146 146
147 147 assert_equal [1,2,3], c.issue_ids.sort
148 148 end
149 149
150 150 def test_commit_referencing_a_subproject_issue
151 151 c = Changeset.new(:repository => Project.find(1).repository,
152 152 :committed_on => Time.now,
153 153 :comments => 'refs #5, a subproject issue')
154 154 c.scan_comment_for_issue_ids
155 155
156 156 assert_equal [5], c.issue_ids.sort
157 157 assert c.issues.first.project != c.project
158 158 end
159 159
160 160 def test_commit_referencing_a_parent_project_issue
161 161 # repository of child project
162 162 r = Repository::Subversion.create!(:project => Project.find(3), :url => 'svn://localhost/test')
163 163
164 164 c = Changeset.new(:repository => r,
165 165 :committed_on => Time.now,
166 166 :comments => 'refs #2, an issue of a parent project')
167 167 c.scan_comment_for_issue_ids
168 168
169 169 assert_equal [2], c.issue_ids.sort
170 170 assert c.issues.first.project != c.project
171 171 end
172 172
173 173 def test_text_tag_revision
174 174 c = Changeset.new(:revision => '520')
175 175 assert_equal 'r520', c.text_tag
176 176 end
177 177
178 178 def test_text_tag_hash
179 179 c = Changeset.new(:scmid => '7234cb2750b63f47bff735edc50a1c0a433c2518', :revision => '7234cb2750b63f47bff735edc50a1c0a433c2518')
180 180 assert_equal 'commit:7234cb2750b63f47bff735edc50a1c0a433c2518', c.text_tag
181 181 end
182 182
183 183 def test_text_tag_hash_all_number
184 184 c = Changeset.new(:scmid => '0123456789', :revision => '0123456789')
185 185 assert_equal 'commit:0123456789', c.text_tag
186 186 end
187 187
188 188 def test_previous
189 189 changeset = Changeset.find_by_revision('3')
190 190 assert_equal Changeset.find_by_revision('2'), changeset.previous
191 191 end
192 192
193 193 def test_previous_nil
194 194 changeset = Changeset.find_by_revision('1')
195 195 assert_nil changeset.previous
196 196 end
197 197
198 198 def test_next
199 199 changeset = Changeset.find_by_revision('2')
200 200 assert_equal Changeset.find_by_revision('3'), changeset.next
201 201 end
202 202
203 203 def test_next_nil
204 204 changeset = Changeset.find_by_revision('10')
205 205 assert_nil changeset.next
206 206 end
207 207
208 208 def test_comments_should_be_converted_to_utf8
209 209 with_settings :commit_logs_encoding => 'ISO-8859-1' do
210 210 c = Changeset.new
211 211 c.comments = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
212 212 assert_equal "Texte encodé en ISO-8859-1.", c.comments
213 213 end
214 214 end
215 215
216 216 def test_invalid_utf8_sequences_in_comments_should_be_stripped
217 217 c = Changeset.new
218 218 c.comments = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
219 219 assert_equal "Texte encod en ISO-8859-1.", c.comments
220 220 end
221 221 end
@@ -1,47 +1,47
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class CommentTest < ActiveSupport::TestCase
21 21 fixtures :users, :news, :comments
22 22
23 23 def setup
24 24 @jsmith = User.find(2)
25 25 @news = News.find(1)
26 26 end
27 27
28 28 def test_create
29 29 comment = Comment.new(:commented => @news, :author => @jsmith, :comments => "my comment")
30 30 assert comment.save
31 31 @news.reload
32 32 assert_equal 2, @news.comments_count
33 33 end
34 34
35 35 def test_validate
36 36 comment = Comment.new(:commented => @news)
37 37 assert !comment.save
38 38 assert_equal 2, comment.errors.length
39 39 end
40 40
41 41 def test_destroy
42 42 comment = Comment.find(1)
43 43 assert comment.destroy
44 44 @news.reload
45 45 assert_equal 0, @news.comments_count
46 46 end
47 47 end
@@ -1,50 +1,50
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class CustomFieldTest < ActiveSupport::TestCase
21 21 fixtures :custom_fields
22 22
23 23 def test_create
24 24 field = UserCustomField.new(:name => 'Money money money', :field_format => 'float')
25 25 assert field.save
26 26 end
27 27
28 28 def test_possible_values_should_accept_an_array
29 29 field = CustomField.new
30 30 field.possible_values = ["One value", ""]
31 31 assert_equal ["One value"], field.possible_values
32 32 end
33 33
34 34 def test_possible_values_should_accept_a_string
35 35 field = CustomField.new
36 36 field.possible_values = "One value"
37 37 assert_equal ["One value"], field.possible_values
38 38 end
39 39
40 40 def test_possible_values_should_accept_a_multiline_string
41 41 field = CustomField.new
42 42 field.possible_values = "One value\nAnd another one \r\n \n"
43 43 assert_equal ["One value", "And another one"], field.possible_values
44 44 end
45 45
46 46 def test_destroy
47 47 field = CustomField.find(1)
48 48 assert field.destroy
49 49 end
50 50 end
@@ -1,123 +1,123
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class CustomValueTest < ActiveSupport::TestCase
21 21 fixtures :custom_fields, :custom_values, :users
22 22
23 23 def test_string_field_validation_with_blank_value
24 24 f = CustomField.new(:field_format => 'string')
25 25 v = CustomValue.new(:custom_field => f)
26 26
27 27 v.value = nil
28 28 assert v.valid?
29 29 v.value = ''
30 30 assert v.valid?
31 31
32 32 f.is_required = true
33 33 v.value = nil
34 34 assert !v.valid?
35 35 v.value = ''
36 36 assert !v.valid?
37 37 end
38 38
39 39 def test_string_field_validation_with_min_and_max_lengths
40 40 f = CustomField.new(:field_format => 'string', :min_length => 2, :max_length => 5)
41 41 v = CustomValue.new(:custom_field => f, :value => '')
42 42 assert v.valid?
43 43 v.value = 'a'
44 44 assert !v.valid?
45 45 v.value = 'a' * 2
46 46 assert v.valid?
47 47 v.value = 'a' * 6
48 48 assert !v.valid?
49 49 end
50 50
51 51 def test_string_field_validation_with_regexp
52 52 f = CustomField.new(:field_format => 'string', :regexp => '^[A-Z0-9]*$')
53 53 v = CustomValue.new(:custom_field => f, :value => '')
54 54 assert v.valid?
55 55 v.value = 'abc'
56 56 assert !v.valid?
57 57 v.value = 'ABC'
58 58 assert v.valid?
59 59 end
60 60
61 61 def test_date_field_validation
62 62 f = CustomField.new(:field_format => 'date')
63 63 v = CustomValue.new(:custom_field => f, :value => '')
64 64 assert v.valid?
65 65 v.value = 'abc'
66 66 assert !v.valid?
67 67 v.value = '1975-07-14'
68 68 assert v.valid?
69 69 end
70 70
71 71 def test_list_field_validation
72 72 f = CustomField.new(:field_format => 'list', :possible_values => ['value1', 'value2'])
73 73 v = CustomValue.new(:custom_field => f, :value => '')
74 74 assert v.valid?
75 75 v.value = 'abc'
76 76 assert !v.valid?
77 77 v.value = 'value2'
78 78 assert v.valid?
79 79 end
80 80
81 81 def test_int_field_validation
82 82 f = CustomField.new(:field_format => 'int')
83 83 v = CustomValue.new(:custom_field => f, :value => '')
84 84 assert v.valid?
85 85 v.value = 'abc'
86 86 assert !v.valid?
87 87 v.value = '123'
88 88 assert v.valid?
89 89 v.value = '+123'
90 90 assert v.valid?
91 91 v.value = '-123'
92 92 assert v.valid?
93 93 end
94 94
95 95 def test_float_field_validation
96 96 v = CustomValue.new(:customized => User.find(:first), :custom_field => UserCustomField.find_by_name('Money'))
97 97 v.value = '11.2'
98 98 assert v.save
99 99 v.value = ''
100 100 assert v.save
101 101 v.value = '-6.250'
102 102 assert v.save
103 103 v.value = '6a'
104 104 assert !v.save
105 105 end
106 106
107 107 def test_default_value
108 108 field = CustomField.find_by_default_value('Default string')
109 109 assert_not_nil field
110 110
111 111 v = CustomValue.new(:custom_field => field)
112 112 assert_equal 'Default string', v.value
113 113
114 114 v = CustomValue.new(:custom_field => field, :value => 'Not empty')
115 115 assert_equal 'Not empty', v.value
116 116 end
117 117
118 118 def test_sti_polymorphic_association
119 119 # Rails uses top level sti class for polymorphic association. See #3978.
120 120 assert !User.find(4).custom_values.empty?
121 121 assert !CustomValue.find(2).customized.nil?
122 122 end
123 123 end
@@ -1,49 +1,49
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class DefaultDataTest < ActiveSupport::TestCase
21 21 include Redmine::I18n
22 22 fixtures :roles
23 23
24 24 def test_no_data
25 25 assert !Redmine::DefaultData::Loader::no_data?
26 26 Role.delete_all("builtin = 0")
27 27 Tracker.delete_all
28 28 IssueStatus.delete_all
29 29 Enumeration.delete_all
30 30 assert Redmine::DefaultData::Loader::no_data?
31 31 end
32 32
33 33 def test_load
34 34 valid_languages.each do |lang|
35 35 begin
36 36 Role.delete_all("builtin = 0")
37 37 Tracker.delete_all
38 38 IssueStatus.delete_all
39 39 Enumeration.delete_all
40 40 assert Redmine::DefaultData::Loader::load(lang)
41 41 assert_not_nil DocumentCategory.first
42 42 assert_not_nil IssuePriority.first
43 43 assert_not_nil TimeEntryActivity.first
44 44 rescue ActiveRecord::RecordInvalid => e
45 45 assert false, ":#{lang} default data is invalid (#{e.message})."
46 46 end
47 47 end
48 48 end
49 49 end
@@ -1,36 +1,36
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class DocumentCategoryTest < ActiveSupport::TestCase
21 21 fixtures :enumerations, :documents, :issues
22 22
23 23 def test_should_be_an_enumeration
24 24 assert DocumentCategory.ancestors.include?(Enumeration)
25 25 end
26 26
27 27 def test_objects_count
28 28 assert_equal 2, DocumentCategory.find_by_name("Uncategorized").objects_count
29 29 assert_equal 0, DocumentCategory.find_by_name("User documentation").objects_count
30 30 end
31 31
32 32 def test_option_name
33 33 assert_equal :enumeration_doc_categories, DocumentCategory.new.option_name
34 34 end
35 35 end
36 36
@@ -1,58 +1,58
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class DocumentTest < ActiveSupport::TestCase
21 21 fixtures :projects, :enumerations, :documents, :attachments
22 22
23 23 def test_create
24 24 doc = Document.new(:project => Project.find(1), :title => 'New document', :category => Enumeration.find_by_name('User documentation'))
25 25 assert doc.save
26 26 end
27 27
28 28 def test_create_should_send_email_notification
29 29 ActionMailer::Base.deliveries.clear
30 30 Setting.notified_events << 'document_added'
31 31 doc = Document.new(:project => Project.find(1), :title => 'New document', :category => Enumeration.find_by_name('User documentation'))
32 32
33 33 assert doc.save
34 34 assert_equal 1, ActionMailer::Base.deliveries.size
35 35 end
36 36
37 37 def test_create_with_default_category
38 38 # Sets a default category
39 39 e = Enumeration.find_by_name('Technical documentation')
40 40 e.update_attributes(:is_default => true)
41 41
42 42 doc = Document.new(:project => Project.find(1), :title => 'New document')
43 43 assert_equal e, doc.category
44 44 assert doc.save
45 45 end
46 46
47 47 def test_updated_on_with_attachments
48 48 d = Document.find(1)
49 49 assert d.attachments.any?
50 50 assert_equal d.attachments.map(&:created_on).max, d.updated_on
51 51 end
52 52
53 53 def test_updated_on_without_attachments
54 54 d = Document.find(2)
55 55 assert d.attachments.empty?
56 56 assert_equal d.created_on, d.updated_on
57 57 end
58 58 end
@@ -1,43 +1,43
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class EnabledModuleTest < ActiveSupport::TestCase
21 21 fixtures :projects, :wikis
22 22
23 23 def test_enabling_wiki_should_create_a_wiki
24 24 CustomField.delete_all
25 25 project = Project.create!(:name => 'Project with wiki', :identifier => 'wikiproject')
26 26 assert_nil project.wiki
27 27 project.enabled_module_names = ['wiki']
28 28 project.reload
29 29 assert_not_nil project.wiki
30 30 assert_equal 'Wiki', project.wiki.start_page
31 31 end
32 32
33 33 def test_reenabling_wiki_should_not_create_another_wiki
34 34 project = Project.find(1)
35 35 assert_not_nil project.wiki
36 36 project.enabled_module_names = []
37 37 project.reload
38 38 assert_no_difference 'Wiki.count' do
39 39 project.enabled_module_names = ['wiki']
40 40 end
41 41 assert_not_nil project.wiki
42 42 end
43 43 end
@@ -1,111 +1,111
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class EnumerationTest < ActiveSupport::TestCase
21 21 fixtures :enumerations, :issues, :custom_fields, :custom_values
22 22
23 23 def setup
24 24 end
25 25
26 26 def test_objects_count
27 27 # low priority
28 28 assert_equal 6, Enumeration.find(4).objects_count
29 29 # urgent
30 30 assert_equal 0, Enumeration.find(7).objects_count
31 31 end
32 32
33 33 def test_in_use
34 34 # low priority
35 35 assert Enumeration.find(4).in_use?
36 36 # urgent
37 37 assert !Enumeration.find(7).in_use?
38 38 end
39 39
40 40 def test_default
41 41 e = Enumeration.default
42 42 assert e.is_a?(Enumeration)
43 43 assert e.is_default?
44 44 assert_equal 'Default Enumeration', e.name
45 45 end
46 46
47 47 def test_create
48 48 e = Enumeration.new(:name => 'Not default', :is_default => false)
49 49 e.type = 'Enumeration'
50 50 assert e.save
51 51 assert_equal 'Default Enumeration', Enumeration.default.name
52 52 end
53 53
54 54 def test_create_as_default
55 55 e = Enumeration.new(:name => 'Very urgent', :is_default => true)
56 56 e.type = 'Enumeration'
57 57 assert e.save
58 58 assert_equal e, Enumeration.default
59 59 end
60 60
61 61 def test_update_default
62 62 e = Enumeration.default
63 63 e.update_attributes(:name => 'Changed', :is_default => true)
64 64 assert_equal e, Enumeration.default
65 65 end
66 66
67 67 def test_update_default_to_non_default
68 68 e = Enumeration.default
69 69 e.update_attributes(:name => 'Changed', :is_default => false)
70 70 assert_nil Enumeration.default
71 71 end
72 72
73 73 def test_change_default
74 74 e = Enumeration.find_by_name('Default Enumeration')
75 75 e.update_attributes(:name => 'Changed Enumeration', :is_default => true)
76 76 assert_equal e, Enumeration.default
77 77 end
78 78
79 79 def test_destroy_with_reassign
80 80 Enumeration.find(4).destroy(Enumeration.find(6))
81 81 assert_nil Issue.find(:first, :conditions => {:priority_id => 4})
82 82 assert_equal 6, Enumeration.find(6).objects_count
83 83 end
84 84
85 85 def test_should_be_customizable
86 86 assert Enumeration.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
87 87 end
88 88
89 89 def test_should_belong_to_a_project
90 90 association = Enumeration.reflect_on_association(:project)
91 91 assert association, "No Project association found"
92 92 assert_equal :belongs_to, association.macro
93 93 end
94 94
95 95 def test_should_act_as_tree
96 96 enumeration = Enumeration.find(4)
97 97
98 98 assert enumeration.respond_to?(:parent)
99 99 assert enumeration.respond_to?(:children)
100 100 end
101 101
102 102 def test_is_override
103 103 # Defaults to off
104 104 enumeration = Enumeration.find(4)
105 105 assert !enumeration.is_override?
106 106
107 107 # Setup as an override
108 108 enumeration.parent = Enumeration.find(5)
109 109 assert enumeration.is_override?
110 110 end
111 111 end
@@ -1,77 +1,77
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class GroupTest < ActiveSupport::TestCase
21 21 fixtures :all
22 22
23 23 def test_create
24 24 g = Group.new(:lastname => 'New group')
25 25 assert g.save
26 26 end
27 27
28 28 def test_roles_given_to_new_user
29 29 group = Group.find(11)
30 30 user = User.find(9)
31 31 project = Project.first
32 32
33 33 Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
34 34 group.users << user
35 35 assert user.member_of?(project)
36 36 end
37 37
38 38 def test_roles_given_to_existing_user
39 39 group = Group.find(11)
40 40 user = User.find(9)
41 41 project = Project.first
42 42
43 43 group.users << user
44 44 m = Member.create!(:principal => group, :project => project, :role_ids => [1, 2])
45 45 assert user.member_of?(project)
46 46 end
47 47
48 48 def test_roles_updated
49 49 group = Group.find(11)
50 50 user = User.find(9)
51 51 project = Project.first
52 52 group.users << user
53 53 m = Member.create!(:principal => group, :project => project, :role_ids => [1])
54 54 assert_equal [1], user.reload.roles_for_project(project).collect(&:id).sort
55 55
56 56 m.role_ids = [1, 2]
57 57 assert_equal [1, 2], user.reload.roles_for_project(project).collect(&:id).sort
58 58
59 59 m.role_ids = [2]
60 60 assert_equal [2], user.reload.roles_for_project(project).collect(&:id).sort
61 61
62 62 m.role_ids = [1]
63 63 assert_equal [1], user.reload.roles_for_project(project).collect(&:id).sort
64 64 end
65 65
66 66 def test_roles_removed_when_removing_group_membership
67 67 assert User.find(8).member_of?(Project.find(5))
68 68 Member.find_by_project_id_and_user_id(5, 10).destroy
69 69 assert !User.find(8).member_of?(Project.find(5))
70 70 end
71 71
72 72 def test_roles_removed_when_removing_user_from_group
73 73 assert User.find(8).member_of?(Project.find(5))
74 74 User.find(8).groups.clear
75 75 assert !User.find(8).member_of?(Project.find(5))
76 76 end
77 77 end
@@ -1,655 +1,655
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../../test_helper'
18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class ApplicationHelperTest < ActionView::TestCase
21 21
22 22 fixtures :projects, :roles, :enabled_modules, :users,
23 23 :repositories, :changesets,
24 24 :trackers, :issue_statuses, :issues, :versions, :documents,
25 25 :wikis, :wiki_pages, :wiki_contents,
26 26 :boards, :messages,
27 27 :attachments,
28 28 :enumerations
29 29
30 30 def setup
31 31 super
32 32 end
33 33
34 34 context "#link_to_if_authorized" do
35 35 context "authorized user" do
36 36 should "be tested"
37 37 end
38 38
39 39 context "unauthorized user" do
40 40 should "be tested"
41 41 end
42 42
43 43 should "allow using the :controller and :action for the target link" do
44 44 User.current = User.find_by_login('admin')
45 45
46 46 @project = Issue.first.project # Used by helper
47 47 response = link_to_if_authorized("By controller/action",
48 48 {:controller => 'issues', :action => 'edit', :id => Issue.first.id})
49 49 assert_match /href/, response
50 50 end
51 51
52 52 end
53 53
54 54 def test_auto_links
55 55 to_test = {
56 56 'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
57 57 'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
58 58 'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
59 59 'https://foo.bar.' => '<a class="external" href="https://foo.bar">https://foo.bar</a>.',
60 60 'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
61 61 'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
62 62 '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>.',
63 63 'http://www.foo.bar/Test_(foobar)' => '<a class="external" href="http://www.foo.bar/Test_(foobar)">http://www.foo.bar/Test_(foobar)</a>',
64 64 '(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>)',
65 65 '(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>)',
66 66 '(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>).',
67 67 '(see "inline link":http://www.foo.bar/Test_(foobar))' => '(see <a href="http://www.foo.bar/Test_(foobar)" class="external">inline link</a>)',
68 68 '(see "inline link":http://www.foo.bar/Test)' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>)',
69 69 '(see "inline link":http://www.foo.bar/Test).' => '(see <a href="http://www.foo.bar/Test" class="external">inline link</a>).',
70 70 'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
71 71 '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>',
72 72 'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
73 73 'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
74 74 'http://foo:bar@www.bar.com' => '<a class="external" href="http://foo:bar@www.bar.com">http://foo:bar@www.bar.com</a>',
75 75 'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
76 76 'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
77 77 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
78 78 # two exclamation marks
79 79 '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>',
80 80 # escaping
81 81 'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo"bar</a>',
82 82 # wrap in angle brackets
83 83 '<http://foo.bar>' => '&lt;<a class="external" href="http://foo.bar">http://foo.bar</a>&gt;'
84 84 }
85 85 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
86 86 end
87 87
88 88 def test_auto_mailto
89 89 assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>',
90 90 textilizable('test@foo.bar')
91 91 end
92 92
93 93 def test_inline_images
94 94 to_test = {
95 95 '!http://foo.bar/image.jpg!' => '<img src="http://foo.bar/image.jpg" alt="" />',
96 96 'floating !>http://foo.bar/image.jpg!' => 'floating <div style="float:right"><img src="http://foo.bar/image.jpg" alt="" /></div>',
97 97 'with class !(some-class)http://foo.bar/image.jpg!' => 'with class <img src="http://foo.bar/image.jpg" class="some-class" alt="" />',
98 98 # inline styles should be stripped
99 99 'with style !{width:100px;height100px}http://foo.bar/image.jpg!' => 'with style <img src="http://foo.bar/image.jpg" alt="" />',
100 100 '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" />',
101 101 '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;" />',
102 102 }
103 103 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
104 104 end
105 105
106 106 def test_inline_images_inside_tags
107 107 raw = <<-RAW
108 108 h1. !foo.png! Heading
109 109
110 110 Centered image:
111 111
112 112 p=. !bar.gif!
113 113 RAW
114 114
115 115 assert textilizable(raw).include?('<img src="foo.png" alt="" />')
116 116 assert textilizable(raw).include?('<img src="bar.gif" alt="" />')
117 117 end
118 118
119 119 def test_attached_images
120 120 to_test = {
121 121 'Inline image: !logo.gif!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
122 122 'Inline image: !logo.GIF!' => 'Inline image: <img src="/attachments/download/3" title="This is a logo" alt="This is a logo" />',
123 123 'No match: !ogo.gif!' => 'No match: <img src="ogo.gif" alt="" />',
124 124 'No match: !ogo.GIF!' => 'No match: <img src="ogo.GIF" alt="" />',
125 125 # link image
126 126 '!logo.gif!:http://foo.bar/' => '<a href="http://foo.bar/"><img src="/attachments/download/3" title="This is a logo" alt="This is a logo" /></a>',
127 127 }
128 128 attachments = Attachment.find(:all)
129 129 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => attachments) }
130 130 end
131 131
132 132 def test_textile_external_links
133 133 to_test = {
134 134 'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
135 135 'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
136 136 '"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
137 137 '"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>',
138 138 "This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
139 139 # no multiline link text
140 140 "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",
141 141 # mailto link
142 142 "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
143 143 # two exclamation marks
144 144 '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
145 145 # escaping
146 146 '"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
147 147 }
148 148 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
149 149 end
150 150
151 151 def test_redmine_links
152 152 issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3},
153 153 :class => 'issue status-1 priority-1 overdue', :title => 'Error 281 when updating a recipe (New)')
154 154
155 155 changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
156 156 :class => 'changeset', :title => 'My very first commit')
157 157 changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
158 158 :class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
159 159
160 160 document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
161 161 :class => 'document')
162 162
163 163 version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
164 164 :class => 'version')
165 165
166 166 message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
167 167
168 168 project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
169 169
170 170 source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
171 171 source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
172 172
173 173 to_test = {
174 174 # tickets
175 175 '#3, [#3], (#3) and #3.' => "#{issue_link}, [#{issue_link}], (#{issue_link}) and #{issue_link}.",
176 176 # changesets
177 177 'r1' => changeset_link,
178 178 'r1.' => "#{changeset_link}.",
179 179 'r1, r2' => "#{changeset_link}, #{changeset_link2}",
180 180 'r1,r2' => "#{changeset_link},#{changeset_link2}",
181 181 # documents
182 182 'document#1' => document_link,
183 183 'document:"Test document"' => document_link,
184 184 # versions
185 185 'version#2' => version_link,
186 186 'version:1.0' => version_link,
187 187 'version:"1.0"' => version_link,
188 188 # source
189 189 'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
190 190 'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
191 191 'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
192 192 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
193 193 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
194 194 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
195 195 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
196 196 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
197 197 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
198 198 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
199 199 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
200 200 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
201 201 # message
202 202 'message#4' => link_to('Post 2', message_url, :class => 'message'),
203 203 'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5'), :class => 'message'),
204 204 # project
205 205 'project#3' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
206 206 'project:subproject1' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
207 207 'project:"eCookbook subProject 1"' => link_to('eCookbook Subproject 1', project_url, :class => 'project'),
208 208 # escaping
209 209 '!#3.' => '#3.',
210 210 '!r1' => 'r1',
211 211 '!document#1' => 'document#1',
212 212 '!document:"Test document"' => 'document:"Test document"',
213 213 '!version#2' => 'version#2',
214 214 '!version:1.0' => 'version:1.0',
215 215 '!version:"1.0"' => 'version:"1.0"',
216 216 '!source:/some/file' => 'source:/some/file',
217 217 # not found
218 218 '#0123456789' => '#0123456789',
219 219 # invalid expressions
220 220 'source:' => 'source:',
221 221 # url hash
222 222 "http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
223 223 }
224 224 @project = Project.find(1)
225 225 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text), "#{text} failed" }
226 226 end
227 227
228 228 def test_attachment_links
229 229 attachment_link = link_to('error281.txt', {:controller => 'attachments', :action => 'download', :id => '1'}, :class => 'attachment')
230 230 to_test = {
231 231 'attachment:error281.txt' => attachment_link
232 232 }
233 233 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text, :attachments => Issue.find(3).attachments), "#{text} failed" }
234 234 end
235 235
236 236 def test_wiki_links
237 237 to_test = {
238 238 '[[CookBook documentation]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
239 239 '[[Another page|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a>',
240 240 # link with anchor
241 241 '[[CookBook documentation#One-section]]' => '<a href="/projects/ecookbook/wiki/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
242 242 '[[Another page#anchor|Page]]' => '<a href="/projects/ecookbook/wiki/Another_page#anchor" class="wiki-page">Page</a>',
243 243 # page that doesn't exist
244 244 '[[Unknown page]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
245 245 '[[Unknown page|404]]' => '<a href="/projects/ecookbook/wiki/Unknown_page" class="wiki-page new">404</a>',
246 246 # link to another project wiki
247 247 '[[onlinestore:]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">onlinestore</a>',
248 248 '[[onlinestore:|Wiki]]' => '<a href="/projects/onlinestore/wiki" class="wiki-page">Wiki</a>',
249 249 '[[onlinestore:Start page]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Start page</a>',
250 250 '[[onlinestore:Start page|Text]]' => '<a href="/projects/onlinestore/wiki/Start_page" class="wiki-page">Text</a>',
251 251 '[[onlinestore:Unknown page]]' => '<a href="/projects/onlinestore/wiki/Unknown_page" class="wiki-page new">Unknown page</a>',
252 252 # striked through link
253 253 '-[[Another page|Page]]-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a></del>',
254 254 '-[[Another page|Page]] link-' => '<del><a href="/projects/ecookbook/wiki/Another_page" class="wiki-page">Page</a> link</del>',
255 255 # escaping
256 256 '![[Another page|Page]]' => '[[Another page|Page]]',
257 257 # project does not exist
258 258 '[[unknowproject:Start]]' => '[[unknowproject:Start]]',
259 259 '[[unknowproject:Start|Page title]]' => '[[unknowproject:Start|Page title]]',
260 260 }
261 261 @project = Project.find(1)
262 262 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
263 263 end
264 264
265 265 def test_html_tags
266 266 to_test = {
267 267 "<div>content</div>" => "<p>&lt;div&gt;content&lt;/div&gt;</p>",
268 268 "<div class=\"bold\">content</div>" => "<p>&lt;div class=\"bold\"&gt;content&lt;/div&gt;</p>",
269 269 "<script>some script;</script>" => "<p>&lt;script&gt;some script;&lt;/script&gt;</p>",
270 270 # do not escape pre/code tags
271 271 "<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
272 272 "<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
273 273 "<pre><div>content</div></pre>" => "<pre>&lt;div&gt;content&lt;/div&gt;</pre>",
274 274 "HTML comment: <!-- no comments -->" => "<p>HTML comment: &lt;!-- no comments --&gt;</p>",
275 275 "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
276 276 # remove attributes except class
277 277 "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
278 278 '<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
279 279 "<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
280 280 '<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
281 281 "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
282 282 }
283 283 to_test.each { |text, result| assert_equal result, textilizable(text) }
284 284 end
285 285
286 286 def test_allowed_html_tags
287 287 to_test = {
288 288 "<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
289 289 "<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
290 290 "<notextile>this is <tag>a tag</tag></notextile>" => "this is &lt;tag&gt;a tag&lt;/tag&gt;"
291 291 }
292 292 to_test.each { |text, result| assert_equal result, textilizable(text) }
293 293 end
294 294
295 295 def test_pre_tags
296 296 raw = <<-RAW
297 297 Before
298 298
299 299 <pre>
300 300 <prepared-statement-cache-size>32</prepared-statement-cache-size>
301 301 </pre>
302 302
303 303 After
304 304 RAW
305 305
306 306 expected = <<-EXPECTED
307 307 <p>Before</p>
308 308 <pre>
309 309 &lt;prepared-statement-cache-size&gt;32&lt;/prepared-statement-cache-size&gt;
310 310 </pre>
311 311 <p>After</p>
312 312 EXPECTED
313 313
314 314 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
315 315 end
316 316
317 317 def test_pre_content_should_not_parse_wiki_and_redmine_links
318 318 raw = <<-RAW
319 319 [[CookBook documentation]]
320 320
321 321 #1
322 322
323 323 <pre>
324 324 [[CookBook documentation]]
325 325
326 326 #1
327 327 </pre>
328 328 RAW
329 329
330 330 expected = <<-EXPECTED
331 331 <p><a href="/projects/ecookbook/wiki/CookBook_documentation" class="wiki-page">CookBook documentation</a></p>
332 332 <p><a href="/issues/1" class="issue status-1 priority-1" title="Can't print recipes (New)">#1</a></p>
333 333 <pre>
334 334 [[CookBook documentation]]
335 335
336 336 #1
337 337 </pre>
338 338 EXPECTED
339 339
340 340 @project = Project.find(1)
341 341 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
342 342 end
343 343
344 344 def test_non_closing_pre_blocks_should_be_closed
345 345 raw = <<-RAW
346 346 <pre><code>
347 347 RAW
348 348
349 349 expected = <<-EXPECTED
350 350 <pre><code>
351 351 </code></pre>
352 352 EXPECTED
353 353
354 354 @project = Project.find(1)
355 355 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
356 356 end
357 357
358 358 def test_syntax_highlight
359 359 raw = <<-RAW
360 360 <pre><code class="ruby">
361 361 # Some ruby code here
362 362 </code></pre>
363 363 RAW
364 364
365 365 expected = <<-EXPECTED
366 366 <pre><code class="ruby syntaxhl"><span class=\"CodeRay\"><span class="no">1</span> <span class="c"># Some ruby code here</span></span>
367 367 </code></pre>
368 368 EXPECTED
369 369
370 370 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
371 371 end
372 372
373 373 def test_wiki_links_in_tables
374 374 to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
375 375 '<tr><td><a href="/projects/ecookbook/wiki/Page" class="wiki-page new">Link title</a></td>' +
376 376 '<td><a href="/projects/ecookbook/wiki/Other_Page" class="wiki-page new">Other title</a></td>' +
377 377 '</tr><tr><td>Cell 21</td><td><a href="/projects/ecookbook/wiki/Last_page" class="wiki-page new">Last page</a></td></tr>'
378 378 }
379 379 @project = Project.find(1)
380 380 to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
381 381 end
382 382
383 383 def test_text_formatting
384 384 to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
385 385 '(_text within parentheses_)' => '(<em>text within parentheses</em>)',
386 386 'a *Humane Web* Text Generator' => 'a <strong>Humane Web</strong> Text Generator',
387 387 '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>',
388 388 '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',
389 389 }
390 390 to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
391 391 end
392 392
393 393 def test_wiki_horizontal_rule
394 394 assert_equal '<hr />', textilizable('---')
395 395 assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
396 396 end
397 397
398 398 def test_footnotes
399 399 raw = <<-RAW
400 400 This is some text[1].
401 401
402 402 fn1. This is the foot note
403 403 RAW
404 404
405 405 expected = <<-EXPECTED
406 406 <p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
407 407 <p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
408 408 EXPECTED
409 409
410 410 assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(raw).gsub(%r{[\r\n\t]}, '')
411 411 end
412 412
413 413 def test_table_of_content
414 414 raw = <<-RAW
415 415 {{toc}}
416 416
417 417 h1. Title
418 418
419 419 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
420 420
421 421 h2. Subtitle with a [[Wiki]] link
422 422
423 423 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
424 424
425 425 h2. Subtitle with [[Wiki|another Wiki]] link
426 426
427 427 h2. Subtitle with %{color:red}red text%
428 428
429 429 h3. Subtitle with *some* _modifiers_
430 430
431 431 h1. Another title
432 432
433 433 h3. An "Internet link":http://www.redmine.org/ inside subtitle
434 434
435 435 h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
436 436
437 437 RAW
438 438
439 439 expected = '<ul class="toc">' +
440 440 '<li><a href="#Title">Title</a>' +
441 441 '<ul>' +
442 442 '<li><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
443 443 '<li><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
444 444 '<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
445 445 '<ul>' +
446 446 '<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
447 447 '</ul>' +
448 448 '</li>' +
449 449 '</ul>' +
450 450 '</li>' +
451 451 '<li><a href="#Another-title">Another title</a>' +
452 452 '<ul>' +
453 453 '<li>' +
454 454 '<ul>' +
455 455 '<li><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
456 456 '</ul>' +
457 457 '</li>' +
458 458 '<li><a href="#Project-Name">Project Name</a></li>' +
459 459 '</ul>' +
460 460 '</li>' +
461 461 '</ul>'
462 462
463 463 @project = Project.find(1)
464 464 assert textilizable(raw).gsub("\n", "").include?(expected)
465 465 end
466 466
467 467 def test_table_of_content_should_contain_included_page_headings
468 468 raw = <<-RAW
469 469 {{toc}}
470 470
471 471 h1. Included
472 472
473 473 {{include(Child_1)}}
474 474 RAW
475 475
476 476 expected = '<ul class="toc">' +
477 477 '<li><a href="#Included">Included</a></li>' +
478 478 '<li><a href="#Child-page-1">Child page 1</a></li>' +
479 479 '</ul>'
480 480
481 481 @project = Project.find(1)
482 482 assert textilizable(raw).gsub("\n", "").include?(expected)
483 483 end
484 484
485 485 def test_blockquote
486 486 # orig raw text
487 487 raw = <<-RAW
488 488 John said:
489 489 > Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
490 490 > Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
491 491 > * Donec odio lorem,
492 492 > * sagittis ac,
493 493 > * malesuada in,
494 494 > * adipiscing eu, dolor.
495 495 >
496 496 > >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
497 497 > Proin a tellus. Nam vel neque.
498 498
499 499 He's right.
500 500 RAW
501 501
502 502 # expected html
503 503 expected = <<-EXPECTED
504 504 <p>John said:</p>
505 505 <blockquote>
506 506 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
507 507 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
508 508 <ul>
509 509 <li>Donec odio lorem,</li>
510 510 <li>sagittis ac,</li>
511 511 <li>malesuada in,</li>
512 512 <li>adipiscing eu, dolor.</li>
513 513 </ul>
514 514 <blockquote>
515 515 <p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
516 516 </blockquote>
517 517 <p>Proin a tellus. Nam vel neque.</p>
518 518 </blockquote>
519 519 <p>He's right.</p>
520 520 EXPECTED
521 521
522 522 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
523 523 end
524 524
525 525 def test_table
526 526 raw = <<-RAW
527 527 This is a table with empty cells:
528 528
529 529 |cell11|cell12||
530 530 |cell21||cell23|
531 531 |cell31|cell32|cell33|
532 532 RAW
533 533
534 534 expected = <<-EXPECTED
535 535 <p>This is a table with empty cells:</p>
536 536
537 537 <table>
538 538 <tr><td>cell11</td><td>cell12</td><td></td></tr>
539 539 <tr><td>cell21</td><td></td><td>cell23</td></tr>
540 540 <tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
541 541 </table>
542 542 EXPECTED
543 543
544 544 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
545 545 end
546 546
547 547 def test_table_with_line_breaks
548 548 raw = <<-RAW
549 549 This is a table with line breaks:
550 550
551 551 |cell11
552 552 continued|cell12||
553 553 |-cell21-||cell23
554 554 cell23 line2
555 555 cell23 *line3*|
556 556 |cell31|cell32
557 557 cell32 line2|cell33|
558 558
559 559 RAW
560 560
561 561 expected = <<-EXPECTED
562 562 <p>This is a table with line breaks:</p>
563 563
564 564 <table>
565 565 <tr>
566 566 <td>cell11<br />continued</td>
567 567 <td>cell12</td>
568 568 <td></td>
569 569 </tr>
570 570 <tr>
571 571 <td><del>cell21</del></td>
572 572 <td></td>
573 573 <td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td>
574 574 </tr>
575 575 <tr>
576 576 <td>cell31</td>
577 577 <td>cell32<br/>cell32 line2</td>
578 578 <td>cell33</td>
579 579 </tr>
580 580 </table>
581 581 EXPECTED
582 582
583 583 assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
584 584 end
585 585
586 586 def test_textile_should_not_mangle_brackets
587 587 assert_equal '<p>[msg1][msg2]</p>', textilizable('[msg1][msg2]')
588 588 end
589 589
590 590 def test_default_formatter
591 591 Setting.text_formatting = 'unknown'
592 592 text = 'a *link*: http://www.example.net/'
593 593 assert_equal '<p>a *link*: <a href="http://www.example.net/">http://www.example.net/</a></p>', textilizable(text)
594 594 Setting.text_formatting = 'textile'
595 595 end
596 596
597 597 def test_due_date_distance_in_words
598 598 to_test = { Date.today => 'Due in 0 days',
599 599 Date.today + 1 => 'Due in 1 day',
600 600 Date.today + 100 => 'Due in about 3 months',
601 601 Date.today + 20000 => 'Due in over 54 years',
602 602 Date.today - 1 => '1 day late',
603 603 Date.today - 100 => 'about 3 months late',
604 604 Date.today - 20000 => 'over 54 years late',
605 605 }
606 606 to_test.each do |date, expected|
607 607 assert_equal expected, due_date_distance_in_words(date)
608 608 end
609 609 end
610 610
611 611 def test_avatar
612 612 # turn on avatars
613 613 Setting.gravatar_enabled = '1'
614 614 assert avatar(User.find_by_mail('jsmith@somenet.foo')).include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
615 615 assert avatar('jsmith <jsmith@somenet.foo>').include?(Digest::MD5.hexdigest('jsmith@somenet.foo'))
616 616 assert_nil avatar('jsmith')
617 617 assert_nil avatar(nil)
618 618
619 619 # turn off avatars
620 620 Setting.gravatar_enabled = '0'
621 621 assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
622 622 end
623 623
624 624 def test_link_to_user
625 625 user = User.find(2)
626 626 t = link_to_user(user)
627 627 assert_equal "<a href=\"/users/2\">#{ user.name }</a>", t
628 628 end
629 629
630 630 def test_link_to_user_should_not_link_to_locked_user
631 631 user = User.find(5)
632 632 assert user.locked?
633 633 t = link_to_user(user)
634 634 assert_equal user.name, t
635 635 end
636 636
637 637 def test_link_to_user_should_not_link_to_anonymous
638 638 user = User.anonymous
639 639 assert user.anonymous?
640 640 t = link_to_user(user)
641 641 assert_equal ::I18n.t(:label_user_anonymous), t
642 642 end
643 643
644 644 def test_link_to_project
645 645 project = Project.find(1)
646 646 assert_equal %(<a href="/projects/ecookbook">eCookbook</a>),
647 647 link_to_project(project)
648 648 assert_equal %(<a href="/projects/ecookbook/settings">eCookbook</a>),
649 649 link_to_project(project, :action => 'settings')
650 650 assert_equal %(<a href="http://test.host/projects/ecookbook?jump=blah">eCookbook</a>),
651 651 link_to_project(project, {:only_path => false, :jump => 'blah'})
652 652 assert_equal %(<a href="/projects/ecookbook/settings" class="project">eCookbook</a>),
653 653 link_to_project(project, {:action => 'settings'}, :class => "project")
654 654 end
655 655 end
@@ -1,29 +1,29
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../../test_helper'
18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class CustomFieldsHelperTest < HelperTestCase
21 21 include CustomFieldsHelper
22 22 include Redmine::I18n
23 23
24 24 def test_format_boolean_value
25 25 I18n.locale = 'en'
26 26 assert_equal 'Yes', format_value('1', 'bool')
27 27 assert_equal 'No', format_value('0', 'bool')
28 28 end
29 29 end
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now