Changed Enumerations to use a Single Table Inheritance
* Added migrations to change Enumerations to an STI relationship * Added TimeEntryActivity model (STI) * Added DocumentCategory model (STI) * Added IssuePriority model (STI) * Added Enumeration#get_subclasses to get a list of the subclasses of Enumeration * Changed Enumeration to use the STI type field instead of the opt field * Changed Enumeration#opt to return the old opt values but with a deprecation warning. * Removed Enumeration::OPTIONS * Removed the dynamic named_scopes in favor of specific named_scopes. Kept for compatibility reasons. * Added Enumeration#default so each subclass can easily find it's default record. * Fixed Enumeration#default to use the STI scoping with a fake default scope for finding Enumeration's default. * Added a 'all' named scope for getting all records in order by position. * Added Deprecation warnings to the old named_scopes in Enumerations. * Moved various methods off of Enumeration and onto the concrete classes * Changed the EnumerationsController to use types * Updated the Enumeration list template * Added has_many relationships to the Enumeration STI classes. * Fixes for tests. #3007 git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2777 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
fbfb349496
commit
62e58f26b0
|
@ -53,7 +53,7 @@ class DocumentsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@categories = Enumeration.document_categories
|
@categories = DocumentCategory.all
|
||||||
if request.post? and @document.update_attributes(params[:document])
|
if request.post? and @document.update_attributes(params[:document])
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
redirect_to :action => 'show', :id => @document
|
redirect_to :action => 'show', :id => @document
|
||||||
|
|
|
@ -31,14 +31,19 @@ class EnumerationsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@enumeration = Enumeration.new(:opt => params[:opt])
|
begin
|
||||||
|
@enumeration = params[:type].constantize.new
|
||||||
|
rescue NameError
|
||||||
|
@enumeration = Enumeration.new
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@enumeration = Enumeration.new(params[:enumeration])
|
@enumeration = Enumeration.new(params[:enumeration])
|
||||||
|
@enumeration.type = params[:enumeration][:type]
|
||||||
if @enumeration.save
|
if @enumeration.save
|
||||||
flash[:notice] = l(:notice_successful_create)
|
flash[:notice] = l(:notice_successful_create)
|
||||||
redirect_to :action => 'list', :opt => @enumeration.opt
|
redirect_to :action => 'list', :type => @enumeration.type
|
||||||
else
|
else
|
||||||
render :action => 'new'
|
render :action => 'new'
|
||||||
end
|
end
|
||||||
|
@ -50,9 +55,10 @@ class EnumerationsController < ApplicationController
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@enumeration = Enumeration.find(params[:id])
|
@enumeration = Enumeration.find(params[:id])
|
||||||
|
@enumeration.type = params[:enumeration][:type] if params[:enumeration][:type]
|
||||||
if @enumeration.update_attributes(params[:enumeration])
|
if @enumeration.update_attributes(params[:enumeration])
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
redirect_to :action => 'list', :opt => @enumeration.opt
|
redirect_to :action => 'list', :type => @enumeration.type
|
||||||
else
|
else
|
||||||
render :action => 'edit'
|
render :action => 'edit'
|
||||||
end
|
end
|
||||||
|
@ -65,12 +71,12 @@ class EnumerationsController < ApplicationController
|
||||||
@enumeration.destroy
|
@enumeration.destroy
|
||||||
redirect_to :action => 'index'
|
redirect_to :action => 'index'
|
||||||
elsif params[:reassign_to_id]
|
elsif params[:reassign_to_id]
|
||||||
if reassign_to = Enumeration.find_by_opt_and_id(@enumeration.opt, params[:reassign_to_id])
|
if reassign_to = Enumeration.find_by_type_and_id(@enumeration.type, params[:reassign_to_id])
|
||||||
@enumeration.destroy(reassign_to)
|
@enumeration.destroy(reassign_to)
|
||||||
redirect_to :action => 'index'
|
redirect_to :action => 'index'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@enumerations = Enumeration.values(@enumeration.opt) - [@enumeration]
|
@enumerations = Enumeration.find(:all, :conditions => ['type = (?)', @enumeration.type]) - [@enumeration]
|
||||||
#rescue
|
#rescue
|
||||||
# flash[:error] = 'Unable to delete enumeration'
|
# flash[:error] = 'Unable to delete enumeration'
|
||||||
# redirect_to :action => 'index'
|
# redirect_to :action => 'index'
|
||||||
|
|
|
@ -113,7 +113,7 @@ class IssuesController < ApplicationController
|
||||||
@changesets.reverse! if User.current.wants_comments_in_reverse_order?
|
@changesets.reverse! if User.current.wants_comments_in_reverse_order?
|
||||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||||
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
||||||
@priorities = Enumeration.priorities
|
@priorities = IssuePriority.all
|
||||||
@time_entry = TimeEntry.new
|
@time_entry = TimeEntry.new
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { render :template => 'issues/show.rhtml' }
|
format.html { render :template => 'issues/show.rhtml' }
|
||||||
|
@ -163,7 +163,7 @@ class IssuesController < ApplicationController
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@priorities = Enumeration.priorities
|
@priorities = IssuePriority.all
|
||||||
render :layout => !request.xhr?
|
render :layout => !request.xhr?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ class IssuesController < ApplicationController
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||||
@priorities = Enumeration.priorities
|
@priorities = IssuePriority.all
|
||||||
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
||||||
@time_entry = TimeEntry.new
|
@time_entry = TimeEntry.new
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ class IssuesController < ApplicationController
|
||||||
def bulk_edit
|
def bulk_edit
|
||||||
if request.post?
|
if request.post?
|
||||||
status = params[:status_id].blank? ? nil : IssueStatus.find_by_id(params[:status_id])
|
status = params[:status_id].blank? ? nil : IssueStatus.find_by_id(params[:status_id])
|
||||||
priority = params[:priority_id].blank? ? nil : Enumeration.find_by_id(params[:priority_id])
|
priority = params[:priority_id].blank? ? nil : IssuePriority.find_by_id(params[:priority_id])
|
||||||
assigned_to = (params[:assigned_to_id].blank? || params[:assigned_to_id] == 'none') ? nil : User.find_by_id(params[:assigned_to_id])
|
assigned_to = (params[:assigned_to_id].blank? || params[:assigned_to_id] == 'none') ? nil : User.find_by_id(params[:assigned_to_id])
|
||||||
category = (params[:category_id].blank? || params[:category_id] == 'none') ? nil : @project.issue_categories.find_by_id(params[:category_id])
|
category = (params[:category_id].blank? || params[:category_id] == 'none') ? nil : @project.issue_categories.find_by_id(params[:category_id])
|
||||||
fixed_version = (params[:fixed_version_id].blank? || params[:fixed_version_id] == 'none') ? nil : @project.versions.find_by_id(params[:fixed_version_id])
|
fixed_version = (params[:fixed_version_id].blank? || params[:fixed_version_id] == 'none') ? nil : @project.versions.find_by_id(params[:fixed_version_id])
|
||||||
|
@ -415,7 +415,7 @@ class IssuesController < ApplicationController
|
||||||
@assignables << @issue.assigned_to if @issue && @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
|
@assignables << @issue.assigned_to if @issue && @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
|
||||||
end
|
end
|
||||||
|
|
||||||
@priorities = Enumeration.priorities.reverse
|
@priorities = IssuePriority.all.reverse
|
||||||
@statuses = IssueStatus.find(:all, :order => 'position')
|
@statuses = IssueStatus.find(:all, :order => 'position')
|
||||||
@back = request.env['HTTP_REFERER']
|
@back = request.env['HTTP_REFERER']
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ class ReportsController < ApplicationController
|
||||||
render :template => "reports/issue_report_details"
|
render :template => "reports/issue_report_details"
|
||||||
when "priority"
|
when "priority"
|
||||||
@field = "priority_id"
|
@field = "priority_id"
|
||||||
@rows = Enumeration.priorities
|
@rows = IssuePriority.all
|
||||||
@data = issues_by_priority
|
@data = issues_by_priority
|
||||||
@report_title = l(:field_priority)
|
@report_title = l(:field_priority)
|
||||||
render :template => "reports/issue_report_details"
|
render :template => "reports/issue_report_details"
|
||||||
|
@ -68,7 +68,7 @@ class ReportsController < ApplicationController
|
||||||
else
|
else
|
||||||
@trackers = @project.trackers
|
@trackers = @project.trackers
|
||||||
@versions = @project.versions.sort
|
@versions = @project.versions.sort
|
||||||
@priorities = Enumeration.priorities
|
@priorities = IssuePriority.all
|
||||||
@categories = @project.issue_categories
|
@categories = @project.issue_categories
|
||||||
@assignees = @project.members.collect { |m| m.user }
|
@assignees = @project.members.collect { |m| m.user }
|
||||||
@authors = @project.members.collect { |m| m.user }
|
@authors = @project.members.collect { |m| m.user }
|
||||||
|
@ -130,7 +130,7 @@ private
|
||||||
p.id as priority_id,
|
p.id as priority_id,
|
||||||
count(i.id) as total
|
count(i.id) as total
|
||||||
from
|
from
|
||||||
#{Issue.table_name} i, #{IssueStatus.table_name} s, #{Enumeration.table_name} p
|
#{Issue.table_name} i, #{IssueStatus.table_name} s, #{IssuePriority.table_name} p
|
||||||
where
|
where
|
||||||
i.status_id=s.id
|
i.status_id=s.id
|
||||||
and i.priority_id=p.id
|
and i.priority_id=p.id
|
||||||
|
|
|
@ -46,7 +46,7 @@ class TimelogController < ApplicationController
|
||||||
:klass => Tracker,
|
:klass => Tracker,
|
||||||
:label => :label_tracker},
|
:label => :label_tracker},
|
||||||
'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
|
'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
|
||||||
:klass => Enumeration,
|
:klass => TimeEntryActivity,
|
||||||
:label => :label_activity},
|
:label => :label_activity},
|
||||||
'issue' => {:sql => "#{TimeEntry.table_name}.issue_id",
|
'issue' => {:sql => "#{TimeEntry.table_name}.issue_id",
|
||||||
:klass => Issue,
|
:klass => Issue,
|
||||||
|
|
|
@ -68,8 +68,8 @@ module IssuesHelper
|
||||||
u = User.find_by_id(detail.value) and value = u.name if detail.value
|
u = User.find_by_id(detail.value) and value = u.name if detail.value
|
||||||
u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
|
u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
|
||||||
when 'priority_id'
|
when 'priority_id'
|
||||||
e = Enumeration.find_by_id(detail.value) and value = e.name if detail.value
|
e = IssuePriority.find_by_id(detail.value) and value = e.name if detail.value
|
||||||
e = Enumeration.find_by_id(detail.old_value) and old_value = e.name if detail.old_value
|
e = IssuePriority.find_by_id(detail.old_value) and old_value = e.name if detail.old_value
|
||||||
when 'category_id'
|
when 'category_id'
|
||||||
c = IssueCategory.find_by_id(detail.value) and value = c.name if detail.value
|
c = IssueCategory.find_by_id(detail.value) and value = c.name if detail.value
|
||||||
c = IssueCategory.find_by_id(detail.old_value) and old_value = c.name if detail.old_value
|
c = IssueCategory.find_by_id(detail.old_value) and old_value = c.name if detail.old_value
|
||||||
|
|
|
@ -27,7 +27,7 @@ module TimelogHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def activity_collection_for_select_options
|
def activity_collection_for_select_options
|
||||||
activities = Enumeration.activities
|
activities = TimeEntryActivity.all
|
||||||
collection = []
|
collection = []
|
||||||
collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default)
|
collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default)
|
||||||
activities.each { |a| collection << [a.name, a.id] }
|
activities.each { |a| collection << [a.name, a.id] }
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
class Document < ActiveRecord::Base
|
class Document < ActiveRecord::Base
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
|
belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id"
|
||||||
acts_as_attachable :delete_permission => :manage_documents
|
acts_as_attachable :delete_permission => :manage_documents
|
||||||
|
|
||||||
acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project
|
acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project
|
||||||
|
@ -31,7 +31,7 @@ class Document < ActiveRecord::Base
|
||||||
|
|
||||||
def after_initialize
|
def after_initialize
|
||||||
if new_record?
|
if new_record?
|
||||||
self.category ||= Enumeration.document_categories.default
|
self.category ||= DocumentCategory.default
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class DocumentCategory < Enumeration
|
||||||
|
has_many :documents, :foreign_key => 'category_id'
|
||||||
|
|
||||||
|
OptionName = :enumeration_doc_categories
|
||||||
|
# Backwards compatiblity. Can be removed post-0.9
|
||||||
|
OptName = 'DCAT'
|
||||||
|
|
||||||
|
def option_name
|
||||||
|
OptionName
|
||||||
|
end
|
||||||
|
|
||||||
|
def objects_count
|
||||||
|
documents.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def transfer_relations(to)
|
||||||
|
documents.update_all("category_id = #{to.id}")
|
||||||
|
end
|
||||||
|
end
|
|
@ -16,53 +16,77 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class Enumeration < ActiveRecord::Base
|
class Enumeration < ActiveRecord::Base
|
||||||
acts_as_list :scope => 'opt = \'#{opt}\''
|
acts_as_list :scope => 'type = \'#{type}\''
|
||||||
|
|
||||||
before_destroy :check_integrity
|
before_destroy :check_integrity
|
||||||
|
|
||||||
validates_presence_of :opt, :name
|
validates_presence_of :name
|
||||||
validates_uniqueness_of :name, :scope => [:opt]
|
validates_uniqueness_of :name, :scope => [:type]
|
||||||
validates_length_of :name, :maximum => 30
|
validates_length_of :name, :maximum => 30
|
||||||
|
|
||||||
# Single table inheritance would be an option
|
# Backwards compatiblity named_scopes.
|
||||||
OPTIONS = {
|
# Can be removed post-0.9
|
||||||
"IPRI" => {:label => :enumeration_issue_priorities, :model => Issue, :foreign_key => :priority_id, :scope => :priorities},
|
named_scope :priorities, :conditions => { :type => "IssuePriority" }, :order => 'position' do
|
||||||
"DCAT" => {:label => :enumeration_doc_categories, :model => Document, :foreign_key => :category_id, :scope => :document_categories},
|
ActiveSupport::Deprecation.warn("Enumeration#priorities is deprecated, use the IssuePriority class. (#{Redmine::Info.issue(3007)})")
|
||||||
"ACTI" => {:label => :enumeration_activities, :model => TimeEntry, :foreign_key => :activity_id, :scope => :activities}
|
|
||||||
}.freeze
|
|
||||||
|
|
||||||
# Creates a named scope for each type of value. The scope has a +default+ method
|
|
||||||
# that returns the default value, or nil if no value is set as default.
|
|
||||||
# Example:
|
|
||||||
# Enumeration.priorities
|
|
||||||
# Enumeration.priorities.default
|
|
||||||
OPTIONS.each do |k, v|
|
|
||||||
next unless v[:scope]
|
|
||||||
named_scope v[:scope], :conditions => { :opt => k }, :order => 'position' do
|
|
||||||
def default
|
|
||||||
find(:first, :conditions => { :is_default => true })
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
named_scope :values, lambda {|opt| { :conditions => { :opt => opt }, :order => 'position' } } do
|
|
||||||
def default
|
def default
|
||||||
find(:first, :conditions => { :is_default => true })
|
find(:first, :conditions => { :is_default => true })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
named_scope :document_categories, :conditions => { :type => "DocumentCategory" }, :order => 'position' do
|
||||||
|
ActiveSupport::Deprecation.warn("Enumeration#document_categories is deprecated, use the DocumentCategories class. (#{Redmine::Info.issue(3007)})")
|
||||||
|
def default
|
||||||
|
find(:first, :conditions => { :is_default => true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
named_scope :activities, :conditions => { :type => "TimeEntryActivity" }, :order => 'position' do
|
||||||
|
ActiveSupport::Deprecation.warn("Enumeration#activities is deprecated, use the TimeEntryActivity class. (#{Redmine::Info.issue(3007)})")
|
||||||
|
def default
|
||||||
|
find(:first, :conditions => { :is_default => true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
named_scope :values, lambda {|type| { :conditions => { :type => type }, :order => 'position' } } do
|
||||||
|
def default
|
||||||
|
find(:first, :conditions => { :is_default => true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
named_scope :all, :order => 'position'
|
||||||
|
|
||||||
|
def self.default
|
||||||
|
# Creates a fake default scope so Enumeration.default will check
|
||||||
|
# it's type. STI subclasses will automatically add their own
|
||||||
|
# types to the finder.
|
||||||
|
if self.descends_from_active_record?
|
||||||
|
find(:first, :conditions => { :is_default => true, :type => 'Enumeration' })
|
||||||
|
else
|
||||||
|
# STI classes are
|
||||||
|
find(:first, :conditions => { :is_default => true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Overloaded on concrete classes
|
||||||
def option_name
|
def option_name
|
||||||
OPTIONS[self.opt][:label]
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
# Backwards compatiblity. Can be removed post-0.9
|
||||||
|
def opt
|
||||||
|
ActiveSupport::Deprecation.warn("Enumeration#opt is deprecated, use the STI classes now. (#{Redmine::Info.issue(3007)})")
|
||||||
|
return OptName
|
||||||
end
|
end
|
||||||
|
|
||||||
def before_save
|
def before_save
|
||||||
if is_default? && is_default_changed?
|
if is_default? && is_default_changed?
|
||||||
Enumeration.update_all("is_default = #{connection.quoted_false}", {:opt => opt})
|
Enumeration.update_all("is_default = #{connection.quoted_false}", {:type => type})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Overloaded on concrete classes
|
||||||
def objects_count
|
def objects_count
|
||||||
OPTIONS[self.opt][:model].count(:conditions => "#{OPTIONS[self.opt][:foreign_key]} = #{id}")
|
0
|
||||||
end
|
end
|
||||||
|
|
||||||
def in_use?
|
def in_use?
|
||||||
|
@ -75,7 +99,7 @@ class Enumeration < ActiveRecord::Base
|
||||||
# If a enumeration is specified, objects are reassigned
|
# If a enumeration is specified, objects are reassigned
|
||||||
def destroy(reassign_to = nil)
|
def destroy(reassign_to = nil)
|
||||||
if reassign_to && reassign_to.is_a?(Enumeration)
|
if reassign_to && reassign_to.is_a?(Enumeration)
|
||||||
OPTIONS[self.opt][:model].update_all("#{OPTIONS[self.opt][:foreign_key]} = #{reassign_to.id}", "#{OPTIONS[self.opt][:foreign_key]} = #{id}")
|
self.transfer_relations(reassign_to)
|
||||||
end
|
end
|
||||||
destroy_without_reassign
|
destroy_without_reassign
|
||||||
end
|
end
|
||||||
|
@ -86,8 +110,22 @@ class Enumeration < ActiveRecord::Base
|
||||||
|
|
||||||
def to_s; name end
|
def to_s; name end
|
||||||
|
|
||||||
|
# Returns the Subclasses of Enumeration. Each Subclass needs to be
|
||||||
|
# required in development mode.
|
||||||
|
#
|
||||||
|
# Note: subclasses is protected in ActiveRecord
|
||||||
|
def self.get_subclasses
|
||||||
|
@@subclasses[Enumeration]
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def check_integrity
|
def check_integrity
|
||||||
raise "Can't delete enumeration" if self.in_use?
|
raise "Can't delete enumeration" if self.in_use?
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Force load the subclasses in development mode
|
||||||
|
require_dependency 'time_entry_activity'
|
||||||
|
require_dependency 'document_category'
|
||||||
|
require_dependency 'issue_priority'
|
||||||
|
|
|
@ -22,7 +22,7 @@ class Issue < ActiveRecord::Base
|
||||||
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
||||||
belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
|
belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
|
||||||
belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
|
belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
|
||||||
belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
|
belongs_to :priority, :class_name => 'IssuePriority', :foreign_key => 'priority_id'
|
||||||
belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
|
belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
|
||||||
|
|
||||||
has_many :journals, :as => :journalized, :dependent => :destroy
|
has_many :journals, :as => :journalized, :dependent => :destroy
|
||||||
|
@ -67,7 +67,7 @@ class Issue < ActiveRecord::Base
|
||||||
if new_record?
|
if new_record?
|
||||||
# set default values for new records only
|
# set default values for new records only
|
||||||
self.status ||= IssueStatus.default
|
self.status ||= IssueStatus.default
|
||||||
self.priority ||= Enumeration.priorities.default
|
self.priority ||= IssuePriority.default
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class IssuePriority < Enumeration
|
||||||
|
has_many :issues, :foreign_key => 'priority_id'
|
||||||
|
|
||||||
|
OptionName = :enumeration_issue_priorities
|
||||||
|
# Backwards compatiblity. Can be removed post-0.9
|
||||||
|
OptName = 'IPRI'
|
||||||
|
|
||||||
|
def option_name
|
||||||
|
OptionName
|
||||||
|
end
|
||||||
|
|
||||||
|
def objects_count
|
||||||
|
issues.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def transfer_relations(to)
|
||||||
|
issues.update_all("priority_id = #{to.id}")
|
||||||
|
end
|
||||||
|
end
|
|
@ -91,7 +91,7 @@ class MailHandler < ActionMailer::Base
|
||||||
project = target_project
|
project = target_project
|
||||||
tracker = (get_keyword(:tracker) && project.trackers.find_by_name(get_keyword(:tracker))) || project.trackers.find(:first)
|
tracker = (get_keyword(:tracker) && project.trackers.find_by_name(get_keyword(:tracker))) || project.trackers.find(:first)
|
||||||
category = (get_keyword(:category) && project.issue_categories.find_by_name(get_keyword(:category)))
|
category = (get_keyword(:category) && project.issue_categories.find_by_name(get_keyword(:category)))
|
||||||
priority = (get_keyword(:priority) && Enumeration.find_by_opt_and_name('IPRI', get_keyword(:priority)))
|
priority = (get_keyword(:priority) && IssuePriority.find_by_name(get_keyword(:priority)))
|
||||||
status = (get_keyword(:status) && IssueStatus.find_by_name(get_keyword(:status)))
|
status = (get_keyword(:status) && IssueStatus.find_by_name(get_keyword(:status)))
|
||||||
|
|
||||||
# check permission
|
# check permission
|
||||||
|
|
|
@ -102,7 +102,7 @@ class Query < ActiveRecord::Base
|
||||||
QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true),
|
QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true),
|
||||||
QueryColumn.new(:tracker, :sortable => "#{Tracker.table_name}.position", :groupable => true),
|
QueryColumn.new(:tracker, :sortable => "#{Tracker.table_name}.position", :groupable => true),
|
||||||
QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position", :groupable => true),
|
QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position", :groupable => true),
|
||||||
QueryColumn.new(:priority, :sortable => "#{Enumeration.table_name}.position", :default_order => 'desc', :groupable => true),
|
QueryColumn.new(:priority, :sortable => "#{IssuePriority.table_name}.position", :default_order => 'desc', :groupable => true),
|
||||||
QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"),
|
QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"),
|
||||||
QueryColumn.new(:author),
|
QueryColumn.new(:author),
|
||||||
QueryColumn.new(:assigned_to, :sortable => ["#{User.table_name}.lastname", "#{User.table_name}.firstname", "#{User.table_name}.id"], :groupable => true),
|
QueryColumn.new(:assigned_to, :sortable => ["#{User.table_name}.lastname", "#{User.table_name}.firstname", "#{User.table_name}.id"], :groupable => true),
|
||||||
|
@ -152,7 +152,7 @@ class Query < ActiveRecord::Base
|
||||||
|
|
||||||
@available_filters = { "status_id" => { :type => :list_status, :order => 1, :values => IssueStatus.find(:all, :order => 'position').collect{|s| [s.name, s.id.to_s] } },
|
@available_filters = { "status_id" => { :type => :list_status, :order => 1, :values => IssueStatus.find(:all, :order => 'position').collect{|s| [s.name, s.id.to_s] } },
|
||||||
"tracker_id" => { :type => :list, :order => 2, :values => trackers.collect{|s| [s.name, s.id.to_s] } },
|
"tracker_id" => { :type => :list, :order => 2, :values => trackers.collect{|s| [s.name, s.id.to_s] } },
|
||||||
"priority_id" => { :type => :list, :order => 3, :values => Enumeration.find(:all, :conditions => ['opt=?','IPRI'], :order => 'position').collect{|s| [s.name, s.id.to_s] } },
|
"priority_id" => { :type => :list, :order => 3, :values => IssuePriority.all.collect{|s| [s.name, s.id.to_s] } },
|
||||||
"subject" => { :type => :text, :order => 8 },
|
"subject" => { :type => :text, :order => 8 },
|
||||||
"created_on" => { :type => :date_past, :order => 9 },
|
"created_on" => { :type => :date_past, :order => 9 },
|
||||||
"updated_on" => { :type => :date_past, :order => 10 },
|
"updated_on" => { :type => :date_past, :order => 10 },
|
||||||
|
|
|
@ -21,7 +21,7 @@ class TimeEntry < ActiveRecord::Base
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :issue
|
belongs_to :issue
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :activity, :class_name => 'Enumeration', :foreign_key => :activity_id
|
belongs_to :activity, :class_name => 'TimeEntryActivity', :foreign_key => 'activity_id'
|
||||||
|
|
||||||
attr_protected :project_id, :user_id, :tyear, :tmonth, :tweek
|
attr_protected :project_id, :user_id, :tyear, :tmonth, :tweek
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class TimeEntry < ActiveRecord::Base
|
||||||
|
|
||||||
def after_initialize
|
def after_initialize
|
||||||
if new_record? && self.activity.nil?
|
if new_record? && self.activity.nil?
|
||||||
if default_activity = Enumeration.activities.default
|
if default_activity = TimeEntryActivity.default
|
||||||
self.activity_id = default_activity.id
|
self.activity_id = default_activity.id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class TimeEntryActivity < Enumeration
|
||||||
|
has_many :time_entries, :foreign_key => 'activity_id'
|
||||||
|
|
||||||
|
OptionName = :enumeration_activities
|
||||||
|
# Backwards compatiblity. Can be removed post-0.9
|
||||||
|
OptName = 'ACTI'
|
||||||
|
|
||||||
|
def option_name
|
||||||
|
OptionName
|
||||||
|
end
|
||||||
|
|
||||||
|
def objects_count
|
||||||
|
time_entries.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def transfer_relations(to)
|
||||||
|
time_entries.update_all("activity_id = #{to.id}")
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<!--[form:document]-->
|
<!--[form:document]-->
|
||||||
<p><label for="document_category_id"><%=l(:field_category)%></label>
|
<p><label for="document_category_id"><%=l(:field_category)%></label>
|
||||||
<%= select('document', 'category_id', Enumeration.document_categories.collect {|c| [c.name, c.id]}) %></p>
|
<%= select('document', 'category_id', DocumentCategory.all.collect {|c| [c.name, c.id]}) %></p>
|
||||||
|
|
||||||
<p><label for="document_title"><%=l(:field_title)%> <span class="required">*</span></label>
|
<p><label for="document_title"><%=l(:field_title)%> <span class="required">*</span></label>
|
||||||
<%= text_field 'document', 'title', :size => 60 %></p>
|
<%= text_field 'document', 'title', :size => 60 %></p>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<%= error_messages_for 'enumeration' %>
|
<%= error_messages_for 'enumeration' %>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<!--[form:optvalue]-->
|
<!--[form:optvalue]-->
|
||||||
<%= hidden_field 'enumeration', 'opt' %>
|
<%= hidden_field 'enumeration', 'type' %>
|
||||||
|
|
||||||
<p><label for="enumeration_name"><%=l(:field_name)%></label>
|
<p><label for="enumeration_name"><%=l(:field_name)%></label>
|
||||||
<%= text_field 'enumeration', 'name' %></p>
|
<%= text_field 'enumeration', 'name' %></p>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<h2><%=l(:label_enumerations)%></h2>
|
<h2><%=l(:label_enumerations)%></h2>
|
||||||
|
|
||||||
<% Enumeration::OPTIONS.each do |option, params| %>
|
<% Enumeration.get_subclasses.each do |klass| %>
|
||||||
<h3><%= l(params[:label]) %></h3>
|
<h3><%= l(klass::OptionName) %></h3>
|
||||||
|
|
||||||
<% enumerations = Enumeration.values(option) %>
|
<% enumerations = klass.all %>
|
||||||
<% if enumerations.any? %>
|
<% if enumerations.any? %>
|
||||||
<table class="list">
|
<table class="list">
|
||||||
<% enumerations.each do |enumeration| %>
|
<% enumerations.each do |enumeration| %>
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
<% reset_cycle %>
|
<% reset_cycle %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<p><%= link_to l(:label_enumeration_new), { :action => 'new', :opt => option } %></p>
|
<p><%= link_to l(:label_enumeration_new), { :action => 'new', :type => klass.name } %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<% html_title(l(:label_enumerations)) -%>
|
<% html_title(l(:label_enumerations)) -%>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<%= select_tag('status_id', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@available_statuses, :id, :name)) %></label>
|
<%= select_tag('status_id', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@available_statuses, :id, :name)) %></label>
|
||||||
<% end %>
|
<% end %>
|
||||||
<label><%= l(:field_priority) %>:
|
<label><%= l(:field_priority) %>:
|
||||||
<%= select_tag('priority_id', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(Enumeration.priorities, :id, :name)) %></label>
|
<%= select_tag('priority_id', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(IssuePriority.all, :id, :name)) %></label>
|
||||||
<label><%= l(:field_category) %>:
|
<label><%= l(:field_category) %>:
|
||||||
<%= select_tag('category_id', content_tag('option', l(:label_no_change_option), :value => '') +
|
<%= select_tag('category_id', content_tag('option', l(:label_no_change_option), :value => '') +
|
||||||
content_tag('option', l(:label_none), :value => 'none') +
|
content_tag('option', l(:label_none), :value => 'none') +
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
:conditions => {:assigned_to_id => User.current.id},
|
:conditions => {:assigned_to_id => User.current.id},
|
||||||
:limit => 10,
|
:limit => 10,
|
||||||
:include => [ :status, :project, :tracker, :priority ],
|
:include => [ :status, :project, :tracker, :priority ],
|
||||||
:order => "#{Enumeration.table_name}.position DESC, #{Issue.table_name}.updated_on DESC") %>
|
:order => "#{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC") %>
|
||||||
<%= render :partial => 'issues/list_simple', :locals => { :issues => assigned_issues } %>
|
<%= render :partial => 'issues/list_simple', :locals => { :issues => assigned_issues } %>
|
||||||
<% if assigned_issues.length > 0 %>
|
<% if assigned_issues.length > 0 %>
|
||||||
<p class="small"><%= link_to l(:label_issue_view_all), :controller => 'issues',
|
<p class="small"><%= link_to l(:label_issue_view_all), :controller => 'issues',
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
class AddTypeToEnumerations < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
add_column :enumerations, :type, :string
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
remove_column :enumerations, :type
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,11 @@
|
||||||
|
class UpdateEnumerationsToSti < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
Enumeration.update_all("type = 'IssuePriority'", "opt = 'IPRI'")
|
||||||
|
Enumeration.update_all("type = 'DocumentCategory'", "opt = 'DCAT'")
|
||||||
|
Enumeration.update_all("type = 'TimeEntryActivity'", "opt = 'ACTI'")
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
# no-op
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,46 +3,67 @@ enumerations_001:
|
||||||
name: Uncategorized
|
name: Uncategorized
|
||||||
id: 1
|
id: 1
|
||||||
opt: DCAT
|
opt: DCAT
|
||||||
|
type: DocumentCategory
|
||||||
enumerations_002:
|
enumerations_002:
|
||||||
name: User documentation
|
name: User documentation
|
||||||
id: 2
|
id: 2
|
||||||
opt: DCAT
|
opt: DCAT
|
||||||
|
type: DocumentCategory
|
||||||
enumerations_003:
|
enumerations_003:
|
||||||
name: Technical documentation
|
name: Technical documentation
|
||||||
id: 3
|
id: 3
|
||||||
opt: DCAT
|
opt: DCAT
|
||||||
|
type: DocumentCategory
|
||||||
enumerations_004:
|
enumerations_004:
|
||||||
name: Low
|
name: Low
|
||||||
id: 4
|
id: 4
|
||||||
opt: IPRI
|
opt: IPRI
|
||||||
|
type: IssuePriority
|
||||||
enumerations_005:
|
enumerations_005:
|
||||||
name: Normal
|
name: Normal
|
||||||
id: 5
|
id: 5
|
||||||
opt: IPRI
|
opt: IPRI
|
||||||
|
type: IssuePriority
|
||||||
is_default: true
|
is_default: true
|
||||||
enumerations_006:
|
enumerations_006:
|
||||||
name: High
|
name: High
|
||||||
id: 6
|
id: 6
|
||||||
opt: IPRI
|
opt: IPRI
|
||||||
|
type: IssuePriority
|
||||||
enumerations_007:
|
enumerations_007:
|
||||||
name: Urgent
|
name: Urgent
|
||||||
id: 7
|
id: 7
|
||||||
opt: IPRI
|
opt: IPRI
|
||||||
|
type: IssuePriority
|
||||||
enumerations_008:
|
enumerations_008:
|
||||||
name: Immediate
|
name: Immediate
|
||||||
id: 8
|
id: 8
|
||||||
opt: IPRI
|
opt: IPRI
|
||||||
|
type: IssuePriority
|
||||||
enumerations_009:
|
enumerations_009:
|
||||||
name: Design
|
name: Design
|
||||||
id: 9
|
id: 9
|
||||||
opt: ACTI
|
opt: ACTI
|
||||||
|
type: TimeEntryActivity
|
||||||
enumerations_010:
|
enumerations_010:
|
||||||
name: Development
|
name: Development
|
||||||
id: 10
|
id: 10
|
||||||
opt: ACTI
|
opt: ACTI
|
||||||
|
type: TimeEntryActivity
|
||||||
is_default: true
|
is_default: true
|
||||||
enumerations_011:
|
enumerations_011:
|
||||||
name: QA
|
name: QA
|
||||||
id: 11
|
id: 11
|
||||||
opt: ACTI
|
opt: ACTI
|
||||||
|
type: TimeEntryActivity
|
||||||
|
enumerations_012:
|
||||||
|
name: Default Enumeration
|
||||||
|
id: 12
|
||||||
|
opt: ''
|
||||||
|
type: Enumeration
|
||||||
|
is_default: true
|
||||||
|
enumerations_013:
|
||||||
|
name: Another Enumeration
|
||||||
|
id: 13
|
||||||
|
opt: ''
|
||||||
|
type: Enumeration
|
||||||
|
|
|
@ -95,7 +95,7 @@ issues_007:
|
||||||
created_on: <%= 10.days.ago.to_date.to_s(:db) %>
|
created_on: <%= 10.days.ago.to_date.to_s(:db) %>
|
||||||
project_id: 1
|
project_id: 1
|
||||||
updated_on: <%= 10.days.ago.to_date.to_s(:db) %>
|
updated_on: <%= 10.days.ago.to_date.to_s(:db) %>
|
||||||
priority_id: 3
|
priority_id: 5
|
||||||
subject: Issue due today
|
subject: Issue due today
|
||||||
id: 7
|
id: 7
|
||||||
fixed_version_id:
|
fixed_version_id:
|
||||||
|
@ -112,7 +112,7 @@ issues_008:
|
||||||
created_on: <%= 10.days.ago.to_date.to_s(:db) %>
|
created_on: <%= 10.days.ago.to_date.to_s(:db) %>
|
||||||
project_id: 1
|
project_id: 1
|
||||||
updated_on: <%= 10.days.ago.to_date.to_s(:db) %>
|
updated_on: <%= 10.days.ago.to_date.to_s(:db) %>
|
||||||
priority_id: 3
|
priority_id: 5
|
||||||
subject: Closed issue
|
subject: Closed issue
|
||||||
id: 8
|
id: 8
|
||||||
fixed_version_id:
|
fixed_version_id:
|
||||||
|
|
|
@ -715,7 +715,7 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||||
:id => 1,
|
:id => 1,
|
||||||
:issue => { :status_id => 2, :assigned_to_id => 3 },
|
:issue => { :status_id => 2, :assigned_to_id => 3 },
|
||||||
:notes => 'Assigned to dlopper',
|
:notes => 'Assigned to dlopper',
|
||||||
:time_entry => { :hours => '', :comments => '', :activity_id => Enumeration.activities.first }
|
:time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
|
||||||
end
|
end
|
||||||
assert_redirected_to :action => 'show', :id => '1'
|
assert_redirected_to :action => 'show', :id => '1'
|
||||||
issue.reload
|
issue.reload
|
||||||
|
@ -753,7 +753,7 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||||
post :edit,
|
post :edit,
|
||||||
:id => 1,
|
:id => 1,
|
||||||
:notes => '2.5 hours added',
|
:notes => '2.5 hours added',
|
||||||
:time_entry => { :hours => '2.5', :comments => '', :activity_id => Enumeration.activities.first }
|
:time_entry => { :hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first }
|
||||||
end
|
end
|
||||||
assert_redirected_to :action => 'show', :id => '1'
|
assert_redirected_to :action => 'show', :id => '1'
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ class IssuesTest < ActionController::IntegrationTest
|
||||||
|
|
||||||
post 'projects/1/issues', :tracker_id => "1",
|
post 'projects/1/issues', :tracker_id => "1",
|
||||||
:issue => { :start_date => "2006-12-26",
|
:issue => { :start_date => "2006-12-26",
|
||||||
:priority_id => "3",
|
:priority_id => "4",
|
||||||
:subject => "new test issue",
|
:subject => "new test issue",
|
||||||
:category_id => "",
|
:category_id => "",
|
||||||
:description => "new issue",
|
:description => "new issue",
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require File.dirname(__FILE__) + '/../test_helper'
|
||||||
|
|
||||||
|
class DocumentCategoryTest < Test::Unit::TestCase
|
||||||
|
fixtures :enumerations, :documents
|
||||||
|
|
||||||
|
def test_should_be_an_enumeration
|
||||||
|
assert DocumentCategory.ancestors.include?(Enumeration)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_objects_count
|
||||||
|
assert_equal 1, DocumentCategory.find_by_name("Uncategorized").objects_count
|
||||||
|
assert_equal 0, DocumentCategory.find_by_name("User documentation").objects_count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_option_name
|
||||||
|
assert_equal :enumeration_doc_categories, DocumentCategory.new.option_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -38,40 +38,42 @@ class EnumerationTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_default
|
def test_default
|
||||||
e = Enumeration.priorities.default
|
e = Enumeration.default
|
||||||
assert e.is_a?(Enumeration)
|
assert e.is_a?(Enumeration)
|
||||||
assert e.is_default?
|
assert e.is_default?
|
||||||
assert_equal 'Normal', e.name
|
assert_equal 'Default Enumeration', e.name
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_create
|
def test_create
|
||||||
e = Enumeration.new(:opt => 'IPRI', :name => 'Very urgent', :is_default => false)
|
e = Enumeration.new(:name => 'Not default', :is_default => false)
|
||||||
|
e.type = 'Enumeration'
|
||||||
assert e.save
|
assert e.save
|
||||||
assert_equal 'Normal', Enumeration.priorities.default.name
|
assert_equal 'Default Enumeration', Enumeration.default.name
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_create_as_default
|
def test_create_as_default
|
||||||
e = Enumeration.new(:opt => 'IPRI', :name => 'Very urgent', :is_default => true)
|
e = Enumeration.new(:name => 'Very urgent', :is_default => true)
|
||||||
|
e.type = 'Enumeration'
|
||||||
assert e.save
|
assert e.save
|
||||||
assert_equal e, Enumeration.priorities.default
|
assert_equal e, Enumeration.default
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_update_default
|
def test_update_default
|
||||||
e = Enumeration.priorities.default
|
e = Enumeration.default
|
||||||
e.update_attributes(:name => 'Changed', :is_default => true)
|
e.update_attributes(:name => 'Changed', :is_default => true)
|
||||||
assert_equal e, Enumeration.priorities.default
|
assert_equal e, Enumeration.default
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_update_default_to_non_default
|
def test_update_default_to_non_default
|
||||||
e = Enumeration.priorities.default
|
e = Enumeration.default
|
||||||
e.update_attributes(:name => 'Changed', :is_default => false)
|
e.update_attributes(:name => 'Changed', :is_default => false)
|
||||||
assert_nil Enumeration.priorities.default
|
assert_nil Enumeration.default
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_change_default
|
def test_change_default
|
||||||
e = Enumeration.find_by_name('Urgent')
|
e = Enumeration.find_by_name('Default Enumeration')
|
||||||
e.update_attributes(:name => 'Urgent', :is_default => true)
|
e.update_attributes(:name => 'Changed Enumeration', :is_default => true)
|
||||||
assert_equal e, Enumeration.priorities.default
|
assert_equal e, Enumeration.default
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_destroy_with_reassign
|
def test_destroy_with_reassign
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require File.dirname(__FILE__) + '/../test_helper'
|
||||||
|
|
||||||
|
class IssuePriorityTest < Test::Unit::TestCase
|
||||||
|
fixtures :enumerations, :issues
|
||||||
|
|
||||||
|
def test_should_be_an_enumeration
|
||||||
|
assert IssuePriority.ancestors.include?(Enumeration)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_objects_count
|
||||||
|
# low priority
|
||||||
|
assert_equal 5, IssuePriority.find(4).objects_count
|
||||||
|
# urgent
|
||||||
|
assert_equal 0, IssuePriority.find(7).objects_count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_option_name
|
||||||
|
assert_equal :enumeration_issue_priorities, IssuePriority.new.option_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -27,14 +27,14 @@ class IssueTest < Test::Unit::TestCase
|
||||||
:time_entries
|
:time_entries
|
||||||
|
|
||||||
def test_create
|
def test_create
|
||||||
issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.priorities.first, :subject => 'test_create', :description => 'IssueTest#test_create', :estimated_hours => '1:30')
|
issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'test_create', :description => 'IssueTest#test_create', :estimated_hours => '1:30')
|
||||||
assert issue.save
|
assert issue.save
|
||||||
issue.reload
|
issue.reload
|
||||||
assert_equal 1.5, issue.estimated_hours
|
assert_equal 1.5, issue.estimated_hours
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_create_minimal
|
def test_create_minimal
|
||||||
issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.priorities.first, :subject => 'test_create')
|
issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'test_create')
|
||||||
assert issue.save
|
assert issue.save
|
||||||
assert issue.description.nil?
|
assert issue.description.nil?
|
||||||
end
|
end
|
||||||
|
@ -123,7 +123,7 @@ class IssueTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_category_based_assignment
|
def test_category_based_assignment
|
||||||
issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.priorities.first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
|
issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
|
||||||
assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
|
assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ class IssueTest < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_should_close_duplicates
|
def test_should_close_duplicates
|
||||||
# Create 3 issues
|
# Create 3 issues
|
||||||
issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.priorities.first, :subject => 'Duplicates test', :description => 'Duplicates test')
|
issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Duplicates test', :description => 'Duplicates test')
|
||||||
assert issue1.save
|
assert issue1.save
|
||||||
issue2 = issue1.clone
|
issue2 = issue1.clone
|
||||||
assert issue2.save
|
assert issue2.save
|
||||||
|
@ -166,7 +166,7 @@ class IssueTest < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_should_not_close_duplicated_issue
|
def test_should_not_close_duplicated_issue
|
||||||
# Create 3 issues
|
# Create 3 issues
|
||||||
issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.priorities.first, :subject => 'Duplicates test', :description => 'Duplicates test')
|
issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Duplicates test', :description => 'Duplicates test')
|
||||||
assert issue1.save
|
assert issue1.save
|
||||||
issue2 = issue1.clone
|
issue2 = issue1.clone
|
||||||
assert issue2.save
|
assert issue2.save
|
||||||
|
@ -248,7 +248,7 @@ class IssueTest < Test::Unit::TestCase
|
||||||
|
|
||||||
def test_create_should_send_email_notification
|
def test_create_should_send_email_notification
|
||||||
ActionMailer::Base.deliveries.clear
|
ActionMailer::Base.deliveries.clear
|
||||||
issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.priorities.first, :subject => 'test_create', :estimated_hours => '1:30')
|
issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'test_create', :estimated_hours => '1:30')
|
||||||
|
|
||||||
assert issue.save
|
assert issue.save
|
||||||
assert_equal 1, ActionMailer::Base.deliveries.size
|
assert_equal 1, ActionMailer::Base.deliveries.size
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require File.dirname(__FILE__) + '/../test_helper'
|
||||||
|
|
||||||
|
class TimeEntryActivityTest < Test::Unit::TestCase
|
||||||
|
fixtures :enumerations, :time_entries
|
||||||
|
|
||||||
|
def test_should_be_an_enumeration
|
||||||
|
assert TimeEntryActivity.ancestors.include?(Enumeration)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_objects_count
|
||||||
|
assert_equal 3, TimeEntryActivity.find_by_name("Design").objects_count
|
||||||
|
assert_equal 1, TimeEntryActivity.find_by_name("Development").objects_count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_option_name
|
||||||
|
assert_equal :enumeration_activities, TimeEntryActivity.new.option_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue