##// END OF EJS Templates
Removed some shoulda context....
Jean-Philippe Lang -
r11635:61dfab12fd72
parent child
Show More
@@ -1,162 +1,163
1 1 module ObjectHelpers
2 2 def User.generate!(attributes={})
3 3 @generated_user_login ||= 'user0'
4 4 @generated_user_login.succ!
5 5 user = User.new(attributes)
6 6 user.login = @generated_user_login.dup if user.login.blank?
7 7 user.mail = "#{@generated_user_login}@example.com" if user.mail.blank?
8 8 user.firstname = "Bob" if user.firstname.blank?
9 9 user.lastname = "Doe" if user.lastname.blank?
10 10 yield user if block_given?
11 11 user.save!
12 12 user
13 13 end
14 14
15 15 def User.add_to_project(user, project, roles=nil)
16 16 roles = Role.find(1) if roles.nil?
17 17 roles = [roles] unless roles.is_a?(Array)
18 18 Member.create!(:principal => user, :project => project, :roles => roles)
19 19 end
20 20
21 21 def Group.generate!(attributes={})
22 22 @generated_group_name ||= 'Group 0'
23 23 @generated_group_name.succ!
24 24 group = Group.new(attributes)
25 25 group.name = @generated_group_name.dup if group.name.blank?
26 26 yield group if block_given?
27 27 group.save!
28 28 group
29 29 end
30 30
31 31 def Project.generate!(attributes={})
32 32 @generated_project_identifier ||= 'project-0000'
33 33 @generated_project_identifier.succ!
34 34 project = Project.new(attributes)
35 35 project.name = @generated_project_identifier.dup if project.name.blank?
36 36 project.identifier = @generated_project_identifier.dup if project.identifier.blank?
37 37 yield project if block_given?
38 38 project.save!
39 39 project
40 40 end
41 41
42 42 def Project.generate_with_parent!(parent, attributes={})
43 43 project = Project.generate!(attributes)
44 44 project.set_parent!(parent)
45 45 project
46 46 end
47 47
48 48 def Tracker.generate!(attributes={})
49 49 @generated_tracker_name ||= 'Tracker 0'
50 50 @generated_tracker_name.succ!
51 51 tracker = Tracker.new(attributes)
52 52 tracker.name = @generated_tracker_name.dup if tracker.name.blank?
53 53 yield tracker if block_given?
54 54 tracker.save!
55 55 tracker
56 56 end
57 57
58 58 def Role.generate!(attributes={})
59 59 @generated_role_name ||= 'Role 0'
60 60 @generated_role_name.succ!
61 61 role = Role.new(attributes)
62 62 role.name = @generated_role_name.dup if role.name.blank?
63 63 yield role if block_given?
64 64 role.save!
65 65 role
66 66 end
67 67
68 68 def Issue.generate!(attributes={})
69 69 issue = Issue.new(attributes)
70 70 issue.project ||= Project.find(1)
71 71 issue.tracker ||= issue.project.trackers.first
72 72 issue.subject = 'Generated' if issue.subject.blank?
73 73 issue.author ||= User.find(2)
74 74 yield issue if block_given?
75 75 issue.save!
76 76 issue
77 77 end
78 78
79 79 # Generates an issue with 2 children and a grandchild
80 80 def Issue.generate_with_descendants!(attributes={})
81 81 issue = Issue.generate!(attributes)
82 82 child = Issue.generate!(:project => issue.project, :subject => 'Child1', :parent_issue_id => issue.id)
83 83 Issue.generate!(:project => issue.project, :subject => 'Child2', :parent_issue_id => issue.id)
84 84 Issue.generate!(:project => issue.project, :subject => 'Child11', :parent_issue_id => child.id)
85 85 issue.reload
86 86 end
87 87
88 88 def Journal.generate!(attributes={})
89 89 journal = Journal.new(attributes)
90 90 journal.user ||= User.first
91 91 journal.journalized ||= Issue.first
92 92 yield journal if block_given?
93 93 journal.save!
94 94 journal
95 95 end
96 96
97 97 def Version.generate!(attributes={})
98 98 @generated_version_name ||= 'Version 0'
99 99 @generated_version_name.succ!
100 100 version = Version.new(attributes)
101 101 version.name = @generated_version_name.dup if version.name.blank?
102 version.project ||= Project.find(1)
102 103 yield version if block_given?
103 104 version.save!
104 105 version
105 106 end
106 107
107 108 def TimeEntry.generate!(attributes={})
108 109 entry = TimeEntry.new(attributes)
109 110 entry.user ||= User.find(2)
110 111 entry.issue ||= Issue.find(1) unless entry.project
111 112 entry.project ||= entry.issue.project
112 113 entry.activity ||= TimeEntryActivity.first
113 114 entry.spent_on ||= Date.today
114 115 entry.hours ||= 1.0
115 116 entry.save!
116 117 entry
117 118 end
118 119
119 120 def AuthSource.generate!(attributes={})
120 121 @generated_auth_source_name ||= 'Auth 0'
121 122 @generated_auth_source_name.succ!
122 123 source = AuthSource.new(attributes)
123 124 source.name = @generated_auth_source_name.dup if source.name.blank?
124 125 yield source if block_given?
125 126 source.save!
126 127 source
127 128 end
128 129
129 130 def Board.generate!(attributes={})
130 131 @generated_board_name ||= 'Forum 0'
131 132 @generated_board_name.succ!
132 133 board = Board.new(attributes)
133 134 board.name = @generated_board_name.dup if board.name.blank?
134 135 board.description = @generated_board_name.dup if board.description.blank?
135 136 yield board if block_given?
136 137 board.save!
137 138 board
138 139 end
139 140
140 141 def Attachment.generate!(attributes={})
141 142 @generated_filename ||= 'testfile0'
142 143 @generated_filename.succ!
143 144 attributes = attributes.dup
144 145 attachment = Attachment.new(attributes)
145 146 attachment.container ||= Issue.find(1)
146 147 attachment.author ||= User.find(2)
147 148 attachment.filename = @generated_filename.dup if attachment.filename.blank?
148 149 attachment.save!
149 150 attachment
150 151 end
151 152
152 153 def CustomField.generate!(attributes={})
153 154 @generated_custom_field_name ||= 'Custom field 0'
154 155 @generated_custom_field_name.succ!
155 156 field = new(attributes)
156 157 field.name = @generated_custom_field_name.dup if field.name.blank?
157 158 field.field_format = 'string' if field.field_format.blank?
158 159 yield field if block_given?
159 160 field.save!
160 161 field
161 162 end
162 163 end
@@ -1,40 +1,38
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2013 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class PatchesTest < ActiveSupport::TestCase
21 21 include Redmine::I18n
22 22
23 context "ActiveRecord::Base.human_attribute_name" do
24 setup do
25 Setting.default_language = 'en'
26 end
23 def setup
24 Setting.default_language = 'en'
25 end
27 26
28 should "transform name to field_name" do
29 assert_equal l('field_last_login_on'), ActiveRecord::Base.human_attribute_name('last_login_on')
30 end
27 test "ActiveRecord::Base.human_attribute_name should transform name to field_name" do
28 assert_equal l('field_last_login_on'), ActiveRecord::Base.human_attribute_name('last_login_on')
29 end
31 30
32 should "cut extra _id suffix for better validation" do
33 assert_equal l('field_last_login_on'), ActiveRecord::Base.human_attribute_name('last_login_on_id')
34 end
31 test "ActiveRecord::Base.human_attribute_name should cut extra _id suffix for better validation" do
32 assert_equal l('field_last_login_on'), ActiveRecord::Base.human_attribute_name('last_login_on_id')
33 end
35 34
36 should "default to humanized value if no translation has been found (useful for custom fields)" do
37 assert_equal 'Patch name', ActiveRecord::Base.human_attribute_name('Patch name')
38 end
35 test "ActiveRecord::Base.human_attribute_name should default to humanized value if no translation has been found (useful for custom fields)" do
36 assert_equal 'Patch name', ActiveRecord::Base.human_attribute_name('Patch name')
39 37 end
40 38 end
@@ -1,193 +1,191
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2013 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../../../test_helper', __FILE__)
19 19
20 20 class Redmine::MenuManager::MapperTest < ActiveSupport::TestCase
21 context "Mapper#initialize" do
22 should "define a root MenuNode if menu is not present in items" do
23 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
24 node = menu_mapper.menu_items
25 assert_not_nil node
26 assert_equal :root, node.name
27 end
21 test "Mapper#initialize should define a root MenuNode if menu is not present in items" do
22 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
23 node = menu_mapper.menu_items
24 assert_not_nil node
25 assert_equal :root, node.name
26 end
28 27
29 should "use existing MenuNode if present" do
30 node = "foo" # just an arbitrary reference
31 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {:test_menu => node})
32 assert_equal node, menu_mapper.menu_items
33 end
28 test "Mapper#initialize should use existing MenuNode if present" do
29 node = "foo" # just an arbitrary reference
30 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {:test_menu => node})
31 assert_equal node, menu_mapper.menu_items
34 32 end
35 33
36 34 def test_push_onto_root
37 35 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
38 36 menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
39 37
40 38 menu_mapper.exists?(:test_overview)
41 39 end
42 40
43 41 def test_push_onto_parent
44 42 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
45 43 menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
46 44 menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview}
47 45
48 46 assert menu_mapper.exists?(:test_child)
49 47 assert_equal :test_child, menu_mapper.find(:test_child).name
50 48 end
51 49
52 50 def test_push_onto_grandparent
53 51 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
54 52 menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
55 53 menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview}
56 54 menu_mapper.push :test_grandchild, { :controller => 'projects', :action => 'show'}, {:parent => :test_child}
57 55
58 56 assert menu_mapper.exists?(:test_grandchild)
59 57 grandchild = menu_mapper.find(:test_grandchild)
60 58 assert_equal :test_grandchild, grandchild.name
61 59 assert_equal :test_child, grandchild.parent.name
62 60 end
63 61
64 62 def test_push_first
65 63 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
66 64 menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
67 65 menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
68 66 menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
69 67 menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
70 68 menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {:first => true}
71 69
72 70 root = menu_mapper.find(:root)
73 71 assert_equal 5, root.children.size
74 72 {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
75 73 assert_not_nil root.children[position]
76 74 assert_equal name, root.children[position].name
77 75 end
78 76
79 77 end
80 78
81 79 def test_push_before
82 80 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
83 81 menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
84 82 menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
85 83 menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
86 84 menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
87 85 menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {:before => :test_fourth}
88 86
89 87 root = menu_mapper.find(:root)
90 88 assert_equal 5, root.children.size
91 89 {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
92 90 assert_not_nil root.children[position]
93 91 assert_equal name, root.children[position].name
94 92 end
95 93
96 94 end
97 95
98 96 def test_push_after
99 97 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
100 98 menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
101 99 menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
102 100 menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
103 101 menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
104 102 menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {:after => :test_third}
105 103
106 104 root = menu_mapper.find(:root)
107 105 assert_equal 5, root.children.size
108 106 {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
109 107 assert_not_nil root.children[position]
110 108 assert_equal name, root.children[position].name
111 109 end
112 110
113 111 end
114 112
115 113 def test_push_last
116 114 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
117 115 menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
118 116 menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
119 117 menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
120 118 menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {:last => true}
121 119 menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
122 120
123 121 root = menu_mapper.find(:root)
124 122 assert_equal 5, root.children.size
125 123 {0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
126 124 assert_not_nil root.children[position]
127 125 assert_equal name, root.children[position].name
128 126 end
129 127
130 128 end
131 129
132 130 def test_exists_for_child_node
133 131 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
134 132 menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
135 133 menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview }
136 134
137 135 assert menu_mapper.exists?(:test_child)
138 136 end
139 137
140 138 def test_exists_for_invalid_node
141 139 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
142 140 menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
143 141
144 142 assert !menu_mapper.exists?(:nothing)
145 143 end
146 144
147 145 def test_find
148 146 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
149 147 menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
150 148
151 149 item = menu_mapper.find(:test_overview)
152 150 assert_equal :test_overview, item.name
153 151 assert_equal({:controller => 'projects', :action => 'show'}, item.url)
154 152 end
155 153
156 154 def test_find_missing
157 155 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
158 156 menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
159 157
160 158 item = menu_mapper.find(:nothing)
161 159 assert_equal nil, item
162 160 end
163 161
164 162 def test_delete
165 163 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
166 164 menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
167 165 assert_not_nil menu_mapper.delete(:test_overview)
168 166
169 167 assert_nil menu_mapper.find(:test_overview)
170 168 end
171 169
172 170 def test_delete_missing
173 171 menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
174 172 assert_nil menu_mapper.delete(:test_missing)
175 173 end
176 174
177 175 test 'deleting all items' do
178 176 # Exposed by deleting :last items
179 177 Redmine::MenuManager.map :test_menu do |menu|
180 178 menu.push :not_last, Redmine::Info.help_url
181 179 menu.push :administration, { :controller => 'projects', :action => 'show'}, {:last => true}
182 180 menu.push :help, Redmine::Info.help_url, :last => true
183 181 end
184 182
185 183 assert_nothing_raised do
186 184 Redmine::MenuManager.map :test_menu do |menu|
187 185 menu.delete(:administration)
188 186 menu.delete(:help)
189 187 menu.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
190 188 end
191 189 end
192 190 end
193 191 end
@@ -1,1145 +1,1130
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2013 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class UserTest < ActiveSupport::TestCase
21 21 fixtures :users, :members, :projects, :roles, :member_roles, :auth_sources,
22 22 :trackers, :issue_statuses,
23 23 :projects_trackers,
24 24 :watchers,
25 25 :issue_categories, :enumerations, :issues,
26 26 :journals, :journal_details,
27 27 :groups_users,
28 28 :enabled_modules
29 29
30 30 def setup
31 31 @admin = User.find(1)
32 32 @jsmith = User.find(2)
33 33 @dlopper = User.find(3)
34 34 end
35 35
36 36 def test_sorted_scope_should_sort_user_by_display_name
37 37 assert_equal User.all.map(&:name).map(&:downcase).sort, User.sorted.all.map(&:name).map(&:downcase)
38 38 end
39 39
40 40 def test_generate
41 41 User.generate!(:firstname => 'Testing connection')
42 42 User.generate!(:firstname => 'Testing connection')
43 43 assert_equal 2, User.count(:all, :conditions => {:firstname => 'Testing connection'})
44 44 end
45 45
46 46 def test_truth
47 47 assert_kind_of User, @jsmith
48 48 end
49 49
50 50 def test_mail_should_be_stripped
51 51 u = User.new
52 52 u.mail = " foo@bar.com "
53 53 assert_equal "foo@bar.com", u.mail
54 54 end
55 55
56 56 def test_mail_validation
57 57 u = User.new
58 58 u.mail = ''
59 59 assert !u.valid?
60 60 assert_include I18n.translate('activerecord.errors.messages.blank'), u.errors[:mail]
61 61 end
62 62
63 63 def test_login_length_validation
64 64 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
65 65 user.login = "x" * (User::LOGIN_LENGTH_LIMIT+1)
66 66 assert !user.valid?
67 67
68 68 user.login = "x" * (User::LOGIN_LENGTH_LIMIT)
69 69 assert user.valid?
70 70 assert user.save
71 71 end
72 72
73 73 def test_generate_password_should_respect_minimum_password_length
74 74 with_settings :password_min_length => 15 do
75 75 user = User.generate!(:generate_password => true)
76 76 assert user.password.length >= 15
77 77 end
78 78 end
79 79
80 80 def test_generate_password_should_not_generate_password_with_less_than_10_characters
81 81 with_settings :password_min_length => 4 do
82 82 user = User.generate!(:generate_password => true)
83 83 assert user.password.length >= 10
84 84 end
85 85 end
86 86
87 87 def test_generate_password_on_create_should_set_password
88 88 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
89 89 user.login = "newuser"
90 90 user.generate_password = true
91 91 assert user.save
92 92
93 93 password = user.password
94 94 assert user.check_password?(password)
95 95 end
96 96
97 97 def test_generate_password_on_update_should_update_password
98 98 user = User.find(2)
99 99 hash = user.hashed_password
100 100 user.generate_password = true
101 101 assert user.save
102 102
103 103 password = user.password
104 104 assert user.check_password?(password)
105 105 assert_not_equal hash, user.reload.hashed_password
106 106 end
107 107
108 108 def test_create
109 109 user = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
110 110
111 111 user.login = "jsmith"
112 112 user.password, user.password_confirmation = "password", "password"
113 113 # login uniqueness
114 114 assert !user.save
115 115 assert_equal 1, user.errors.count
116 116
117 117 user.login = "newuser"
118 118 user.password, user.password_confirmation = "password", "pass"
119 119 # password confirmation
120 120 assert !user.save
121 121 assert_equal 1, user.errors.count
122 122
123 123 user.password, user.password_confirmation = "password", "password"
124 124 assert user.save
125 125 end
126 126
127 127 def test_user_before_create_should_set_the_mail_notification_to_the_default_setting
128 128 @user1 = User.generate!
129 129 assert_equal 'only_my_events', @user1.mail_notification
130 130 with_settings :default_notification_option => 'all' do
131 131 @user2 = User.generate!
132 132 assert_equal 'all', @user2.mail_notification
133 133 end
134 134 end
135 135
136 136 def test_user_login_should_be_case_insensitive
137 137 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
138 138 u.login = 'newuser'
139 139 u.password, u.password_confirmation = "password", "password"
140 140 assert u.save
141 141 u = User.new(:firstname => "Similar", :lastname => "User", :mail => "similaruser@somenet.foo")
142 142 u.login = 'NewUser'
143 143 u.password, u.password_confirmation = "password", "password"
144 144 assert !u.save
145 145 assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:login]
146 146 end
147 147
148 148 def test_mail_uniqueness_should_not_be_case_sensitive
149 149 u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
150 150 u.login = 'newuser1'
151 151 u.password, u.password_confirmation = "password", "password"
152 152 assert u.save
153 153
154 154 u = User.new(:firstname => "new", :lastname => "user", :mail => "newUser@Somenet.foo")
155 155 u.login = 'newuser2'
156 156 u.password, u.password_confirmation = "password", "password"
157 157 assert !u.save
158 158 assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:mail]
159 159 end
160 160
161 161 def test_update
162 162 assert_equal "admin", @admin.login
163 163 @admin.login = "john"
164 164 assert @admin.save, @admin.errors.full_messages.join("; ")
165 165 @admin.reload
166 166 assert_equal "john", @admin.login
167 167 end
168 168
169 169 def test_update_should_not_fail_for_legacy_user_with_different_case_logins
170 170 u1 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser1@somenet.foo")
171 171 u1.login = 'newuser1'
172 172 assert u1.save
173 173
174 174 u2 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser2@somenet.foo")
175 175 u2.login = 'newuser1'
176 176 assert u2.save(:validate => false)
177 177
178 178 user = User.find(u2.id)
179 179 user.firstname = "firstname"
180 180 assert user.save, "Save failed"
181 181 end
182 182
183 183 def test_destroy_should_delete_members_and_roles
184 184 members = Member.find_all_by_user_id(2)
185 185 ms = members.size
186 186 rs = members.collect(&:roles).flatten.size
187 187
188 188 assert_difference 'Member.count', - ms do
189 189 assert_difference 'MemberRole.count', - rs do
190 190 User.find(2).destroy
191 191 end
192 192 end
193 193
194 194 assert_nil User.find_by_id(2)
195 195 assert Member.find_all_by_user_id(2).empty?
196 196 end
197 197
198 198 def test_destroy_should_update_attachments
199 199 attachment = Attachment.create!(:container => Project.find(1),
200 200 :file => uploaded_test_file("testfile.txt", "text/plain"),
201 201 :author_id => 2)
202 202
203 203 User.find(2).destroy
204 204 assert_nil User.find_by_id(2)
205 205 assert_equal User.anonymous, attachment.reload.author
206 206 end
207 207
208 208 def test_destroy_should_update_comments
209 209 comment = Comment.create!(
210 210 :commented => News.create!(:project_id => 1, :author_id => 1, :title => 'foo', :description => 'foo'),
211 211 :author => User.find(2),
212 212 :comments => 'foo'
213 213 )
214 214
215 215 User.find(2).destroy
216 216 assert_nil User.find_by_id(2)
217 217 assert_equal User.anonymous, comment.reload.author
218 218 end
219 219
220 220 def test_destroy_should_update_issues
221 221 issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
222 222
223 223 User.find(2).destroy
224 224 assert_nil User.find_by_id(2)
225 225 assert_equal User.anonymous, issue.reload.author
226 226 end
227 227
228 228 def test_destroy_should_unassign_issues
229 229 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
230 230
231 231 User.find(2).destroy
232 232 assert_nil User.find_by_id(2)
233 233 assert_nil issue.reload.assigned_to
234 234 end
235 235
236 236 def test_destroy_should_update_journals
237 237 issue = Issue.create!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'foo')
238 238 issue.init_journal(User.find(2), "update")
239 239 issue.save!
240 240
241 241 User.find(2).destroy
242 242 assert_nil User.find_by_id(2)
243 243 assert_equal User.anonymous, issue.journals.first.reload.user
244 244 end
245 245
246 246 def test_destroy_should_update_journal_details_old_value
247 247 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo', :assigned_to_id => 2)
248 248 issue.init_journal(User.find(1), "update")
249 249 issue.assigned_to_id = nil
250 250 assert_difference 'JournalDetail.count' do
251 251 issue.save!
252 252 end
253 253 journal_detail = JournalDetail.first(:order => 'id DESC')
254 254 assert_equal '2', journal_detail.old_value
255 255
256 256 User.find(2).destroy
257 257 assert_nil User.find_by_id(2)
258 258 assert_equal User.anonymous.id.to_s, journal_detail.reload.old_value
259 259 end
260 260
261 261 def test_destroy_should_update_journal_details_value
262 262 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
263 263 issue.init_journal(User.find(1), "update")
264 264 issue.assigned_to_id = 2
265 265 assert_difference 'JournalDetail.count' do
266 266 issue.save!
267 267 end
268 268 journal_detail = JournalDetail.first(:order => 'id DESC')
269 269 assert_equal '2', journal_detail.value
270 270
271 271 User.find(2).destroy
272 272 assert_nil User.find_by_id(2)
273 273 assert_equal User.anonymous.id.to_s, journal_detail.reload.value
274 274 end
275 275
276 276 def test_destroy_should_update_messages
277 277 board = Board.create!(:project_id => 1, :name => 'Board', :description => 'Board')
278 278 message = Message.create!(:board_id => board.id, :author_id => 2, :subject => 'foo', :content => 'foo')
279 279
280 280 User.find(2).destroy
281 281 assert_nil User.find_by_id(2)
282 282 assert_equal User.anonymous, message.reload.author
283 283 end
284 284
285 285 def test_destroy_should_update_news
286 286 news = News.create!(:project_id => 1, :author_id => 2, :title => 'foo', :description => 'foo')
287 287
288 288 User.find(2).destroy
289 289 assert_nil User.find_by_id(2)
290 290 assert_equal User.anonymous, news.reload.author
291 291 end
292 292
293 293 def test_destroy_should_delete_private_queries
294 294 query = Query.new(:name => 'foo', :is_public => false)
295 295 query.project_id = 1
296 296 query.user_id = 2
297 297 query.save!
298 298
299 299 User.find(2).destroy
300 300 assert_nil User.find_by_id(2)
301 301 assert_nil Query.find_by_id(query.id)
302 302 end
303 303
304 304 def test_destroy_should_update_public_queries
305 305 query = Query.new(:name => 'foo', :is_public => true)
306 306 query.project_id = 1
307 307 query.user_id = 2
308 308 query.save!
309 309
310 310 User.find(2).destroy
311 311 assert_nil User.find_by_id(2)
312 312 assert_equal User.anonymous, query.reload.user
313 313 end
314 314
315 315 def test_destroy_should_update_time_entries
316 316 entry = TimeEntry.new(:hours => '2', :spent_on => Date.today, :activity => TimeEntryActivity.create!(:name => 'foo'))
317 317 entry.project_id = 1
318 318 entry.user_id = 2
319 319 entry.save!
320 320
321 321 User.find(2).destroy
322 322 assert_nil User.find_by_id(2)
323 323 assert_equal User.anonymous, entry.reload.user
324 324 end
325 325
326 326 def test_destroy_should_delete_tokens
327 327 token = Token.create!(:user_id => 2, :value => 'foo')
328 328
329 329 User.find(2).destroy
330 330 assert_nil User.find_by_id(2)
331 331 assert_nil Token.find_by_id(token.id)
332 332 end
333 333
334 334 def test_destroy_should_delete_watchers
335 335 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'foo')
336 336 watcher = Watcher.create!(:user_id => 2, :watchable => issue)
337 337
338 338 User.find(2).destroy
339 339 assert_nil User.find_by_id(2)
340 340 assert_nil Watcher.find_by_id(watcher.id)
341 341 end
342 342
343 343 def test_destroy_should_update_wiki_contents
344 344 wiki_content = WikiContent.create!(
345 345 :text => 'foo',
346 346 :author_id => 2,
347 347 :page => WikiPage.create!(:title => 'Foo', :wiki => Wiki.create!(:project_id => 1, :start_page => 'Start'))
348 348 )
349 349 wiki_content.text = 'bar'
350 350 assert_difference 'WikiContent::Version.count' do
351 351 wiki_content.save!
352 352 end
353 353
354 354 User.find(2).destroy
355 355 assert_nil User.find_by_id(2)
356 356 assert_equal User.anonymous, wiki_content.reload.author
357 357 wiki_content.versions.each do |version|
358 358 assert_equal User.anonymous, version.reload.author
359 359 end
360 360 end
361 361
362 362 def test_destroy_should_nullify_issue_categories
363 363 category = IssueCategory.create!(:project_id => 1, :assigned_to_id => 2, :name => 'foo')
364 364
365 365 User.find(2).destroy
366 366 assert_nil User.find_by_id(2)
367 367 assert_nil category.reload.assigned_to_id
368 368 end
369 369
370 370 def test_destroy_should_nullify_changesets
371 371 changeset = Changeset.create!(
372 372 :repository => Repository::Subversion.create!(
373 373 :project_id => 1,
374 374 :url => 'file:///tmp',
375 375 :identifier => 'tmp'
376 376 ),
377 377 :revision => '12',
378 378 :committed_on => Time.now,
379 379 :committer => 'jsmith'
380 380 )
381 381 assert_equal 2, changeset.user_id
382 382
383 383 User.find(2).destroy
384 384 assert_nil User.find_by_id(2)
385 385 assert_nil changeset.reload.user_id
386 386 end
387 387
388 388 def test_anonymous_user_should_not_be_destroyable
389 389 assert_no_difference 'User.count' do
390 390 assert_equal false, User.anonymous.destroy
391 391 end
392 392 end
393 393
394 394 def test_validate_login_presence
395 395 @admin.login = ""
396 396 assert !@admin.save
397 397 assert_equal 1, @admin.errors.count
398 398 end
399 399
400 400 def test_validate_mail_notification_inclusion
401 401 u = User.new
402 402 u.mail_notification = 'foo'
403 403 u.save
404 404 assert_not_nil u.errors[:mail_notification]
405 405 end
406 406
407 context "User#try_to_login" do
408 should "fall-back to case-insensitive if user login is not found as-typed." do
409 user = User.try_to_login("AdMin", "admin")
410 assert_kind_of User, user
411 assert_equal "admin", user.login
412 end
413
414 should "select the exact matching user first" do
415 case_sensitive_user = User.generate! do |user|
416 user.password = "admin123"
417 end
418 # bypass validations to make it appear like existing data
419 case_sensitive_user.update_attribute(:login, 'ADMIN')
420
421 user = User.try_to_login("ADMIN", "admin123")
422 assert_kind_of User, user
423 assert_equal "ADMIN", user.login
407 test "User#try_to_login should fall-back to case-insensitive if user login is not found as-typed" do
408 user = User.try_to_login("AdMin", "admin")
409 assert_kind_of User, user
410 assert_equal "admin", user.login
411 end
424 412
413 test "User#try_to_login should select the exact matching user first" do
414 case_sensitive_user = User.generate! do |user|
415 user.password = "admin123"
425 416 end
417 # bypass validations to make it appear like existing data
418 case_sensitive_user.update_attribute(:login, 'ADMIN')
419
420 user = User.try_to_login("ADMIN", "admin123")
421 assert_kind_of User, user
422 assert_equal "ADMIN", user.login
426 423 end
427 424
428 425 def test_password
429 426 user = User.try_to_login("admin", "admin")
430 427 assert_kind_of User, user
431 428 assert_equal "admin", user.login
432 429 user.password = "hello123"
433 430 assert user.save
434 431
435 432 user = User.try_to_login("admin", "hello123")
436 433 assert_kind_of User, user
437 434 assert_equal "admin", user.login
438 435 end
439 436
440 437 def test_validate_password_length
441 438 with_settings :password_min_length => '100' do
442 439 user = User.new(:firstname => "new100", :lastname => "user100", :mail => "newuser100@somenet.foo")
443 440 user.login = "newuser100"
444 441 user.password, user.password_confirmation = "password100", "password100"
445 442 assert !user.save
446 443 assert_equal 1, user.errors.count
447 444 end
448 445 end
449 446
450 447 def test_name_format
451 448 assert_equal 'John S.', @jsmith.name(:firstname_lastinitial)
452 449 assert_equal 'Smith, John', @jsmith.name(:lastname_coma_firstname)
453 450 with_settings :user_format => :firstname_lastname do
454 451 assert_equal 'John Smith', @jsmith.reload.name
455 452 end
456 453 with_settings :user_format => :username do
457 454 assert_equal 'jsmith', @jsmith.reload.name
458 455 end
459 456 with_settings :user_format => :lastname do
460 457 assert_equal 'Smith', @jsmith.reload.name
461 458 end
462 459 end
463 460
464 461 def test_today_should_return_the_day_according_to_user_time_zone
465 462 preference = User.find(1).pref
466 463 date = Date.new(2012, 05, 15)
467 464 time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
468 465 Date.stubs(:today).returns(date)
469 466 Time.stubs(:now).returns(time)
470 467
471 468 preference.update_attribute :time_zone, 'Baku' # UTC+4
472 469 assert_equal '2012-05-16', User.find(1).today.to_s
473 470
474 471 preference.update_attribute :time_zone, 'La Paz' # UTC-4
475 472 assert_equal '2012-05-15', User.find(1).today.to_s
476 473
477 474 preference.update_attribute :time_zone, ''
478 475 assert_equal '2012-05-15', User.find(1).today.to_s
479 476 end
480 477
481 478 def test_time_to_date_should_return_the_date_according_to_user_time_zone
482 479 preference = User.find(1).pref
483 480 time = Time.gm(2012, 05, 15, 23, 30).utc # 2012-05-15 23:30 UTC
484 481
485 482 preference.update_attribute :time_zone, 'Baku' # UTC+4
486 483 assert_equal '2012-05-16', User.find(1).time_to_date(time).to_s
487 484
488 485 preference.update_attribute :time_zone, 'La Paz' # UTC-4
489 486 assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
490 487
491 488 preference.update_attribute :time_zone, ''
492 489 assert_equal '2012-05-15', User.find(1).time_to_date(time).to_s
493 490 end
494 491
495 492 def test_fields_for_order_statement_should_return_fields_according_user_format_setting
496 493 with_settings :user_format => 'lastname_coma_firstname' do
497 494 assert_equal ['users.lastname', 'users.firstname', 'users.id'], User.fields_for_order_statement
498 495 end
499 496 end
500 497
501 498 def test_fields_for_order_statement_width_table_name_should_prepend_table_name
502 499 with_settings :user_format => 'lastname_firstname' do
503 500 assert_equal ['authors.lastname', 'authors.firstname', 'authors.id'], User.fields_for_order_statement('authors')
504 501 end
505 502 end
506 503
507 504 def test_fields_for_order_statement_with_blank_format_should_return_default
508 505 with_settings :user_format => '' do
509 506 assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
510 507 end
511 508 end
512 509
513 510 def test_fields_for_order_statement_with_invalid_format_should_return_default
514 511 with_settings :user_format => 'foo' do
515 512 assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
516 513 end
517 514 end
518 515
519 516 def test_lock
520 517 user = User.try_to_login("jsmith", "jsmith")
521 518 assert_equal @jsmith, user
522 519
523 520 @jsmith.status = User::STATUS_LOCKED
524 521 assert @jsmith.save
525 522
526 523 user = User.try_to_login("jsmith", "jsmith")
527 524 assert_equal nil, user
528 525 end
529 526
530 context ".try_to_login" do
531 context "with good credentials" do
532 should "return the user" do
533 user = User.try_to_login("admin", "admin")
534 assert_kind_of User, user
535 assert_equal "admin", user.login
536 end
537 end
527 test ".try_to_login with good credentials should return the user" do
528 user = User.try_to_login("admin", "admin")
529 assert_kind_of User, user
530 assert_equal "admin", user.login
531 end
538 532
539 context "with wrong credentials" do
540 should "return nil" do
541 assert_nil User.try_to_login("admin", "foo")
542 end
543 end
533 test ".try_to_login with wrong credentials should return nil" do
534 assert_nil User.try_to_login("admin", "foo")
544 535 end
545 536
546 537 if ldap_configured?
547 538 context "#try_to_login using LDAP" do
548 539 context "with failed connection to the LDAP server" do
549 540 should "return nil" do
550 541 @auth_source = AuthSourceLdap.find(1)
551 542 AuthSource.any_instance.stubs(:initialize_ldap_con).raises(Net::LDAP::LdapError, 'Cannot connect')
552 543
553 544 assert_equal nil, User.try_to_login('edavis', 'wrong')
554 545 end
555 546 end
556 547
557 548 context "with an unsuccessful authentication" do
558 549 should "return nil" do
559 550 assert_equal nil, User.try_to_login('edavis', 'wrong')
560 551 end
561 552 end
562 553
563 554 context "binding with user's account" do
564 555 setup do
565 556 @auth_source = AuthSourceLdap.find(1)
566 557 @auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
567 558 @auth_source.account_password = ''
568 559 @auth_source.save!
569 560
570 561 @ldap_user = User.new(:mail => 'example1@redmine.org', :firstname => 'LDAP', :lastname => 'user', :auth_source_id => 1)
571 562 @ldap_user.login = 'example1'
572 563 @ldap_user.save!
573 564 end
574 565
575 566 context "with a successful authentication" do
576 567 should "return the user" do
577 568 assert_equal @ldap_user, User.try_to_login('example1', '123456')
578 569 end
579 570 end
580 571
581 572 context "with an unsuccessful authentication" do
582 573 should "return nil" do
583 574 assert_nil User.try_to_login('example1', '11111')
584 575 end
585 576 end
586 577 end
587 578
588 579 context "on the fly registration" do
589 580 setup do
590 581 @auth_source = AuthSourceLdap.find(1)
591 582 @auth_source.update_attribute :onthefly_register, true
592 583 end
593 584
594 585 context "with a successful authentication" do
595 586 should "create a new user account if it doesn't exist" do
596 587 assert_difference('User.count') do
597 588 user = User.try_to_login('edavis', '123456')
598 589 assert !user.admin?
599 590 end
600 591 end
601 592
602 593 should "retrieve existing user" do
603 594 user = User.try_to_login('edavis', '123456')
604 595 user.admin = true
605 596 user.save!
606 597
607 598 assert_no_difference('User.count') do
608 599 user = User.try_to_login('edavis', '123456')
609 600 assert user.admin?
610 601 end
611 602 end
612 603 end
613 604
614 605 context "binding with user's account" do
615 606 setup do
616 607 @auth_source = AuthSourceLdap.find(1)
617 608 @auth_source.account = "uid=$login,ou=Person,dc=redmine,dc=org"
618 609 @auth_source.account_password = ''
619 610 @auth_source.save!
620 611 end
621 612
622 613 context "with a successful authentication" do
623 614 should "create a new user account if it doesn't exist" do
624 615 assert_difference('User.count') do
625 616 user = User.try_to_login('example1', '123456')
626 617 assert_kind_of User, user
627 618 end
628 619 end
629 620 end
630 621
631 622 context "with an unsuccessful authentication" do
632 623 should "return nil" do
633 624 assert_nil User.try_to_login('example1', '11111')
634 625 end
635 626 end
636 627 end
637 628 end
638 629 end
639 630
640 631 else
641 632 puts "Skipping LDAP tests."
642 633 end
643 634
644 635 def test_create_anonymous
645 636 AnonymousUser.delete_all
646 637 anon = User.anonymous
647 638 assert !anon.new_record?
648 639 assert_kind_of AnonymousUser, anon
649 640 end
650 641
651 642 def test_ensure_single_anonymous_user
652 643 AnonymousUser.delete_all
653 644 anon1 = User.anonymous
654 645 assert !anon1.new_record?
655 646 assert_kind_of AnonymousUser, anon1
656 647 anon2 = AnonymousUser.create(
657 648 :lastname => 'Anonymous', :firstname => '',
658 649 :mail => '', :login => '', :status => 0)
659 650 assert_equal 1, anon2.errors.count
660 651 end
661 652
662 653 def test_rss_key
663 654 assert_nil @jsmith.rss_token
664 655 key = @jsmith.rss_key
665 656 assert_equal 40, key.length
666 657
667 658 @jsmith.reload
668 659 assert_equal key, @jsmith.rss_key
669 660 end
670 661
671 662 def test_rss_key_should_not_be_generated_twice
672 663 assert_difference 'Token.count', 1 do
673 664 key1 = @jsmith.rss_key
674 665 key2 = @jsmith.rss_key
675 666 assert_equal key1, key2
676 667 end
677 668 end
678 669
679 670 def test_api_key_should_not_be_generated_twice
680 671 assert_difference 'Token.count', 1 do
681 672 key1 = @jsmith.api_key
682 673 key2 = @jsmith.api_key
683 674 assert_equal key1, key2
684 675 end
685 676 end
686 677
687 context "User#api_key" do
688 should "generate a new one if the user doesn't have one" do
689 user = User.generate!(:api_token => nil)
690 assert_nil user.api_token
678 test "#api_key should generate a new one if the user doesn't have one" do
679 user = User.generate!(:api_token => nil)
680 assert_nil user.api_token
691 681
692 key = user.api_key
693 assert_equal 40, key.length
694 user.reload
695 assert_equal key, user.api_key
696 end
682 key = user.api_key
683 assert_equal 40, key.length
684 user.reload
685 assert_equal key, user.api_key
686 end
697 687
698 should "return the existing api token value" do
699 user = User.generate!
700 token = Token.create!(:action => 'api')
701 user.api_token = token
702 assert user.save
688 test "#api_key should return the existing api token value" do
689 user = User.generate!
690 token = Token.create!(:action => 'api')
691 user.api_token = token
692 assert user.save
703 693
704 assert_equal token.value, user.api_key
705 end
694 assert_equal token.value, user.api_key
706 695 end
707 696
708 context "User#find_by_api_key" do
709 should "return nil if no matching key is found" do
710 assert_nil User.find_by_api_key('zzzzzzzzz')
711 end
697 test "#find_by_api_key should return nil if no matching key is found" do
698 assert_nil User.find_by_api_key('zzzzzzzzz')
699 end
712 700
713 should "return nil if the key is found for an inactive user" do
714 user = User.generate!
715 user.status = User::STATUS_LOCKED
716 token = Token.create!(:action => 'api')
717 user.api_token = token
718 user.save
701 test "#find_by_api_key should return nil if the key is found for an inactive user" do
702 user = User.generate!
703 user.status = User::STATUS_LOCKED
704 token = Token.create!(:action => 'api')
705 user.api_token = token
706 user.save
719 707
720 assert_nil User.find_by_api_key(token.value)
721 end
708 assert_nil User.find_by_api_key(token.value)
709 end
722 710
723 should "return the user if the key is found for an active user" do
724 user = User.generate!
725 token = Token.create!(:action => 'api')
726 user.api_token = token
727 user.save
711 test "#find_by_api_key should return the user if the key is found for an active user" do
712 user = User.generate!
713 token = Token.create!(:action => 'api')
714 user.api_token = token
715 user.save
728 716
729 assert_equal user, User.find_by_api_key(token.value)
730 end
717 assert_equal user, User.find_by_api_key(token.value)
731 718 end
732 719
733 720 def test_default_admin_account_changed_should_return_false_if_account_was_not_changed
734 721 user = User.find_by_login("admin")
735 722 user.password = "admin"
736 723 assert user.save(:validate => false)
737 724
738 725 assert_equal false, User.default_admin_account_changed?
739 726 end
740 727
741 728 def test_default_admin_account_changed_should_return_true_if_password_was_changed
742 729 user = User.find_by_login("admin")
743 730 user.password = "newpassword"
744 731 user.save!
745 732
746 733 assert_equal true, User.default_admin_account_changed?
747 734 end
748 735
749 736 def test_default_admin_account_changed_should_return_true_if_account_is_disabled
750 737 user = User.find_by_login("admin")
751 738 user.password = "admin"
752 739 user.status = User::STATUS_LOCKED
753 740 assert user.save(:validate => false)
754 741
755 742 assert_equal true, User.default_admin_account_changed?
756 743 end
757 744
758 745 def test_default_admin_account_changed_should_return_true_if_account_does_not_exist
759 746 user = User.find_by_login("admin")
760 747 user.destroy
761 748
762 749 assert_equal true, User.default_admin_account_changed?
763 750 end
764 751
765 752 def test_membership_with_project_should_return_membership
766 753 project = Project.find(1)
767 754
768 755 membership = @jsmith.membership(project)
769 756 assert_kind_of Member, membership
770 757 assert_equal @jsmith, membership.user
771 758 assert_equal project, membership.project
772 759 end
773 760
774 761 def test_membership_with_project_id_should_return_membership
775 762 project = Project.find(1)
776 763
777 764 membership = @jsmith.membership(1)
778 765 assert_kind_of Member, membership
779 766 assert_equal @jsmith, membership.user
780 767 assert_equal project, membership.project
781 768 end
782 769
783 770 def test_membership_for_non_member_should_return_nil
784 771 project = Project.find(1)
785 772
786 773 user = User.generate!
787 774 membership = user.membership(1)
788 775 assert_nil membership
789 776 end
790 777
791 778 def test_roles_for_project
792 779 # user with a role
793 780 roles = @jsmith.roles_for_project(Project.find(1))
794 781 assert_kind_of Role, roles.first
795 782 assert_equal "Manager", roles.first.name
796 783
797 784 # user with no role
798 785 assert_nil @dlopper.roles_for_project(Project.find(2)).detect {|role| role.member?}
799 786 end
800 787
801 788 def test_projects_by_role_for_user_with_role
802 789 user = User.find(2)
803 790 assert_kind_of Hash, user.projects_by_role
804 791 assert_equal 2, user.projects_by_role.size
805 792 assert_equal [1,5], user.projects_by_role[Role.find(1)].collect(&:id).sort
806 793 assert_equal [2], user.projects_by_role[Role.find(2)].collect(&:id).sort
807 794 end
808 795
809 796 def test_accessing_projects_by_role_with_no_projects_should_return_an_empty_array
810 797 user = User.find(2)
811 798 assert_equal [], user.projects_by_role[Role.find(3)]
812 799 # should not update the hash
813 800 assert_nil user.projects_by_role.values.detect(&:blank?)
814 801 end
815 802
816 803 def test_projects_by_role_for_user_with_no_role
817 804 user = User.generate!
818 805 assert_equal({}, user.projects_by_role)
819 806 end
820 807
821 808 def test_projects_by_role_for_anonymous
822 809 assert_equal({}, User.anonymous.projects_by_role)
823 810 end
824 811
825 812 def test_valid_notification_options
826 813 # without memberships
827 814 assert_equal 5, User.find(7).valid_notification_options.size
828 815 # with memberships
829 816 assert_equal 6, User.find(2).valid_notification_options.size
830 817 end
831 818
832 819 def test_valid_notification_options_class_method
833 820 assert_equal 5, User.valid_notification_options.size
834 821 assert_equal 5, User.valid_notification_options(User.find(7)).size
835 822 assert_equal 6, User.valid_notification_options(User.find(2)).size
836 823 end
837 824
838 825 def test_mail_notification_all
839 826 @jsmith.mail_notification = 'all'
840 827 @jsmith.notified_project_ids = []
841 828 @jsmith.save
842 829 @jsmith.reload
843 830 assert @jsmith.projects.first.recipients.include?(@jsmith.mail)
844 831 end
845 832
846 833 def test_mail_notification_selected
847 834 @jsmith.mail_notification = 'selected'
848 835 @jsmith.notified_project_ids = [1]
849 836 @jsmith.save
850 837 @jsmith.reload
851 838 assert Project.find(1).recipients.include?(@jsmith.mail)
852 839 end
853 840
854 841 def test_mail_notification_only_my_events
855 842 @jsmith.mail_notification = 'only_my_events'
856 843 @jsmith.notified_project_ids = []
857 844 @jsmith.save
858 845 @jsmith.reload
859 846 assert !@jsmith.projects.first.recipients.include?(@jsmith.mail)
860 847 end
861 848
862 849 def test_comments_sorting_preference
863 850 assert !@jsmith.wants_comments_in_reverse_order?
864 851 @jsmith.pref.comments_sorting = 'asc'
865 852 assert !@jsmith.wants_comments_in_reverse_order?
866 853 @jsmith.pref.comments_sorting = 'desc'
867 854 assert @jsmith.wants_comments_in_reverse_order?
868 855 end
869 856
870 857 def test_find_by_mail_should_be_case_insensitive
871 858 u = User.find_by_mail('JSmith@somenet.foo')
872 859 assert_not_nil u
873 860 assert_equal 'jsmith@somenet.foo', u.mail
874 861 end
875 862
876 863 def test_random_password
877 864 u = User.new
878 865 u.random_password
879 866 assert !u.password.blank?
880 867 assert !u.password_confirmation.blank?
881 868 end
882 869
883 context "#change_password_allowed?" do
884 should "be allowed if no auth source is set" do
885 user = User.generate!
886 assert user.change_password_allowed?
887 end
870 test "#change_password_allowed? should be allowed if no auth source is set" do
871 user = User.generate!
872 assert user.change_password_allowed?
873 end
888 874
889 should "delegate to the auth source" do
890 user = User.generate!
875 test "#change_password_allowed? should delegate to the auth source" do
876 user = User.generate!
891 877
892 allowed_auth_source = AuthSource.generate!
893 def allowed_auth_source.allow_password_changes?; true; end
878 allowed_auth_source = AuthSource.generate!
879 def allowed_auth_source.allow_password_changes?; true; end
894 880
895 denied_auth_source = AuthSource.generate!
896 def denied_auth_source.allow_password_changes?; false; end
881 denied_auth_source = AuthSource.generate!
882 def denied_auth_source.allow_password_changes?; false; end
897 883
898 assert user.change_password_allowed?
884 assert user.change_password_allowed?
899 885
900 user.auth_source = allowed_auth_source
901 assert user.change_password_allowed?, "User not allowed to change password, though auth source does"
886 user.auth_source = allowed_auth_source
887 assert user.change_password_allowed?, "User not allowed to change password, though auth source does"
902 888
903 user.auth_source = denied_auth_source
904 assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
905 end
889 user.auth_source = denied_auth_source
890 assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
906 891 end
907 892
908 893 def test_own_account_deletable_should_be_true_with_unsubscrive_enabled
909 894 with_settings :unsubscribe => '1' do
910 895 assert_equal true, User.find(2).own_account_deletable?
911 896 end
912 897 end
913 898
914 899 def test_own_account_deletable_should_be_false_with_unsubscrive_disabled
915 900 with_settings :unsubscribe => '0' do
916 901 assert_equal false, User.find(2).own_account_deletable?
917 902 end
918 903 end
919 904
920 905 def test_own_account_deletable_should_be_false_for_a_single_admin
921 906 User.delete_all(["admin = ? AND id <> ?", true, 1])
922 907
923 908 with_settings :unsubscribe => '1' do
924 909 assert_equal false, User.find(1).own_account_deletable?
925 910 end
926 911 end
927 912
928 913 def test_own_account_deletable_should_be_true_for_an_admin_if_other_admin_exists
929 914 User.generate! do |user|
930 915 user.admin = true
931 916 end
932 917
933 918 with_settings :unsubscribe => '1' do
934 919 assert_equal true, User.find(1).own_account_deletable?
935 920 end
936 921 end
937 922
938 923 context "#allowed_to?" do
939 924 context "with a unique project" do
940 925 should "return false if project is archived" do
941 926 project = Project.find(1)
942 927 Project.any_instance.stubs(:status).returns(Project::STATUS_ARCHIVED)
943 928 assert_equal false, @admin.allowed_to?(:view_issues, Project.find(1))
944 929 end
945 930
946 931 should "return false for write action if project is closed" do
947 932 project = Project.find(1)
948 933 Project.any_instance.stubs(:status).returns(Project::STATUS_CLOSED)
949 934 assert_equal false, @admin.allowed_to?(:edit_project, Project.find(1))
950 935 end
951 936
952 937 should "return true for read action if project is closed" do
953 938 project = Project.find(1)
954 939 Project.any_instance.stubs(:status).returns(Project::STATUS_CLOSED)
955 940 assert_equal true, @admin.allowed_to?(:view_project, Project.find(1))
956 941 end
957 942
958 943 should "return false if related module is disabled" do
959 944 project = Project.find(1)
960 945 project.enabled_module_names = ["issue_tracking"]
961 946 assert_equal true, @admin.allowed_to?(:add_issues, project)
962 947 assert_equal false, @admin.allowed_to?(:view_wiki_pages, project)
963 948 end
964 949
965 950 should "authorize nearly everything for admin users" do
966 951 project = Project.find(1)
967 952 assert ! @admin.member_of?(project)
968 953 %w(edit_issues delete_issues manage_news add_documents manage_wiki).each do |p|
969 954 assert_equal true, @admin.allowed_to?(p.to_sym, project)
970 955 end
971 956 end
972 957
973 958 should "authorize normal users depending on their roles" do
974 959 project = Project.find(1)
975 960 assert_equal true, @jsmith.allowed_to?(:delete_messages, project) #Manager
976 961 assert_equal false, @dlopper.allowed_to?(:delete_messages, project) #Developper
977 962 end
978 963 end
979 964
980 965 context "with multiple projects" do
981 966 should "return false if array is empty" do
982 967 assert_equal false, @admin.allowed_to?(:view_project, [])
983 968 end
984 969
985 970 should "return true only if user has permission on all these projects" do
986 971 assert_equal true, @admin.allowed_to?(:view_project, Project.all)
987 972 assert_equal false, @dlopper.allowed_to?(:view_project, Project.all) #cannot see Project(2)
988 973 assert_equal true, @jsmith.allowed_to?(:edit_issues, @jsmith.projects) #Manager or Developer everywhere
989 974 assert_equal false, @jsmith.allowed_to?(:delete_issue_watchers, @jsmith.projects) #Dev cannot delete_issue_watchers
990 975 end
991 976
992 977 should "behave correctly with arrays of 1 project" do
993 978 assert_equal false, User.anonymous.allowed_to?(:delete_issues, [Project.first])
994 979 end
995 980 end
996 981
997 982 context "with options[:global]" do
998 983 should "authorize if user has at least one role that has this permission" do
999 984 @dlopper2 = User.find(5) #only Developper on a project, not Manager anywhere
1000 985 @anonymous = User.find(6)
1001 986 assert_equal true, @jsmith.allowed_to?(:delete_issue_watchers, nil, :global => true)
1002 987 assert_equal false, @dlopper2.allowed_to?(:delete_issue_watchers, nil, :global => true)
1003 988 assert_equal true, @dlopper2.allowed_to?(:add_issues, nil, :global => true)
1004 989 assert_equal false, @anonymous.allowed_to?(:add_issues, nil, :global => true)
1005 990 assert_equal true, @anonymous.allowed_to?(:view_issues, nil, :global => true)
1006 991 end
1007 992 end
1008 993 end
1009 994
1010 995 context "User#notify_about?" do
1011 996 context "Issues" do
1012 997 setup do
1013 998 @project = Project.find(1)
1014 999 @author = User.generate!
1015 1000 @assignee = User.generate!
1016 1001 @issue = Issue.generate!(:project => @project, :assigned_to => @assignee, :author => @author)
1017 1002 end
1018 1003
1019 1004 should "be true for a user with :all" do
1020 1005 @author.update_attribute(:mail_notification, 'all')
1021 1006 assert @author.notify_about?(@issue)
1022 1007 end
1023 1008
1024 1009 should "be false for a user with :none" do
1025 1010 @author.update_attribute(:mail_notification, 'none')
1026 1011 assert ! @author.notify_about?(@issue)
1027 1012 end
1028 1013
1029 1014 should "be false for a user with :only_my_events and isn't an author, creator, or assignee" do
1030 1015 @user = User.generate!(:mail_notification => 'only_my_events')
1031 1016 Member.create!(:user => @user, :project => @project, :role_ids => [1])
1032 1017 assert ! @user.notify_about?(@issue)
1033 1018 end
1034 1019
1035 1020 should "be true for a user with :only_my_events and is the author" do
1036 1021 @author.update_attribute(:mail_notification, 'only_my_events')
1037 1022 assert @author.notify_about?(@issue)
1038 1023 end
1039 1024
1040 1025 should "be true for a user with :only_my_events and is the assignee" do
1041 1026 @assignee.update_attribute(:mail_notification, 'only_my_events')
1042 1027 assert @assignee.notify_about?(@issue)
1043 1028 end
1044 1029
1045 1030 should "be true for a user with :only_assigned and is the assignee" do
1046 1031 @assignee.update_attribute(:mail_notification, 'only_assigned')
1047 1032 assert @assignee.notify_about?(@issue)
1048 1033 end
1049 1034
1050 1035 should "be false for a user with :only_assigned and is not the assignee" do
1051 1036 @author.update_attribute(:mail_notification, 'only_assigned')
1052 1037 assert ! @author.notify_about?(@issue)
1053 1038 end
1054 1039
1055 1040 should "be true for a user with :only_owner and is the author" do
1056 1041 @author.update_attribute(:mail_notification, 'only_owner')
1057 1042 assert @author.notify_about?(@issue)
1058 1043 end
1059 1044
1060 1045 should "be false for a user with :only_owner and is not the author" do
1061 1046 @assignee.update_attribute(:mail_notification, 'only_owner')
1062 1047 assert ! @assignee.notify_about?(@issue)
1063 1048 end
1064 1049
1065 1050 should "be true for a user with :selected and is the author" do
1066 1051 @author.update_attribute(:mail_notification, 'selected')
1067 1052 assert @author.notify_about?(@issue)
1068 1053 end
1069 1054
1070 1055 should "be true for a user with :selected and is the assignee" do
1071 1056 @assignee.update_attribute(:mail_notification, 'selected')
1072 1057 assert @assignee.notify_about?(@issue)
1073 1058 end
1074 1059
1075 1060 should "be false for a user with :selected and is not the author or assignee" do
1076 1061 @user = User.generate!(:mail_notification => 'selected')
1077 1062 Member.create!(:user => @user, :project => @project, :role_ids => [1])
1078 1063 assert ! @user.notify_about?(@issue)
1079 1064 end
1080 1065 end
1081 1066 end
1082 1067
1083 1068 def test_notify_about_news
1084 1069 user = User.generate!
1085 1070 news = News.new
1086 1071
1087 1072 User::MAIL_NOTIFICATION_OPTIONS.map(&:first).each do |option|
1088 1073 user.mail_notification = option
1089 1074 assert_equal (option != 'none'), user.notify_about?(news)
1090 1075 end
1091 1076 end
1092 1077
1093 1078 def test_salt_unsalted_passwords
1094 1079 # Restore a user with an unsalted password
1095 1080 user = User.find(1)
1096 1081 user.salt = nil
1097 1082 user.hashed_password = User.hash_password("unsalted")
1098 1083 user.save!
1099 1084
1100 1085 User.salt_unsalted_passwords!
1101 1086
1102 1087 user.reload
1103 1088 # Salt added
1104 1089 assert !user.salt.blank?
1105 1090 # Password still valid
1106 1091 assert user.check_password?("unsalted")
1107 1092 assert_equal user, User.try_to_login(user.login, "unsalted")
1108 1093 end
1109 1094
1110 1095 if Object.const_defined?(:OpenID)
1111 1096
1112 1097 def test_setting_identity_url
1113 1098 normalized_open_id_url = 'http://example.com/'
1114 1099 u = User.new( :identity_url => 'http://example.com/' )
1115 1100 assert_equal normalized_open_id_url, u.identity_url
1116 1101 end
1117 1102
1118 1103 def test_setting_identity_url_without_trailing_slash
1119 1104 normalized_open_id_url = 'http://example.com/'
1120 1105 u = User.new( :identity_url => 'http://example.com' )
1121 1106 assert_equal normalized_open_id_url, u.identity_url
1122 1107 end
1123 1108
1124 1109 def test_setting_identity_url_without_protocol
1125 1110 normalized_open_id_url = 'http://example.com/'
1126 1111 u = User.new( :identity_url => 'example.com' )
1127 1112 assert_equal normalized_open_id_url, u.identity_url
1128 1113 end
1129 1114
1130 1115 def test_setting_blank_identity_url
1131 1116 u = User.new( :identity_url => 'example.com' )
1132 1117 u.identity_url = ''
1133 1118 assert u.identity_url.blank?
1134 1119 end
1135 1120
1136 1121 def test_setting_invalid_identity_url
1137 1122 u = User.new( :identity_url => 'this is not an openid url' )
1138 1123 assert u.identity_url.blank?
1139 1124 end
1140 1125
1141 1126 else
1142 1127 puts "Skipping openid tests."
1143 1128 end
1144 1129
1145 1130 end
@@ -1,254 +1,243
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2013 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class VersionTest < ActiveSupport::TestCase
21 21 fixtures :projects, :users, :issues, :issue_statuses, :trackers, :enumerations, :versions, :projects_trackers
22 22
23 23 def setup
24 24 end
25 25
26 26 def test_create
27 27 v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '2011-03-25')
28 28 assert v.save
29 29 assert_equal 'open', v.status
30 30 assert_equal 'none', v.sharing
31 31 end
32 32
33 33 def test_invalid_effective_date_validation
34 34 v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '99999-01-01')
35 35 assert !v.valid?
36 36 v.effective_date = '2012-11-33'
37 37 assert !v.valid?
38 38 v.effective_date = '2012-31-11'
39 39 assert !v.valid?
40 40 v.effective_date = '-2012-31-11'
41 41 assert !v.valid?
42 42 v.effective_date = 'ABC'
43 43 assert !v.valid?
44 44 assert_include I18n.translate('activerecord.errors.messages.not_a_date'),
45 45 v.errors[:effective_date]
46 46 end
47 47
48 48 def test_progress_should_be_0_with_no_assigned_issues
49 49 project = Project.find(1)
50 50 v = Version.create!(:project => project, :name => 'Progress')
51 51 assert_equal 0, v.completed_percent
52 52 assert_equal 0, v.closed_percent
53 53 end
54 54
55 55 def test_progress_should_be_0_with_unbegun_assigned_issues
56 56 project = Project.find(1)
57 57 v = Version.create!(:project => project, :name => 'Progress')
58 58 add_issue(v)
59 59 add_issue(v, :done_ratio => 0)
60 60 assert_progress_equal 0, v.completed_percent
61 61 assert_progress_equal 0, v.closed_percent
62 62 end
63 63
64 64 def test_progress_should_be_100_with_closed_assigned_issues
65 65 project = Project.find(1)
66 66 status = IssueStatus.where(:is_closed => true).first
67 67 v = Version.create!(:project => project, :name => 'Progress')
68 68 add_issue(v, :status => status)
69 69 add_issue(v, :status => status, :done_ratio => 20)
70 70 add_issue(v, :status => status, :done_ratio => 70, :estimated_hours => 25)
71 71 add_issue(v, :status => status, :estimated_hours => 15)
72 72 assert_progress_equal 100.0, v.completed_percent
73 73 assert_progress_equal 100.0, v.closed_percent
74 74 end
75 75
76 76 def test_progress_should_consider_done_ratio_of_open_assigned_issues
77 77 project = Project.find(1)
78 78 v = Version.create!(:project => project, :name => 'Progress')
79 79 add_issue(v)
80 80 add_issue(v, :done_ratio => 20)
81 81 add_issue(v, :done_ratio => 70)
82 82 assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_percent
83 83 assert_progress_equal 0, v.closed_percent
84 84 end
85 85
86 86 def test_progress_should_consider_closed_issues_as_completed
87 87 project = Project.find(1)
88 88 v = Version.create!(:project => project, :name => 'Progress')
89 89 add_issue(v)
90 90 add_issue(v, :done_ratio => 20)
91 91 add_issue(v, :status => IssueStatus.where(:is_closed => true).first)
92 92 assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_percent
93 93 assert_progress_equal (100.0)/3, v.closed_percent
94 94 end
95 95
96 96 def test_progress_should_consider_estimated_hours_to_weigth_issues
97 97 project = Project.find(1)
98 98 v = Version.create!(:project => project, :name => 'Progress')
99 99 add_issue(v, :estimated_hours => 10)
100 100 add_issue(v, :estimated_hours => 20, :done_ratio => 30)
101 101 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
102 102 add_issue(v, :estimated_hours => 25, :status => IssueStatus.where(:is_closed => true).first)
103 103 assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_percent
104 104 assert_progress_equal 25.0/95.0*100, v.closed_percent
105 105 end
106 106
107 107 def test_progress_should_consider_average_estimated_hours_to_weigth_unestimated_issues
108 108 project = Project.find(1)
109 109 v = Version.create!(:project => project, :name => 'Progress')
110 110 add_issue(v, :done_ratio => 20)
111 111 add_issue(v, :status => IssueStatus.where(:is_closed => true).first)
112 112 add_issue(v, :estimated_hours => 10, :done_ratio => 30)
113 113 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
114 114 assert_progress_equal (25.0*0.2 + 25.0*1 + 10.0*0.3 + 40.0*0.1)/100.0*100, v.completed_percent
115 115 assert_progress_equal 25.0/100.0*100, v.closed_percent
116 116 end
117 117
118 118 def test_should_sort_scheduled_then_unscheduled_versions
119 119 Version.delete_all
120 120 v4 = Version.create!(:project_id => 1, :name => 'v4')
121 121 v3 = Version.create!(:project_id => 1, :name => 'v2', :effective_date => '2012-07-14')
122 122 v2 = Version.create!(:project_id => 1, :name => 'v1')
123 123 v1 = Version.create!(:project_id => 1, :name => 'v3', :effective_date => '2012-08-02')
124 124 v5 = Version.create!(:project_id => 1, :name => 'v5', :effective_date => '2012-07-02')
125 125
126 126 assert_equal [v5, v3, v1, v2, v4], [v1, v2, v3, v4, v5].sort
127 127 assert_equal [v5, v3, v1, v2, v4], Version.sorted.all
128 128 end
129 129
130 130 def test_completed_should_be_false_when_due_today
131 131 version = Version.create!(:project_id => 1, :effective_date => Date.today, :name => 'Due today')
132 132 assert_equal false, version.completed?
133 133 end
134 134
135 context "#behind_schedule?" do
136 setup do
137 ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
138 @project = Project.create!(:name => 'test0', :identifier => 'test0')
139 @project.trackers << Tracker.create!(:name => 'track')
140
141 @version = Version.create!(:project => @project, :effective_date => nil, :name => 'version')
142 end
143
144 should "be false if there are no issues assigned" do
145 @version.update_attribute(:effective_date, Date.yesterday)
146 assert_equal false, @version.behind_schedule?
147 end
148
149 should "be false if there is no effective_date" do
150 assert_equal false, @version.behind_schedule?
151 end
152
153 should "be false if all of the issues are ahead of schedule" do
154 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
155 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
156 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
157 assert_equal 60, @version.completed_percent
158 assert_equal false, @version.behind_schedule?
159 end
160
161 should "be true if any of the issues are behind schedule" do
162 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
163 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
164 add_issue(@version, :start_date => 7.days.ago, :done_ratio => 20) # 14 day span, 20% done, 50% time left
165 assert_equal 40, @version.completed_percent
166 assert_equal true, @version.behind_schedule?
167 end
168
169 should "be false if all of the issues are complete" do
170 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
171 add_issue(@version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
172 add_issue(@version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
173 assert_equal 100, @version.completed_percent
174 assert_equal false, @version.behind_schedule?
175 end
176 end
177
178 context "#estimated_hours" do
179 setup do
180 @version = Version.create!(:project_id => 1, :name => '#estimated_hours')
181 end
182
183 should "return 0 with no assigned issues" do
184 assert_equal 0, @version.estimated_hours
185 end
186
187 should "return 0 with no estimated hours" do
188 add_issue(@version)
189 assert_equal 0, @version.estimated_hours
190 end
191
192 should "return the sum of estimated hours" do
193 add_issue(@version, :estimated_hours => 2.5)
194 add_issue(@version, :estimated_hours => 5)
195 assert_equal 7.5, @version.estimated_hours
196 end
197
198 should "return the sum of leaves estimated hours" do
199 parent = add_issue(@version)
200 add_issue(@version, :estimated_hours => 2.5, :parent_issue_id => parent.id)
201 add_issue(@version, :estimated_hours => 5, :parent_issue_id => parent.id)
202 assert_equal 7.5, @version.estimated_hours
203 end
135 test "#behind_schedule? should be false if there are no issues assigned" do
136 version = Version.generate!(:effective_date => Date.yesterday)
137 assert_equal false, version.behind_schedule?
138 end
139
140 test "#behind_schedule? should be false if there is no effective_date" do
141 version = Version.generate!(:effective_date => nil)
142 assert_equal false, version.behind_schedule?
143 end
144
145 test "#behind_schedule? should be false if all of the issues are ahead of schedule" do
146 version = Version.generate!(:effective_date => 7.days.from_now.to_date)
147 add_issue(version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
148 add_issue(version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
149 assert_equal 60, version.completed_percent
150 assert_equal false, version.behind_schedule?
151 end
152
153 test "#behind_schedule? should be true if any of the issues are behind schedule" do
154 version = Version.generate!(:effective_date => 7.days.from_now.to_date)
155 add_issue(version, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
156 add_issue(version, :start_date => 7.days.ago, :done_ratio => 20) # 14 day span, 20% done, 50% time left
157 assert_equal 40, version.completed_percent
158 assert_equal true, version.behind_schedule?
159 end
160
161 test "#behind_schedule? should be false if all of the issues are complete" do
162 version = Version.generate!(:effective_date => 7.days.from_now.to_date)
163 add_issue(version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
164 add_issue(version, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
165 assert_equal 100, version.completed_percent
166 assert_equal false, version.behind_schedule?
167 end
168
169 test "#estimated_hours should return 0 with no assigned issues" do
170 version = Version.generate!
171 assert_equal 0, version.estimated_hours
172 end
173
174 test "#estimated_hours should return 0 with no estimated hours" do
175 version = Version.generate!
176 add_issue(version)
177 assert_equal 0, version.estimated_hours
178 end
179
180 test "#estimated_hours should return return the sum of estimated hours" do
181 version = Version.generate!
182 add_issue(version, :estimated_hours => 2.5)
183 add_issue(version, :estimated_hours => 5)
184 assert_equal 7.5, version.estimated_hours
185 end
186
187 test "#estimated_hours should return the sum of leaves estimated hours" do
188 version = Version.generate!
189 parent = add_issue(version)
190 add_issue(version, :estimated_hours => 2.5, :parent_issue_id => parent.id)
191 add_issue(version, :estimated_hours => 5, :parent_issue_id => parent.id)
192 assert_equal 7.5, version.estimated_hours
204 193 end
205 194
206 195 test "should update all issue's fixed_version associations in case the hierarchy changed XXX" do
207 196 User.current = User.find(1) # Need the admin's permissions
208 197
209 198 @version = Version.find(7)
210 199 # Separate hierarchy
211 200 project_1_issue = Issue.find(1)
212 201 project_1_issue.fixed_version = @version
213 202 assert project_1_issue.save, project_1_issue.errors.full_messages.to_s
214 203
215 204 project_5_issue = Issue.find(6)
216 205 project_5_issue.fixed_version = @version
217 206 assert project_5_issue.save
218 207
219 208 # Project
220 209 project_2_issue = Issue.find(4)
221 210 project_2_issue.fixed_version = @version
222 211 assert project_2_issue.save
223 212
224 213 # Update the sharing
225 214 @version.sharing = 'none'
226 215 assert @version.save
227 216
228 217 # Project 1 now out of the shared scope
229 218 project_1_issue.reload
230 219 assert_equal nil, project_1_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
231 220
232 221 # Project 5 now out of the shared scope
233 222 project_5_issue.reload
234 223 assert_equal nil, project_5_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
235 224
236 225 # Project 2 issue remains
237 226 project_2_issue.reload
238 227 assert_equal @version, project_2_issue.fixed_version
239 228 end
240 229
241 230 private
242 231
243 232 def add_issue(version, attributes={})
244 233 Issue.create!({:project => version.project,
245 234 :fixed_version => version,
246 235 :subject => 'Test',
247 236 :author => User.first,
248 237 :tracker => version.project.trackers.first}.merge(attributes))
249 238 end
250 239
251 240 def assert_progress_equal(expected_float, actual_float, message="")
252 241 assert_in_delta(expected_float, actual_float, 0.000001, message="")
253 242 end
254 243 end
General Comments 0
You need to be logged in to leave comments. Login now