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