-# redMine - project management software
-# Copyright (C) 2006 Jean-Philippe Lang
+# Redmine - project management software
+# Copyright (C) 2006-2011 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
@versions = @project.shared_versions.sort
@priorities = IssuePriority.all
@categories = @project.issue_categories
- @assignees = @project.members.collect { |m| m.user }.sort
- @authors = @project.members.collect { |m| m.user }.sort
+ @assignees = (Setting.issue_group_assignment? ? @project.principals : @project.users).sort
+ @authors = @project.users.sort
@subprojects = @project.descendants.visible
@issues_by_tracker = Issue.by_tracker(@project)
@report_title = l(:field_category)
when "assigned_to"
@field = "assigned_to_id"
- @rows = @project.members.collect { |m| m.user }.sort
+ @rows = (Setting.issue_group_assignment? ? @project.principals : @project.users).sort
@data = Issue.by_assigned_to(@project)
@report_title = l(:field_assigned_to)
when "author"
@field = "author_id"
- @rows = @project.members.collect { |m| m.user }.sort
+ @rows = @project.users.sort
@data = Issue.by_author(@project)
@report_title = l(:field_author)
when "subproject"
# Redmine - project management software
-# Copyright (C) 2006-2009 Jean-Philippe Lang
+# Copyright (C) 2006-2011 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
validates_presence_of :lastname
validates_uniqueness_of :lastname, :case_sensitive => false
validates_length_of :lastname, :maximum => 30
-
+
+ before_destroy :remove_references_before_destroy
+
def to_s
lastname.to_s
end
+ alias :name :to_s
+
def user_added(user)
members.each do |member|
next if member.project.nil?
:conditions => ["#{Member.table_name}.user_id = ? AND #{MemberRole.table_name}.inherited_from IN (?)", user.id, member.member_role_ids]).each(&:destroy)
end
end
+
+ private
+
+ # Removes references that are not handled by associations
+ def remove_references_before_destroy
+ return if self.id.nil?
+
+ Issue.update_all 'assigned_to_id = NULL', ['assigned_to_id = ?', id]
+ end
end
belongs_to :tracker
belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_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 => 'Principal', :foreign_key => 'assigned_to_id'
belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
belongs_to :priority, :class_name => 'IssuePriority', :foreign_key => 'priority_id'
belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
when 'all'
nil
when 'default'
- "(#{table_name}.is_private = #{connection.quoted_false} OR #{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id = #{user.id})"
+ user_ids = [user.id] + user.groups.map(&:id)
+ "(#{table_name}.is_private = #{connection.quoted_false} OR #{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids}))"
when 'own'
- "(#{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id = #{user.id})"
+ user_ids = [user.id] + user.groups.map(&:id)
+ "(#{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids}))"
else
'1=0'
end
when 'all'
true
when 'default'
- !self.is_private? || self.author == user || self.assigned_to == user
+ !self.is_private? || self.author == user || user.is_or_belongs_to?(assigned_to)
when 'own'
- self.author == user || self.assigned_to == user
+ self.author == user || user.is_or_belongs_to?(assigned_to)
else
false
end
# Author and assignee are always notified unless they have been
# locked or don't want to be notified
notified << author if author && author.active? && author.notify_about?(self)
- notified << assigned_to if assigned_to && assigned_to.active? && assigned_to.notify_about?(self)
+ if assigned_to
+ if assigned_to.is_a?(Group)
+ notified += assigned_to.users.select {|u| u.active? && u.notify_about?(self)}
+ else
+ notified << assigned_to if assigned_to.active? && assigned_to.notify_about?(self)
+ end
+ end
notified.uniq!
# Remove users that can not view the issue
notified.reject! {|user| !visible?(user)}
class IssueCategory < ActiveRecord::Base
belongs_to :project
- belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
+ belongs_to :assigned_to, :class_name => 'Principal', :foreign_key => 'assigned_to_id'
has_many :issues, :foreign_key => 'category_id', :dependent => :nullify
validates_presence_of :name
# Returns a Hash of issue attributes extracted from keywords in the email body
def issue_attributes_from_keywords(issue)
- assigned_to = (k = get_keyword(:assigned_to, :override => true)) && find_user_from_keyword(k)
- assigned_to = nil if assigned_to && !issue.assignable_users.include?(assigned_to)
+ assigned_to = (k = get_keyword(:assigned_to, :override => true)) && find_assignee_from_keyword(k, issue)
attrs = {
'tracker_id' => (k = get_keyword(:tracker)) && issue.project.trackers.named(k).first.try(:id),
end
body.strip
end
-
- def find_user_from_keyword(keyword)
- user ||= User.find_by_mail(keyword)
- user ||= User.find_by_login(keyword)
- if user.nil? && keyword.match(/ /)
+
+ def find_assignee_from_keyword(keyword, issue)
+ keyword = keyword.to_s.downcase
+ assignable = issue.assignable_users
+ assignee = nil
+ assignee ||= assignable.detect {|a| a.mail.to_s.downcase == keyword || a.login.to_s.downcase == keyword}
+ if assignee.nil? && keyword.match(/ /)
firstname, lastname = *(keyword.split) # "First Last Throwaway"
- user ||= User.find_by_firstname_and_lastname(firstname, lastname)
+ assignee ||= assignable.detect {|a| a.is_a?(User) && a.firstname.to_s.downcase == firstname && a.lastname.to_s.downcase == lastname}
+ end
+ if assignee.nil?
+ assignee ||= assignable.detect {|a| a.is_a?(Group) && a.name.downcase == keyword}
end
- user
+ assignee
end
end
# Redmine - project management software
-# Copyright (C) 2006-2009 Jean-Philippe Lang
+# Copyright (C) 2006-2011 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
has_many :members, :foreign_key => 'user_id', :dependent => :destroy
has_many :memberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :project, :roles ], :conditions => "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}", :order => "#{Project.table_name}.name"
has_many :projects, :through => :memberships
+ has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
# Groups and active users
named_scope :active, :conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status = 1)"
Member.delete_all(['project_id = ?', id])
end
- # Users issues can be assigned to
+ # Users/groups issues can be assigned to
def assignable_users
- members.select {|m| m.roles.detect {|role| role.assignable?}}.collect {|m| m.user}.sort
+ assignable = Setting.issue_group_assignment? ? member_principals : members
+ assignable.select {|m| m.roles.detect {|role| role.assignable?}}.collect {|m| m.principal}.sort
end
# Returns the mail adresses of users that should be always notified on project events
"estimated_hours" => { :type => :float, :order => 13 },
"done_ratio" => { :type => :integer, :order => 14 }}
- user_values = []
- user_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
+ principals = []
if project
- user_values += project.users.sort.collect{|s| [s.name, s.id.to_s] }
+ principals += project.principals.sort
else
all_projects = Project.visible.all
if all_projects.any?
# members of visible projects
- user_values += User.active.find(:all, :conditions => ["#{User.table_name}.id IN (SELECT DISTINCT user_id FROM members WHERE project_id IN (?))", all_projects.collect(&:id)]).sort.collect{|s| [s.name, s.id.to_s] }
+ principals += Principal.active.find(:all, :conditions => ["#{User.table_name}.id IN (SELECT DISTINCT user_id FROM members WHERE project_id IN (?))", all_projects.collect(&:id)]).sort
# project filter
project_values = []
@available_filters["project_id"] = { :type => :list, :order => 1, :values => project_values} unless project_values.empty?
end
end
- @available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => user_values } unless user_values.empty?
- @available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } unless user_values.empty?
+ users = principals.select {|p| p.is_a?(User)}
+
+ assigned_to_values = []
+ assigned_to_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
+ assigned_to_values += (Setting.issue_group_assignment? ? principals : users).collect{|s| [s.name, s.id.to_s] }
+ @available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => assigned_to_values } unless assigned_to_values.empty?
+
+ author_values = []
+ author_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
+ author_values += users.collect{|s| [s.name, s.id.to_s] }
+ @available_filters["author_id"] = { :type => :list, :order => 5, :values => author_values } unless author_values.empty?
group_values = Group.all.collect {|g| [g.name, g.id.to_s] }
@available_filters["member_of_group"] = { :type => :list_optional, :order => 6, :values => group_values } unless group_values.empty?
has_and_belongs_to_many :groups, :after_add => Proc.new {|user, group| group.user_added(user)},
:after_remove => Proc.new {|user, group| group.user_removed(user)}
- has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
has_many :changesets, :dependent => :nullify
has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
has_one :rss_token, :class_name => 'Token', :conditions => "action='feeds'"
@projects_by_role
end
+ # Returns true if user is arg or belongs to arg
+ def is_or_belongs_to?(arg)
+ if arg.is_a?(User)
+ self == arg
+ elsif arg.is_a?(Group)
+ arg.users.include?(self)
+ else
+ false
+ end
+ end
+
# Return true if the user is allowed to do the specified action on a specific context
# Action can be:
# * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
true
when 'selected'
# user receives notifications for created/assigned issues on unselected projects
- if object.is_a?(Issue) && (object.author == self || object.assigned_to == self)
+ if object.is_a?(Issue) && (object.author == self || is_or_belongs_to?(object.assigned_to))
true
else
false
when 'none'
false
when 'only_my_events'
- if object.is_a?(Issue) && (object.author == self || object.assigned_to == self)
+ if object.is_a?(Issue) && (object.author == self || is_or_belongs_to?(object.assigned_to))
true
else
false
end
when 'only_assigned'
- if object.is_a?(Issue) && object.assigned_to == self
+ if object.is_a?(Issue) && is_or_belongs_to?(object.assigned_to)
true
else
false
<div class="box">
<p><%= f.text_field :name, :size => 30, :required => true %></p>
-<p><%= f.select :assigned_to_id, @project.users.sort.collect{|u| [u.name, u.id]}, :include_blank => true %></p>
+<p><%= f.select :assigned_to_id, @project.assignable_users.sort.collect{|u| [u.name, u.id]}, :include_blank => true %></p>
</div>
<div class="box tabular settings">
<p><%= setting_check_box :cross_project_issue_relations %></p>
+<p><%= setting_check_box :issue_group_assignment %></p>
+
<p><%= setting_check_box :display_subprojects_issues %></p>
<p><%= setting_select :issue_done_ratio, Issue::DONE_RATIO_OPTIONS.collect {|i| [l("setting_issue_done_ratio_#{i}"), i]} %></p>
enumeration_doc_categories: Категории документи
enumeration_activities: Дейности (time tracking)
enumeration_system_activity: Системна активност
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
setting_commit_logtime_enabled: Enable time logging
setting_commit_logtime_activity_id: Activity for logged time
setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+ setting_issue_group_assignment: Allow issue assignment to groups
permission_add_project: Create project
permission_add_subprojects: Create subprojects
text_scm_command_not_available: La orden para el Scm no está disponible. Por favor, compruebe la configuración en el panel de administración.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
setting_commit_logtime_enabled: Permettre la saisie de temps
setting_commit_logtime_activity_id: Activité pour le temps saisi
setting_gantt_items_limit: Nombre maximum d'éléments affichés sur le gantt
+ setting_issue_group_assignment: Permettre l'assignement des demandes aux groupes
permission_add_project: Créer un projet
permission_add_subprojects: Créer des sous-projets
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_issues_destroy_descendants_confirmation: %{count}個の子チケットも削除されます。
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Comando de versionamento não disponível. Por favor verifique as configurações no painel de administração.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
enumeration_system_activity: Systemaktivitet
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
enumeration_doc_categories: 文件分類
enumeration_activities: 活動 (時間追蹤)
enumeration_system_activity: 系統活動
+ setting_issue_group_assignment: Allow issue assignment to groups
text_scm_command_not_available: Scm command is not available. Please check settings on the administration panel.
notice_issue_successful_create: Issue %{id} created.
label_between: between
+ setting_issue_group_assignment: Allow issue assignment to groups
format: symbol
cross_project_issue_relations:
default: 0
+issue_group_assignment:
+ default: 0
notified_events:
serialized: true
default:
assert_not_nil v
assert_equal 'Value for field 2', v.value
end
+
+ def test_post_new_with_group_assignment
+ group = Group.find(11)
+ project = Project.find(1)
+ project.members << Member.new(:principal => group, :roles => [Role.first])
+
+ with_settings :issue_group_assignment => '1' do
+ @request.session[:user_id] = 2
+ assert_difference 'Issue.count' do
+ post :create, :project_id => project.id,
+ :issue => {:tracker_id => 3,
+ :status_id => 1,
+ :subject => 'This is the test_new_with_group_assignment issue',
+ :assigned_to_id => group.id}
+ end
+ end
+ assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
+
+ issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
+ assert_not_nil issue
+ assert_equal group, issue.assigned_to
+ end
def test_post_create_without_start_date
@request.session[:user_id] = 2
assert_equal 1, journal.details.size
end
+ def test_bulk_update_with_group_assignee
+ group = Group.find(11)
+ project = Project.find(1)
+ project.members << Member.new(:principal => group, :roles => [Role.first])
+
+ @request.session[:user_id] = 2
+ # update issues assignee
+ post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
+ :issue => {:priority_id => '',
+ :assigned_to_id => group.id,
+ :custom_field_values => {'2' => ''}}
+
+ assert_response 302
+ assert_equal [group, group], Issue.find_all_by_id([1, 2]).collect {|i| i.assigned_to}
+ end
+
def test_bulk_update_on_different_projects
@request.session[:user_id] = 2
# update issues priority
# Redmine - project management software
-# Copyright (C) 2006-2009 Jean-Philippe Lang
+# Copyright (C) 2006-2011 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
User.find(8).groups.clear
assert !User.find(8).member_of?(Project.find(5))
end
+
+ def test_destroy_should_unassign_issues
+ group = Group.first
+ Issue.update_all(["assigned_to_id = ?", group.id], 'id = 1')
+
+ assert group.destroy
+ assert group.destroyed?
+
+ assert_equal nil, Issue.find(1).assigned_to_id
+ end
end
-# redMine - project management software
-# Copyright (C) 2006-2007 Jean-Philippe Lang
+# Redmine - project management software
+# Copyright (C) 2006-2011 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
@category = IssueCategory.find(1)
end
+ def test_create
+ assert IssueCategory.new(:project_id => 2, :name => 'New category').save
+ category = IssueCategory.first(:order => 'id DESC')
+ assert_equal 'New category', category.name
+ end
+
+ def test_create_with_group_assignment
+ assert IssueCategory.new(:project_id => 2, :name => 'Group assignment', :assigned_to_id => 11).save
+ category = IssueCategory.first(:order => 'id DESC')
+ assert_kind_of Group, category.assigned_to
+ assert_equal Group.find(11), category.assigned_to
+ end
+
def test_destroy
issue = @category.issues.first
@category.destroy
issue.reload
assert_equal 'PostgreSQL', issue.custom_value_for(field).value
end
+
+ def test_create_with_group_assignment
+ with_settings :issue_group_assignment => '1' do
+ assert Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1, :subject => 'Group assignment', :assigned_to_id => 11).save
+ issue = Issue.first(:order => 'id DESC')
+ assert_kind_of Group, issue.assigned_to
+ assert_equal Group.find(11), issue.assigned_to
+ end
+ end
def assert_visibility_match(user, issues)
assert_equal issues.collect(&:id).sort, Issue.all.select {|issue| issue.visible?(user)}.collect(&:id).sort
# author is not a member of project anymore
assert !copy.recipients.include?(copy.author.mail)
end
+
+ def test_recipients_should_include_the_assigned_group_members
+ group_member = User.generate_with_protected!
+ group = Group.generate!
+ group.users << group_member
+
+ issue = Issue.find(12)
+ issue.assigned_to = group
+ assert issue.recipients.include?(group_member.mail)
+ end
def test_watcher_recipients_should_not_include_users_that_cannot_view_the_issue
user = User.find(3)
assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length, "User #{user_id} appears more or less than once"
end
end
+
+ context "with issue_group_assignment" do
+ should "include groups" do
+ issue = Issue.new(:project => Project.find(2))
+
+ with_settings :issue_group_assignment => '1' do
+ assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
+ assert issue.assignable_users.include?(Group.find(11))
+ end
+ end
+ end
+
+ context "without issue_group_assignment" do
+ should "not include groups" do
+ issue = Issue.new(:project => Project.find(2))
+
+ with_settings :issue_group_assignment => '0' do
+ assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
+ assert !issue.assignable_users.include?(Group.find(11))
+ end
+ end
+ end
end
def test_create_should_send_email_notification
assert_equal 'Urgent', issue.priority.to_s
assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
end
+
+ def test_add_issue_with_group_assignment
+ with_settings :issue_group_assignment => '1' do
+ issue = submit_email('ticket_on_given_project.eml') do |email|
+ email.gsub!('Assigned to: John Smith', 'Assigned to: B Team')
+ end
+ assert issue.is_a?(Issue)
+ assert !issue.new_record?
+ issue.reload
+ assert_equal Group.find(11), issue.assigned_to
+ end
+ end
def test_add_issue_with_partial_attributes_override
issue = submit_email('ticket_with_attributes.eml', :issue => {:priority => 'High'}, :allow_override => ['tracker'])
def submit_email(filename, options={})
raw = IO.read(File.join(FIXTURES_PATH, filename))
+ yield raw if block_given?
MailHandler.receive(raw, options)
end