##// END OF EJS Templates
Added some tests for projects controller and helper....
Jean-Philippe Lang -
r976:eb7cbd481e44
parent child
Show More
@@ -0,0 +1,41
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require File.dirname(__FILE__) + '/../../test_helper'
19
20 class ProjectsHelperTest < HelperTestCase
21 include ProjectsHelper
22 include ActionView::Helpers::TextHelper
23 fixtures :projects, :trackers, :issue_statuses, :issues, :enumerations, :users, :issue_categories
24
25 def setup
26 super
27 end
28
29 if Object.const_defined?(:Magick)
30 def test_gantt_image
31 assert gantt_image(Issue.find(:all, :conditions => "start_date IS NOT NULL AND due_date IS NOT NULL"), Date.today, 6, 2)
32 end
33
34 def test_gantt_image_with_days
35 assert gantt_image(Issue.find(:all, :conditions => "start_date IS NOT NULL AND due_date IS NOT NULL"), Date.today, 3, 4)
36 end
37 else
38 puts "RMagick not installed. Skipping tests !!!"
39 def test_fake; assert true end
40 end
41 end
@@ -1,199 +1,199
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 18 module ProjectsHelper
19 19 def link_to_version(version, options = {})
20 20 return '' unless version && version.is_a?(Version)
21 21 link_to version.name, {:controller => 'projects',
22 22 :action => 'roadmap',
23 23 :id => version.project_id,
24 24 :completed => (version.completed? ? 1 : nil),
25 25 :anchor => version.name
26 26 }, options
27 27 end
28 28
29 29 def project_settings_tabs
30 30 tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural},
31 31 {:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural},
32 32 {:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural},
33 33 {:name => 'versions', :action => :manage_versions, :partial => 'projects/settings/versions', :label => :label_version_plural},
34 34 {:name => 'categories', :action => :manage_categories, :partial => 'projects/settings/issue_categories', :label => :label_issue_category_plural},
35 35 {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki},
36 36 {:name => 'repository', :action => :manage_repository, :partial => 'projects/settings/repository', :label => :label_repository},
37 37 {:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural}
38 38 ]
39 39 tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
40 40 end
41 41
42 42 # Generates a gantt image
43 43 # Only defined if RMagick is avalaible
44 44 def gantt_image(events, date_from, months, zoom)
45 45 date_to = (date_from >> months)-1
46 46 show_weeks = zoom > 1
47 47 show_days = zoom > 2
48 48
49 49 subject_width = 320
50 50 header_heigth = 18
51 51 # width of one day in pixels
52 52 zoom = zoom*2
53 53 g_width = (date_to - date_from + 1)*zoom
54 54 g_height = 20 * events.length + 20
55 55 headers_heigth = (show_weeks ? 2*header_heigth : header_heigth)
56 56 height = g_height + headers_heigth
57 57
58 58 imgl = Magick::ImageList.new
59 59 imgl.new_image(subject_width+g_width+1, height)
60 60 gc = Magick::Draw.new
61 61
62 62 # Subjects
63 63 top = headers_heigth + 20
64 64 gc.fill('black')
65 65 gc.stroke('transparent')
66 66 gc.stroke_width(1)
67 67 events.each do |i|
68 68 gc.text(4, top + 2, (i.is_a?(Issue) ? i.subject : i.name))
69 69 top = top + 20
70 70 end
71 71
72 72 # Months headers
73 73 month_f = date_from
74 74 left = subject_width
75 75 months.times do
76 76 width = ((month_f >> 1) - month_f) * zoom
77 77 gc.fill('white')
78 78 gc.stroke('grey')
79 79 gc.stroke_width(1)
80 80 gc.rectangle(left, 0, left + width, height)
81 81 gc.fill('black')
82 82 gc.stroke('transparent')
83 83 gc.stroke_width(1)
84 84 gc.text(left.round + 8, 14, "#{month_f.year}-#{month_f.month}")
85 85 left = left + width
86 86 month_f = month_f >> 1
87 87 end
88 88
89 89 # Weeks headers
90 90 if show_weeks
91 91 left = subject_width
92 92 height = header_heigth
93 93 if date_from.cwday == 1
94 94 # date_from is monday
95 95 week_f = date_from
96 96 else
97 97 # find next monday after date_from
98 98 week_f = date_from + (7 - date_from.cwday + 1)
99 99 width = (7 - date_from.cwday + 1) * zoom
100 100 gc.fill('white')
101 101 gc.stroke('grey')
102 102 gc.stroke_width(1)
103 103 gc.rectangle(left, header_heigth, left + width, 2*header_heigth + g_height-1)
104 104 left = left + width
105 105 end
106 106 while week_f <= date_to
107 107 width = (week_f + 6 <= date_to) ? 7 * zoom : (date_to - week_f + 1) * zoom
108 108 gc.fill('white')
109 109 gc.stroke('grey')
110 110 gc.stroke_width(1)
111 111 gc.rectangle(left.round, header_heigth, left.round + width, 2*header_heigth + g_height-1)
112 112 gc.fill('black')
113 113 gc.stroke('transparent')
114 114 gc.stroke_width(1)
115 115 gc.text(left.round + 2, header_heigth + 14, week_f.cweek.to_s)
116 116 left = left + width
117 117 week_f = week_f+7
118 118 end
119 119 end
120 120
121 121 # Days details (week-end in grey)
122 122 if show_days
123 123 left = subject_width
124 124 height = g_height + header_heigth - 1
125 125 wday = date_from.cwday
126 126 (date_to - date_from + 1).to_i.times do
127 127 width = zoom
128 128 gc.fill(wday == 6 || wday == 7 ? '#eee' : 'white')
129 129 gc.stroke('grey')
130 130 gc.stroke_width(1)
131 131 gc.rectangle(left, 2*header_heigth, left + width, 2*header_heigth + g_height-1)
132 132 left = left + width
133 133 wday = wday + 1
134 134 wday = 1 if wday > 7
135 135 end
136 136 end
137 137
138 138 # border
139 139 gc.fill('transparent')
140 140 gc.stroke('grey')
141 141 gc.stroke_width(1)
142 142 gc.rectangle(0, 0, subject_width+g_width, headers_heigth)
143 143 gc.stroke('black')
144 144 gc.rectangle(0, 0, subject_width+g_width, g_height+ headers_heigth-1)
145 145
146 146 # content
147 147 top = headers_heigth + 20
148 148 gc.stroke('transparent')
149 149 events.each do |i|
150 150 if i.is_a?(Issue)
151 151 i_start_date = (i.start_date >= date_from ? i.start_date : date_from )
152 152 i_end_date = (i.due_date <= date_to ? i.due_date : date_to )
153 153 i_done_date = i.start_date + ((i.due_date - i.start_date+1)*i.done_ratio/100).floor
154 154 i_done_date = (i_done_date <= date_from ? date_from : i_done_date )
155 155 i_done_date = (i_done_date >= date_to ? date_to : i_done_date )
156 156 i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today
157 157
158 158 i_left = subject_width + ((i_start_date - date_from)*zoom).floor
159 159 i_width = ((i_end_date - i_start_date + 1)*zoom).floor # total width of the issue
160 160 d_width = ((i_done_date - i_start_date)*zoom).floor # done width
161 161 l_width = i_late_date ? ((i_late_date - i_start_date+1)*zoom).floor : 0 # delay width
162 162
163 163 gc.fill('grey')
164 164 gc.rectangle(i_left, top, i_left + i_width, top - 6)
165 165 gc.fill('red')
166 166 gc.rectangle(i_left, top, i_left + l_width, top - 6) if l_width > 0
167 167 gc.fill('blue')
168 168 gc.rectangle(i_left, top, i_left + d_width, top - 6) if d_width > 0
169 169 gc.fill('black')
170 170 gc.text(i_left + i_width + 5,top + 1, "#{i.status.name} #{i.done_ratio}%")
171 171 else
172 172 i_left = subject_width + ((i.start_date - date_from)*zoom).floor
173 173 gc.fill('green')
174 174 gc.rectangle(i_left, top, i_left + 6, top - 6)
175 175 gc.fill('black')
176 176 gc.text(i_left + 11, top + 1, i.name)
177 177 end
178 178 top = top + 20
179 179 end
180 180
181 181 # today red line
182 if Date.today >= @date_from and Date.today <= @date_to
182 if Date.today >= date_from and Date.today <= date_to
183 183 gc.stroke('red')
184 x = (Date.today-@date_from+1)*zoom + subject_width
184 x = (Date.today-date_from+1)*zoom + subject_width
185 185 gc.line(x, headers_heigth, x, headers_heigth + g_height-1)
186 186 end
187 187
188 188 gc.draw(imgl)
189 189 imgl
190 190 end if Object.const_defined?(:Magick)
191 191
192 192 def new_issue_selector
193 193 trackers = @project.trackers
194 194 # can't use form tag inside helper
195 195 content_tag('form',
196 196 select_tag('tracker_id', '<option></option>' + options_from_collection_for_select(trackers, 'id', 'name'), :onchange => "if (this.value != '') {this.form.submit()}"),
197 197 :action => url_for(:controller => 'projects', :action => 'add_issue', :id => @project), :method => 'get')
198 198 end
199 199 end
@@ -1,58 +1,60
1 1 ---
2 2 issues_001:
3 3 created_on: <%= 3.days.ago.to_date.to_s(:db) %>
4 4 project_id: 1
5 5 updated_on: <%= 1.day.ago.to_date.to_s(:db) %>
6 6 priority_id: 4
7 7 subject: Can't print recipes
8 8 id: 1
9 9 fixed_version_id:
10 10 category_id: 1
11 11 description: Unable to print recipes
12 12 tracker_id: 1
13 13 assigned_to_id:
14 14 author_id: 2
15 15 status_id: 1
16 16 issues_002:
17 17 created_on: 2006-07-19 21:04:21 +02:00
18 18 project_id: 1
19 19 updated_on: 2006-07-19 21:09:50 +02:00
20 20 priority_id: 5
21 21 subject: Add ingredients categories
22 22 id: 2
23 23 fixed_version_id:
24 24 category_id:
25 25 description: Ingredients should be classified by categories
26 26 tracker_id: 2
27 27 assigned_to_id: 3
28 28 author_id: 2
29 29 status_id: 2
30 30 issues_003:
31 31 created_on: 2006-07-19 21:07:27 +02:00
32 32 project_id: 1
33 33 updated_on: 2006-07-19 21:07:27 +02:00
34 34 priority_id: 4
35 35 subject: Error 281 when updating a recipe
36 36 id: 3
37 37 fixed_version_id:
38 38 category_id:
39 39 description: Error 281 is encountered when saving a recipe
40 40 tracker_id: 1
41 41 assigned_to_id:
42 42 author_id: 2
43 43 status_id: 1
44 start_date: <%= 1.day.from_now.to_date.to_s(:db) %>
45 due_date: <%= 40.day.ago.to_date.to_s(:db) %>
44 46 issues_004:
45 47 created_on: 2006-07-19 21:07:27 +02:00
46 48 project_id: 2
47 49 updated_on: 2006-07-19 21:07:27 +02:00
48 50 priority_id: 4
49 51 subject: Issue on project 2
50 52 id: 4
51 53 fixed_version_id:
52 54 category_id:
53 55 description: Issue on project 2
54 56 tracker_id: 1
55 57 assigned_to_id:
56 58 author_id: 2
57 59 status_id: 1
58 60
@@ -1,211 +1,257
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 18 require File.dirname(__FILE__) + '/../test_helper'
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 < Test::Unit::TestCase
25 25 fixtures :projects, :versions, :users, :roles, :members, :issues, :journals, :journal_details, :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations
26 26
27 27 def setup
28 28 @controller = ProjectsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 end
32 32
33 33 def test_index
34 34 get :index
35 35 assert_response :success
36 36 assert_template 'list'
37 37 end
38 38
39 39 def test_list
40 40 get :list
41 41 assert_response :success
42 42 assert_template 'list'
43 43 assert_not_nil assigns(:project_tree)
44 44 # Root project as hash key
45 45 assert assigns(:project_tree).has_key?(Project.find(1))
46 46 # Subproject in corresponding value
47 47 assert assigns(:project_tree)[Project.find(1)].include?(Project.find(3))
48 48 end
49 49
50 50 def test_show
51 51 get :show, :id => 1
52 52 assert_response :success
53 53 assert_template 'show'
54 54 assert_not_nil assigns(:project)
55 55 end
56 56
57 def test_settings
58 @request.session[:user_id] = 2 # manager
59 get :settings, :id => 1
60 assert_response :success
61 assert_template 'settings'
62 end
63
64 def test_edit
65 @request.session[:user_id] = 2 # manager
66 post :edit, :id => 1, :project => {:name => 'Test changed name'}
67 assert_redirected_to 'projects/settings/1'
68 project = Project.find(1)
69 assert_equal 'Test changed name', project.name
70 end
71
72 def test_get_destroy
73 @request.session[:user_id] = 1 # admin
74 get :destroy, :id => 1
75 assert_response :success
76 assert_template 'destroy'
77 assert_not_nil Project.find_by_id(1)
78 end
79
80 def test_post_destroy
81 @request.session[:user_id] = 1 # admin
82 post :destroy, :id => 1, :confirm => 1
83 assert_redirected_to 'admin/projects'
84 assert_nil Project.find_by_id(1)
85 end
86
57 87 def test_list_documents
58 88 get :list_documents, :id => 1
59 89 assert_response :success
60 90 assert_template 'list_documents'
61 91 assert_not_nil assigns(:grouped)
62 92 end
63 93
64 94 def test_bulk_edit_issues
65 95 @request.session[:user_id] = 2
66 96 # update issues priority
67 97 post :bulk_edit_issues, :id => 1, :issue_ids => [1, 2], :priority_id => 7, :notes => 'Bulk editing', :assigned_to_id => ''
68 98 assert_response 302
69 99 # check that the issues were updated
70 100 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
71 101 assert_equal 'Bulk editing', Issue.find(1).journals.find(:first, :order => 'created_on DESC').notes
72 102 end
73 103
104 def test_move_issues_to_another_project
105 @request.session[:user_id] = 1
106 post :move_issues, :id => 1, :issue_ids => [1, 2], :new_project_id => 2
107 assert_redirected_to 'projects/1/issues'
108 assert_equal 2, Issue.find(1).project_id
109 assert_equal 2, Issue.find(2).project_id
110 end
111
112 def test_move_issues_to_another_tracker
113 @request.session[:user_id] = 1
114 post :move_issues, :id => 1, :issue_ids => [1, 2], :new_tracker_id => 3
115 assert_redirected_to 'projects/1/issues'
116 assert_equal 3, Issue.find(1).tracker_id
117 assert_equal 3, Issue.find(2).tracker_id
118 end
119
74 120 def test_list_files
75 121 get :list_files, :id => 1
76 122 assert_response :success
77 123 assert_template 'list_files'
78 124 assert_not_nil assigns(:versions)
79 125 end
80 126
81 127 def test_changelog
82 128 get :changelog, :id => 1
83 129 assert_response :success
84 130 assert_template 'changelog'
85 131 assert_not_nil assigns(:versions)
86 132 end
87 133
88 134 def test_roadmap
89 135 get :roadmap, :id => 1
90 136 assert_response :success
91 137 assert_template 'roadmap'
92 138 assert_not_nil assigns(:versions)
93 139 # Version with no date set appears
94 140 assert assigns(:versions).include?(Version.find(3))
95 141 # Completed version doesn't appear
96 142 assert !assigns(:versions).include?(Version.find(1))
97 143 end
98 144
99 145 def test_roadmap_with_completed_versions
100 146 get :roadmap, :id => 1, :completed => 1
101 147 assert_response :success
102 148 assert_template 'roadmap'
103 149 assert_not_nil assigns(:versions)
104 150 # Version with no date set appears
105 151 assert assigns(:versions).include?(Version.find(3))
106 152 # Completed version appears
107 153 assert assigns(:versions).include?(Version.find(1))
108 154 end
109 155
110 156 def test_activity
111 157 get :activity, :id => 1, :year => 2.days.ago.to_date.year, :month => 2.days.ago.to_date.month
112 158 assert_response :success
113 159 assert_template 'activity'
114 160 assert_not_nil assigns(:events_by_day)
115 161
116 162 assert_tag :tag => "h3",
117 163 :content => /#{2.days.ago.to_date.day}/,
118 164 :sibling => { :tag => "ul",
119 165 :child => { :tag => "li",
120 166 :child => { :tag => "p",
121 167 :content => /(#{IssueStatus.find(2).name})/,
122 168 }
123 169 }
124 170 }
125 171
126 172 get :activity, :id => 1, :year => 3.days.ago.to_date.year, :month => 3.days.ago.to_date.month
127 173 assert_response :success
128 174 assert_template 'activity'
129 175 assert_not_nil assigns(:events_by_day)
130 176
131 177 assert_tag :tag => "h3",
132 178 :content => /#{3.day.ago.to_date.day}/,
133 179 :sibling => { :tag => "ul",
134 180 :child => { :tag => "li",
135 181 :child => { :tag => "p",
136 182 :content => /#{Issue.find(1).subject}/,
137 183 }
138 184 }
139 185 }
140 186 end
141 187
142 188 def test_calendar
143 189 get :calendar, :id => 1
144 190 assert_response :success
145 191 assert_template 'calendar'
146 192 assert_not_nil assigns(:calendar)
147 193 end
148 194
149 195 def test_calendar_with_subprojects
150 196 get :calendar, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
151 197 assert_response :success
152 198 assert_template 'calendar'
153 199 assert_not_nil assigns(:calendar)
154 200 end
155 201
156 202 def test_gantt
157 203 get :gantt, :id => 1
158 204 assert_response :success
159 205 assert_template 'gantt.rhtml'
160 206 assert_not_nil assigns(:events)
161 207 end
162 208
163 209 def test_gantt_with_subprojects
164 210 get :gantt, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
165 211 assert_response :success
166 212 assert_template 'gantt.rhtml'
167 213 assert_not_nil assigns(:events)
168 214 end
169 215
170 216 def test_gantt_export_to_pdf
171 217 get :gantt, :id => 1, :format => 'pdf'
172 218 assert_response :success
173 219 assert_template 'gantt.rfpdf'
174 220 assert_equal 'application/pdf', @response.content_type
175 221 assert_not_nil assigns(:events)
176 222 end
177 223
178 224 def test_archive
179 225 @request.session[:user_id] = 1 # admin
180 226 post :archive, :id => 1
181 227 assert_redirected_to 'admin/projects'
182 228 assert !Project.find(1).active?
183 229 end
184 230
185 231 def test_unarchive
186 232 @request.session[:user_id] = 1 # admin
187 233 Project.find(1).archive
188 234 post :unarchive, :id => 1
189 235 assert_redirected_to 'admin/projects'
190 236 assert Project.find(1).active?
191 237 end
192 238
193 239 def test_add_issue
194 240 @request.session[:user_id] = 2
195 241 get :add_issue, :id => 1, :tracker_id => 1
196 242 assert_response :success
197 243 assert_template 'add_issue'
198 244 post :add_issue, :id => 1, :issue => {:tracker_id => 1, :subject => 'This is the test_add_issue issue', :description => 'This is the description', :priority_id => 5}
199 245 assert_redirected_to 'projects/1/issues'
200 246 assert Issue.find_by_subject('This is the test_add_issue issue')
201 247 end
202 248
203 249 def test_copy_issue
204 250 @request.session[:user_id] = 2
205 251 get :add_issue, :id => 1, :copy_from => 1
206 252 assert_template 'add_issue'
207 253 assert_not_nil assigns(:issue)
208 254 orig = Issue.find(1)
209 255 assert_equal orig.subject, assigns(:issue).subject
210 256 end
211 257 end
General Comments 0
You need to be logged in to leave comments. Login now