Patch #11898 » inherit_cats-2.2.3.patch
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 |