##// END OF EJS Templates
Removes #move_to= (#12909)....
Jean-Philippe Lang -
r14957:39ff11ba06a7
parent child
Show More
@@ -1,134 +1,118
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 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 module Redmine
18 module Redmine
19 module Acts
19 module Acts
20 module Positioned
20 module Positioned
21 def self.included(base)
21 def self.included(base)
22 base.extend ClassMethods
22 base.extend ClassMethods
23 end
23 end
24
24
25 # This extension provides the capabilities for reordering objects in a list.
25 # This extension provides the capabilities for reordering objects in a list.
26 # The class needs to have a +position+ column defined as an integer on the
26 # The class needs to have a +position+ column defined as an integer on the
27 # mapped database table.
27 # mapped database table.
28 module ClassMethods
28 module ClassMethods
29 # Configuration options are:
29 # Configuration options are:
30 #
30 #
31 # * +scope+ - restricts what is to be considered a list. Must be a symbol
31 # * +scope+ - restricts what is to be considered a list. Must be a symbol
32 # or an array of symbols
32 # or an array of symbols
33 def acts_as_positioned(options = {})
33 def acts_as_positioned(options = {})
34 class_attribute :positioned_options
34 class_attribute :positioned_options
35 self.positioned_options = {:scope => Array(options[:scope])}
35 self.positioned_options = {:scope => Array(options[:scope])}
36
36
37 send :include, Redmine::Acts::Positioned::InstanceMethods
37 send :include, Redmine::Acts::Positioned::InstanceMethods
38
38
39 before_save :set_default_position
39 before_save :set_default_position
40 after_save :update_position
40 after_save :update_position
41 after_destroy :remove_position
41 after_destroy :remove_position
42 end
42 end
43 end
43 end
44
44
45 module InstanceMethods
45 module InstanceMethods
46 def self.included(base)
46 def self.included(base)
47 base.extend ClassMethods
47 base.extend ClassMethods
48 end
48 end
49
49
50 # Move to the given position
51 # For compatibility with the previous way of sorting items
52 def move_to=(pos)
53 case pos.to_s
54 when 'highest'
55 self.position = 1
56 when 'higher'
57 self.position -= 1 if position > 1
58 when 'lower'
59 self.position += 1
60 when 'lowest'
61 self.position = nil
62 set_default_position
63 end
64 end
65
66 private
50 private
67
51
68 def position_scope
52 def position_scope
69 build_position_scope {|c| send(c)}
53 build_position_scope {|c| send(c)}
70 end
54 end
71
55
72 def position_scope_was
56 def position_scope_was
73 build_position_scope {|c| send("#{c}_was")}
57 build_position_scope {|c| send("#{c}_was")}
74 end
58 end
75
59
76 def build_position_scope
60 def build_position_scope
77 condition_hash = self.class.positioned_options[:scope].inject({}) do |h, column|
61 condition_hash = self.class.positioned_options[:scope].inject({}) do |h, column|
78 h[column] = yield(column)
62 h[column] = yield(column)
79 h
63 h
80 end
64 end
81 self.class.where(condition_hash)
65 self.class.where(condition_hash)
82 end
66 end
83
67
84 def set_default_position
68 def set_default_position
85 if position.nil?
69 if position.nil?
86 self.position = position_scope.maximum(:position).to_i + (new_record? ? 1 : 0)
70 self.position = position_scope.maximum(:position).to_i + (new_record? ? 1 : 0)
87 end
71 end
88 end
72 end
89
73
90 def update_position
74 def update_position
91 if !new_record? && position_scope_changed?
75 if !new_record? && position_scope_changed?
92 remove_position
76 remove_position
93 insert_position
77 insert_position
94 elsif position_changed?
78 elsif position_changed?
95 if position_was.nil?
79 if position_was.nil?
96 insert_position
80 insert_position
97 else
81 else
98 shift_positions
82 shift_positions
99 end
83 end
100 end
84 end
101 end
85 end
102
86
103 def insert_position
87 def insert_position
104 position_scope.where("position >= ? AND id <> ?", position, id).update_all("position = position + 1")
88 position_scope.where("position >= ? AND id <> ?", position, id).update_all("position = position + 1")
105 end
89 end
106
90
107 def remove_position
91 def remove_position
108 position_scope_was.where("position >= ? AND id <> ?", position_was, id).update_all("position = position - 1")
92 position_scope_was.where("position >= ? AND id <> ?", position_was, id).update_all("position = position - 1")
109 end
93 end
110
94
111 def position_scope_changed?
95 def position_scope_changed?
112 (changed & self.class.positioned_options[:scope].map(&:to_s)).any?
96 (changed & self.class.positioned_options[:scope].map(&:to_s)).any?
113 end
97 end
114
98
115 def shift_positions
99 def shift_positions
116 offset = position_was <=> position
100 offset = position_was <=> position
117 min, max = [position, position_was].sort
101 min, max = [position, position_was].sort
118 r = position_scope.where("id <> ? AND position BETWEEN ? AND ?", id, min, max).update_all("position = position + #{offset}")
102 r = position_scope.where("id <> ? AND position BETWEEN ? AND ?", id, min, max).update_all("position = position + #{offset}")
119 if r != max - min
103 if r != max - min
120 reset_positions_in_list
104 reset_positions_in_list
121 end
105 end
122 end
106 end
123
107
124 def reset_positions_in_list
108 def reset_positions_in_list
125 position_scope.reorder(:position, :id).pluck(:id).each_with_index do |record_id, p|
109 position_scope.reorder(:position, :id).pluck(:id).each_with_index do |record_id, p|
126 self.class.where(:id => record_id).update_all(:position => p+1)
110 self.class.where(:id => record_id).update_all(:position => p+1)
127 end
111 end
128 end
112 end
129 end
113 end
130 end
114 end
131 end
115 end
132 end
116 end
133
117
134 ActiveRecord::Base.send :include, Redmine::Acts::Positioned
118 ActiveRecord::Base.send :include, Redmine::Acts::Positioned
@@ -1,208 +1,208
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 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 RolesControllerTest < ActionController::TestCase
20 class RolesControllerTest < ActionController::TestCase
21 fixtures :roles, :users, :members, :member_roles, :workflows, :trackers
21 fixtures :roles, :users, :members, :member_roles, :workflows, :trackers
22
22
23 def setup
23 def setup
24 User.current = nil
24 User.current = nil
25 @request.session[:user_id] = 1 # admin
25 @request.session[:user_id] = 1 # admin
26 end
26 end
27
27
28 def test_index
28 def test_index
29 get :index
29 get :index
30 assert_response :success
30 assert_response :success
31 assert_template 'index'
31 assert_template 'index'
32
32
33 assert_not_nil assigns(:roles)
33 assert_not_nil assigns(:roles)
34 assert_equal Role.order('builtin, position').to_a, assigns(:roles)
34 assert_equal Role.order('builtin, position').to_a, assigns(:roles)
35
35
36 assert_select 'a[href="/roles/1/edit"]', :text => 'Manager'
36 assert_select 'a[href="/roles/1/edit"]', :text => 'Manager'
37 end
37 end
38
38
39 def test_new
39 def test_new
40 get :new
40 get :new
41 assert_response :success
41 assert_response :success
42 assert_template 'new'
42 assert_template 'new'
43 end
43 end
44
44
45 def test_new_with_copy
45 def test_new_with_copy
46 copy_from = Role.find(2)
46 copy_from = Role.find(2)
47
47
48 get :new, :copy => copy_from.id.to_s
48 get :new, :copy => copy_from.id.to_s
49 assert_response :success
49 assert_response :success
50 assert_template 'new'
50 assert_template 'new'
51
51
52 role = assigns(:role)
52 role = assigns(:role)
53 assert_equal copy_from.permissions, role.permissions
53 assert_equal copy_from.permissions, role.permissions
54
54
55 assert_select 'form' do
55 assert_select 'form' do
56 # blank name
56 # blank name
57 assert_select 'input[name=?][value=""]', 'role[name]'
57 assert_select 'input[name=?][value=""]', 'role[name]'
58 # edit_project permission checked
58 # edit_project permission checked
59 assert_select 'input[type=checkbox][name=?][value=edit_project][checked=checked]', 'role[permissions][]'
59 assert_select 'input[type=checkbox][name=?][value=edit_project][checked=checked]', 'role[permissions][]'
60 # add_project permission not checked
60 # add_project permission not checked
61 assert_select 'input[type=checkbox][name=?][value=add_project]', 'role[permissions][]'
61 assert_select 'input[type=checkbox][name=?][value=add_project]', 'role[permissions][]'
62 assert_select 'input[type=checkbox][name=?][value=add_project][checked=checked]', 'role[permissions][]', 0
62 assert_select 'input[type=checkbox][name=?][value=add_project][checked=checked]', 'role[permissions][]', 0
63 # workflow copy selected
63 # workflow copy selected
64 assert_select 'select[name=?]', 'copy_workflow_from' do
64 assert_select 'select[name=?]', 'copy_workflow_from' do
65 assert_select 'option[value="2"][selected=selected]'
65 assert_select 'option[value="2"][selected=selected]'
66 end
66 end
67 end
67 end
68 end
68 end
69
69
70 def test_create_with_validaton_failure
70 def test_create_with_validaton_failure
71 post :create, :role => {:name => '',
71 post :create, :role => {:name => '',
72 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
72 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
73 :assignable => '0'}
73 :assignable => '0'}
74
74
75 assert_response :success
75 assert_response :success
76 assert_template 'new'
76 assert_template 'new'
77 assert_select 'div#errorExplanation'
77 assert_select 'div#errorExplanation'
78 end
78 end
79
79
80 def test_create_without_workflow_copy
80 def test_create_without_workflow_copy
81 post :create, :role => {:name => 'RoleWithoutWorkflowCopy',
81 post :create, :role => {:name => 'RoleWithoutWorkflowCopy',
82 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
82 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
83 :assignable => '0'}
83 :assignable => '0'}
84
84
85 assert_redirected_to '/roles'
85 assert_redirected_to '/roles'
86 role = Role.find_by_name('RoleWithoutWorkflowCopy')
86 role = Role.find_by_name('RoleWithoutWorkflowCopy')
87 assert_not_nil role
87 assert_not_nil role
88 assert_equal [:add_issues, :edit_issues, :log_time], role.permissions
88 assert_equal [:add_issues, :edit_issues, :log_time], role.permissions
89 assert !role.assignable?
89 assert !role.assignable?
90 end
90 end
91
91
92 def test_create_with_workflow_copy
92 def test_create_with_workflow_copy
93 post :create, :role => {:name => 'RoleWithWorkflowCopy',
93 post :create, :role => {:name => 'RoleWithWorkflowCopy',
94 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
94 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
95 :assignable => '0'},
95 :assignable => '0'},
96 :copy_workflow_from => '1'
96 :copy_workflow_from => '1'
97
97
98 assert_redirected_to '/roles'
98 assert_redirected_to '/roles'
99 role = Role.find_by_name('RoleWithWorkflowCopy')
99 role = Role.find_by_name('RoleWithWorkflowCopy')
100 assert_not_nil role
100 assert_not_nil role
101 assert_equal Role.find(1).workflow_rules.size, role.workflow_rules.size
101 assert_equal Role.find(1).workflow_rules.size, role.workflow_rules.size
102 end
102 end
103
103
104 def test_edit
104 def test_edit
105 get :edit, :id => 1
105 get :edit, :id => 1
106 assert_response :success
106 assert_response :success
107 assert_template 'edit'
107 assert_template 'edit'
108 assert_equal Role.find(1), assigns(:role)
108 assert_equal Role.find(1), assigns(:role)
109 assert_select 'select[name=?]', 'role[issues_visibility]'
109 assert_select 'select[name=?]', 'role[issues_visibility]'
110 end
110 end
111
111
112 def test_edit_anonymous
112 def test_edit_anonymous
113 get :edit, :id => Role.anonymous.id
113 get :edit, :id => Role.anonymous.id
114 assert_response :success
114 assert_response :success
115 assert_template 'edit'
115 assert_template 'edit'
116 assert_select 'select[name=?]', 'role[issues_visibility]', 0
116 assert_select 'select[name=?]', 'role[issues_visibility]', 0
117 end
117 end
118
118
119 def test_edit_invalid_should_respond_with_404
119 def test_edit_invalid_should_respond_with_404
120 get :edit, :id => 999
120 get :edit, :id => 999
121 assert_response 404
121 assert_response 404
122 end
122 end
123
123
124 def test_update
124 def test_update
125 put :update, :id => 1,
125 put :update, :id => 1,
126 :role => {:name => 'Manager',
126 :role => {:name => 'Manager',
127 :permissions => ['edit_project', ''],
127 :permissions => ['edit_project', ''],
128 :assignable => '0'}
128 :assignable => '0'}
129
129
130 assert_redirected_to '/roles'
130 assert_redirected_to '/roles'
131 role = Role.find(1)
131 role = Role.find(1)
132 assert_equal [:edit_project], role.permissions
132 assert_equal [:edit_project], role.permissions
133 end
133 end
134
134
135 def test_update_with_failure
135 def test_update_with_failure
136 put :update, :id => 1, :role => {:name => ''}
136 put :update, :id => 1, :role => {:name => ''}
137 assert_response :success
137 assert_response :success
138 assert_template 'edit'
138 assert_template 'edit'
139 end
139 end
140
140
141 def test_destroy
141 def test_destroy
142 r = Role.create!(:name => 'ToBeDestroyed', :permissions => [:view_wiki_pages])
142 r = Role.create!(:name => 'ToBeDestroyed', :permissions => [:view_wiki_pages])
143
143
144 delete :destroy, :id => r
144 delete :destroy, :id => r
145 assert_redirected_to '/roles'
145 assert_redirected_to '/roles'
146 assert_nil Role.find_by_id(r.id)
146 assert_nil Role.find_by_id(r.id)
147 end
147 end
148
148
149 def test_destroy_role_in_use
149 def test_destroy_role_in_use
150 delete :destroy, :id => 1
150 delete :destroy, :id => 1
151 assert_redirected_to '/roles'
151 assert_redirected_to '/roles'
152 assert_equal 'This role is in use and cannot be deleted.', flash[:error]
152 assert_equal 'This role is in use and cannot be deleted.', flash[:error]
153 assert_not_nil Role.find_by_id(1)
153 assert_not_nil Role.find_by_id(1)
154 end
154 end
155
155
156 def test_get_permissions
156 def test_get_permissions
157 get :permissions
157 get :permissions
158 assert_response :success
158 assert_response :success
159 assert_template 'permissions'
159 assert_template 'permissions'
160
160
161 assert_not_nil assigns(:roles)
161 assert_not_nil assigns(:roles)
162 assert_equal Role.order('builtin, position').to_a, assigns(:roles)
162 assert_equal Role.order('builtin, position').to_a, assigns(:roles)
163
163
164 assert_select 'input[name=?][type=checkbox][value=add_issues][checked=checked]', 'permissions[3][]'
164 assert_select 'input[name=?][type=checkbox][value=add_issues][checked=checked]', 'permissions[3][]'
165 assert_select 'input[name=?][type=checkbox][value=delete_issues]:not([checked])', 'permissions[3][]'
165 assert_select 'input[name=?][type=checkbox][value=delete_issues]:not([checked])', 'permissions[3][]'
166 end
166 end
167
167
168 def test_post_permissions
168 def test_post_permissions
169 post :permissions, :permissions => { '0' => '', '1' => ['edit_issues'], '3' => ['add_issues', 'delete_issues']}
169 post :permissions, :permissions => { '0' => '', '1' => ['edit_issues'], '3' => ['add_issues', 'delete_issues']}
170 assert_redirected_to '/roles'
170 assert_redirected_to '/roles'
171
171
172 assert_equal [:edit_issues], Role.find(1).permissions
172 assert_equal [:edit_issues], Role.find(1).permissions
173 assert_equal [:add_issues, :delete_issues], Role.find(3).permissions
173 assert_equal [:add_issues, :delete_issues], Role.find(3).permissions
174 assert Role.find(2).permissions.empty?
174 assert Role.find(2).permissions.empty?
175 end
175 end
176
176
177 def test_clear_all_permissions
177 def test_clear_all_permissions
178 post :permissions, :permissions => { '0' => '' }
178 post :permissions, :permissions => { '0' => '' }
179 assert_redirected_to '/roles'
179 assert_redirected_to '/roles'
180 assert Role.find(1).permissions.empty?
180 assert Role.find(1).permissions.empty?
181 end
181 end
182
182
183 def test_move_highest
183 def test_move_highest
184 put :update, :id => 3, :role => {:move_to => 'highest'}
184 put :update, :id => 3, :role => {:position => 1}
185 assert_redirected_to '/roles'
185 assert_redirected_to '/roles'
186 assert_equal 1, Role.find(3).position
186 assert_equal 1, Role.find(3).position
187 end
187 end
188
188
189 def test_move_higher
189 def test_move_higher
190 position = Role.find(3).position
190 position = Role.find(3).position
191 put :update, :id => 3, :role => {:move_to => 'higher'}
191 put :update, :id => 3, :role => {:position => position - 1}
192 assert_redirected_to '/roles'
192 assert_redirected_to '/roles'
193 assert_equal position - 1, Role.find(3).position
193 assert_equal position - 1, Role.find(3).position
194 end
194 end
195
195
196 def test_move_lower
196 def test_move_lower
197 position = Role.find(2).position
197 position = Role.find(2).position
198 put :update, :id => 2, :role => {:move_to => 'lower'}
198 put :update, :id => 2, :role => {:position => position + 1}
199 assert_redirected_to '/roles'
199 assert_redirected_to '/roles'
200 assert_equal position + 1, Role.find(2).position
200 assert_equal position + 1, Role.find(2).position
201 end
201 end
202
202
203 def test_move_lowest
203 def test_move_lowest
204 put :update, :id => 2, :role => {:move_to => 'lowest'}
204 put :update, :id => 2, :role => {:position => Role.givable.count}
205 assert_redirected_to '/roles'
205 assert_redirected_to '/roles'
206 assert_equal Role.givable.count, Role.find(2).position
206 assert_equal Role.givable.count, Role.find(2).position
207 end
207 end
208 end
208 end
@@ -1,175 +1,175
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 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 EnumerationTest < ActiveSupport::TestCase
20 class EnumerationTest < ActiveSupport::TestCase
21 fixtures :enumerations, :issues, :custom_fields, :custom_values
21 fixtures :enumerations, :issues, :custom_fields, :custom_values
22
22
23 def test_objects_count
23 def test_objects_count
24 # low priority
24 # low priority
25 assert_equal 6, Enumeration.find(4).objects_count
25 assert_equal 6, Enumeration.find(4).objects_count
26 # urgent
26 # urgent
27 assert_equal 0, Enumeration.find(7).objects_count
27 assert_equal 0, Enumeration.find(7).objects_count
28 end
28 end
29
29
30 def test_in_use
30 def test_in_use
31 # low priority
31 # low priority
32 assert Enumeration.find(4).in_use?
32 assert Enumeration.find(4).in_use?
33 # urgent
33 # urgent
34 assert !Enumeration.find(7).in_use?
34 assert !Enumeration.find(7).in_use?
35 end
35 end
36
36
37 def test_default
37 def test_default
38 e = Enumeration.default
38 e = Enumeration.default
39 assert e.is_a?(Enumeration)
39 assert e.is_a?(Enumeration)
40 assert e.is_default?
40 assert e.is_default?
41 assert e.active?
41 assert e.active?
42 assert_equal 'Default Enumeration', e.name
42 assert_equal 'Default Enumeration', e.name
43 end
43 end
44
44
45 def test_default_non_active
45 def test_default_non_active
46 e = Enumeration.find(12)
46 e = Enumeration.find(12)
47 assert e.is_a?(Enumeration)
47 assert e.is_a?(Enumeration)
48 assert e.is_default?
48 assert e.is_default?
49 assert e.active?
49 assert e.active?
50 e.update_attributes(:active => false)
50 e.update_attributes(:active => false)
51 assert e.is_default?
51 assert e.is_default?
52 assert !e.active?
52 assert !e.active?
53 end
53 end
54
54
55 def test_create
55 def test_create
56 e = Enumeration.new(:name => 'Not default', :is_default => false)
56 e = Enumeration.new(:name => 'Not default', :is_default => false)
57 e.type = 'Enumeration'
57 e.type = 'Enumeration'
58 assert e.save
58 assert e.save
59 assert_equal 'Default Enumeration', Enumeration.default.name
59 assert_equal 'Default Enumeration', Enumeration.default.name
60 end
60 end
61
61
62 def test_create_as_default
62 def test_create_as_default
63 e = Enumeration.new(:name => 'Very urgent', :is_default => true)
63 e = Enumeration.new(:name => 'Very urgent', :is_default => true)
64 e.type = 'Enumeration'
64 e.type = 'Enumeration'
65 assert e.save
65 assert e.save
66 assert_equal e, Enumeration.default
66 assert_equal e, Enumeration.default
67 end
67 end
68
68
69 def test_update_default
69 def test_update_default
70 e = Enumeration.default
70 e = Enumeration.default
71 e.update_attributes(:name => 'Changed', :is_default => true)
71 e.update_attributes(:name => 'Changed', :is_default => true)
72 assert_equal e, Enumeration.default
72 assert_equal e, Enumeration.default
73 end
73 end
74
74
75 def test_update_default_to_non_default
75 def test_update_default_to_non_default
76 e = Enumeration.default
76 e = Enumeration.default
77 e.update_attributes(:name => 'Changed', :is_default => false)
77 e.update_attributes(:name => 'Changed', :is_default => false)
78 assert_nil Enumeration.default
78 assert_nil Enumeration.default
79 end
79 end
80
80
81 def test_change_default
81 def test_change_default
82 e = Enumeration.find_by_name('Default Enumeration')
82 e = Enumeration.find_by_name('Default Enumeration')
83 e.update_attributes(:name => 'Changed Enumeration', :is_default => true)
83 e.update_attributes(:name => 'Changed Enumeration', :is_default => true)
84 assert_equal e, Enumeration.default
84 assert_equal e, Enumeration.default
85 end
85 end
86
86
87 def test_destroy_with_reassign
87 def test_destroy_with_reassign
88 Enumeration.find(4).destroy(Enumeration.find(6))
88 Enumeration.find(4).destroy(Enumeration.find(6))
89 assert_nil Issue.where(:priority_id => 4).first
89 assert_nil Issue.where(:priority_id => 4).first
90 assert_equal 6, Enumeration.find(6).objects_count
90 assert_equal 6, Enumeration.find(6).objects_count
91 end
91 end
92
92
93 def test_should_be_customizable
93 def test_should_be_customizable
94 assert Enumeration.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
94 assert Enumeration.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
95 end
95 end
96
96
97 def test_should_belong_to_a_project
97 def test_should_belong_to_a_project
98 association = Enumeration.reflect_on_association(:project)
98 association = Enumeration.reflect_on_association(:project)
99 assert association, "No Project association found"
99 assert association, "No Project association found"
100 assert_equal :belongs_to, association.macro
100 assert_equal :belongs_to, association.macro
101 end
101 end
102
102
103 def test_should_act_as_tree
103 def test_should_act_as_tree
104 enumeration = Enumeration.find(4)
104 enumeration = Enumeration.find(4)
105
105
106 assert enumeration.respond_to?(:parent)
106 assert enumeration.respond_to?(:parent)
107 assert enumeration.respond_to?(:children)
107 assert enumeration.respond_to?(:children)
108 end
108 end
109
109
110 def test_is_override
110 def test_is_override
111 # Defaults to off
111 # Defaults to off
112 enumeration = Enumeration.find(4)
112 enumeration = Enumeration.find(4)
113 assert !enumeration.is_override?
113 assert !enumeration.is_override?
114
114
115 # Setup as an override
115 # Setup as an override
116 enumeration.parent = Enumeration.find(5)
116 enumeration.parent = Enumeration.find(5)
117 assert enumeration.is_override?
117 assert enumeration.is_override?
118 end
118 end
119
119
120 def test_get_subclasses
120 def test_get_subclasses
121 classes = Enumeration.get_subclasses
121 classes = Enumeration.get_subclasses
122 assert_include IssuePriority, classes
122 assert_include IssuePriority, classes
123 assert_include DocumentCategory, classes
123 assert_include DocumentCategory, classes
124 assert_include TimeEntryActivity, classes
124 assert_include TimeEntryActivity, classes
125
125
126 classes.each do |klass|
126 classes.each do |klass|
127 assert_equal Enumeration, klass.superclass
127 assert_equal Enumeration, klass.superclass
128 end
128 end
129 end
129 end
130
130
131 def test_list_should_be_scoped_for_each_type
131 def test_list_should_be_scoped_for_each_type
132 Enumeration.delete_all
132 Enumeration.delete_all
133
133
134 a = IssuePriority.create!(:name => 'A')
134 a = IssuePriority.create!(:name => 'A')
135 b = IssuePriority.create!(:name => 'B')
135 b = IssuePriority.create!(:name => 'B')
136 c = DocumentCategory.create!(:name => 'C')
136 c = DocumentCategory.create!(:name => 'C')
137
137
138 assert_equal [1, 2, 1], [a, b, c].map(&:reload).map(&:position)
138 assert_equal [1, 2, 1], [a, b, c].map(&:reload).map(&:position)
139 end
139 end
140
140
141 def test_override_should_be_created_with_same_position_as_parent
141 def test_override_should_be_created_with_same_position_as_parent
142 Enumeration.delete_all
142 Enumeration.delete_all
143
143
144 a = IssuePriority.create!(:name => 'A')
144 a = IssuePriority.create!(:name => 'A')
145 b = IssuePriority.create!(:name => 'B')
145 b = IssuePriority.create!(:name => 'B')
146 override = IssuePriority.create!(:name => 'BB', :parent_id => b.id)
146 override = IssuePriority.create!(:name => 'BB', :parent_id => b.id)
147
147
148 assert_equal [1, 2, 2], [a, b, override].map(&:reload).map(&:position)
148 assert_equal [1, 2, 2], [a, b, override].map(&:reload).map(&:position)
149 end
149 end
150
150
151 def test_override_position_should_be_updated_with_parent_position
151 def test_override_position_should_be_updated_with_parent_position
152 Enumeration.delete_all
152 Enumeration.delete_all
153
153
154 a = IssuePriority.create!(:name => 'A')
154 a = IssuePriority.create!(:name => 'A')
155 b = IssuePriority.create!(:name => 'B')
155 b = IssuePriority.create!(:name => 'B')
156 override = IssuePriority.create!(:name => 'BB', :parent_id => b.id)
156 override = IssuePriority.create!(:name => 'BB', :parent_id => b.id)
157 b.move_to = 'higher'
157 b.position -= 1
158 b.save!
158 b.save!
159
159
160 assert_equal [2, 1, 1], [a, b, override].map(&:reload).map(&:position)
160 assert_equal [2, 1, 1], [a, b, override].map(&:reload).map(&:position)
161 end
161 end
162
162
163 def test_destroying_override_should_not_update_positions
163 def test_destroying_override_should_not_update_positions
164 Enumeration.delete_all
164 Enumeration.delete_all
165
165
166 a = IssuePriority.create!(:name => 'A')
166 a = IssuePriority.create!(:name => 'A')
167 b = IssuePriority.create!(:name => 'B')
167 b = IssuePriority.create!(:name => 'B')
168 c = IssuePriority.create!(:name => 'C')
168 c = IssuePriority.create!(:name => 'C')
169 override = IssuePriority.create!(:name => 'BB', :parent_id => b.id)
169 override = IssuePriority.create!(:name => 'BB', :parent_id => b.id)
170 assert_equal [1, 2, 3, 2], [a, b, c, override].map(&:reload).map(&:position)
170 assert_equal [1, 2, 3, 2], [a, b, c, override].map(&:reload).map(&:position)
171
171
172 override.destroy
172 override.destroy
173 assert_equal [1, 2, 3], [a, b, c].map(&:reload).map(&:position)
173 assert_equal [1, 2, 3], [a, b, c].map(&:reload).map(&:position)
174 end
174 end
175 end
175 end
@@ -1,102 +1,102
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 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 IssuePriorityTest < ActiveSupport::TestCase
20 class IssuePriorityTest < ActiveSupport::TestCase
21 fixtures :enumerations, :issues
21 fixtures :enumerations, :issues
22
22
23 def test_named_scope
23 def test_named_scope
24 assert_equal Enumeration.find_by_name('Normal'), Enumeration.named('normal').first
24 assert_equal Enumeration.find_by_name('Normal'), Enumeration.named('normal').first
25 end
25 end
26
26
27 def test_default_should_return_the_default_priority
27 def test_default_should_return_the_default_priority
28 assert_equal Enumeration.find_by_name('Normal'), IssuePriority.default
28 assert_equal Enumeration.find_by_name('Normal'), IssuePriority.default
29 end
29 end
30
30
31 def test_default_should_return_nil_when_no_default_priority
31 def test_default_should_return_nil_when_no_default_priority
32 IssuePriority.update_all :is_default => false
32 IssuePriority.update_all :is_default => false
33 assert_nil IssuePriority.default
33 assert_nil IssuePriority.default
34 end
34 end
35
35
36 def test_should_be_an_enumeration
36 def test_should_be_an_enumeration
37 assert IssuePriority.ancestors.include?(Enumeration)
37 assert IssuePriority.ancestors.include?(Enumeration)
38 end
38 end
39
39
40 def test_objects_count
40 def test_objects_count
41 # low priority
41 # low priority
42 assert_equal 6, IssuePriority.find(4).objects_count
42 assert_equal 6, IssuePriority.find(4).objects_count
43 # urgent
43 # urgent
44 assert_equal 0, IssuePriority.find(7).objects_count
44 assert_equal 0, IssuePriority.find(7).objects_count
45 end
45 end
46
46
47 def test_option_name
47 def test_option_name
48 assert_equal :enumeration_issue_priorities, IssuePriority.new.option_name
48 assert_equal :enumeration_issue_priorities, IssuePriority.new.option_name
49 end
49 end
50
50
51 def test_should_be_created_at_last_position
51 def test_should_be_created_at_last_position
52 IssuePriority.delete_all
52 IssuePriority.delete_all
53
53
54 priorities = [1, 2, 3].map {|i| IssuePriority.create!(:name => "P#{i}")}
54 priorities = [1, 2, 3].map {|i| IssuePriority.create!(:name => "P#{i}")}
55 assert_equal [1, 2, 3], priorities.map(&:position)
55 assert_equal [1, 2, 3], priorities.map(&:position)
56 end
56 end
57
57
58 def test_clear_position_names_should_set_position_names_to_nil
58 def test_clear_position_names_should_set_position_names_to_nil
59 IssuePriority.clear_position_names
59 IssuePriority.clear_position_names
60 assert IssuePriority.all.all? {|priority| priority.position_name.nil?}
60 assert IssuePriority.all.all? {|priority| priority.position_name.nil?}
61 end
61 end
62
62
63 def test_compute_position_names_with_default_priority
63 def test_compute_position_names_with_default_priority
64 IssuePriority.clear_position_names
64 IssuePriority.clear_position_names
65
65
66 IssuePriority.compute_position_names
66 IssuePriority.compute_position_names
67 assert_equal %w(lowest default high3 high2 highest), IssuePriority.active.to_a.sort.map(&:position_name)
67 assert_equal %w(lowest default high3 high2 highest), IssuePriority.active.to_a.sort.map(&:position_name)
68 end
68 end
69
69
70 def test_compute_position_names_without_default_priority_should_split_priorities
70 def test_compute_position_names_without_default_priority_should_split_priorities
71 IssuePriority.clear_position_names
71 IssuePriority.clear_position_names
72 IssuePriority.update_all :is_default => false
72 IssuePriority.update_all :is_default => false
73
73
74 IssuePriority.compute_position_names
74 IssuePriority.compute_position_names
75 assert_equal %w(lowest low2 default high2 highest), IssuePriority.active.to_a.sort.map(&:position_name)
75 assert_equal %w(lowest low2 default high2 highest), IssuePriority.active.to_a.sort.map(&:position_name)
76 end
76 end
77
77
78 def test_adding_a_priority_should_update_position_names
78 def test_adding_a_priority_should_update_position_names
79 priority = IssuePriority.create!(:name => 'New')
79 priority = IssuePriority.create!(:name => 'New')
80 assert_equal %w(lowest default high4 high3 high2 highest), IssuePriority.active.to_a.sort.map(&:position_name)
80 assert_equal %w(lowest default high4 high3 high2 highest), IssuePriority.active.to_a.sort.map(&:position_name)
81 end
81 end
82
82
83 def test_moving_a_priority_should_update_position_names
83 def test_moving_a_priority_should_update_position_names
84 prio = IssuePriority.first
84 prio = IssuePriority.first
85 prio.move_to = 'lowest'
85 prio.position = IssuePriority.count
86 prio.save!
86 prio.save!
87 prio.reload
87 prio.reload
88 assert_equal 'highest', prio.position_name
88 assert_equal 'highest', prio.position_name
89 end
89 end
90
90
91 def test_deactivating_a_priority_should_update_position_names
91 def test_deactivating_a_priority_should_update_position_names
92 prio = IssuePriority.active.order(:position).last
92 prio = IssuePriority.active.order(:position).last
93 prio.active = false
93 prio.active = false
94 prio.save
94 prio.save
95 assert_equal 'highest', IssuePriority.active.order(:position).last.position_name
95 assert_equal 'highest', IssuePriority.active.order(:position).last.position_name
96 end
96 end
97
97
98 def test_destroying_a_priority_should_update_position_names
98 def test_destroying_a_priority_should_update_position_names
99 IssuePriority.find_by_position_name('highest').destroy
99 IssuePriority.find_by_position_name('highest').destroy
100 assert_equal %w(lowest default high2 highest), IssuePriority.active.to_a.sort.map(&:position_name)
100 assert_equal %w(lowest default high2 highest), IssuePriority.active.to_a.sort.map(&:position_name)
101 end
101 end
102 end
102 end
General Comments 0
You need to be logged in to leave comments. Login now