##// END OF EJS Templates
Fixed test failures introduced by r14288 (#19656)....
Jean-Philippe Lang -
r13909:ff2532e52d40
parent child
Show More
@@ -1,235 +1,235
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class ProjectEnumerationsControllerTest < ActionController::TestCase
20 class ProjectEnumerationsControllerTest < ActionController::TestCase
21 fixtures :projects, :trackers, :issue_statuses, :issues,
21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 :enumerations, :users, :issue_categories,
22 :enumerations, :users, :issue_categories,
23 :projects_trackers,
23 :projects_trackers,
24 :roles,
24 :roles,
25 :member_roles,
25 :member_roles,
26 :members,
26 :members,
27 :enabled_modules,
27 :enabled_modules,
28 :custom_fields, :custom_fields_projects,
28 :custom_fields, :custom_fields_projects,
29 :custom_fields_trackers, :custom_values,
29 :custom_fields_trackers, :custom_values,
30 :time_entries
30 :time_entries
31
31
32 self.use_transactional_fixtures = false
32 self.use_transactional_fixtures = false
33
33
34 def setup
34 def setup
35 @request.session[:user_id] = nil
35 @request.session[:user_id] = nil
36 Setting.default_language = 'en'
36 Setting.default_language = 'en'
37 end
37 end
38
38
39 def test_update_to_override_system_activities
39 def test_update_to_override_system_activities
40 @request.session[:user_id] = 2 # manager
40 @request.session[:user_id] = 2 # manager
41 billable_field = TimeEntryActivityCustomField.find_by_name("Billable")
41 billable_field = TimeEntryActivityCustomField.find_by_name("Billable")
42
42
43 put :update, :project_id => 1, :enumerations => {
43 put :update, :project_id => 1, :enumerations => {
44 "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # Design, De-activate
44 "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # Design, De-activate
45 "10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"}, # Development, Change custom value
45 "10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"}, # Development, Change custom value
46 "14"=>{"parent_id"=>"14", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"}, # Inactive Activity, Activate with custom value
46 "14"=>{"parent_id"=>"14", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"}, # Inactive Activity, Activate with custom value
47 "11"=>{"parent_id"=>"11", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"} # QA, no changes
47 "11"=>{"parent_id"=>"11", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"} # QA, no changes
48 }
48 }
49
49
50 assert_response :redirect
50 assert_response :redirect
51 assert_redirected_to '/projects/ecookbook/settings/activities'
51 assert_redirected_to '/projects/ecookbook/settings/activities'
52
52
53 # Created project specific activities...
53 # Created project specific activities...
54 project = Project.find('ecookbook')
54 project = Project.find('ecookbook')
55
55
56 # ... Design
56 # ... Design
57 design = project.time_entry_activities.find_by_name("Design")
57 design = project.time_entry_activities.find_by_name("Design")
58 assert design, "Project activity not found"
58 assert design, "Project activity not found"
59
59
60 assert_equal 9, design.parent_id # Relate to the system activity
60 assert_equal 9, design.parent_id # Relate to the system activity
61 assert_not_equal design.parent.id, design.id # Different records
61 assert_not_equal design.parent.id, design.id # Different records
62 assert_equal design.parent.name, design.name # Same name
62 assert_equal design.parent.name, design.name # Same name
63 assert !design.active?
63 assert !design.active?
64
64
65 # ... Development
65 # ... Development
66 development = project.time_entry_activities.find_by_name("Development")
66 development = project.time_entry_activities.find_by_name("Development")
67 assert development, "Project activity not found"
67 assert development, "Project activity not found"
68
68
69 assert_equal 10, development.parent_id # Relate to the system activity
69 assert_equal 10, development.parent_id # Relate to the system activity
70 assert_not_equal development.parent.id, development.id # Different records
70 assert_not_equal development.parent.id, development.id # Different records
71 assert_equal development.parent.name, development.name # Same name
71 assert_equal development.parent.name, development.name # Same name
72 assert development.active?
72 assert development.active?
73 assert_equal "0", development.custom_value_for(billable_field).value
73 assert_equal "0", development.custom_value_for(billable_field).value
74
74
75 # ... Inactive Activity
75 # ... Inactive Activity
76 previously_inactive = project.time_entry_activities.find_by_name("Inactive Activity")
76 previously_inactive = project.time_entry_activities.find_by_name("Inactive Activity")
77 assert previously_inactive, "Project activity not found"
77 assert previously_inactive, "Project activity not found"
78
78
79 assert_equal 14, previously_inactive.parent_id # Relate to the system activity
79 assert_equal 14, previously_inactive.parent_id # Relate to the system activity
80 assert_not_equal previously_inactive.parent.id, previously_inactive.id # Different records
80 assert_not_equal previously_inactive.parent.id, previously_inactive.id # Different records
81 assert_equal previously_inactive.parent.name, previously_inactive.name # Same name
81 assert_equal previously_inactive.parent.name, previously_inactive.name # Same name
82 assert previously_inactive.active?
82 assert previously_inactive.active?
83 assert_equal "1", previously_inactive.custom_value_for(billable_field).value
83 assert_equal "1", previously_inactive.custom_value_for(billable_field).value
84
84
85 # ... QA
85 # ... QA
86 assert_equal nil, project.time_entry_activities.find_by_name("QA"), "Custom QA activity created when it wasn't modified"
86 assert_equal nil, project.time_entry_activities.find_by_name("QA"), "Custom QA activity created when it wasn't modified"
87 end
87 end
88
88
89 def test_update_will_update_project_specific_activities
89 def test_update_will_update_project_specific_activities
90 @request.session[:user_id] = 2 # manager
90 @request.session[:user_id] = 2 # manager
91
91
92 project_activity = TimeEntryActivity.new({
92 project_activity = TimeEntryActivity.new({
93 :name => 'Project Specific',
93 :name => 'Project Specific',
94 :parent => TimeEntryActivity.first,
94 :parent => TimeEntryActivity.first,
95 :project => Project.find(1),
95 :project => Project.find(1),
96 :active => true
96 :active => true
97 })
97 })
98 assert project_activity.save
98 assert project_activity.save
99 project_activity_two = TimeEntryActivity.new({
99 project_activity_two = TimeEntryActivity.new({
100 :name => 'Project Specific Two',
100 :name => 'Project Specific Two',
101 :parent => TimeEntryActivity.last,
101 :parent => TimeEntryActivity.last,
102 :project => Project.find(1),
102 :project => Project.find(1),
103 :active => true
103 :active => true
104 })
104 })
105 assert project_activity_two.save
105 assert project_activity_two.save
106
106
107
107
108 put :update, :project_id => 1, :enumerations => {
108 put :update, :project_id => 1, :enumerations => {
109 project_activity.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # De-activate
109 project_activity.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"}, # De-activate
110 project_activity_two.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"} # De-activate
110 project_activity_two.id => {"custom_field_values"=>{"7" => "1"}, "active"=>"0"} # De-activate
111 }
111 }
112
112
113 assert_response :redirect
113 assert_response :redirect
114 assert_redirected_to '/projects/ecookbook/settings/activities'
114 assert_redirected_to '/projects/ecookbook/settings/activities'
115
115
116 # Created project specific activities...
116 # Created project specific activities...
117 project = Project.find('ecookbook')
117 project = Project.find('ecookbook')
118 assert_equal 2, project.time_entry_activities.count
118 assert_equal 2, project.time_entry_activities.count
119
119
120 activity_one = project.time_entry_activities.find_by_name(project_activity.name)
120 activity_one = project.time_entry_activities.find_by_name(project_activity.name)
121 assert activity_one, "Project activity not found"
121 assert activity_one, "Project activity not found"
122 assert_equal project_activity.id, activity_one.id
122 assert_equal project_activity.id, activity_one.id
123 assert !activity_one.active?
123 assert !activity_one.active?
124
124
125 activity_two = project.time_entry_activities.find_by_name(project_activity_two.name)
125 activity_two = project.time_entry_activities.find_by_name(project_activity_two.name)
126 assert activity_two, "Project activity not found"
126 assert activity_two, "Project activity not found"
127 assert_equal project_activity_two.id, activity_two.id
127 assert_equal project_activity_two.id, activity_two.id
128 assert !activity_two.active?
128 assert !activity_two.active?
129 end
129 end
130
130
131 def test_update_when_creating_new_activities_will_convert_existing_data
131 def test_update_when_creating_new_activities_will_convert_existing_data
132 assert_equal 3, TimeEntry.where(:activity_id => 9, :project_id => 1).count
132 assert_equal 3, TimeEntry.where(:activity_id => 9, :project_id => 1).count
133
133
134 @request.session[:user_id] = 2 # manager
134 @request.session[:user_id] = 2 # manager
135 put :update, :project_id => 1, :enumerations => {
135 put :update, :project_id => 1, :enumerations => {
136 "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"} # Design, De-activate
136 "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"} # Design, De-activate
137 }
137 }
138 assert_response :redirect
138 assert_response :redirect
139
139
140 # No more TimeEntries using the system activity
140 # No more TimeEntries using the system activity
141 assert_equal 0, TimeEntry.where(:activity_id => 9, :project_id => 1).count,
141 assert_equal 0, TimeEntry.where(:activity_id => 9, :project_id => 1).count,
142 "Time Entries still assigned to system activities"
142 "Time Entries still assigned to system activities"
143 # All TimeEntries using project activity
143 # All TimeEntries using project activity
144 project_specific_activity = TimeEntryActivity.find_by_parent_id_and_project_id(9, 1)
144 project_specific_activity = TimeEntryActivity.find_by_parent_id_and_project_id(9, 1)
145 assert_equal 3, TimeEntry.where(:activity_id => project_specific_activity.id,
145 assert_equal 3, TimeEntry.where(:activity_id => project_specific_activity.id,
146 :project_id => 1).count
146 :project_id => 1).count
147 "No Time Entries assigned to the project activity"
147 "No Time Entries assigned to the project activity"
148 end
148 end
149
149
150 def test_update_when_creating_new_activities_will_not_convert_existing_data_if_an_exception_is_raised
150 def test_update_when_creating_new_activities_will_not_convert_existing_data_if_an_exception_is_raised
151 # TODO: Need to cause an exception on create but these tests
151 # TODO: Need to cause an exception on create but these tests
152 # aren't setup for mocking. Just create a record now so the
152 # aren't setup for mocking. Just create a record now so the
153 # second one is a dupicate
153 # second one is a dupicate
154 parent = TimeEntryActivity.find(9)
154 parent = TimeEntryActivity.find(9)
155 TimeEntryActivity.create!({:name => parent.name, :project_id => 1,
155 TimeEntryActivity.create!({:name => parent.name, :project_id => 1,
156 :position => parent.position, :active => true})
156 :position => parent.position, :active => true, :parent_id => 9})
157 TimeEntry.create!({:project_id => 1, :hours => 1.0, :user => User.find(1),
157 TimeEntry.create!({:project_id => 1, :hours => 1.0, :user => User.find(1),
158 :issue_id => 3, :activity_id => 10, :spent_on => '2009-01-01'})
158 :issue_id => 3, :activity_id => 10, :spent_on => '2009-01-01'})
159 assert_equal 3, TimeEntry.where(:activity_id => 9, :project_id => 1).count
159 assert_equal 3, TimeEntry.where(:activity_id => 9, :project_id => 1).count
160 assert_equal 1, TimeEntry.where(:activity_id => 10, :project_id => 1).count
160 assert_equal 1, TimeEntry.where(:activity_id => 10, :project_id => 1).count
161
161
162 @request.session[:user_id] = 2 # manager
162 @request.session[:user_id] = 2 # manager
163 put :update, :project_id => 1, :enumerations => {
163 put :update, :project_id => 1, :enumerations => {
164 # Design
164 # Design
165 "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"},
165 "9"=> {"parent_id"=>"9", "custom_field_values"=>{"7" => "1"}, "active"=>"0"},
166 # Development, Change custom value
166 # Development, Change custom value
167 "10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"}
167 "10"=> {"parent_id"=>"10", "custom_field_values"=>{"7"=>"0"}, "active"=>"1"}
168 }
168 }
169 assert_response :redirect
169 assert_response :redirect
170
170
171 # TimeEntries shouldn't have been reassigned on the failed record
171 # TimeEntries shouldn't have been reassigned on the failed record
172 assert_equal 3, TimeEntry.where(:activity_id => 9,
172 assert_equal 3, TimeEntry.where(:activity_id => 9,
173 :project_id => 1).count
173 :project_id => 1).count
174 "Time Entries are not assigned to system activities"
174 "Time Entries are not assigned to system activities"
175 # TimeEntries shouldn't have been reassigned on the saved record either
175 # TimeEntries shouldn't have been reassigned on the saved record either
176 assert_equal 1, TimeEntry.where(:activity_id => 10,
176 assert_equal 1, TimeEntry.where(:activity_id => 10,
177 :project_id => 1).count
177 :project_id => 1).count
178 "Time Entries are not assigned to system activities"
178 "Time Entries are not assigned to system activities"
179 end
179 end
180
180
181 def test_destroy
181 def test_destroy
182 @request.session[:user_id] = 2 # manager
182 @request.session[:user_id] = 2 # manager
183 project_activity = TimeEntryActivity.new({
183 project_activity = TimeEntryActivity.new({
184 :name => 'Project Specific',
184 :name => 'Project Specific',
185 :parent => TimeEntryActivity.first,
185 :parent => TimeEntryActivity.first,
186 :project => Project.find(1),
186 :project => Project.find(1),
187 :active => true
187 :active => true
188 })
188 })
189 assert project_activity.save
189 assert project_activity.save
190 project_activity_two = TimeEntryActivity.new({
190 project_activity_two = TimeEntryActivity.new({
191 :name => 'Project Specific Two',
191 :name => 'Project Specific Two',
192 :parent => TimeEntryActivity.last,
192 :parent => TimeEntryActivity.last,
193 :project => Project.find(1),
193 :project => Project.find(1),
194 :active => true
194 :active => true
195 })
195 })
196 assert project_activity_two.save
196 assert project_activity_two.save
197
197
198 delete :destroy, :project_id => 1
198 delete :destroy, :project_id => 1
199 assert_response :redirect
199 assert_response :redirect
200 assert_redirected_to '/projects/ecookbook/settings/activities'
200 assert_redirected_to '/projects/ecookbook/settings/activities'
201
201
202 assert_nil TimeEntryActivity.find_by_id(project_activity.id)
202 assert_nil TimeEntryActivity.find_by_id(project_activity.id)
203 assert_nil TimeEntryActivity.find_by_id(project_activity_two.id)
203 assert_nil TimeEntryActivity.find_by_id(project_activity_two.id)
204 end
204 end
205
205
206 def test_destroy_should_reassign_time_entries_back_to_the_system_activity
206 def test_destroy_should_reassign_time_entries_back_to_the_system_activity
207 @request.session[:user_id] = 2 # manager
207 @request.session[:user_id] = 2 # manager
208 project_activity = TimeEntryActivity.new({
208 project_activity = TimeEntryActivity.new({
209 :name => 'Project Specific Design',
209 :name => 'Project Specific Design',
210 :parent => TimeEntryActivity.find(9),
210 :parent => TimeEntryActivity.find(9),
211 :project => Project.find(1),
211 :project => Project.find(1),
212 :active => true
212 :active => true
213 })
213 })
214 assert project_activity.save
214 assert project_activity.save
215 assert TimeEntry.where(["project_id = ? AND activity_id = ?", 1, 9]).
215 assert TimeEntry.where(["project_id = ? AND activity_id = ?", 1, 9]).
216 update_all("activity_id = '#{project_activity.id}'")
216 update_all("activity_id = '#{project_activity.id}'")
217 assert_equal 3, TimeEntry.where(:activity_id => project_activity.id,
217 assert_equal 3, TimeEntry.where(:activity_id => project_activity.id,
218 :project_id => 1).count
218 :project_id => 1).count
219 delete :destroy, :project_id => 1
219 delete :destroy, :project_id => 1
220 assert_response :redirect
220 assert_response :redirect
221 assert_redirected_to '/projects/ecookbook/settings/activities'
221 assert_redirected_to '/projects/ecookbook/settings/activities'
222
222
223 assert_nil TimeEntryActivity.find_by_id(project_activity.id)
223 assert_nil TimeEntryActivity.find_by_id(project_activity.id)
224 assert_equal 0, TimeEntry.where(
224 assert_equal 0, TimeEntry.where(
225 :activity_id => project_activity.id,
225 :activity_id => project_activity.id,
226 :project_id => 1
226 :project_id => 1
227 ).count,
227 ).count,
228 "TimeEntries still assigned to project specific activity"
228 "TimeEntries still assigned to project specific activity"
229 assert_equal 3, TimeEntry.where(
229 assert_equal 3, TimeEntry.where(
230 :activity_id => 9,
230 :activity_id => 9,
231 :project_id => 1
231 :project_id => 1
232 ).count,
232 ).count,
233 "TimeEntries still assigned to project specific activity"
233 "TimeEntries still assigned to project specific activity"
234 end
234 end
235 end
235 end
@@ -1,809 +1,809
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 # Redmine - project management software
2 # Redmine - project management software
3 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 # Copyright (C) 2006-2015 Jean-Philippe Lang
4 #
4 #
5 # This program is free software; you can redistribute it and/or
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
8 # of the License, or (at your option) any later version.
9 #
9 #
10 # This program is distributed in the hope that it will be useful,
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
13 # GNU General Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
18
19 require File.expand_path('../../test_helper', __FILE__)
19 require File.expand_path('../../test_helper', __FILE__)
20
20
21 class TimelogControllerTest < ActionController::TestCase
21 class TimelogControllerTest < ActionController::TestCase
22 fixtures :projects, :enabled_modules, :roles, :members,
22 fixtures :projects, :enabled_modules, :roles, :members,
23 :member_roles, :issues, :time_entries, :users,
23 :member_roles, :issues, :time_entries, :users,
24 :trackers, :enumerations, :issue_statuses,
24 :trackers, :enumerations, :issue_statuses,
25 :custom_fields, :custom_values,
25 :custom_fields, :custom_values,
26 :projects_trackers, :custom_fields_trackers,
26 :projects_trackers, :custom_fields_trackers,
27 :custom_fields_projects
27 :custom_fields_projects
28
28
29 include Redmine::I18n
29 include Redmine::I18n
30
30
31 def test_new
31 def test_new
32 @request.session[:user_id] = 3
32 @request.session[:user_id] = 3
33 get :new
33 get :new
34 assert_response :success
34 assert_response :success
35 assert_template 'new'
35 assert_template 'new'
36 assert_select 'input[name=?][type=hidden]', 'project_id', 0
36 assert_select 'input[name=?][type=hidden]', 'project_id', 0
37 assert_select 'input[name=?][type=hidden]', 'issue_id', 0
37 assert_select 'input[name=?][type=hidden]', 'issue_id', 0
38 assert_select 'select[name=?]', 'time_entry[project_id]' do
38 assert_select 'select[name=?]', 'time_entry[project_id]' do
39 # blank option for project
39 # blank option for project
40 assert_select 'option[value=""]'
40 assert_select 'option[value=""]'
41 end
41 end
42 end
42 end
43
43
44 def test_new_with_project_id
44 def test_new_with_project_id
45 @request.session[:user_id] = 3
45 @request.session[:user_id] = 3
46 get :new, :project_id => 1
46 get :new, :project_id => 1
47 assert_response :success
47 assert_response :success
48 assert_template 'new'
48 assert_template 'new'
49 assert_select 'input[name=?][type=hidden]', 'project_id'
49 assert_select 'input[name=?][type=hidden]', 'project_id'
50 assert_select 'input[name=?][type=hidden]', 'issue_id', 0
50 assert_select 'input[name=?][type=hidden]', 'issue_id', 0
51 assert_select 'select[name=?]', 'time_entry[project_id]', 0
51 assert_select 'select[name=?]', 'time_entry[project_id]', 0
52 end
52 end
53
53
54 def test_new_with_issue_id
54 def test_new_with_issue_id
55 @request.session[:user_id] = 3
55 @request.session[:user_id] = 3
56 get :new, :issue_id => 2
56 get :new, :issue_id => 2
57 assert_response :success
57 assert_response :success
58 assert_template 'new'
58 assert_template 'new'
59 assert_select 'input[name=?][type=hidden]', 'project_id', 0
59 assert_select 'input[name=?][type=hidden]', 'project_id', 0
60 assert_select 'input[name=?][type=hidden]', 'issue_id'
60 assert_select 'input[name=?][type=hidden]', 'issue_id'
61 assert_select 'select[name=?]', 'time_entry[project_id]', 0
61 assert_select 'select[name=?]', 'time_entry[project_id]', 0
62 end
62 end
63
63
64 def test_new_without_project_should_prefill_the_form
64 def test_new_without_project_should_prefill_the_form
65 @request.session[:user_id] = 3
65 @request.session[:user_id] = 3
66 get :new, :time_entry => {:project_id => '1'}
66 get :new, :time_entry => {:project_id => '1'}
67 assert_response :success
67 assert_response :success
68 assert_template 'new'
68 assert_template 'new'
69 assert_select 'select[name=?]', 'time_entry[project_id]' do
69 assert_select 'select[name=?]', 'time_entry[project_id]' do
70 assert_select 'option[value="1"][selected=selected]'
70 assert_select 'option[value="1"][selected=selected]'
71 end
71 end
72 end
72 end
73
73
74 def test_new_without_project_should_deny_without_permission
74 def test_new_without_project_should_deny_without_permission
75 Role.all.each {|role| role.remove_permission! :log_time}
75 Role.all.each {|role| role.remove_permission! :log_time}
76 @request.session[:user_id] = 3
76 @request.session[:user_id] = 3
77
77
78 get :new
78 get :new
79 assert_response 403
79 assert_response 403
80 end
80 end
81
81
82 def test_new_should_select_default_activity
82 def test_new_should_select_default_activity
83 @request.session[:user_id] = 3
83 @request.session[:user_id] = 3
84 get :new, :project_id => 1
84 get :new, :project_id => 1
85 assert_response :success
85 assert_response :success
86 assert_select 'select[name=?]', 'time_entry[activity_id]' do
86 assert_select 'select[name=?]', 'time_entry[activity_id]' do
87 assert_select 'option[selected=selected]', :text => 'Development'
87 assert_select 'option[selected=selected]', :text => 'Development'
88 end
88 end
89 end
89 end
90
90
91 def test_new_should_only_show_active_time_entry_activities
91 def test_new_should_only_show_active_time_entry_activities
92 @request.session[:user_id] = 3
92 @request.session[:user_id] = 3
93 get :new, :project_id => 1
93 get :new, :project_id => 1
94 assert_response :success
94 assert_response :success
95 assert_select 'option', :text => 'Inactive Activity', :count => 0
95 assert_select 'option', :text => 'Inactive Activity', :count => 0
96 end
96 end
97
97
98 def test_post_new_as_js_should_update_activity_options
98 def test_post_new_as_js_should_update_activity_options
99 @request.session[:user_id] = 3
99 @request.session[:user_id] = 3
100 post :new, :time_entry => {:project_id => 1}, :format => 'js'
100 post :new, :time_entry => {:project_id => 1}, :format => 'js'
101 assert_response :success
101 assert_response :success
102 assert_include '#time_entry_activity_id', response.body
102 assert_include '#time_entry_activity_id', response.body
103 end
103 end
104
104
105 def test_get_edit_existing_time
105 def test_get_edit_existing_time
106 @request.session[:user_id] = 2
106 @request.session[:user_id] = 2
107 get :edit, :id => 2, :project_id => nil
107 get :edit, :id => 2, :project_id => nil
108 assert_response :success
108 assert_response :success
109 assert_template 'edit'
109 assert_template 'edit'
110 assert_select 'form[action=?]', '/time_entries/2'
110 assert_select 'form[action=?]', '/time_entries/2'
111 end
111 end
112
112
113 def test_get_edit_with_an_existing_time_entry_with_inactive_activity
113 def test_get_edit_with_an_existing_time_entry_with_inactive_activity
114 te = TimeEntry.find(1)
114 te = TimeEntry.find(1)
115 te.activity = TimeEntryActivity.find_by_name("Inactive Activity")
115 te.activity = TimeEntryActivity.find_by_name("Inactive Activity")
116 te.save!
116 te.save!(:validate => false)
117
117
118 @request.session[:user_id] = 1
118 @request.session[:user_id] = 1
119 get :edit, :project_id => 1, :id => 1
119 get :edit, :project_id => 1, :id => 1
120 assert_response :success
120 assert_response :success
121 assert_template 'edit'
121 assert_template 'edit'
122 # Blank option since nothing is pre-selected
122 # Blank option since nothing is pre-selected
123 assert_select 'option', :text => '--- Please select ---'
123 assert_select 'option', :text => '--- Please select ---'
124 end
124 end
125
125
126 def test_post_create
126 def test_post_create
127 @request.session[:user_id] = 3
127 @request.session[:user_id] = 3
128 assert_difference 'TimeEntry.count' do
128 assert_difference 'TimeEntry.count' do
129 post :create, :project_id => 1,
129 post :create, :project_id => 1,
130 :time_entry => {:comments => 'Some work on TimelogControllerTest',
130 :time_entry => {:comments => 'Some work on TimelogControllerTest',
131 # Not the default activity
131 # Not the default activity
132 :activity_id => '11',
132 :activity_id => '11',
133 :spent_on => '2008-03-14',
133 :spent_on => '2008-03-14',
134 :issue_id => '1',
134 :issue_id => '1',
135 :hours => '7.3'}
135 :hours => '7.3'}
136 assert_redirected_to '/projects/ecookbook/time_entries'
136 assert_redirected_to '/projects/ecookbook/time_entries'
137 end
137 end
138
138
139 t = TimeEntry.order('id DESC').first
139 t = TimeEntry.order('id DESC').first
140 assert_not_nil t
140 assert_not_nil t
141 assert_equal 'Some work on TimelogControllerTest', t.comments
141 assert_equal 'Some work on TimelogControllerTest', t.comments
142 assert_equal 1, t.project_id
142 assert_equal 1, t.project_id
143 assert_equal 1, t.issue_id
143 assert_equal 1, t.issue_id
144 assert_equal 11, t.activity_id
144 assert_equal 11, t.activity_id
145 assert_equal 7.3, t.hours
145 assert_equal 7.3, t.hours
146 assert_equal 3, t.user_id
146 assert_equal 3, t.user_id
147 end
147 end
148
148
149 def test_post_create_with_blank_issue
149 def test_post_create_with_blank_issue
150 @request.session[:user_id] = 3
150 @request.session[:user_id] = 3
151 assert_difference 'TimeEntry.count' do
151 assert_difference 'TimeEntry.count' do
152 post :create, :project_id => 1,
152 post :create, :project_id => 1,
153 :time_entry => {:comments => 'Some work on TimelogControllerTest',
153 :time_entry => {:comments => 'Some work on TimelogControllerTest',
154 # Not the default activity
154 # Not the default activity
155 :activity_id => '11',
155 :activity_id => '11',
156 :issue_id => '',
156 :issue_id => '',
157 :spent_on => '2008-03-14',
157 :spent_on => '2008-03-14',
158 :hours => '7.3'}
158 :hours => '7.3'}
159 assert_redirected_to '/projects/ecookbook/time_entries'
159 assert_redirected_to '/projects/ecookbook/time_entries'
160 end
160 end
161
161
162 t = TimeEntry.order('id DESC').first
162 t = TimeEntry.order('id DESC').first
163 assert_not_nil t
163 assert_not_nil t
164 assert_equal 'Some work on TimelogControllerTest', t.comments
164 assert_equal 'Some work on TimelogControllerTest', t.comments
165 assert_equal 1, t.project_id
165 assert_equal 1, t.project_id
166 assert_nil t.issue_id
166 assert_nil t.issue_id
167 assert_equal 11, t.activity_id
167 assert_equal 11, t.activity_id
168 assert_equal 7.3, t.hours
168 assert_equal 7.3, t.hours
169 assert_equal 3, t.user_id
169 assert_equal 3, t.user_id
170 end
170 end
171
171
172 def test_create_on_project_with_time_tracking_disabled_should_fail
172 def test_create_on_project_with_time_tracking_disabled_should_fail
173 Project.find(1).disable_module! :time_tracking
173 Project.find(1).disable_module! :time_tracking
174
174
175 @request.session[:user_id] = 2
175 @request.session[:user_id] = 2
176 assert_no_difference 'TimeEntry.count' do
176 assert_no_difference 'TimeEntry.count' do
177 post :create, :time_entry => {
177 post :create, :time_entry => {
178 :project_id => '1', :issue_id => '',
178 :project_id => '1', :issue_id => '',
179 :activity_id => '11', :spent_on => '2008-03-14', :hours => '7.3'
179 :activity_id => '11', :spent_on => '2008-03-14', :hours => '7.3'
180 }
180 }
181 end
181 end
182 end
182 end
183
183
184 def test_create_on_project_without_permission_should_fail
184 def test_create_on_project_without_permission_should_fail
185 Role.find(1).remove_permission! :log_time
185 Role.find(1).remove_permission! :log_time
186
186
187 @request.session[:user_id] = 2
187 @request.session[:user_id] = 2
188 assert_no_difference 'TimeEntry.count' do
188 assert_no_difference 'TimeEntry.count' do
189 post :create, :time_entry => {
189 post :create, :time_entry => {
190 :project_id => '1', :issue_id => '',
190 :project_id => '1', :issue_id => '',
191 :activity_id => '11', :spent_on => '2008-03-14', :hours => '7.3'
191 :activity_id => '11', :spent_on => '2008-03-14', :hours => '7.3'
192 }
192 }
193 end
193 end
194 end
194 end
195
195
196 def test_create_on_issue_in_project_with_time_tracking_disabled_should_fail
196 def test_create_on_issue_in_project_with_time_tracking_disabled_should_fail
197 Project.find(1).disable_module! :time_tracking
197 Project.find(1).disable_module! :time_tracking
198
198
199 @request.session[:user_id] = 2
199 @request.session[:user_id] = 2
200 assert_no_difference 'TimeEntry.count' do
200 assert_no_difference 'TimeEntry.count' do
201 post :create, :time_entry => {
201 post :create, :time_entry => {
202 :project_id => '', :issue_id => '1',
202 :project_id => '', :issue_id => '1',
203 :activity_id => '11', :spent_on => '2008-03-14', :hours => '7.3'
203 :activity_id => '11', :spent_on => '2008-03-14', :hours => '7.3'
204 }
204 }
205 assert_select_error /Issue is invalid/
205 assert_select_error /Issue is invalid/
206 end
206 end
207 end
207 end
208
208
209 def test_create_on_issue_in_project_without_permission_should_fail
209 def test_create_on_issue_in_project_without_permission_should_fail
210 Role.find(1).remove_permission! :log_time
210 Role.find(1).remove_permission! :log_time
211
211
212 @request.session[:user_id] = 2
212 @request.session[:user_id] = 2
213 assert_no_difference 'TimeEntry.count' do
213 assert_no_difference 'TimeEntry.count' do
214 post :create, :time_entry => {
214 post :create, :time_entry => {
215 :project_id => '', :issue_id => '1',
215 :project_id => '', :issue_id => '1',
216 :activity_id => '11', :spent_on => '2008-03-14', :hours => '7.3'
216 :activity_id => '11', :spent_on => '2008-03-14', :hours => '7.3'
217 }
217 }
218 assert_select_error /Issue is invalid/
218 assert_select_error /Issue is invalid/
219 end
219 end
220 end
220 end
221
221
222 def test_create_and_continue_at_project_level
222 def test_create_and_continue_at_project_level
223 @request.session[:user_id] = 2
223 @request.session[:user_id] = 2
224 assert_difference 'TimeEntry.count' do
224 assert_difference 'TimeEntry.count' do
225 post :create, :time_entry => {:project_id => '1',
225 post :create, :time_entry => {:project_id => '1',
226 :activity_id => '11',
226 :activity_id => '11',
227 :issue_id => '',
227 :issue_id => '',
228 :spent_on => '2008-03-14',
228 :spent_on => '2008-03-14',
229 :hours => '7.3'},
229 :hours => '7.3'},
230 :continue => '1'
230 :continue => '1'
231 assert_redirected_to '/time_entries/new?time_entry%5Bactivity_id%5D=11&time_entry%5Bissue_id%5D=&time_entry%5Bproject_id%5D=1'
231 assert_redirected_to '/time_entries/new?time_entry%5Bactivity_id%5D=11&time_entry%5Bissue_id%5D=&time_entry%5Bproject_id%5D=1'
232 end
232 end
233 end
233 end
234
234
235 def test_create_and_continue_at_issue_level
235 def test_create_and_continue_at_issue_level
236 @request.session[:user_id] = 2
236 @request.session[:user_id] = 2
237 assert_difference 'TimeEntry.count' do
237 assert_difference 'TimeEntry.count' do
238 post :create, :time_entry => {:project_id => '',
238 post :create, :time_entry => {:project_id => '',
239 :activity_id => '11',
239 :activity_id => '11',
240 :issue_id => '1',
240 :issue_id => '1',
241 :spent_on => '2008-03-14',
241 :spent_on => '2008-03-14',
242 :hours => '7.3'},
242 :hours => '7.3'},
243 :continue => '1'
243 :continue => '1'
244 assert_redirected_to '/time_entries/new?time_entry%5Bactivity_id%5D=11&time_entry%5Bissue_id%5D=1&time_entry%5Bproject_id%5D='
244 assert_redirected_to '/time_entries/new?time_entry%5Bactivity_id%5D=11&time_entry%5Bissue_id%5D=1&time_entry%5Bproject_id%5D='
245 end
245 end
246 end
246 end
247
247
248 def test_create_and_continue_with_project_id
248 def test_create_and_continue_with_project_id
249 @request.session[:user_id] = 2
249 @request.session[:user_id] = 2
250 assert_difference 'TimeEntry.count' do
250 assert_difference 'TimeEntry.count' do
251 post :create, :project_id => 1,
251 post :create, :project_id => 1,
252 :time_entry => {:activity_id => '11',
252 :time_entry => {:activity_id => '11',
253 :issue_id => '',
253 :issue_id => '',
254 :spent_on => '2008-03-14',
254 :spent_on => '2008-03-14',
255 :hours => '7.3'},
255 :hours => '7.3'},
256 :continue => '1'
256 :continue => '1'
257 assert_redirected_to '/projects/ecookbook/time_entries/new?time_entry%5Bactivity_id%5D=11&time_entry%5Bissue_id%5D=&time_entry%5Bproject_id%5D='
257 assert_redirected_to '/projects/ecookbook/time_entries/new?time_entry%5Bactivity_id%5D=11&time_entry%5Bissue_id%5D=&time_entry%5Bproject_id%5D='
258 end
258 end
259 end
259 end
260
260
261 def test_create_and_continue_with_issue_id
261 def test_create_and_continue_with_issue_id
262 @request.session[:user_id] = 2
262 @request.session[:user_id] = 2
263 assert_difference 'TimeEntry.count' do
263 assert_difference 'TimeEntry.count' do
264 post :create, :issue_id => 1,
264 post :create, :issue_id => 1,
265 :time_entry => {:activity_id => '11',
265 :time_entry => {:activity_id => '11',
266 :issue_id => '1',
266 :issue_id => '1',
267 :spent_on => '2008-03-14',
267 :spent_on => '2008-03-14',
268 :hours => '7.3'},
268 :hours => '7.3'},
269 :continue => '1'
269 :continue => '1'
270 assert_redirected_to '/issues/1/time_entries/new?time_entry%5Bactivity_id%5D=11&time_entry%5Bissue_id%5D=1&time_entry%5Bproject_id%5D='
270 assert_redirected_to '/issues/1/time_entries/new?time_entry%5Bactivity_id%5D=11&time_entry%5Bissue_id%5D=1&time_entry%5Bproject_id%5D='
271 end
271 end
272 end
272 end
273
273
274 def test_create_without_log_time_permission_should_be_denied
274 def test_create_without_log_time_permission_should_be_denied
275 @request.session[:user_id] = 2
275 @request.session[:user_id] = 2
276 Role.find_by_name('Manager').remove_permission! :log_time
276 Role.find_by_name('Manager').remove_permission! :log_time
277 post :create, :project_id => 1,
277 post :create, :project_id => 1,
278 :time_entry => {:activity_id => '11',
278 :time_entry => {:activity_id => '11',
279 :issue_id => '',
279 :issue_id => '',
280 :spent_on => '2008-03-14',
280 :spent_on => '2008-03-14',
281 :hours => '7.3'}
281 :hours => '7.3'}
282
282
283 assert_response 403
283 assert_response 403
284 end
284 end
285
285
286 def test_create_without_project_and_issue_should_fail
286 def test_create_without_project_and_issue_should_fail
287 @request.session[:user_id] = 2
287 @request.session[:user_id] = 2
288 post :create, :time_entry => {:issue_id => ''}
288 post :create, :time_entry => {:issue_id => ''}
289
289
290 assert_response :success
290 assert_response :success
291 assert_template 'new'
291 assert_template 'new'
292 end
292 end
293
293
294 def test_create_with_failure
294 def test_create_with_failure
295 @request.session[:user_id] = 2
295 @request.session[:user_id] = 2
296 post :create, :project_id => 1,
296 post :create, :project_id => 1,
297 :time_entry => {:activity_id => '',
297 :time_entry => {:activity_id => '',
298 :issue_id => '',
298 :issue_id => '',
299 :spent_on => '2008-03-14',
299 :spent_on => '2008-03-14',
300 :hours => '7.3'}
300 :hours => '7.3'}
301
301
302 assert_response :success
302 assert_response :success
303 assert_template 'new'
303 assert_template 'new'
304 end
304 end
305
305
306 def test_create_without_project
306 def test_create_without_project
307 @request.session[:user_id] = 2
307 @request.session[:user_id] = 2
308 assert_difference 'TimeEntry.count' do
308 assert_difference 'TimeEntry.count' do
309 post :create, :time_entry => {:project_id => '1',
309 post :create, :time_entry => {:project_id => '1',
310 :activity_id => '11',
310 :activity_id => '11',
311 :issue_id => '',
311 :issue_id => '',
312 :spent_on => '2008-03-14',
312 :spent_on => '2008-03-14',
313 :hours => '7.3'}
313 :hours => '7.3'}
314 end
314 end
315
315
316 assert_redirected_to '/projects/ecookbook/time_entries'
316 assert_redirected_to '/projects/ecookbook/time_entries'
317 time_entry = TimeEntry.order('id DESC').first
317 time_entry = TimeEntry.order('id DESC').first
318 assert_equal 1, time_entry.project_id
318 assert_equal 1, time_entry.project_id
319 end
319 end
320
320
321 def test_create_without_project_should_fail_with_issue_not_inside_project
321 def test_create_without_project_should_fail_with_issue_not_inside_project
322 @request.session[:user_id] = 2
322 @request.session[:user_id] = 2
323 assert_no_difference 'TimeEntry.count' do
323 assert_no_difference 'TimeEntry.count' do
324 post :create, :time_entry => {:project_id => '1',
324 post :create, :time_entry => {:project_id => '1',
325 :activity_id => '11',
325 :activity_id => '11',
326 :issue_id => '5',
326 :issue_id => '5',
327 :spent_on => '2008-03-14',
327 :spent_on => '2008-03-14',
328 :hours => '7.3'}
328 :hours => '7.3'}
329 end
329 end
330
330
331 assert_response :success
331 assert_response :success
332 assert assigns(:time_entry).errors[:issue_id].present?
332 assert assigns(:time_entry).errors[:issue_id].present?
333 end
333 end
334
334
335 def test_create_without_project_should_deny_without_permission
335 def test_create_without_project_should_deny_without_permission
336 @request.session[:user_id] = 2
336 @request.session[:user_id] = 2
337 Project.find(3).disable_module!(:time_tracking)
337 Project.find(3).disable_module!(:time_tracking)
338
338
339 assert_no_difference 'TimeEntry.count' do
339 assert_no_difference 'TimeEntry.count' do
340 post :create, :time_entry => {:project_id => '3',
340 post :create, :time_entry => {:project_id => '3',
341 :activity_id => '11',
341 :activity_id => '11',
342 :issue_id => '',
342 :issue_id => '',
343 :spent_on => '2008-03-14',
343 :spent_on => '2008-03-14',
344 :hours => '7.3'}
344 :hours => '7.3'}
345 end
345 end
346
346
347 assert_response 403
347 assert_response 403
348 end
348 end
349
349
350 def test_create_without_project_with_failure
350 def test_create_without_project_with_failure
351 @request.session[:user_id] = 2
351 @request.session[:user_id] = 2
352 assert_no_difference 'TimeEntry.count' do
352 assert_no_difference 'TimeEntry.count' do
353 post :create, :time_entry => {:project_id => '1',
353 post :create, :time_entry => {:project_id => '1',
354 :activity_id => '11',
354 :activity_id => '11',
355 :issue_id => '',
355 :issue_id => '',
356 :spent_on => '2008-03-14',
356 :spent_on => '2008-03-14',
357 :hours => ''}
357 :hours => ''}
358 end
358 end
359
359
360 assert_response :success
360 assert_response :success
361 assert_select 'select[name=?]', 'time_entry[project_id]' do
361 assert_select 'select[name=?]', 'time_entry[project_id]' do
362 assert_select 'option[value="1"][selected=selected]'
362 assert_select 'option[value="1"][selected=selected]'
363 end
363 end
364 end
364 end
365
365
366 def test_update
366 def test_update
367 entry = TimeEntry.find(1)
367 entry = TimeEntry.find(1)
368 assert_equal 1, entry.issue_id
368 assert_equal 1, entry.issue_id
369 assert_equal 2, entry.user_id
369 assert_equal 2, entry.user_id
370
370
371 @request.session[:user_id] = 1
371 @request.session[:user_id] = 1
372 put :update, :id => 1,
372 put :update, :id => 1,
373 :time_entry => {:issue_id => '2',
373 :time_entry => {:issue_id => '2',
374 :hours => '8'}
374 :hours => '8'}
375 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
375 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
376 entry.reload
376 entry.reload
377
377
378 assert_equal 8, entry.hours
378 assert_equal 8, entry.hours
379 assert_equal 2, entry.issue_id
379 assert_equal 2, entry.issue_id
380 assert_equal 2, entry.user_id
380 assert_equal 2, entry.user_id
381 end
381 end
382
382
383 def test_update_should_allow_to_change_issue_to_another_project
383 def test_update_should_allow_to_change_issue_to_another_project
384 entry = TimeEntry.generate!(:issue_id => 1)
384 entry = TimeEntry.generate!(:issue_id => 1)
385
385
386 @request.session[:user_id] = 1
386 @request.session[:user_id] = 1
387 put :update, :id => entry.id, :time_entry => {:issue_id => '5'}
387 put :update, :id => entry.id, :time_entry => {:issue_id => '5'}
388 assert_response 302
388 assert_response 302
389 entry.reload
389 entry.reload
390
390
391 assert_equal 5, entry.issue_id
391 assert_equal 5, entry.issue_id
392 assert_equal 3, entry.project_id
392 assert_equal 3, entry.project_id
393 end
393 end
394
394
395 def test_update_should_not_allow_to_change_issue_to_an_invalid_project
395 def test_update_should_not_allow_to_change_issue_to_an_invalid_project
396 entry = TimeEntry.generate!(:issue_id => 1)
396 entry = TimeEntry.generate!(:issue_id => 1)
397 Project.find(3).disable_module!(:time_tracking)
397 Project.find(3).disable_module!(:time_tracking)
398
398
399 @request.session[:user_id] = 1
399 @request.session[:user_id] = 1
400 put :update, :id => entry.id, :time_entry => {:issue_id => '5'}
400 put :update, :id => entry.id, :time_entry => {:issue_id => '5'}
401 assert_response 200
401 assert_response 200
402 assert_include "Issue is invalid", assigns(:time_entry).errors.full_messages
402 assert_include "Issue is invalid", assigns(:time_entry).errors.full_messages
403 end
403 end
404
404
405 def test_get_bulk_edit
405 def test_get_bulk_edit
406 @request.session[:user_id] = 2
406 @request.session[:user_id] = 2
407 get :bulk_edit, :ids => [1, 2]
407 get :bulk_edit, :ids => [1, 2]
408 assert_response :success
408 assert_response :success
409 assert_template 'bulk_edit'
409 assert_template 'bulk_edit'
410
410
411 assert_select 'ul#bulk-selection' do
411 assert_select 'ul#bulk-selection' do
412 assert_select 'li', 2
412 assert_select 'li', 2
413 assert_select 'li a', :text => '03/23/2007 - eCookbook: 4.25 hours'
413 assert_select 'li a', :text => '03/23/2007 - eCookbook: 4.25 hours'
414 end
414 end
415
415
416 assert_select 'form#bulk_edit_form[action=?]', '/time_entries/bulk_update' do
416 assert_select 'form#bulk_edit_form[action=?]', '/time_entries/bulk_update' do
417 # System wide custom field
417 # System wide custom field
418 assert_select 'select[name=?]', 'time_entry[custom_field_values][10]'
418 assert_select 'select[name=?]', 'time_entry[custom_field_values][10]'
419
419
420 # Activities
420 # Activities
421 assert_select 'select[name=?]', 'time_entry[activity_id]' do
421 assert_select 'select[name=?]', 'time_entry[activity_id]' do
422 assert_select 'option[value=""]', :text => '(No change)'
422 assert_select 'option[value=""]', :text => '(No change)'
423 assert_select 'option[value="9"]', :text => 'Design'
423 assert_select 'option[value="9"]', :text => 'Design'
424 end
424 end
425 end
425 end
426 end
426 end
427
427
428 def test_get_bulk_edit_on_different_projects
428 def test_get_bulk_edit_on_different_projects
429 @request.session[:user_id] = 2
429 @request.session[:user_id] = 2
430 get :bulk_edit, :ids => [1, 2, 6]
430 get :bulk_edit, :ids => [1, 2, 6]
431 assert_response :success
431 assert_response :success
432 assert_template 'bulk_edit'
432 assert_template 'bulk_edit'
433 end
433 end
434
434
435 def test_bulk_edit_with_edit_own_time_entries_permission
435 def test_bulk_edit_with_edit_own_time_entries_permission
436 @request.session[:user_id] = 2
436 @request.session[:user_id] = 2
437 Role.find_by_name('Manager').remove_permission! :edit_time_entries
437 Role.find_by_name('Manager').remove_permission! :edit_time_entries
438 Role.find_by_name('Manager').add_permission! :edit_own_time_entries
438 Role.find_by_name('Manager').add_permission! :edit_own_time_entries
439 ids = (0..1).map {TimeEntry.generate!(:user => User.find(2)).id}
439 ids = (0..1).map {TimeEntry.generate!(:user => User.find(2)).id}
440
440
441 get :bulk_edit, :ids => ids
441 get :bulk_edit, :ids => ids
442 assert_response :success
442 assert_response :success
443 end
443 end
444
444
445 def test_bulk_update
445 def test_bulk_update
446 @request.session[:user_id] = 2
446 @request.session[:user_id] = 2
447 # update time entry activity
447 # update time entry activity
448 post :bulk_update, :ids => [1, 2], :time_entry => { :activity_id => 9}
448 post :bulk_update, :ids => [1, 2], :time_entry => { :activity_id => 9}
449
449
450 assert_response 302
450 assert_response 302
451 # check that the issues were updated
451 # check that the issues were updated
452 assert_equal [9, 9], TimeEntry.where(:id => [1, 2]).collect {|i| i.activity_id}
452 assert_equal [9, 9], TimeEntry.where(:id => [1, 2]).collect {|i| i.activity_id}
453 end
453 end
454
454
455 def test_bulk_update_with_failure
455 def test_bulk_update_with_failure
456 @request.session[:user_id] = 2
456 @request.session[:user_id] = 2
457 post :bulk_update, :ids => [1, 2], :time_entry => { :hours => 'A'}
457 post :bulk_update, :ids => [1, 2], :time_entry => { :hours => 'A'}
458
458
459 assert_response 302
459 assert_response 302
460 assert_match /Failed to save 2 time entrie/, flash[:error]
460 assert_match /Failed to save 2 time entrie/, flash[:error]
461 end
461 end
462
462
463 def test_bulk_update_on_different_projects
463 def test_bulk_update_on_different_projects
464 @request.session[:user_id] = 2
464 @request.session[:user_id] = 2
465 # makes user a manager on the other project
465 # makes user a manager on the other project
466 Member.create!(:user_id => 2, :project_id => 3, :role_ids => [1])
466 Member.create!(:user_id => 2, :project_id => 3, :role_ids => [1])
467
467
468 # update time entry activity
468 # update time entry activity
469 post :bulk_update, :ids => [1, 2, 4], :time_entry => { :activity_id => 9 }
469 post :bulk_update, :ids => [1, 2, 4], :time_entry => { :activity_id => 9 }
470
470
471 assert_response 302
471 assert_response 302
472 # check that the issues were updated
472 # check that the issues were updated
473 assert_equal [9, 9, 9], TimeEntry.where(:id => [1, 2, 4]).collect {|i| i.activity_id}
473 assert_equal [9, 9, 9], TimeEntry.where(:id => [1, 2, 4]).collect {|i| i.activity_id}
474 end
474 end
475
475
476 def test_bulk_update_on_different_projects_without_rights
476 def test_bulk_update_on_different_projects_without_rights
477 @request.session[:user_id] = 3
477 @request.session[:user_id] = 3
478 user = User.find(3)
478 user = User.find(3)
479 action = { :controller => "timelog", :action => "bulk_update" }
479 action = { :controller => "timelog", :action => "bulk_update" }
480 assert user.allowed_to?(action, TimeEntry.find(1).project)
480 assert user.allowed_to?(action, TimeEntry.find(1).project)
481 assert ! user.allowed_to?(action, TimeEntry.find(5).project)
481 assert ! user.allowed_to?(action, TimeEntry.find(5).project)
482 post :bulk_update, :ids => [1, 5], :time_entry => { :activity_id => 9 }
482 post :bulk_update, :ids => [1, 5], :time_entry => { :activity_id => 9 }
483 assert_response 403
483 assert_response 403
484 end
484 end
485
485
486 def test_bulk_update_with_edit_own_time_entries_permission
486 def test_bulk_update_with_edit_own_time_entries_permission
487 @request.session[:user_id] = 2
487 @request.session[:user_id] = 2
488 Role.find_by_name('Manager').remove_permission! :edit_time_entries
488 Role.find_by_name('Manager').remove_permission! :edit_time_entries
489 Role.find_by_name('Manager').add_permission! :edit_own_time_entries
489 Role.find_by_name('Manager').add_permission! :edit_own_time_entries
490 ids = (0..1).map {TimeEntry.generate!(:user => User.find(2)).id}
490 ids = (0..1).map {TimeEntry.generate!(:user => User.find(2)).id}
491
491
492 post :bulk_update, :ids => ids, :time_entry => { :activity_id => 9 }
492 post :bulk_update, :ids => ids, :time_entry => { :activity_id => 9 }
493 assert_response 302
493 assert_response 302
494 end
494 end
495
495
496 def test_bulk_update_with_edit_own_time_entries_permissions_should_be_denied_for_time_entries_of_other_user
496 def test_bulk_update_with_edit_own_time_entries_permissions_should_be_denied_for_time_entries_of_other_user
497 @request.session[:user_id] = 2
497 @request.session[:user_id] = 2
498 Role.find_by_name('Manager').remove_permission! :edit_time_entries
498 Role.find_by_name('Manager').remove_permission! :edit_time_entries
499 Role.find_by_name('Manager').add_permission! :edit_own_time_entries
499 Role.find_by_name('Manager').add_permission! :edit_own_time_entries
500
500
501 post :bulk_update, :ids => [1, 2], :time_entry => { :activity_id => 9 }
501 post :bulk_update, :ids => [1, 2], :time_entry => { :activity_id => 9 }
502 assert_response 403
502 assert_response 403
503 end
503 end
504
504
505 def test_bulk_update_custom_field
505 def test_bulk_update_custom_field
506 @request.session[:user_id] = 2
506 @request.session[:user_id] = 2
507 post :bulk_update, :ids => [1, 2], :time_entry => { :custom_field_values => {'10' => '0'} }
507 post :bulk_update, :ids => [1, 2], :time_entry => { :custom_field_values => {'10' => '0'} }
508
508
509 assert_response 302
509 assert_response 302
510 assert_equal ["0", "0"], TimeEntry.where(:id => [1, 2]).collect {|i| i.custom_value_for(10).value}
510 assert_equal ["0", "0"], TimeEntry.where(:id => [1, 2]).collect {|i| i.custom_value_for(10).value}
511 end
511 end
512
512
513 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
513 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
514 @request.session[:user_id] = 2
514 @request.session[:user_id] = 2
515 post :bulk_update, :ids => [1,2], :back_url => '/time_entries'
515 post :bulk_update, :ids => [1,2], :back_url => '/time_entries'
516
516
517 assert_response :redirect
517 assert_response :redirect
518 assert_redirected_to '/time_entries'
518 assert_redirected_to '/time_entries'
519 end
519 end
520
520
521 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
521 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
522 @request.session[:user_id] = 2
522 @request.session[:user_id] = 2
523 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
523 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
524
524
525 assert_response :redirect
525 assert_response :redirect
526 assert_redirected_to :controller => 'timelog', :action => 'index', :project_id => Project.find(1).identifier
526 assert_redirected_to :controller => 'timelog', :action => 'index', :project_id => Project.find(1).identifier
527 end
527 end
528
528
529 def test_post_bulk_update_without_edit_permission_should_be_denied
529 def test_post_bulk_update_without_edit_permission_should_be_denied
530 @request.session[:user_id] = 2
530 @request.session[:user_id] = 2
531 Role.find_by_name('Manager').remove_permission! :edit_time_entries
531 Role.find_by_name('Manager').remove_permission! :edit_time_entries
532 post :bulk_update, :ids => [1,2]
532 post :bulk_update, :ids => [1,2]
533
533
534 assert_response 403
534 assert_response 403
535 end
535 end
536
536
537 def test_destroy
537 def test_destroy
538 @request.session[:user_id] = 2
538 @request.session[:user_id] = 2
539 delete :destroy, :id => 1
539 delete :destroy, :id => 1
540 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
540 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
541 assert_equal I18n.t(:notice_successful_delete), flash[:notice]
541 assert_equal I18n.t(:notice_successful_delete), flash[:notice]
542 assert_nil TimeEntry.find_by_id(1)
542 assert_nil TimeEntry.find_by_id(1)
543 end
543 end
544
544
545 def test_destroy_should_fail
545 def test_destroy_should_fail
546 # simulate that this fails (e.g. due to a plugin), see #5700
546 # simulate that this fails (e.g. due to a plugin), see #5700
547 TimeEntry.any_instance.expects(:destroy).returns(false)
547 TimeEntry.any_instance.expects(:destroy).returns(false)
548
548
549 @request.session[:user_id] = 2
549 @request.session[:user_id] = 2
550 delete :destroy, :id => 1
550 delete :destroy, :id => 1
551 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
551 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
552 assert_equal I18n.t(:notice_unable_delete_time_entry), flash[:error]
552 assert_equal I18n.t(:notice_unable_delete_time_entry), flash[:error]
553 assert_not_nil TimeEntry.find_by_id(1)
553 assert_not_nil TimeEntry.find_by_id(1)
554 end
554 end
555
555
556 def test_index_all_projects
556 def test_index_all_projects
557 get :index
557 get :index
558 assert_response :success
558 assert_response :success
559 assert_template 'index'
559 assert_template 'index'
560 assert_not_nil assigns(:total_hours)
560 assert_not_nil assigns(:total_hours)
561 assert_equal "162.90", "%.2f" % assigns(:total_hours)
561 assert_equal "162.90", "%.2f" % assigns(:total_hours)
562 assert_select 'form#query_form[action=?]', '/time_entries'
562 assert_select 'form#query_form[action=?]', '/time_entries'
563 end
563 end
564
564
565 def test_index_all_projects_should_show_log_time_link
565 def test_index_all_projects_should_show_log_time_link
566 @request.session[:user_id] = 2
566 @request.session[:user_id] = 2
567 get :index
567 get :index
568 assert_response :success
568 assert_response :success
569 assert_template 'index'
569 assert_template 'index'
570 assert_select 'a[href=?]', '/time_entries/new', :text => /Log time/
570 assert_select 'a[href=?]', '/time_entries/new', :text => /Log time/
571 end
571 end
572
572
573 def test_index_my_spent_time
573 def test_index_my_spent_time
574 @request.session[:user_id] = 2
574 @request.session[:user_id] = 2
575 get :index, :user_id => 'me'
575 get :index, :user_id => 'me'
576 assert_response :success
576 assert_response :success
577 assert_template 'index'
577 assert_template 'index'
578 assert assigns(:entries).all? {|entry| entry.user_id == 2}
578 assert assigns(:entries).all? {|entry| entry.user_id == 2}
579 end
579 end
580
580
581 def test_index_at_project_level
581 def test_index_at_project_level
582 get :index, :project_id => 'ecookbook'
582 get :index, :project_id => 'ecookbook'
583 assert_response :success
583 assert_response :success
584 assert_template 'index'
584 assert_template 'index'
585 assert_not_nil assigns(:entries)
585 assert_not_nil assigns(:entries)
586 assert_equal 4, assigns(:entries).size
586 assert_equal 4, assigns(:entries).size
587 # project and subproject
587 # project and subproject
588 assert_equal [1, 3], assigns(:entries).collect(&:project_id).uniq.sort
588 assert_equal [1, 3], assigns(:entries).collect(&:project_id).uniq.sort
589 assert_not_nil assigns(:total_hours)
589 assert_not_nil assigns(:total_hours)
590 assert_equal "162.90", "%.2f" % assigns(:total_hours)
590 assert_equal "162.90", "%.2f" % assigns(:total_hours)
591 assert_select 'form#query_form[action=?]', '/projects/ecookbook/time_entries'
591 assert_select 'form#query_form[action=?]', '/projects/ecookbook/time_entries'
592 end
592 end
593
593
594 def test_index_with_display_subprojects_issues_to_false_should_not_include_subproject_entries
594 def test_index_with_display_subprojects_issues_to_false_should_not_include_subproject_entries
595 entry = TimeEntry.generate!(:project => Project.find(3))
595 entry = TimeEntry.generate!(:project => Project.find(3))
596
596
597 with_settings :display_subprojects_issues => '0' do
597 with_settings :display_subprojects_issues => '0' do
598 get :index, :project_id => 'ecookbook'
598 get :index, :project_id => 'ecookbook'
599 assert_response :success
599 assert_response :success
600 assert_template 'index'
600 assert_template 'index'
601 assert_not_include entry, assigns(:entries)
601 assert_not_include entry, assigns(:entries)
602 end
602 end
603 end
603 end
604
604
605 def test_index_with_display_subprojects_issues_to_false_and_subproject_filter_should_include_subproject_entries
605 def test_index_with_display_subprojects_issues_to_false_and_subproject_filter_should_include_subproject_entries
606 entry = TimeEntry.generate!(:project => Project.find(3))
606 entry = TimeEntry.generate!(:project => Project.find(3))
607
607
608 with_settings :display_subprojects_issues => '0' do
608 with_settings :display_subprojects_issues => '0' do
609 get :index, :project_id => 'ecookbook', :subproject_id => 3
609 get :index, :project_id => 'ecookbook', :subproject_id => 3
610 assert_response :success
610 assert_response :success
611 assert_template 'index'
611 assert_template 'index'
612 assert_include entry, assigns(:entries)
612 assert_include entry, assigns(:entries)
613 end
613 end
614 end
614 end
615
615
616 def test_index_at_project_level_with_date_range
616 def test_index_at_project_level_with_date_range
617 get :index, :project_id => 'ecookbook',
617 get :index, :project_id => 'ecookbook',
618 :f => ['spent_on'],
618 :f => ['spent_on'],
619 :op => {'spent_on' => '><'},
619 :op => {'spent_on' => '><'},
620 :v => {'spent_on' => ['2007-03-20', '2007-04-30']}
620 :v => {'spent_on' => ['2007-03-20', '2007-04-30']}
621 assert_response :success
621 assert_response :success
622 assert_template 'index'
622 assert_template 'index'
623 assert_not_nil assigns(:entries)
623 assert_not_nil assigns(:entries)
624 assert_equal 3, assigns(:entries).size
624 assert_equal 3, assigns(:entries).size
625 assert_not_nil assigns(:total_hours)
625 assert_not_nil assigns(:total_hours)
626 assert_equal "12.90", "%.2f" % assigns(:total_hours)
626 assert_equal "12.90", "%.2f" % assigns(:total_hours)
627 assert_select 'form#query_form[action=?]', '/projects/ecookbook/time_entries'
627 assert_select 'form#query_form[action=?]', '/projects/ecookbook/time_entries'
628 end
628 end
629
629
630 def test_index_at_project_level_with_date_range_using_from_and_to_params
630 def test_index_at_project_level_with_date_range_using_from_and_to_params
631 get :index, :project_id => 'ecookbook', :from => '2007-03-20', :to => '2007-04-30'
631 get :index, :project_id => 'ecookbook', :from => '2007-03-20', :to => '2007-04-30'
632 assert_response :success
632 assert_response :success
633 assert_template 'index'
633 assert_template 'index'
634 assert_not_nil assigns(:entries)
634 assert_not_nil assigns(:entries)
635 assert_equal 3, assigns(:entries).size
635 assert_equal 3, assigns(:entries).size
636 assert_not_nil assigns(:total_hours)
636 assert_not_nil assigns(:total_hours)
637 assert_equal "12.90", "%.2f" % assigns(:total_hours)
637 assert_equal "12.90", "%.2f" % assigns(:total_hours)
638 assert_select 'form#query_form[action=?]', '/projects/ecookbook/time_entries'
638 assert_select 'form#query_form[action=?]', '/projects/ecookbook/time_entries'
639 end
639 end
640
640
641 def test_index_at_project_level_with_period
641 def test_index_at_project_level_with_period
642 get :index, :project_id => 'ecookbook',
642 get :index, :project_id => 'ecookbook',
643 :f => ['spent_on'],
643 :f => ['spent_on'],
644 :op => {'spent_on' => '>t-'},
644 :op => {'spent_on' => '>t-'},
645 :v => {'spent_on' => ['7']}
645 :v => {'spent_on' => ['7']}
646 assert_response :success
646 assert_response :success
647 assert_template 'index'
647 assert_template 'index'
648 assert_not_nil assigns(:entries)
648 assert_not_nil assigns(:entries)
649 assert_not_nil assigns(:total_hours)
649 assert_not_nil assigns(:total_hours)
650 assert_select 'form#query_form[action=?]', '/projects/ecookbook/time_entries'
650 assert_select 'form#query_form[action=?]', '/projects/ecookbook/time_entries'
651 end
651 end
652
652
653 def test_index_at_issue_level
653 def test_index_at_issue_level
654 get :index, :issue_id => 1
654 get :index, :issue_id => 1
655 assert_response :success
655 assert_response :success
656 assert_template 'index'
656 assert_template 'index'
657 assert_not_nil assigns(:entries)
657 assert_not_nil assigns(:entries)
658 assert_equal 2, assigns(:entries).size
658 assert_equal 2, assigns(:entries).size
659 assert_not_nil assigns(:total_hours)
659 assert_not_nil assigns(:total_hours)
660 assert_equal 154.25, assigns(:total_hours)
660 assert_equal 154.25, assigns(:total_hours)
661 # display all time
661 # display all time
662 assert_nil assigns(:from)
662 assert_nil assigns(:from)
663 assert_nil assigns(:to)
663 assert_nil assigns(:to)
664 assert_select 'form#query_form[action=?]', '/issues/1/time_entries'
664 assert_select 'form#query_form[action=?]', '/issues/1/time_entries'
665 end
665 end
666
666
667 def test_index_should_sort_by_spent_on_and_created_on
667 def test_index_should_sort_by_spent_on_and_created_on
668 t1 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-16', :created_on => '2012-06-16 20:00:00', :activity_id => 10)
668 t1 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-16', :created_on => '2012-06-16 20:00:00', :activity_id => 10)
669 t2 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-16', :created_on => '2012-06-16 20:05:00', :activity_id => 10)
669 t2 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-16', :created_on => '2012-06-16 20:05:00', :activity_id => 10)
670 t3 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-15', :created_on => '2012-06-16 20:10:00', :activity_id => 10)
670 t3 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-15', :created_on => '2012-06-16 20:10:00', :activity_id => 10)
671
671
672 get :index, :project_id => 1,
672 get :index, :project_id => 1,
673 :f => ['spent_on'],
673 :f => ['spent_on'],
674 :op => {'spent_on' => '><'},
674 :op => {'spent_on' => '><'},
675 :v => {'spent_on' => ['2012-06-15', '2012-06-16']}
675 :v => {'spent_on' => ['2012-06-15', '2012-06-16']}
676 assert_response :success
676 assert_response :success
677 assert_equal [t2, t1, t3], assigns(:entries)
677 assert_equal [t2, t1, t3], assigns(:entries)
678
678
679 get :index, :project_id => 1,
679 get :index, :project_id => 1,
680 :f => ['spent_on'],
680 :f => ['spent_on'],
681 :op => {'spent_on' => '><'},
681 :op => {'spent_on' => '><'},
682 :v => {'spent_on' => ['2012-06-15', '2012-06-16']},
682 :v => {'spent_on' => ['2012-06-15', '2012-06-16']},
683 :sort => 'spent_on'
683 :sort => 'spent_on'
684 assert_response :success
684 assert_response :success
685 assert_equal [t3, t1, t2], assigns(:entries)
685 assert_equal [t3, t1, t2], assigns(:entries)
686 end
686 end
687
687
688 def test_index_with_filter_on_issue_custom_field
688 def test_index_with_filter_on_issue_custom_field
689 issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {2 => 'filter_on_issue_custom_field'})
689 issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {2 => 'filter_on_issue_custom_field'})
690 entry = TimeEntry.generate!(:issue => issue, :hours => 2.5)
690 entry = TimeEntry.generate!(:issue => issue, :hours => 2.5)
691
691
692 get :index, :f => ['issue.cf_2'], :op => {'issue.cf_2' => '='}, :v => {'issue.cf_2' => ['filter_on_issue_custom_field']}
692 get :index, :f => ['issue.cf_2'], :op => {'issue.cf_2' => '='}, :v => {'issue.cf_2' => ['filter_on_issue_custom_field']}
693 assert_response :success
693 assert_response :success
694 assert_equal [entry], assigns(:entries)
694 assert_equal [entry], assigns(:entries)
695 end
695 end
696
696
697 def test_index_with_issue_custom_field_column
697 def test_index_with_issue_custom_field_column
698 issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {2 => 'filter_on_issue_custom_field'})
698 issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {2 => 'filter_on_issue_custom_field'})
699 entry = TimeEntry.generate!(:issue => issue, :hours => 2.5)
699 entry = TimeEntry.generate!(:issue => issue, :hours => 2.5)
700
700
701 get :index, :c => %w(project spent_on issue comments hours issue.cf_2)
701 get :index, :c => %w(project spent_on issue comments hours issue.cf_2)
702 assert_response :success
702 assert_response :success
703 assert_include :'issue.cf_2', assigns(:query).column_names
703 assert_include :'issue.cf_2', assigns(:query).column_names
704 assert_select 'td.issue_cf_2', :text => 'filter_on_issue_custom_field'
704 assert_select 'td.issue_cf_2', :text => 'filter_on_issue_custom_field'
705 end
705 end
706
706
707 def test_index_with_time_entry_custom_field_column
707 def test_index_with_time_entry_custom_field_column
708 field = TimeEntryCustomField.generate!(:field_format => 'string')
708 field = TimeEntryCustomField.generate!(:field_format => 'string')
709 entry = TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value'})
709 entry = TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value'})
710 field_name = "cf_#{field.id}"
710 field_name = "cf_#{field.id}"
711
711
712 get :index, :c => ["hours", field_name]
712 get :index, :c => ["hours", field_name]
713 assert_response :success
713 assert_response :success
714 assert_include field_name.to_sym, assigns(:query).column_names
714 assert_include field_name.to_sym, assigns(:query).column_names
715 assert_select "td.#{field_name}", :text => 'CF Value'
715 assert_select "td.#{field_name}", :text => 'CF Value'
716 end
716 end
717
717
718 def test_index_with_time_entry_custom_field_sorting
718 def test_index_with_time_entry_custom_field_sorting
719 field = TimeEntryCustomField.generate!(:field_format => 'string', :name => 'String Field')
719 field = TimeEntryCustomField.generate!(:field_format => 'string', :name => 'String Field')
720 TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 1'})
720 TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 1'})
721 TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 3'})
721 TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 3'})
722 TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 2'})
722 TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 2'})
723 field_name = "cf_#{field.id}"
723 field_name = "cf_#{field.id}"
724
724
725 get :index, :c => ["hours", field_name], :sort => field_name
725 get :index, :c => ["hours", field_name], :sort => field_name
726 assert_response :success
726 assert_response :success
727 assert_include field_name.to_sym, assigns(:query).column_names
727 assert_include field_name.to_sym, assigns(:query).column_names
728 assert_select "th a.sort", :text => 'String Field'
728 assert_select "th a.sort", :text => 'String Field'
729
729
730 # Make sure that values are properly sorted
730 # Make sure that values are properly sorted
731 values = assigns(:entries).map {|e| e.custom_field_value(field)}.compact
731 values = assigns(:entries).map {|e| e.custom_field_value(field)}.compact
732 assert_equal 3, values.size
732 assert_equal 3, values.size
733 assert_equal values.sort, values
733 assert_equal values.sort, values
734 end
734 end
735
735
736 def test_index_atom_feed
736 def test_index_atom_feed
737 get :index, :project_id => 1, :format => 'atom'
737 get :index, :project_id => 1, :format => 'atom'
738 assert_response :success
738 assert_response :success
739 assert_equal 'application/atom+xml', @response.content_type
739 assert_equal 'application/atom+xml', @response.content_type
740 assert_not_nil assigns(:items)
740 assert_not_nil assigns(:items)
741 assert assigns(:items).first.is_a?(TimeEntry)
741 assert assigns(:items).first.is_a?(TimeEntry)
742 end
742 end
743
743
744 def test_index_at_project_level_should_include_csv_export_dialog
744 def test_index_at_project_level_should_include_csv_export_dialog
745 get :index, :project_id => 'ecookbook',
745 get :index, :project_id => 'ecookbook',
746 :f => ['spent_on'],
746 :f => ['spent_on'],
747 :op => {'spent_on' => '>='},
747 :op => {'spent_on' => '>='},
748 :v => {'spent_on' => ['2007-04-01']},
748 :v => {'spent_on' => ['2007-04-01']},
749 :c => ['spent_on', 'user']
749 :c => ['spent_on', 'user']
750 assert_response :success
750 assert_response :success
751
751
752 assert_select '#csv-export-options' do
752 assert_select '#csv-export-options' do
753 assert_select 'form[action=?][method=get]', '/projects/ecookbook/time_entries.csv' do
753 assert_select 'form[action=?][method=get]', '/projects/ecookbook/time_entries.csv' do
754 # filter
754 # filter
755 assert_select 'input[name=?][value=?]', 'f[]', 'spent_on'
755 assert_select 'input[name=?][value=?]', 'f[]', 'spent_on'
756 assert_select 'input[name=?][value=?]', 'op[spent_on]', '>='
756 assert_select 'input[name=?][value=?]', 'op[spent_on]', '>='
757 assert_select 'input[name=?][value=?]', 'v[spent_on][]', '2007-04-01'
757 assert_select 'input[name=?][value=?]', 'v[spent_on][]', '2007-04-01'
758 # columns
758 # columns
759 assert_select 'input[name=?][value=?]', 'c[]', 'spent_on'
759 assert_select 'input[name=?][value=?]', 'c[]', 'spent_on'
760 assert_select 'input[name=?][value=?]', 'c[]', 'user'
760 assert_select 'input[name=?][value=?]', 'c[]', 'user'
761 assert_select 'input[name=?]', 'c[]', 2
761 assert_select 'input[name=?]', 'c[]', 2
762 end
762 end
763 end
763 end
764 end
764 end
765
765
766 def test_index_cross_project_should_include_csv_export_dialog
766 def test_index_cross_project_should_include_csv_export_dialog
767 get :index
767 get :index
768 assert_response :success
768 assert_response :success
769
769
770 assert_select '#csv-export-options' do
770 assert_select '#csv-export-options' do
771 assert_select 'form[action=?][method=get]', '/time_entries.csv'
771 assert_select 'form[action=?][method=get]', '/time_entries.csv'
772 end
772 end
773 end
773 end
774
774
775 def test_index_at_issue_level_should_include_csv_export_dialog
775 def test_index_at_issue_level_should_include_csv_export_dialog
776 get :index, :issue_id => 3
776 get :index, :issue_id => 3
777 assert_response :success
777 assert_response :success
778
778
779 assert_select '#csv-export-options' do
779 assert_select '#csv-export-options' do
780 assert_select 'form[action=?][method=get]', '/issues/3/time_entries.csv'
780 assert_select 'form[action=?][method=get]', '/issues/3/time_entries.csv'
781 end
781 end
782 end
782 end
783
783
784 def test_index_csv_all_projects
784 def test_index_csv_all_projects
785 with_settings :date_format => '%m/%d/%Y' do
785 with_settings :date_format => '%m/%d/%Y' do
786 get :index, :format => 'csv'
786 get :index, :format => 'csv'
787 assert_response :success
787 assert_response :success
788 assert_equal 'text/csv; header=present', response.content_type
788 assert_equal 'text/csv; header=present', response.content_type
789 end
789 end
790 end
790 end
791
791
792 def test_index_csv
792 def test_index_csv
793 with_settings :date_format => '%m/%d/%Y' do
793 with_settings :date_format => '%m/%d/%Y' do
794 get :index, :project_id => 1, :format => 'csv'
794 get :index, :project_id => 1, :format => 'csv'
795 assert_response :success
795 assert_response :success
796 assert_equal 'text/csv; header=present', response.content_type
796 assert_equal 'text/csv; header=present', response.content_type
797 end
797 end
798 end
798 end
799
799
800 def test_index_csv_should_fill_issue_column_with_tracker_id_and_subject
800 def test_index_csv_should_fill_issue_column_with_tracker_id_and_subject
801 issue = Issue.find(1)
801 issue = Issue.find(1)
802 entry = TimeEntry.generate!(:issue => issue, :comments => "Issue column content test")
802 entry = TimeEntry.generate!(:issue => issue, :comments => "Issue column content test")
803
803
804 get :index, :format => 'csv'
804 get :index, :format => 'csv'
805 line = response.body.split("\n").detect {|l| l.include?(entry.comments)}
805 line = response.body.split("\n").detect {|l| l.include?(entry.comments)}
806 assert_not_nil line
806 assert_not_nil line
807 assert_include "#{issue.tracker} #1: #{issue.subject}", line
807 assert_include "#{issue.tracker} #1: #{issue.subject}", line
808 end
808 end
809 end
809 end
@@ -1,123 +1,123
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class TimeEntryActivityTest < ActiveSupport::TestCase
20 class TimeEntryActivityTest < ActiveSupport::TestCase
21 fixtures :enumerations, :time_entries, :custom_fields,
21 fixtures :enumerations, :time_entries, :custom_fields,
22 :issues, :projects, :users,
22 :issues, :projects, :users,
23 :members, :roles, :member_roles,
23 :members, :roles, :member_roles,
24 :trackers, :issue_statuses,
24 :trackers, :issue_statuses,
25 :projects_trackers,
25 :projects_trackers,
26 :issue_categories,
26 :issue_categories,
27 :groups_users,
27 :groups_users,
28 :enabled_modules
28 :enabled_modules
29
29
30 include Redmine::I18n
30 include Redmine::I18n
31
31
32 def test_should_be_an_enumeration
32 def test_should_be_an_enumeration
33 assert TimeEntryActivity.ancestors.include?(Enumeration)
33 assert TimeEntryActivity.ancestors.include?(Enumeration)
34 end
34 end
35
35
36 def test_objects_count
36 def test_objects_count
37 assert_equal 3, TimeEntryActivity.find_by_name("Design").objects_count
37 assert_equal 3, TimeEntryActivity.find_by_name("Design").objects_count
38 assert_equal 2, TimeEntryActivity.find_by_name("Development").objects_count
38 assert_equal 2, TimeEntryActivity.find_by_name("Development").objects_count
39 end
39 end
40
40
41 def test_option_name
41 def test_option_name
42 assert_equal :enumeration_activities, TimeEntryActivity.new.option_name
42 assert_equal :enumeration_activities, TimeEntryActivity.new.option_name
43 end
43 end
44
44
45 def test_create_with_custom_field
45 def test_create_with_custom_field
46 field = TimeEntryActivityCustomField.find_by_name('Billable')
46 field = TimeEntryActivityCustomField.find_by_name('Billable')
47 e = TimeEntryActivity.new(:name => 'Custom Data')
47 e = TimeEntryActivity.new(:name => 'Custom Data')
48 e.custom_field_values = {field.id => "1"}
48 e.custom_field_values = {field.id => "1"}
49 assert e.save
49 assert e.save
50
50
51 e.reload
51 e.reload
52 assert_equal "1", e.custom_value_for(field).value
52 assert_equal "1", e.custom_value_for(field).value
53 end
53 end
54
54
55 def test_create_without_required_custom_field_should_fail
55 def test_create_without_required_custom_field_should_fail
56 set_language_if_valid 'en'
56 set_language_if_valid 'en'
57 field = TimeEntryActivityCustomField.find_by_name('Billable')
57 field = TimeEntryActivityCustomField.find_by_name('Billable')
58 field.update_attribute(:is_required, true)
58 field.update_attribute(:is_required, true)
59
59
60 e = TimeEntryActivity.new(:name => 'Custom Data')
60 e = TimeEntryActivity.new(:name => 'Custom Data')
61 assert !e.save
61 assert !e.save
62 assert_equal ["Billable cannot be blank"], e.errors.full_messages
62 assert_equal ["Billable cannot be blank"], e.errors.full_messages
63 end
63 end
64
64
65 def test_create_with_required_custom_field_should_succeed
65 def test_create_with_required_custom_field_should_succeed
66 field = TimeEntryActivityCustomField.find_by_name('Billable')
66 field = TimeEntryActivityCustomField.find_by_name('Billable')
67 field.update_attribute(:is_required, true)
67 field.update_attribute(:is_required, true)
68
68
69 e = TimeEntryActivity.new(:name => 'Custom Data')
69 e = TimeEntryActivity.new(:name => 'Custom Data')
70 e.custom_field_values = {field.id => "1"}
70 e.custom_field_values = {field.id => "1"}
71 assert e.save
71 assert e.save
72 end
72 end
73
73
74 def test_update_with_required_custom_field_change
74 def test_update_with_required_custom_field_change
75 set_language_if_valid 'en'
75 set_language_if_valid 'en'
76 field = TimeEntryActivityCustomField.find_by_name('Billable')
76 field = TimeEntryActivityCustomField.find_by_name('Billable')
77 field.update_attribute(:is_required, true)
77 field.update_attribute(:is_required, true)
78
78
79 e = TimeEntryActivity.find(10)
79 e = TimeEntryActivity.find(10)
80 assert e.available_custom_fields.include?(field)
80 assert e.available_custom_fields.include?(field)
81 # No change to custom field, record can be saved
81 # No change to custom field, record can be saved
82 assert e.save
82 assert e.save
83 # Blanking custom field, save should fail
83 # Blanking custom field, save should fail
84 e.custom_field_values = {field.id => ""}
84 e.custom_field_values = {field.id => ""}
85 assert !e.save
85 assert !e.save
86 assert_equal ["Billable cannot be blank"], e.errors.full_messages
86 assert_equal ["Billable cannot be blank"], e.errors.full_messages
87
87
88 # Update custom field to valid value, save should succeed
88 # Update custom field to valid value, save should succeed
89 e.custom_field_values = {field.id => "0"}
89 e.custom_field_values = {field.id => "0"}
90 assert e.save
90 assert e.save
91 e.reload
91 e.reload
92 assert_equal "0", e.custom_value_for(field).value
92 assert_equal "0", e.custom_value_for(field).value
93 end
93 end
94
94
95 def test_system_activity_with_child_in_use_should_be_in_use
95 def test_system_activity_with_child_in_use_should_be_in_use
96 project = Project.generate!
96 project = Project.generate!
97 system_activity = TimeEntryActivity.create!(:name => 'Activity')
97 system_activity = TimeEntryActivity.create!(:name => 'Activity')
98 project_activity = TimeEntryActivity.create!(:name => 'Activity', :project => project, :parent_id => system_activity.id)
98 project_activity = TimeEntryActivity.create!(:name => 'Activity', :project => project, :parent_id => system_activity.id)
99
99
100 TimeEntry.generate!(:project => project, :activity => project_activity)
100 TimeEntry.generate!(:project => project, :activity => project_activity)
101
101
102 assert project_activity.in_use?
102 assert project_activity.in_use?
103 assert system_activity.in_use?
103 assert system_activity.in_use?
104 end
104 end
105
105
106 def test_destroying_a_system_activity_should_reassign_children_activities
106 def test_destroying_a_system_activity_should_reassign_children_activities
107 project = Project.generate!
107 project = Project.generate!
108 entries = []
109
108 system_activity = TimeEntryActivity.create!(:name => 'Activity')
110 system_activity = TimeEntryActivity.create!(:name => 'Activity')
111 entries << TimeEntry.generate!(:project => project, :activity => system_activity)
112
109 project_activity = TimeEntryActivity.create!(:name => 'Activity', :project => project, :parent_id => system_activity.id)
113 project_activity = TimeEntryActivity.create!(:name => 'Activity', :project => project, :parent_id => system_activity.id)
110
114 entries << TimeEntry.generate!(:project => project.reload, :activity => project_activity)
111 entries = [
112 TimeEntry.generate!(:project => project, :activity => system_activity),
113 TimeEntry.generate!(:project => project, :activity => project_activity)
114 ]
115
115
116 assert_difference 'TimeEntryActivity.count', -2 do
116 assert_difference 'TimeEntryActivity.count', -2 do
117 assert_nothing_raised do
117 assert_nothing_raised do
118 assert system_activity.destroy(TimeEntryActivity.find_by_name('Development'))
118 assert system_activity.destroy(TimeEntryActivity.find_by_name('Development'))
119 end
119 end
120 end
120 end
121 assert entries.all? {|entry| entry.reload.activity.name == 'Development'}
121 assert entries.all? {|entry| entry.reload.activity.name == 'Development'}
122 end
122 end
123 end
123 end
@@ -1,47 +1,47
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class TimeEntryQueryTest < ActiveSupport::TestCase
20 class TimeEntryQueryTest < ActiveSupport::TestCase
21 fixtures :issues, :projects, :users,
21 fixtures :issues, :projects, :users,
22 :members, :roles, :member_roles,
22 :members, :roles, :member_roles,
23 :trackers, :issue_statuses,
23 :trackers, :issue_statuses,
24 :projects_trackers,
24 :projects_trackers,
25 :journals, :journal_details,
25 :journals, :journal_details,
26 :issue_categories, :enumerations,
26 :issue_categories, :enumerations,
27 :groups_users,
27 :groups_users,
28 :enabled_modules
28 :enabled_modules
29
29
30 def test_activity_filter_should_consider_system_and_project_activities
30 def test_activity_filter_should_consider_system_and_project_activities
31 TimeEntry.delete_all
31 TimeEntry.delete_all
32 system = TimeEntryActivity.create!(:name => 'Foo')
32 system = TimeEntryActivity.create!(:name => 'Foo')
33 TimeEntry.generate!(:activity => system, :hours => 1.0)
33 override = TimeEntryActivity.create!(:name => 'Foo', :parent_id => system.id, :project_id => 1)
34 override = TimeEntryActivity.create!(:name => 'Foo', :parent_id => system.id, :project_id => 1)
34 other = TimeEntryActivity.create!(:name => 'Bar')
35 other = TimeEntryActivity.create!(:name => 'Bar')
35 TimeEntry.generate!(:activity => system, :hours => 1.0)
36 TimeEntry.generate!(:activity => override, :hours => 2.0)
36 TimeEntry.generate!(:activity => override, :hours => 2.0)
37 TimeEntry.generate!(:activity => other, :hours => 4.0)
37 TimeEntry.generate!(:activity => other, :hours => 4.0)
38
38
39 query = TimeEntryQuery.new(:name => '_')
39 query = TimeEntryQuery.new(:name => '_')
40 query.add_filter('activity_id', '=', [system.id.to_s])
40 query.add_filter('activity_id', '=', [system.id.to_s])
41 assert_equal 3.0, query.results_scope.sum(:hours)
41 assert_equal 3.0, query.results_scope.sum(:hours)
42
42
43 query = TimeEntryQuery.new(:name => '_')
43 query = TimeEntryQuery.new(:name => '_')
44 query.add_filter('activity_id', '!', [system.id.to_s])
44 query.add_filter('activity_id', '!', [system.id.to_s])
45 assert_equal 4.0, query.results_scope.sum(:hours)
45 assert_equal 4.0, query.results_scope.sum(:hours)
46 end
46 end
47 end
47 end
General Comments 0
You need to be logged in to leave comments. Login now