Project

General

Profile

Patch #11898 » inherit_cats-2.2.3.patch

Patch for 2.2.3 - Ruedi Silvestri, 2013-02-25 15:57

View differences:

app/controllers/issue_categories_controller.rb (working copy)
95 95
    if @issue_count == 0 || params[:todo] || api_request?
96 96
      reassign_to = nil
97 97
      if params[:reassign_to_id] && (params[:todo] == 'reassign' || params[:todo].blank?)
98
        reassign_to = @project.issue_categories.find_by_id(params[:reassign_to_id])
98
        reassign_to = IssueCategory.find_by_id(params[:reassign_to_id])
99 99
      end
100 100
      @category.destroy(reassign_to)
101 101
      respond_to do |format|
......
104 104
      end
105 105
      return
106 106
    end
107
    @categories = @project.issue_categories - [@category]
107
	old = nil
108
    @categories = @project.inherited_categories(true).reject { |cat|
109
	  if cat.id == @category.id then
110
	    true
111
	  else
112
	    cr = (old == cat.name)
113
		old = cat.name
114
		cr
115
	  end
116
	}
108 117
  end
109 118

  
110 119
private
app/controllers/projects_controller.rb (working copy)
182 182
  def update
183 183
    @project.safe_attributes = params[:project]
184 184
    if validate_parent_id && @project.save
185
      @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
185
	  new_inherit = params[:project].has_key?('inherit') ? params[:project]['inherit'] : nil
186
	  if new_inherit == "1" then new_inherit = true
187
	  elsif new_inherit == "0" then new_inherit = false
188
	  end
189
	  new_parent = params[:project].has_key?('parent_id') ? params[:project]['parent_id'] : @project.parent
190
      @project.set_allowed_parent!(new_parent, new_inherit) if (params[:project].has_key?('parent_id') || params[:project].has_key?('inherit'))
186 191
      respond_to do |format|
187 192
        format.html {
188 193
          flash[:notice] = l(:notice_successful_update)
app/helpers/application_helper.rb (working copy)
1284 1284
  def link_to_content_update(text, url_params = {}, html_options = {})
1285 1285
    link_to(text, url_params, html_options)
1286 1286
  end
1287

  
1288
  def format_project(proj, list)
1289
    resul = ''
1290
	list.reverse.each { |p|
1291
	  break if p == proj
1292
	  resul += "#{p.name} » "
1293
	}
1294
	resul += proj.name
1295
  end
1296

  
1287 1297
end
app/helpers/issue_categories_helper.rb (working copy)
18 18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 19

  
20 20
module IssueCategoriesHelper
21
  def options_for_reassign(categ, categs, proj)
22
    projs = proj.inherited_projects
23
    cats = categs.sort { |a, b| 
24
	  (a.project_id == b.project_id) ? (a.name <=> b.name) : (a.project.rgt <=> b.project.rgt)
25
	}
26
    return options_for_select(cats.map { |cat|
27
	  ["#{cat.name} (#{format_project cat.project, projs})", cat.id]
28
	})
29
  end
30

  
21 31
end
app/models/issue_category.rb (working copy)
34 34
  # Destroy the category
35 35
  # If a category is specified, issues are reassigned to this category
36 36
  def destroy(reassign_to = nil)
37
    if reassign_to && reassign_to.is_a?(IssueCategory) && reassign_to.project == self.project
37
    if reassign_to && reassign_to.is_a?(IssueCategory) && (self.project.inherited_projects.include?(reassign_to.project) || (self.project == reassign_to.project))
38 38
      Issue.update_all("category_id = #{reassign_to.id}", "category_id = #{id}")
39 39
    end
40 40
    destroy_without_reassign
app/models/project.rb (working copy)
127 127
    end
128 128
  end
129 129

  
130
  # walks ancestors up to the first that doesn't inherit from his parent
131
  def inherited_projects
132
  	l = [self]
133
	self_and_ancestors.reverse.each { |p| 
134
	  if p.inherit and ! p.parent.nil?
135
		l << p.parent
136
	  else
137
		break
138
	  end
139
	}
140
	return l
141
  end
142

  
143
  # get inherited categories (all = false) or all categories from inherited
144
  # projects if all is true
145
  def inherited_categories(all = false)
146
	categs = IssueCategory.find(:all ,
147
						  :joins => :project,
148
						  :conditions => { :project_id => inherited_projects },
149
						  :order => "name, #{Project.table_name}.rgt")
150
	old = nil
151
	# a category from a deep project masks categories of same name from others
152
	return all ? categs : categs.reject { |c| cr = (c.name == old)
153
	  old = c.name
154
	  cr 
155
	}
156
  end
157

  
130 158
  def identifier=(identifier)
131 159
    super unless identifier_frozen?
132 160
  end
......
350 378
  end
351 379

  
352 380
  # Sets the parent of the project with authorization check
353
  def set_allowed_parent!(p)
381
  def set_allowed_parent!(p, i = nil)
354 382
    unless p.nil? || p.is_a?(Project)
355 383
      if p.to_s.blank?
356 384
        p = nil
......
366 394
    elsif !allowed_parents.include?(p)
367 395
      return false
368 396
    end
369
    set_parent!(p)
397
    set_parent!(p, i)
370 398
  end
371 399

  
372 400
  # Sets the parent of the project
373 401
  # Argument can be either a Project, a String, a Fixnum or nil
374
  def set_parent!(p)
402
  def set_parent!(p, i = nil)
403
    i = self.inherit if i.nil?
375 404
    unless p.nil? || p.is_a?(Project)
376 405
      if p.to_s.blank?
377 406
        p = nil
......
380 409
        return false unless p
381 410
      end
382 411
    end
412
	i = false if p.nil?
383 413
    if p == parent && !p.nil?
384
      # Nothing to do
414
	  adjust_inheritance((self.inherit ? self.parent : nil), i ? p : nil)
415
	  Project.update(self.id, :inherit => i) unless (i == self.inherit)
416
	  self.inherit = i
385 417
      true
386 418
    elsif p.nil? || (p.active? && move_possible?(p))
419
	  adjust_inheritance((self.inherit ? self.parent : nil), i ? p : nil)
420
	  Project.update(self.id, :inherit => i) unless (i == self.inherit)
421
	  self.inherit = i
387 422
      set_or_update_position_under(p)
388 423
      Issue.update_versions_from_hierarchy_change(self)
389 424
      true
......
973 1008
      move_to_child_of(target_parent)
974 1009
    end
975 1010
  end
1011

  
1012
  # adjusts inherited issue categories when inherit is set to false or
1013
  #  when parent is changed - new and old are direct inherited projects
1014
  #  they are nil if inherit is false
1015
  # For each lost category, a categorie of same name is created in current
1016
  #  project, and issues are reaffected
1017
  def adjust_inheritance(old, new)
1018
  	if (inherit && new.nil?) then
1019
	  self.inherit = false
1020
	  Project.update(id, {:inherit => false})
1021
	end
1022
    return if old.nil?
1023
	lost_categories = old.inherited_categories
1024
	lost_categories -= new.inherited_categories if ! new.nil?
1025
	subprojs = self_and_descendants
1026
	Issue.transaction do
1027
		lost_categories.each { |cat|
1028
		  if ! Issue.find(:all,
1029
						:joins => :project,
1030
						:conditions => [ "category_id = ? and #{Project.table_name}.lft > ? and #{Project.table_name}.rgt < ?", cat.id, self.lft, self.rgt]
1031
		  ).empty? then
1032
			newcat=IssueCategory.create!(:name => cat.name, :project_id => self.id)
1033
			n = Issue.update_all({:category_id => newcat.id},
1034
						 { :category_id => cat, :project_id => subprojs})
1035
		  end
1036
		}
1037
	end
1038
  end
976 1039
end
app/views/issue_categories/destroy.html.erb (working copy)
7 7
<% if @categories.size > 0 %>
8 8
<label><%= radio_button_tag 'todo', 'reassign', false %> <%= l(:text_issue_category_reassign_to) %></label>:
9 9
<%= label_tag "reassign_to_id", l(:description_issue_category_reassign), :class => "hidden-for-sighted" %>
10
<%= select_tag 'reassign_to_id', options_from_collection_for_select(@categories, 'id', 'name') %></p>
10
<!-- %= select_tag 'reassign_to_id', options_from_collection_for_select(@categories, 'id', 'name') %-->
11
<%= select_tag 'reassign_to_id', options_for_reassign(@category, @categories, @project) %>
12
</p>
13

  
11 14
<% end %>
12 15
</div>
13 16

  
app/views/issues/_attributes.html.erb (working copy)
18 18
<p><%= f.select :assigned_to_id, principals_options_for_select(@issue.assignable_users, @issue.assigned_to), :include_blank => true, :required => @issue.required_attribute?('assigned_to_id') %></p>
19 19
<% end %>
20 20

  
21
<% if @issue.safe_attribute?('category_id') && @issue.project.issue_categories.any? %>
22
<p><%= f.select :category_id, (@issue.project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true, :required => @issue.required_attribute?('category_id') %>
21
<% if @issue.safe_attribute?('category_id') && @issue.project.inherited_categories.any? %>
22
<p><%= f.select :category_id, (@issue.project.inherited_categories.collect {|c| [c.name, c.id]}), :include_blank => true, :required => @issue.required_attribute?('category_id') %>
23 23
<%= link_to(image_tag('add.png', :style => 'vertical-align: middle;'),
24 24
            new_project_issue_category_path(@issue.project),
25 25
            :remote => true,
app/views/projects/_form.html.erb (working copy)
6 6

  
7 7
<% unless @project.allowed_parents.compact.empty? %>
8 8
    <p><%= label(:project, :parent_id, l(:field_parent)) %><%= parent_project_select_tag(@project) %></p>
9
	<p><%= f.check_box :inherit %></p>
9 10
<% end %>
10 11

  
11 12
<p><%= f.text_area :description, :rows => 5, :class => 'wiki-edit' %></p>
app/views/projects/settings/_issue_categories.html.erb (working copy)
25 25
<% else %>
26 26
<p class="nodata"><%= l(:label_no_data) %></p>
27 27
<% end %>
28
<p><%= link_to l(:label_issue_category_new), new_project_issue_category_path(@project), :class => 'icon icon-add' if User.current.allowed_to?(:manage_categories, @project) %></p>
29
<% strict_inherited = (@project.inherited_categories(true) - @project.issue_categories) %>
30
<% if ! strict_inherited.empty? %>
31
  <% masked = false %>
32
  <% inherited = @project.inherited_categories %>
33
  <h3><%= l(:text_issue_categories_inherited) %></h3>
34
  <table class="list">
35
    <thead><tr>
36
		<th><%= l(:label_project) %></th><th><%= l(:label_issue_category) %></th>
37
	</tr></thead>
38
	<tbody>
39
	  <% projs = @project.inherited_projects; projs.shift %>
40
	  <% for p in projs %>
41
	    <% for c in p.issue_categories %>
42
		  <tr>
43
		    <td><%= format_project(p, projs) %></td>
44
			<td><%= c.name %>
45
			  <% if ! inherited.include?(c) %>*<% masked = true %><% end %>
46
			</td>
47
		  </tr>
48
		<% end %>
49
	  <% end %>
50
	</tbody>
51
  </table>
52
  <% if masked %>
53
    <p>* : <%= l(:text_issue_category_masked) %></p>
54
  <% end %>
55
<% end %>
28 56

  
29
<p><%= link_to l(:label_issue_category_new), new_project_issue_category_path(@project), :class => 'icon icon-add' if User.current.allowed_to?(:manage_categories, @project) %></p>
config/locales/en.yml (working copy)
332 332
  field_timeout: "Timeout (in seconds)"
333 333
  field_board_parent: Parent forum
334 334
  field_private_notes: Private notes
335
  field_inherit: Inherits categories from parent
335 336

  
337

  
336 338
  setting_app_title: Application title
337 339
  setting_app_subtitle: Application subtitle
338 340
  setting_welcome_text: Welcome text
......
1032 1034
  text_account_destroy_confirmation: "Are you sure you want to proceed?\nYour account will be permanently deleted, with no way to reactivate it."
1033 1035
  text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
1034 1036
  text_project_closed: This project is closed and read-only.
1037
  text_issue_categories_inherited: "Categories from inherited projects"
1038
  text_issue_category_masked: "category is masked by one with same name in a deeper project"
1035 1039

  
1040

  
1036 1041
  default_role_manager: Manager
1037 1042
  default_role_developer: Developer
1038 1043
  default_role_reporter: Reporter
db/migrate/20120830171625_add_inherit_to_project.rb (working copy)
1
class AddInheritToProject < ActiveRecord::Migration
2
  def change
3
    add_column :projects, :inherit, :boolean
4
  end
5
end
test/functional/issue_categories_controller_inheritance_test.rb (working copy)
1
# This program is free software; you can redistribute it and/or
2
# modify it under the terms of the GNU General Public License
3
# as published by the Free Software Foundation; either version 2
4
# of the License, or (at your option) any later version.
5
#
6
# This program is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9
# GNU General Public License for more details.
10
#
11
# You should have received a copy of the GNU General Public License
12
# along with this program; if not, write to the Free Software
13
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
14

  
15
require File.expand_path('../../test_helper', __FILE__)
16
require 'projects_controller'
17

  
18
class IssueCategoriesControllerInheritanceTest < ActionController::TestCase
19
  fixtures :trackers, :issue_statuses, :enumerations, :workflows, :users
20

  
21
  def setup
22
    @controller = IssueCategoriesController.new
23
    @request    = ActionController::TestRequest.new
24
    @response   = ActionController::TestResponse.new
25
    User.current = nil
26
	@request.session[:user_id] = 1
27
 
28
	wt = WorkflowTransition.find(:first)
29
	@tracker = wt.tracker
30
	@status = wt.old_status
31

  
32
	@pa = Project.create!(:name => 'A', :identifier => 'a')
33
	@pb = Project.create!(:name => 'B', :identifier => 'b', :trackers => [@tracker])
34
	@pc = Project.create!(:name => 'C', :identifier => 'c', :parent_id => @pb.id, :inherit => true, :trackers => [@tracker])
35
	@pd = Project.create!(:name => 'D', :identifier => 'd', :parent_id => @pc.id, :inherit => true, :trackers => [@tracker])
36
	@pe = Project.create!(:name => 'E', :identifier => 'e', :parent_id => @pd.id, :inherit => true, :trackers => [@tracker])
37
	@pf = Project.create!(:name => 'F', :identifier => 'f', :parent_id => @pb.id, :inherit => true, :trackers => [@tracker])
38
	@pg = Project.create!(:name => 'G', :identifier => 'g', :trackers => [@tracker])
39
	@pa.reload
40
	@pb.reload
41
	@pc.reload
42
	@pd.reload
43
	@pd.reload
44
	@ca1 = IssueCategory.create!(:project => @pa, :name => 'ca1')
45
	@cb1 = IssueCategory.create!(:project => @pb, :name => 'cb1')
46
	@cb2 = IssueCategory.create!(:project => @pb, :name => 'cb2')
47
	@cd1 = IssueCategory.create!(:project => @pd, :name => 'cd1')
48
	@cd2 = IssueCategory.create!(:project => @pd, :name => 'cb2')
49
  end
50

  
51
  def test_destroy_no_reassign
52
    is1 = Issue.create! :tracker => @tracker, :project => @pe, :status => @status, :author_id => 1, :subject => 'IS1', :category => @cd1
53
    delete :destroy, :id => @cd1.id, :todo => "nil"
54
	is1.reload
55
	assert_nil is1.category
56
  end
57

  
58
  def test_destroy_reassign_same_project
59
    is1 = Issue.create! :tracker => @tracker, :project => @pe, :status => @status, :author_id => 1, :subject => 'IS1', :category => @cd1
60
    delete :destroy, :id => @cd1.id, :todo => 'reassign', :reassign_to_id => @cd2.id
61
	is1.reload
62
	assert_equal @cd2, is1.category
63
  end
64

  
65
  def test_destroy_reassign_upper_project
66
    is1 = Issue.create! :tracker => @tracker, :project => @pe, :status => @status, :author_id => 1, :subject => 'IS1', :category => @cd1
67
    delete :destroy, :id => @cd1.id, :todo => 'reassign', :reassign_to_id => @cb1.id
68
    is1.reload
69
	assert_equal @cb1, is1.category
70
  end
71

  
72
  def test_destroy_reassign_demasked_category
73
    is1 = Issue.create! :tracker => @tracker, :project => @pe, :status => @status, :author_id => 1, :subject => 'IS1', :category => @cd2
74
    delete :destroy, :id => @cd2.id, :todo => 'reassign', :reassign_to_id => @cb2.id
75
    is1.reload
76
	assert_equal @cb2, is1.category
77
  end
78

  
79
  def test_categories_list_no_mask
80
    is1 = Issue.create! :tracker => @tracker, :project => @pe, :status => @status, :author_id => 1, :subject => 'IS1', :category => @cd2
81
    delete :destroy, :id => @cd2.id
82
	assert_response(:success)
83
	assert assigns.has_key?('categories')
84
	assert_equal [@cb1, @cb2, @cd1], assigns(:categories)
85
  end
86

  
87
  def test_categories_list_with_mask
88
    is1 = Issue.create! :tracker => @tracker, :project => @pe, :status => @status, :author_id => 1, :subject => 'IS1', :category => @cd1
89
    delete :destroy, :id => @cd1.id
90
	assert_response(:success)
91
	assert assigns.has_key?('categories')
92
	assert_equal [@cb1, @cd2], assigns(:categories)
93
  end
94

  
95
end
test/functional/projects_controller_inheritance_test.rb (working copy)
1
# This program is free software; you can redistribute it and/or
2
# modify it under the terms of the GNU General Public License
3
# as published by the Free Software Foundation; either version 2
4
# of the License, or (at your option) any later version.
5
#
6
# This program is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9
# GNU General Public License for more details.
10
#
11
# You should have received a copy of the GNU General Public License
12
# along with this program; if not, write to the Free Software
13
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
14

  
15
require File.expand_path('../../test_helper', __FILE__)
16
require 'projects_controller'
17

  
18
class ProjectsControllerInheritanceTest < ActionController::TestCase
19
  fixtures :trackers, :issue_statuses, :enumerations, :workflows, :users
20

  
21
  def setup
22
    @controller = ProjectsController.new
23
    @request    = ActionController::TestRequest.new
24
    @response   = ActionController::TestResponse.new
25
    User.current = nil
26
	@request.session[:user_id] = 1
27
 
28
	wt = WorkflowTransition.find(:first)
29
	@tracker = wt.tracker
30
	@status = wt.old_status
31

  
32
	@pa = Project.create!(:name => 'A', :identifier => 'a')
33
	@pb = Project.create!(:name => 'B', :identifier => 'b', :trackers => [@tracker])
34
	@pc = Project.create!(:name => 'C', :identifier => 'c', :parent_id => @pb.id, :inherit => true, :trackers => [@tracker])
35
	@pd = Project.create!(:name => 'D', :identifier => 'd', :parent_id => @pc.id, :inherit => true, :trackers => [@tracker])
36
	@pe = Project.create!(:name => 'E', :identifier => 'e', :parent_id => @pd.id, :inherit => true, :trackers => [@tracker])
37
	@pf = Project.create!(:name => 'F', :identifier => 'f', :parent_id => @pb.id, :inherit => true, :trackers => [@tracker])
38
	@pg = Project.create!(:name => 'G', :identifier => 'g', :trackers => [@tracker])
39
	@pa.reload
40
	@pb.reload
41
	@pc.reload
42
	@pd.reload
43
	@pd.reload
44
	@ca1 = IssueCategory.create!(:project => @pa, :name => 'ca1')
45
	@cb1 = IssueCategory.create!(:project => @pb, :name => 'cb1')
46
	@cb2 = IssueCategory.create!(:project => @pb, :name => 'cb2')
47
	@cd1 = IssueCategory.create!(:project => @pd, :name => 'cd1')
48
	@cd2 = IssueCategory.create!(:project => @pd, :name => 'cb2')
49
  end
50

  
51
  def test_adjust_set_inherit_to_false
52
  	is1 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issueb', :category => @cb1)
53
  	is2 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issued', :category => @cd1)
54
	post :update, :id => @pc.identifier, :project => {:inherit => "0"}
55
	assert_response(:redirect)
56
	assert_redirected_to "/projects/#{@pc.identifier}/settings"
57
	@pc.reload
58
	assert ! @pc.inherit
59
	assert_equal @pb, @pc.parent
60
	is1.reload
61
	is2.reload
62
	assert_equal @cd1, is2.category
63
	assert_equal 1, @pc.issue_categories.size
64
	cat = @pc.issue_categories[0]
65
	assert_equal cat, is1.category
66
	assert_equal @cb1.name, cat.name
67
  end
68

  
69
  def test_adjust_set_parent_nil
70
  	is1 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issueb', :category => @cb1)
71
  	is2 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issued', :category => @cd1)
72
	post :update, :id => @pc.identifier, :project => {:parent_id => ""}
73
	assert_response(:redirect)
74
	assert_redirected_to "/projects/#{@pc.identifier}/settings"
75
	@pc.reload
76
	assert ! @pc.inherit
77
	assert_nil @pc.parent
78
	is1.reload
79
	is2.reload
80
	assert_equal @cd1, is2.category
81
	assert_equal 1, @pc.issue_categories.size
82
	cat = @pc.issue_categories[0]
83
	assert_equal cat, is1.category
84
	assert_equal @cb1.name, cat.name
85
  end
86

  
87
  def test_adjust_inheritance_with_loss
88
  	is1 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issueb', :category => @cb1)
89
  	is2 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issued', :category => @cd1)
90
	post :update, :id => @pc.identifier, :project => {:parent_id => @pa.id}
91
	assert_response(:redirect)
92
	assert_redirected_to "/projects/#{@pc.identifier}/settings"
93
	@pc.reload
94
	assert @pc.inherit
95
	assert_equal @pa, @pc.parent
96
	is1.reload
97
	is2.reload
98
	assert_equal @cd1, is2.category
99
	assert_equal 1, @pc.issue_categories.size
100
	cat = @pc.issue_categories[0]
101
	assert_equal cat, is1.category
102
	assert_equal @cb1.name, cat.name
103
  end
104

  
105
  def test_adjust_inheritance_no_loss
106
  	is1 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issueb', :category => @cb1)
107
  	is2 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issued', :category => @cd1)
108
	post :update, :id => @pd.identifier, :project => {:parent_id => @pf.id}
109
	assert_redirected_to "/projects/#{@pd.identifier}/settings"
110
	@pd.reload
111
	assert @pd.inherit
112
	assert_equal @pf, @pd.parent
113
	is1.reload
114
	is2.reload
115
	assert_equal @cd1, is2.category
116
	assert_equal 2, @pd.issue_categories.size
117
	assert_equal @cb1, is1.category
118
  end
119

  
120
  def test_set_inherit
121
    @pf.inherit = false
122
	@pf.save!
123
	@pf.reload
124
	assert ! @pf.inherit
125
	post :update, :id => @pf.identifier, :project => {:inherit => true}
126
	assert_redirected_to "/projects/#{@pf.identifier}/settings"
127
	@pf.reload
128
	assert @pf.inherit
129
  end
130

  
131
end
test/unit/helpers/issue_categories_helper_test.rb (working copy)
1
# encoding: utf-8
2

  
3
# This program is free software; you can redistribute it and/or
4
# modify it under the terms of the GNU General Public License
5
# as published by the Free Software Foundation; either version 2
6
# of the License, or (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16

  
17
require File.expand_path('../../../test_helper', __FILE__)
18

  
19
class IssueCategoryHelperTest < ActionView::TestCase
20
  include IssueCategoriesHelper
21

  
22
  fixtures :trackers, :issue_statuses, :enumerations, :users, :workflows
23

  
24
  def setup
25
    super
26
	User.current = nil
27
	wt = WorkflowTransition.find(:first)
28
	@tracker = wt.tracker
29
	@status = wt.old_status
30

  
31
	@pa = Project.create!(:name => 'A', :identifier => 'a')
32
	@pb = Project.create!(:name => 'B', :identifier => 'b', :trackers => [@tracker])
33
	@pc = Project.create!(:name => 'C', :identifier => 'c', :parent_id => @pb.id, :inherit => true, :trackers => [@tracker])
34
	@pd = Project.create!(:name => 'D', :identifier => 'd', :parent_id => @pc.id, :inherit => true, :trackers => [@tracker])
35
	@pe = Project.create!(:name => 'E', :identifier => 'e', :parent_id => @pd.id, :inherit => true, :trackers => [@tracker])
36
	@pf = Project.create!(:name => 'F', :identifier => 'f', :parent_id => @pb.id, :inherit => true, :trackers => [@tracker])
37
	@pg = Project.create!(:name => 'G', :identifier => 'g', :trackers => [@tracker])
38
	@pa.reload
39
	@pb.reload
40
	@pc.reload
41
	@pd.reload
42
	@pd.reload
43
	@ca1 = IssueCategory.create!(:project => @pa, :name => 'ca1')
44
	@cb1 = IssueCategory.create!(:project => @pb, :name => 'cb1')
45
	@cb2 = IssueCategory.create!(:project => @pb, :name => 'cb2')
46
	@cd1 = IssueCategory.create!(:project => @pd, :name => 'cd1')
47
	@cd2 = IssueCategory.create!(:project => @pd, :name => 'cb2')
48
  end
49

  
50
  def test_format_project
51
    list = @pe.inherited_projects
52
	assert_equal 'B » C » D', format_project(@pd, list)
53
	assert_equal 'B', format_project(@pb, list)
54
	assert_equal 'B » C » D » E', format_project(@pe, list)
55
  end
56

  
57
  def test_options_for_reassign_no_inheritance
58
    @pd.inherit = false
59
	@pd.save
60
	categs = @pd.inherited_categories - [@cd1]
61
	assert_equal "<option value=\"#{@cd2.id}\">cb2 (D)</option>", options_for_reassign(@cd1, categs, @pd)
62
  end
63

  
64
  def test_options_for_reassign_with_masked_categ
65
    categs = @pd.inherited_categories - [ @cd1 ]
66
	assert_equal "<option value=\"#{@cd2.id}\">cb2 (B » C » D)</option>\n<option value=\"#{@cb1.id}\">cb1 (B)</option>", options_for_reassign(@cd1, categs, @pd)
67
  end
68

  
69
  def test_options_for_reassign_no_masked_categ
70
    categs = (@pd.issue_categories | @pc.inherited_categories) - [ @cd2 ]
71
	assert_equal "<option value=\"#{@cd1.id}\">cd1 (B » C » D)</option>\n<option value=\"#{@cb1.id}\">cb1 (B)</option>\n<option value=\"#{@cb2.id}\">cb2 (B)</option>", options_for_reassign(@cd1, categs, @pd)
72
  end
73

  
74
end
test/unit/inherited_categories_test.rb (working copy)
1
# This program is free software; you can redistribute it and/or
2
# modify it under the terms of the GNU General Public License
3
# as published by the Free Software Foundation; either version 2
4
# of the License, or (at your option) any later version.
5
#
6
# This program is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9
# GNU General Public License for more details.
10
#
11
# You should have received a copy of the GNU General Public License
12
# along with this program; if not, write to the Free Software
13
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
14

  
15
require File.expand_path('../../test_helper', __FILE__)
16

  
17
class InheritedCategoriesTest < ActiveSupport::TestCase
18
  fixtures :trackers, :issue_statuses, :enumerations, :workflows, :users
19

  
20
  def setup
21
	wt = WorkflowTransition.find(:first)
22
	@tracker = wt.tracker
23
	@status = wt.old_status
24

  
25
	@pa = Project.create!(:name => 'A', :identifier => 'a')
26
	@pb = Project.create!(:name => 'B', :identifier => 'b', :trackers => [@tracker])
27
	@pc = Project.create!(:name => 'C', :identifier => 'c', :parent_id => @pb.id, :inherit => true, :trackers => [@tracker])
28
	@pd = Project.create!(:name => 'D', :identifier => 'd', :parent_id => @pc.id, :inherit => true, :trackers => [@tracker])
29
	@pe = Project.create!(:name => 'E', :identifier => 'e', :parent_id => @pd.id, :inherit => true, :trackers => [@tracker])
30
	@pf = Project.create!(:name => 'F', :identifier => 'f', :parent_id => @pb.id, :inherit => true, :trackers => [@tracker])
31
	@pg = Project.create!(:name => 'G', :identifier => 'g', :trackers => [@tracker])
32
	@pa.reload
33
	@pb.reload
34
	@pc.reload
35
	@pd.reload
36
	@pd.reload
37
	@ca1 = IssueCategory.create!(:project => @pa, :name => 'ca1')
38
	@cb1 = IssueCategory.create!(:project => @pb, :name => 'cb1')
39
	@cb2 = IssueCategory.create!(:project => @pb, :name => 'cb2')
40
	@cd1 = IssueCategory.create!(:project => @pd, :name => 'cd1')
41
	@cd2 = IssueCategory.create!(:project => @pd, :name => 'cb2')
42
  end
43

  
44
  def test_inherited_project_self
45
  	assert_equal [ @pb ], @pb.inherited_projects
46
  	assert_equal [ @pa ], @pa.inherited_projects
47
  end
48

  
49
  def test_inherited_project
50
    assert_equal [ @pd, @pc, @pb ], @pd.inherited_projects
51
  end
52

  
53
  def test_inherited_categories_self
54
  	assert_equal @pa.issue_categories, @pa.inherited_categories
55
  	assert_equal @pb.issue_categories, @pb.inherited_categories
56
  	assert_equal @pg.issue_categories, @pg.inherited_categories
57
  end
58

  
59
  def test_inherited_categories
60
    assert_equal [ @cb1, @cd2, @cd1 ], @pd.inherited_categories
61
    assert_equal [ @cb1, @cd2, @cd1 ], @pe.inherited_categories
62
	assert @pg.inherited_categories.empty?
63
  end
64

  
65
  def test_adjust_inheritance_to_nil
66
  	is1 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issueb', :category => @cb1)
67
  	is2 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issued', :category => @cd1)
68
	@pc.send :adjust_inheritance, @pb, nil
69
	assert ! @pc.inherit
70
	@pc.reload
71
	assert ! @pc.inherit
72
	is1.reload
73
	is2.reload
74
	assert_equal @cd1, is2.category
75
	assert_equal 1, @pc.issue_categories.size
76
	cat = @pc.issue_categories[0]
77
	assert_equal cat, is1.category
78
	assert_equal @cb1.name, cat.name
79
  end
80

  
81
  def test_adjust_inheritance_with_loss
82
  	is1 = Issue.create!(:project => @pd, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issueb', :category => @cb1)
83
  	is2 = Issue.create!(:project => @pd, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issued', :category => @cd1)
84
	@pc.send :adjust_inheritance, @pb, @pa
85
	is1.reload
86
	is2.reload
87
	assert_equal @cd1, is2.category
88
	assert_equal 1, @pc.issue_categories.size
89
	cat = @pc.issue_categories[0]
90
	assert_equal cat, is1.category
91
	assert_equal @cb1.name, cat.name
92
  end
93

  
94
  def test_adjust_inheritance_no_loss
95
  	is1 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issueb', :category => @cb1)
96
  	is2 = Issue.create!(:project => @pe, :tracker => @tracker, :status => @status, :author_id => 1, :subject => 'issued', :category => @cd1)
97
	@pd.send :adjust_inheritance, @pc, @pf
98
	is1.reload
99
	is2.reload
100
	assert_equal @cd1, is2.category
101
	assert @pc.issue_categories.empty?
102
	assert_equal @cb1, is1.category
103
  end
104

  
105
end
test/unit/inherited_issue_category_test.rb (working copy)
1
# This program is free software; you can redistribute it and/or
2
# modify it under the terms of the GNU General Public License
3
# as published by the Free Software Foundation; either version 2
4
# of the License, or (at your option) any later version.
5
#
6
# This program is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9
# GNU General Public License for more details.
10
#
11
# You should have received a copy of the GNU General Public License
12
# along with this program; if not, write to the Free Software
13
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
14

  
15
require File.expand_path('../../test_helper', __FILE__)
16

  
17
class InheritedIssueCategoryTest < ActiveSupport::TestCase
18
  fixtures :trackers, :issue_statuses, :enumerations, :workflows, :users
19

  
20
  def setup
21
	wt = WorkflowTransition.find(:first)
22
	@tracker = wt.tracker
23
	@status = wt.old_status
24

  
25
	@pa = Project.create!(:name => 'A', :identifier => 'a')
26
	@pb = Project.create!(:name => 'B', :identifier => 'b', :trackers => [@tracker])
27
	@pc = Project.create!(:name => 'C', :identifier => 'c', :parent_id => @pb.id, :inherit => true, :trackers => [@tracker])
28
	@pd = Project.create!(:name => 'D', :identifier => 'd', :parent_id => @pc.id, :inherit => true, :trackers => [@tracker])
29
	@pe = Project.create!(:name => 'E', :identifier => 'e', :parent_id => @pd.id, :inherit => true, :trackers => [@tracker])
30
	@pf = Project.create!(:name => 'F', :identifier => 'f', :parent_id => @pb.id, :inherit => true, :trackers => [@tracker])
31
	@pg = Project.create!(:name => 'G', :identifier => 'g', :trackers => [@tracker])
32
	@pa.reload
33
	@pb.reload
34
	@pc.reload
35
	@pd.reload
36
	@pd.reload
37
	@ca1 = IssueCategory.create!(:project => @pa, :name => 'ca1')
38
	@cb1 = IssueCategory.create!(:project => @pb, :name => 'cb1')
39
	@cb2 = IssueCategory.create!(:project => @pb, :name => 'cb2')
40
	@cd1 = IssueCategory.create!(:project => @pd, :name => 'cd1')
41
	@cd2 = IssueCategory.create!(:project => @pd, :name => 'cb2')
42
  end
43

  
44
  def test_destroy_no_reassign
45
    is1 = Issue.create! :tracker => @tracker, :project => @pe, :status => @status, :author_id => 1, :subject => 'IS1', :category => @cd1
46
	@cd1.destroy
47
    is1.reload
48
	assert_nil is1.category
49
  end
50

  
51
  def test_destroy_inaccessible_reassign
52
    @pc.inherit = false
53
	@pc.save
54
    is1 = Issue.create! :tracker => @tracker, :project => @pe, :status => @status, :author_id => 1, :subject => 'IS1', :category => @cd1
55
	@cd1.destroy(@cb1)
56
    is1.reload
57
	assert_nil is1.category
58
  end
59

  
60
  def test_destroy_reassign_same_project
61
    is1 = Issue.create! :tracker => @tracker, :project => @pe, :status => @status, :author_id => 1, :subject => 'IS1', :category => @cd1
62
	@cd1.destroy @cd2
63
    is1.reload
64
	assert_equal @cd2, is1.category
65
  end
66

  
67
  def test_destroy_reassign_upper_project
68
    is1 = Issue.create! :tracker => @tracker, :project => @pe, :status => @status, :author_id => 1, :subject => 'IS1', :category => @cd1
69
	@cd1.destroy @cb1
70
    is1.reload
71
	assert_equal @cb1, is1.category
72
  end
73

  
74
  def test_destroy_reassign_demasked_category
75
    is1 = Issue.create! :tracker => @tracker, :project => @pe, :status => @status, :author_id => 1, :subject => 'IS1', :category => @cd2
76
	@cd2.destroy @cb2
77
    is1.reload
78
	assert_equal @cb2, is1.category
79
  end
80

  
81
end
(3-3/8)