##// END OF EJS Templates
Added project specific Enumeration overrides....
Eric Davis -
r2833:29301c8a381a
parent child
Show More
@@ -0,0 +1,11
1 class AddProjectToEnumerations < ActiveRecord::Migration
2 def self.up
3 add_column :enumerations, :project_id, :integer, :null => true, :default => nil
4 add_index :enumerations, :project_id
5 end
6
7 def self.down
8 remove_index :enumerations, :project_id
9 remove_column :enumerations, :project_id
10 end
11 end
@@ -0,0 +1,9
1 class AddParentIdToEnumerations < ActiveRecord::Migration
2 def self.up
3 add_column :enumerations, :parent_id, :integer, :null => true, :default => nil
4 end
5
6 def self.down
7 remove_column :enumerations, :parent_id
8 end
9 end
@@ -1,140 +1,148
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 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 class Enumeration < ActiveRecord::Base
18 class Enumeration < ActiveRecord::Base
19 belongs_to :project
20
19 acts_as_list :scope => 'type = \'#{type}\''
21 acts_as_list :scope => 'type = \'#{type}\''
20 acts_as_customizable
22 acts_as_customizable
23 acts_as_tree :order => 'position ASC'
21
24
22 before_destroy :check_integrity
25 before_destroy :check_integrity
23
26
24 validates_presence_of :name
27 validates_presence_of :name
25 validates_uniqueness_of :name, :scope => [:type]
28 validates_uniqueness_of :name, :scope => [:type]
26 validates_length_of :name, :maximum => 30
29 validates_length_of :name, :maximum => 30
27
30
28 # Backwards compatiblity named_scopes.
31 # Backwards compatiblity named_scopes.
29 # Can be removed post-0.9
32 # Can be removed post-0.9
30 named_scope :priorities, :conditions => { :type => "IssuePriority" }, :order => 'position' do
33 named_scope :priorities, :conditions => { :type => "IssuePriority" }, :order => 'position' do
31 ActiveSupport::Deprecation.warn("Enumeration#priorities is deprecated, use the IssuePriority class. (#{Redmine::Info.issue(3007)})")
34 ActiveSupport::Deprecation.warn("Enumeration#priorities is deprecated, use the IssuePriority class. (#{Redmine::Info.issue(3007)})")
32 def default
35 def default
33 find(:first, :conditions => { :is_default => true })
36 find(:first, :conditions => { :is_default => true })
34 end
37 end
35 end
38 end
36
39
37 named_scope :document_categories, :conditions => { :type => "DocumentCategory" }, :order => 'position' do
40 named_scope :document_categories, :conditions => { :type => "DocumentCategory" }, :order => 'position' do
38 ActiveSupport::Deprecation.warn("Enumeration#document_categories is deprecated, use the DocumentCategories class. (#{Redmine::Info.issue(3007)})")
41 ActiveSupport::Deprecation.warn("Enumeration#document_categories is deprecated, use the DocumentCategories class. (#{Redmine::Info.issue(3007)})")
39 def default
42 def default
40 find(:first, :conditions => { :is_default => true })
43 find(:first, :conditions => { :is_default => true })
41 end
44 end
42 end
45 end
43
46
44 named_scope :activities, :conditions => { :type => "TimeEntryActivity" }, :order => 'position' do
47 named_scope :activities, :conditions => { :type => "TimeEntryActivity" }, :order => 'position' do
45 ActiveSupport::Deprecation.warn("Enumeration#activities is deprecated, use the TimeEntryActivity class. (#{Redmine::Info.issue(3007)})")
48 ActiveSupport::Deprecation.warn("Enumeration#activities is deprecated, use the TimeEntryActivity class. (#{Redmine::Info.issue(3007)})")
46 def default
49 def default
47 find(:first, :conditions => { :is_default => true })
50 find(:first, :conditions => { :is_default => true })
48 end
51 end
49 end
52 end
50
53
51 named_scope :values, lambda {|type| { :conditions => { :type => type }, :order => 'position' } } do
54 named_scope :values, lambda {|type| { :conditions => { :type => type }, :order => 'position' } } do
52 def default
55 def default
53 find(:first, :conditions => { :is_default => true })
56 find(:first, :conditions => { :is_default => true })
54 end
57 end
55 end
58 end
56 # End backwards compatiblity named_scopes
59 # End backwards compatiblity named_scopes
57
60
58 named_scope :all, :order => 'position'
61 named_scope :all, :order => 'position'
59
62
60 named_scope :active, lambda {
63 named_scope :active, lambda {
61 {
64 {
62 :conditions => {:active => true},
65 :conditions => {:active => true},
63 :order => 'position'
66 :order => 'position'
64 }
67 }
65 }
68 }
66
69
67 def self.default
70 def self.default
68 # Creates a fake default scope so Enumeration.default will check
71 # Creates a fake default scope so Enumeration.default will check
69 # it's type. STI subclasses will automatically add their own
72 # it's type. STI subclasses will automatically add their own
70 # types to the finder.
73 # types to the finder.
71 if self.descends_from_active_record?
74 if self.descends_from_active_record?
72 find(:first, :conditions => { :is_default => true, :type => 'Enumeration' })
75 find(:first, :conditions => { :is_default => true, :type => 'Enumeration' })
73 else
76 else
74 # STI classes are
77 # STI classes are
75 find(:first, :conditions => { :is_default => true })
78 find(:first, :conditions => { :is_default => true })
76 end
79 end
77 end
80 end
78
81
79 # Overloaded on concrete classes
82 # Overloaded on concrete classes
80 def option_name
83 def option_name
81 nil
84 nil
82 end
85 end
83
86
84 # Backwards compatiblity. Can be removed post-0.9
87 # Backwards compatiblity. Can be removed post-0.9
85 def opt
88 def opt
86 ActiveSupport::Deprecation.warn("Enumeration#opt is deprecated, use the STI classes now. (#{Redmine::Info.issue(3007)})")
89 ActiveSupport::Deprecation.warn("Enumeration#opt is deprecated, use the STI classes now. (#{Redmine::Info.issue(3007)})")
87 return OptName
90 return OptName
88 end
91 end
89
92
90 def before_save
93 def before_save
91 if is_default? && is_default_changed?
94 if is_default? && is_default_changed?
92 Enumeration.update_all("is_default = #{connection.quoted_false}", {:type => type})
95 Enumeration.update_all("is_default = #{connection.quoted_false}", {:type => type})
93 end
96 end
94 end
97 end
95
98
96 # Overloaded on concrete classes
99 # Overloaded on concrete classes
97 def objects_count
100 def objects_count
98 0
101 0
99 end
102 end
100
103
101 def in_use?
104 def in_use?
102 self.objects_count != 0
105 self.objects_count != 0
103 end
106 end
104
107
108 # Is this enumeration overiding a system level enumeration?
109 def is_override?
110 !self.parent.nil?
111 end
112
105 alias :destroy_without_reassign :destroy
113 alias :destroy_without_reassign :destroy
106
114
107 # Destroy the enumeration
115 # Destroy the enumeration
108 # If a enumeration is specified, objects are reassigned
116 # If a enumeration is specified, objects are reassigned
109 def destroy(reassign_to = nil)
117 def destroy(reassign_to = nil)
110 if reassign_to && reassign_to.is_a?(Enumeration)
118 if reassign_to && reassign_to.is_a?(Enumeration)
111 self.transfer_relations(reassign_to)
119 self.transfer_relations(reassign_to)
112 end
120 end
113 destroy_without_reassign
121 destroy_without_reassign
114 end
122 end
115
123
116 def <=>(enumeration)
124 def <=>(enumeration)
117 position <=> enumeration.position
125 position <=> enumeration.position
118 end
126 end
119
127
120 def to_s; name end
128 def to_s; name end
121
129
122 # Returns the Subclasses of Enumeration. Each Subclass needs to be
130 # Returns the Subclasses of Enumeration. Each Subclass needs to be
123 # required in development mode.
131 # required in development mode.
124 #
132 #
125 # Note: subclasses is protected in ActiveRecord
133 # Note: subclasses is protected in ActiveRecord
126 def self.get_subclasses
134 def self.get_subclasses
127 @@subclasses[Enumeration]
135 @@subclasses[Enumeration]
128 end
136 end
129
137
130 private
138 private
131 def check_integrity
139 def check_integrity
132 raise "Can't delete enumeration" if self.in_use?
140 raise "Can't delete enumeration" if self.in_use?
133 end
141 end
134
142
135 end
143 end
136
144
137 # Force load the subclasses in development mode
145 # Force load the subclasses in development mode
138 require_dependency 'time_entry_activity'
146 require_dependency 'time_entry_activity'
139 require_dependency 'document_category'
147 require_dependency 'document_category'
140 require_dependency 'issue_priority'
148 require_dependency 'issue_priority'
@@ -1,89 +1,111
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
2 # Copyright (C) 2006-2008 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.dirname(__FILE__) + '/../test_helper'
18 require File.dirname(__FILE__) + '/../test_helper'
19
19
20 class EnumerationTest < ActiveSupport::TestCase
20 class EnumerationTest < ActiveSupport::TestCase
21 fixtures :enumerations, :issues, :custom_fields, :custom_values
21 fixtures :enumerations, :issues, :custom_fields, :custom_values
22
22
23 def setup
23 def setup
24 end
24 end
25
25
26 def test_objects_count
26 def test_objects_count
27 # low priority
27 # low priority
28 assert_equal 5, Enumeration.find(4).objects_count
28 assert_equal 5, Enumeration.find(4).objects_count
29 # urgent
29 # urgent
30 assert_equal 0, Enumeration.find(7).objects_count
30 assert_equal 0, Enumeration.find(7).objects_count
31 end
31 end
32
32
33 def test_in_use
33 def test_in_use
34 # low priority
34 # low priority
35 assert Enumeration.find(4).in_use?
35 assert Enumeration.find(4).in_use?
36 # urgent
36 # urgent
37 assert !Enumeration.find(7).in_use?
37 assert !Enumeration.find(7).in_use?
38 end
38 end
39
39
40 def test_default
40 def test_default
41 e = Enumeration.default
41 e = Enumeration.default
42 assert e.is_a?(Enumeration)
42 assert e.is_a?(Enumeration)
43 assert e.is_default?
43 assert e.is_default?
44 assert_equal 'Default Enumeration', e.name
44 assert_equal 'Default Enumeration', e.name
45 end
45 end
46
46
47 def test_create
47 def test_create
48 e = Enumeration.new(:name => 'Not default', :is_default => false)
48 e = Enumeration.new(:name => 'Not default', :is_default => false)
49 e.type = 'Enumeration'
49 e.type = 'Enumeration'
50 assert e.save
50 assert e.save
51 assert_equal 'Default Enumeration', Enumeration.default.name
51 assert_equal 'Default Enumeration', Enumeration.default.name
52 end
52 end
53
53
54 def test_create_as_default
54 def test_create_as_default
55 e = Enumeration.new(:name => 'Very urgent', :is_default => true)
55 e = Enumeration.new(:name => 'Very urgent', :is_default => true)
56 e.type = 'Enumeration'
56 e.type = 'Enumeration'
57 assert e.save
57 assert e.save
58 assert_equal e, Enumeration.default
58 assert_equal e, Enumeration.default
59 end
59 end
60
60
61 def test_update_default
61 def test_update_default
62 e = Enumeration.default
62 e = Enumeration.default
63 e.update_attributes(:name => 'Changed', :is_default => true)
63 e.update_attributes(:name => 'Changed', :is_default => true)
64 assert_equal e, Enumeration.default
64 assert_equal e, Enumeration.default
65 end
65 end
66
66
67 def test_update_default_to_non_default
67 def test_update_default_to_non_default
68 e = Enumeration.default
68 e = Enumeration.default
69 e.update_attributes(:name => 'Changed', :is_default => false)
69 e.update_attributes(:name => 'Changed', :is_default => false)
70 assert_nil Enumeration.default
70 assert_nil Enumeration.default
71 end
71 end
72
72
73 def test_change_default
73 def test_change_default
74 e = Enumeration.find_by_name('Default Enumeration')
74 e = Enumeration.find_by_name('Default Enumeration')
75 e.update_attributes(:name => 'Changed Enumeration', :is_default => true)
75 e.update_attributes(:name => 'Changed Enumeration', :is_default => true)
76 assert_equal e, Enumeration.default
76 assert_equal e, Enumeration.default
77 end
77 end
78
78
79 def test_destroy_with_reassign
79 def test_destroy_with_reassign
80 Enumeration.find(4).destroy(Enumeration.find(6))
80 Enumeration.find(4).destroy(Enumeration.find(6))
81 assert_nil Issue.find(:first, :conditions => {:priority_id => 4})
81 assert_nil Issue.find(:first, :conditions => {:priority_id => 4})
82 assert_equal 5, Enumeration.find(6).objects_count
82 assert_equal 5, Enumeration.find(6).objects_count
83 end
83 end
84
84
85 def test_should_be_customizable
85 def test_should_be_customizable
86 assert Enumeration.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
86 assert Enumeration.included_modules.include?(Redmine::Acts::Customizable::InstanceMethods)
87 end
87 end
88
88
89 def test_should_belong_to_a_project
90 association = Enumeration.reflect_on_association(:project)
91 assert association, "No Project association found"
92 assert_equal :belongs_to, association.macro
93 end
94
95 def test_should_act_as_tree
96 enumeration = Enumeration.find(4)
97
98 assert enumeration.respond_to?(:parent)
99 assert enumeration.respond_to?(:children)
100 end
101
102 def test_is_override
103 # Defaults to off
104 enumeration = Enumeration.find(4)
105 assert !enumeration.is_override?
106
107 # Setup as an override
108 enumeration.parent = Enumeration.find(5)
109 assert enumeration.is_override?
110 end
89 end
111 end
General Comments 0
You need to be logged in to leave comments. Login now