##// END OF EJS Templates
Code cleanup....
Jean-Philippe Lang -
r10758:24be0551ccd7
parent child
Show More
@@ -1,107 +1,106
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class QueriesController < ApplicationController
19 19 menu_item :issues
20 20 before_filter :find_query, :except => [:new, :create, :index]
21 21 before_filter :find_optional_project, :only => [:new, :create]
22 22
23 23 accept_api_auth :index
24 24
25 25 include QueriesHelper
26 26
27 27 def index
28 28 case params[:format]
29 29 when 'xml', 'json'
30 30 @offset, @limit = api_offset_and_limit
31 31 else
32 32 @limit = per_page_option
33 33 end
34 34
35 35 @query_count = IssueQuery.visible.count
36 36 @query_pages = Paginator.new self, @query_count, @limit, params['page']
37 37 @queries = IssueQuery.visible.all(:limit => @limit, :offset => @offset, :order => "#{Query.table_name}.name")
38 38
39 39 respond_to do |format|
40 format.html { render :nothing => true }
41 40 format.api
42 41 end
43 42 end
44 43
45 44 def new
46 45 @query = IssueQuery.new
47 46 @query.user = User.current
48 47 @query.project = @project
49 48 @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
50 49 @query.build_from_params(params)
51 50 end
52 51
53 52 def create
54 53 @query = IssueQuery.new(params[:query])
55 54 @query.user = User.current
56 55 @query.project = params[:query_is_for_all] ? nil : @project
57 56 @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
58 57 @query.build_from_params(params)
59 58 @query.column_names = nil if params[:default_columns]
60 59
61 60 if @query.save
62 61 flash[:notice] = l(:notice_successful_create)
63 62 redirect_to _issues_path(@project, :query_id => @query)
64 63 else
65 64 render :action => 'new', :layout => !request.xhr?
66 65 end
67 66 end
68 67
69 68 def edit
70 69 end
71 70
72 71 def update
73 72 @query.attributes = params[:query]
74 73 @query.project = nil if params[:query_is_for_all]
75 74 @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
76 75 @query.build_from_params(params)
77 76 @query.column_names = nil if params[:default_columns]
78 77
79 78 if @query.save
80 79 flash[:notice] = l(:notice_successful_update)
81 80 redirect_to _issues_path(@project, :query_id => @query)
82 81 else
83 82 render :action => 'edit'
84 83 end
85 84 end
86 85
87 86 def destroy
88 87 @query.destroy
89 88 redirect_to _issues_path(@project, :set_filter => 1)
90 89 end
91 90
92 91 private
93 92 def find_query
94 93 @query = IssueQuery.find(params[:id])
95 94 @project = @query.project
96 95 render_403 unless @query.editable_by?(User.current)
97 96 rescue ActiveRecord::RecordNotFound
98 97 render_404
99 98 end
100 99
101 100 def find_optional_project
102 101 @project = Project.find(params[:project_id]) if params[:project_id]
103 102 render_403 unless User.current.allowed_to?(:save_queries, @project, :global => true)
104 103 rescue ActiveRecord::RecordNotFound
105 104 render_404
106 105 end
107 106 end
@@ -1,128 +1,128
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class WorkflowsController < ApplicationController
19 19 layout 'admin'
20 20
21 21 before_filter :require_admin, :find_roles, :find_trackers
22 22
23 23 def index
24 24 @workflow_counts = WorkflowTransition.count_by_tracker_and_role
25 25 end
26 26
27 27 def edit
28 28 @role = Role.find_by_id(params[:role_id]) if params[:role_id]
29 29 @tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id]
30 30
31 31 if request.post?
32 32 WorkflowTransition.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
33 33 (params[:issue_status] || []).each { |status_id, transitions|
34 34 transitions.each { |new_status_id, options|
35 35 author = options.is_a?(Array) && options.include?('author') && !options.include?('always')
36 36 assignee = options.is_a?(Array) && options.include?('assignee') && !options.include?('always')
37 37 WorkflowTransition.create(:role_id => @role.id, :tracker_id => @tracker.id, :old_status_id => status_id, :new_status_id => new_status_id, :author => author, :assignee => assignee)
38 38 }
39 39 }
40 40 if @role.save
41 41 redirect_to workflows_edit_path(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
42 42 return
43 43 end
44 44 end
45 45
46 46 @used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
47 47 if @tracker && @used_statuses_only && @tracker.issue_statuses.any?
48 48 @statuses = @tracker.issue_statuses
49 49 end
50 50 @statuses ||= IssueStatus.sorted.all
51 51
52 52 if @tracker && @role && @statuses.any?
53 53 workflows = WorkflowTransition.where(:role_id => @role.id, :tracker_id => @tracker.id).all
54 54 @workflows = {}
55 55 @workflows['always'] = workflows.select {|w| !w.author && !w.assignee}
56 56 @workflows['author'] = workflows.select {|w| w.author}
57 57 @workflows['assignee'] = workflows.select {|w| w.assignee}
58 58 end
59 59 end
60 60
61 61 def permissions
62 62 @role = Role.find_by_id(params[:role_id]) if params[:role_id]
63 63 @tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id]
64 64
65 65 if request.post? && @role && @tracker
66 66 WorkflowPermission.replace_permissions(@tracker, @role, params[:permissions] || {})
67 67 redirect_to workflows_permissions_path(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
68 68 return
69 69 end
70 70
71 71 @used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
72 72 if @tracker && @used_statuses_only && @tracker.issue_statuses.any?
73 73 @statuses = @tracker.issue_statuses
74 74 end
75 75 @statuses ||= IssueStatus.sorted.all
76 76
77 77 if @role && @tracker
78 78 @fields = (Tracker::CORE_FIELDS_ALL - @tracker.disabled_core_fields).map {|field| [field, l("field_"+field.sub(/_id$/, ''))]}
79 79 @custom_fields = @tracker.custom_fields
80 80
81 81 @permissions = WorkflowPermission.where(:tracker_id => @tracker.id, :role_id => @role.id).all.inject({}) do |h, w|
82 82 h[w.old_status_id] ||= {}
83 83 h[w.old_status_id][w.field_name] = w.rule
84 84 h
85 85 end
86 86 @statuses.each {|status| @permissions[status.id] ||= {}}
87 87 end
88 88 end
89 89
90 90 def copy
91 91
92 92 if params[:source_tracker_id].blank? || params[:source_tracker_id] == 'any'
93 93 @source_tracker = nil
94 94 else
95 95 @source_tracker = Tracker.find_by_id(params[:source_tracker_id].to_i)
96 96 end
97 97 if params[:source_role_id].blank? || params[:source_role_id] == 'any'
98 98 @source_role = nil
99 99 else
100 100 @source_role = Role.find_by_id(params[:source_role_id].to_i)
101 101 end
102 102
103 103 @target_trackers = params[:target_tracker_ids].blank? ? nil : Tracker.find_all_by_id(params[:target_tracker_ids])
104 104 @target_roles = params[:target_role_ids].blank? ? nil : Role.find_all_by_id(params[:target_role_ids])
105 105
106 106 if request.post?
107 107 if params[:source_tracker_id].blank? || params[:source_role_id].blank? || (@source_tracker.nil? && @source_role.nil?)
108 108 flash.now[:error] = l(:error_workflow_copy_source)
109 elsif @target_trackers.nil? || @target_roles.nil?
109 elsif @target_trackers.blank? || @target_roles.blank?
110 110 flash.now[:error] = l(:error_workflow_copy_target)
111 111 else
112 112 WorkflowRule.copy(@source_tracker, @source_role, @target_trackers, @target_roles)
113 113 flash[:notice] = l(:notice_successful_update)
114 114 redirect_to workflows_copy_path(:source_tracker_id => @source_tracker, :source_role_id => @source_role)
115 115 end
116 116 end
117 117 end
118 118
119 119 private
120 120
121 121 def find_roles
122 122 @roles = Role.sorted.all
123 123 end
124 124
125 125 def find_trackers
126 126 @trackers = Tracker.sorted.all
127 127 end
128 128 end
@@ -1,206 +1,212
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class MessagesControllerTest < ActionController::TestCase
21 21 fixtures :projects, :users, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
22 22
23 23 def setup
24 24 User.current = nil
25 25 end
26 26
27 27 def test_show
28 28 get :show, :board_id => 1, :id => 1
29 29 assert_response :success
30 30 assert_template 'show'
31 31 assert_not_nil assigns(:board)
32 32 assert_not_nil assigns(:project)
33 33 assert_not_nil assigns(:topic)
34 34 end
35 35
36 36 def test_show_should_contain_reply_field_tags_for_quoting
37 37 @request.session[:user_id] = 2
38 38 get :show, :board_id => 1, :id => 1
39 39 assert_response :success
40 40
41 41 # tags required by MessagesController#quote
42 42 assert_tag 'input', :attributes => {:id => 'message_subject'}
43 43 assert_tag 'textarea', :attributes => {:id => 'message_content'}
44 44 assert_tag 'div', :attributes => {:id => 'reply'}
45 45 end
46 46
47 47 def test_show_with_pagination
48 48 message = Message.find(1)
49 49 assert_difference 'Message.count', 30 do
50 50 30.times do
51 51 message.children << Message.new(:subject => 'Reply', :content => 'Reply body', :author_id => 2, :board_id => 1)
52 52 end
53 53 end
54 54 get :show, :board_id => 1, :id => 1, :r => message.children.last(:order => 'id').id
55 55 assert_response :success
56 56 assert_template 'show'
57 57 replies = assigns(:replies)
58 58 assert_not_nil replies
59 59 assert !replies.include?(message.children.first(:order => 'id'))
60 60 assert replies.include?(message.children.last(:order => 'id'))
61 61 end
62 62
63 63 def test_show_with_reply_permission
64 64 @request.session[:user_id] = 2
65 65 get :show, :board_id => 1, :id => 1
66 66 assert_response :success
67 67 assert_template 'show'
68 68 assert_tag :div, :attributes => { :id => 'reply' },
69 69 :descendant => { :tag => 'textarea', :attributes => { :id => 'message_content' } }
70 70 end
71 71
72 72 def test_show_message_not_found
73 73 get :show, :board_id => 1, :id => 99999
74 74 assert_response 404
75 75 end
76 76
77 77 def test_get_new
78 78 @request.session[:user_id] = 2
79 79 get :new, :board_id => 1
80 80 assert_response :success
81 81 assert_template 'new'
82 82 end
83 83
84 def test_get_new_with_invalid_board
85 @request.session[:user_id] = 2
86 get :new, :board_id => 99
87 assert_response 404
88 end
89
84 90 def test_post_new
85 91 @request.session[:user_id] = 2
86 92 ActionMailer::Base.deliveries.clear
87 93
88 94 with_settings :notified_events => %w(message_posted) do
89 95 post :new, :board_id => 1,
90 96 :message => { :subject => 'Test created message',
91 97 :content => 'Message body'}
92 98 end
93 99 message = Message.find_by_subject('Test created message')
94 100 assert_not_nil message
95 101 assert_redirected_to "/boards/1/topics/#{message.to_param}"
96 102 assert_equal 'Message body', message.content
97 103 assert_equal 2, message.author_id
98 104 assert_equal 1, message.board_id
99 105
100 106 mail = ActionMailer::Base.deliveries.last
101 107 assert_not_nil mail
102 108 assert_equal "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] Test created message", mail.subject
103 109 assert_mail_body_match 'Message body', mail
104 110 # author
105 111 assert mail.bcc.include?('jsmith@somenet.foo')
106 112 # project member
107 113 assert mail.bcc.include?('dlopper@somenet.foo')
108 114 end
109 115
110 116 def test_get_edit
111 117 @request.session[:user_id] = 2
112 118 get :edit, :board_id => 1, :id => 1
113 119 assert_response :success
114 120 assert_template 'edit'
115 121 end
116 122
117 123 def test_post_edit
118 124 @request.session[:user_id] = 2
119 125 post :edit, :board_id => 1, :id => 1,
120 126 :message => { :subject => 'New subject',
121 127 :content => 'New body'}
122 128 assert_redirected_to '/boards/1/topics/1'
123 129 message = Message.find(1)
124 130 assert_equal 'New subject', message.subject
125 131 assert_equal 'New body', message.content
126 132 end
127 133
128 134 def test_post_edit_sticky_and_locked
129 135 @request.session[:user_id] = 2
130 136 post :edit, :board_id => 1, :id => 1,
131 137 :message => { :subject => 'New subject',
132 138 :content => 'New body',
133 139 :locked => '1',
134 140 :sticky => '1'}
135 141 assert_redirected_to '/boards/1/topics/1'
136 142 message = Message.find(1)
137 143 assert_equal true, message.sticky?
138 144 assert_equal true, message.locked?
139 145 end
140 146
141 147 def test_post_edit_should_allow_to_change_board
142 148 @request.session[:user_id] = 2
143 149 post :edit, :board_id => 1, :id => 1,
144 150 :message => { :subject => 'New subject',
145 151 :content => 'New body',
146 152 :board_id => 2}
147 153 assert_redirected_to '/boards/2/topics/1'
148 154 message = Message.find(1)
149 155 assert_equal Board.find(2), message.board
150 156 end
151 157
152 158 def test_reply
153 159 @request.session[:user_id] = 2
154 160 post :reply, :board_id => 1, :id => 1, :reply => { :content => 'This is a test reply', :subject => 'Test reply' }
155 161 reply = Message.order('id DESC').first
156 162 assert_redirected_to "/boards/1/topics/1?r=#{reply.id}"
157 163 assert Message.find_by_subject('Test reply')
158 164 end
159 165
160 166 def test_destroy_topic
161 167 @request.session[:user_id] = 2
162 168 assert_difference 'Message.count', -3 do
163 169 post :destroy, :board_id => 1, :id => 1
164 170 end
165 171 assert_redirected_to '/projects/ecookbook/boards/1'
166 172 assert_nil Message.find_by_id(1)
167 173 end
168 174
169 175 def test_destroy_reply
170 176 @request.session[:user_id] = 2
171 177 assert_difference 'Message.count', -1 do
172 178 post :destroy, :board_id => 1, :id => 2
173 179 end
174 180 assert_redirected_to '/boards/1/topics/1?r=2'
175 181 assert_nil Message.find_by_id(2)
176 182 end
177 183
178 184 def test_quote
179 185 @request.session[:user_id] = 2
180 186 xhr :get, :quote, :board_id => 1, :id => 3
181 187 assert_response :success
182 188 assert_equal 'text/javascript', response.content_type
183 189 assert_template 'quote'
184 190 assert_include 'RE: First post', response.body
185 191 assert_include '> An other reply', response.body
186 192 end
187 193
188 194 def test_preview_new
189 195 @request.session[:user_id] = 2
190 196 post :preview,
191 197 :board_id => 1,
192 198 :message => {:subject => "", :content => "Previewed text"}
193 199 assert_response :success
194 200 assert_template 'common/_preview'
195 201 end
196 202
197 203 def test_preview_edit
198 204 @request.session[:user_id] = 2
199 205 post :preview,
200 206 :id => 4,
201 207 :board_id => 1,
202 208 :message => {:subject => "", :content => "Previewed text"}
203 209 assert_response :success
204 210 assert_template 'common/_preview'
205 211 end
206 212 end
@@ -1,284 +1,290
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class QueriesControllerTest < ActionController::TestCase
21 21 fixtures :projects, :users, :members, :member_roles, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :queries, :enabled_modules
22 22
23 23 def setup
24 24 User.current = nil
25 25 end
26 26
27 def test_index
28 get :index
29 # HTML response not implemented
30 assert_response 406
31 end
32
27 33 def test_new_project_query
28 34 @request.session[:user_id] = 2
29 35 get :new, :project_id => 1
30 36 assert_response :success
31 37 assert_template 'new'
32 38 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
33 39 :name => 'query[is_public]',
34 40 :checked => nil }
35 41 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
36 42 :name => 'query_is_for_all',
37 43 :checked => nil,
38 44 :disabled => nil }
39 45 assert_select 'select[name=?]', 'c[]' do
40 46 assert_select 'option[value=tracker]'
41 47 assert_select 'option[value=subject]'
42 48 end
43 49 end
44 50
45 51 def test_new_global_query
46 52 @request.session[:user_id] = 2
47 53 get :new
48 54 assert_response :success
49 55 assert_template 'new'
50 56 assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
51 57 :name => 'query[is_public]' }
52 58 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
53 59 :name => 'query_is_for_all',
54 60 :checked => 'checked',
55 61 :disabled => nil }
56 62 end
57 63
58 64 def test_new_on_invalid_project
59 65 @request.session[:user_id] = 2
60 66 get :new, :project_id => 'invalid'
61 67 assert_response 404
62 68 end
63 69
64 70 def test_create_project_public_query
65 71 @request.session[:user_id] = 2
66 72 post :create,
67 73 :project_id => 'ecookbook',
68 74 :default_columns => '1',
69 75 :f => ["status_id", "assigned_to_id"],
70 76 :op => {"assigned_to_id" => "=", "status_id" => "o"},
71 77 :v => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
72 78 :query => {"name" => "test_new_project_public_query", "is_public" => "1"}
73 79
74 80 q = Query.find_by_name('test_new_project_public_query')
75 81 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
76 82 assert q.is_public?
77 83 assert q.has_default_columns?
78 84 assert q.valid?
79 85 end
80 86
81 87 def test_create_project_private_query
82 88 @request.session[:user_id] = 3
83 89 post :create,
84 90 :project_id => 'ecookbook',
85 91 :default_columns => '1',
86 92 :fields => ["status_id", "assigned_to_id"],
87 93 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
88 94 :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
89 95 :query => {"name" => "test_new_project_private_query", "is_public" => "1"}
90 96
91 97 q = Query.find_by_name('test_new_project_private_query')
92 98 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
93 99 assert !q.is_public?
94 100 assert q.has_default_columns?
95 101 assert q.valid?
96 102 end
97 103
98 104 def test_create_global_private_query_with_custom_columns
99 105 @request.session[:user_id] = 3
100 106 post :create,
101 107 :fields => ["status_id", "assigned_to_id"],
102 108 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
103 109 :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
104 110 :query => {"name" => "test_new_global_private_query", "is_public" => "1"},
105 111 :c => ["", "tracker", "subject", "priority", "category"]
106 112
107 113 q = Query.find_by_name('test_new_global_private_query')
108 114 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
109 115 assert !q.is_public?
110 116 assert !q.has_default_columns?
111 117 assert_equal [:tracker, :subject, :priority, :category], q.columns.collect {|c| c.name}
112 118 assert q.valid?
113 119 end
114 120
115 121 def test_create_global_query_with_custom_filters
116 122 @request.session[:user_id] = 3
117 123 post :create,
118 124 :fields => ["assigned_to_id"],
119 125 :operators => {"assigned_to_id" => "="},
120 126 :values => { "assigned_to_id" => ["me"]},
121 127 :query => {"name" => "test_new_global_query"}
122 128
123 129 q = Query.find_by_name('test_new_global_query')
124 130 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
125 131 assert !q.has_filter?(:status_id)
126 132 assert_equal ['assigned_to_id'], q.filters.keys
127 133 assert q.valid?
128 134 end
129 135
130 136 def test_create_with_sort
131 137 @request.session[:user_id] = 1
132 138 post :create,
133 139 :default_columns => '1',
134 140 :operators => {"status_id" => "o"},
135 141 :values => {"status_id" => ["1"]},
136 142 :query => {:name => "test_new_with_sort",
137 143 :is_public => "1",
138 144 :sort_criteria => {"0" => ["due_date", "desc"], "1" => ["tracker", ""]}}
139 145
140 146 query = Query.find_by_name("test_new_with_sort")
141 147 assert_not_nil query
142 148 assert_equal [['due_date', 'desc'], ['tracker', 'asc']], query.sort_criteria
143 149 end
144 150
145 151 def test_create_with_failure
146 152 @request.session[:user_id] = 2
147 153 assert_no_difference '::Query.count' do
148 154 post :create, :project_id => 'ecookbook', :query => {:name => ''}
149 155 end
150 156 assert_response :success
151 157 assert_template 'new'
152 158 assert_select 'input[name=?]', 'query[name]'
153 159 end
154 160
155 161 def test_edit_global_public_query
156 162 @request.session[:user_id] = 1
157 163 get :edit, :id => 4
158 164 assert_response :success
159 165 assert_template 'edit'
160 166 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
161 167 :name => 'query[is_public]',
162 168 :checked => 'checked' }
163 169 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
164 170 :name => 'query_is_for_all',
165 171 :checked => 'checked',
166 172 :disabled => 'disabled' }
167 173 end
168 174
169 175 def test_edit_global_private_query
170 176 @request.session[:user_id] = 3
171 177 get :edit, :id => 3
172 178 assert_response :success
173 179 assert_template 'edit'
174 180 assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
175 181 :name => 'query[is_public]' }
176 182 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
177 183 :name => 'query_is_for_all',
178 184 :checked => 'checked',
179 185 :disabled => 'disabled' }
180 186 end
181 187
182 188 def test_edit_project_private_query
183 189 @request.session[:user_id] = 3
184 190 get :edit, :id => 2
185 191 assert_response :success
186 192 assert_template 'edit'
187 193 assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
188 194 :name => 'query[is_public]' }
189 195 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
190 196 :name => 'query_is_for_all',
191 197 :checked => nil,
192 198 :disabled => nil }
193 199 end
194 200
195 201 def test_edit_project_public_query
196 202 @request.session[:user_id] = 2
197 203 get :edit, :id => 1
198 204 assert_response :success
199 205 assert_template 'edit'
200 206 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
201 207 :name => 'query[is_public]',
202 208 :checked => 'checked'
203 209 }
204 210 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
205 211 :name => 'query_is_for_all',
206 212 :checked => nil,
207 213 :disabled => 'disabled' }
208 214 end
209 215
210 216 def test_edit_sort_criteria
211 217 @request.session[:user_id] = 1
212 218 get :edit, :id => 5
213 219 assert_response :success
214 220 assert_template 'edit'
215 221 assert_tag :tag => 'select', :attributes => { :name => 'query[sort_criteria][0][]' },
216 222 :child => { :tag => 'option', :attributes => { :value => 'priority',
217 223 :selected => 'selected' } }
218 224 assert_tag :tag => 'select', :attributes => { :name => 'query[sort_criteria][0][]' },
219 225 :child => { :tag => 'option', :attributes => { :value => 'desc',
220 226 :selected => 'selected' } }
221 227 end
222 228
223 229 def test_edit_invalid_query
224 230 @request.session[:user_id] = 2
225 231 get :edit, :id => 99
226 232 assert_response 404
227 233 end
228 234
229 235 def test_udpate_global_private_query
230 236 @request.session[:user_id] = 3
231 237 put :update,
232 238 :id => 3,
233 239 :default_columns => '1',
234 240 :fields => ["status_id", "assigned_to_id"],
235 241 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
236 242 :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
237 243 :query => {"name" => "test_edit_global_private_query", "is_public" => "1"}
238 244
239 245 assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 3
240 246 q = Query.find_by_name('test_edit_global_private_query')
241 247 assert !q.is_public?
242 248 assert q.has_default_columns?
243 249 assert q.valid?
244 250 end
245 251
246 252 def test_update_global_public_query
247 253 @request.session[:user_id] = 1
248 254 put :update,
249 255 :id => 4,
250 256 :default_columns => '1',
251 257 :fields => ["status_id", "assigned_to_id"],
252 258 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
253 259 :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
254 260 :query => {"name" => "test_edit_global_public_query", "is_public" => "1"}
255 261
256 262 assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 4
257 263 q = Query.find_by_name('test_edit_global_public_query')
258 264 assert q.is_public?
259 265 assert q.has_default_columns?
260 266 assert q.valid?
261 267 end
262 268
263 269 def test_update_with_failure
264 270 @request.session[:user_id] = 1
265 271 put :update, :id => 4, :query => {:name => ''}
266 272 assert_response :success
267 273 assert_template 'edit'
268 274 end
269 275
270 276 def test_destroy
271 277 @request.session[:user_id] = 2
272 278 delete :destroy, :id => 1
273 279 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :set_filter => 1, :query_id => nil
274 280 assert_nil Query.find_by_id(1)
275 281 end
276 282
277 283 def test_backslash_should_be_escaped_in_filters
278 284 @request.session[:user_id] = 2
279 285 get :new, :subject => 'foo/bar'
280 286 assert_response :success
281 287 assert_template 'new'
282 288 assert_include 'addFilter("subject", "=", ["foo\/bar"]);', response.body
283 289 end
284 290 end
@@ -1,308 +1,328
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class WorkflowsControllerTest < ActionController::TestCase
21 21 fixtures :roles, :trackers, :workflows, :users, :issue_statuses
22 22
23 23 def setup
24 24 User.current = nil
25 25 @request.session[:user_id] = 1 # admin
26 26 end
27 27
28 28 def test_index
29 29 get :index
30 30 assert_response :success
31 31 assert_template 'index'
32 32
33 33 count = WorkflowTransition.count(:all, :conditions => 'role_id = 1 AND tracker_id = 2')
34 34 assert_tag :tag => 'a', :content => count.to_s,
35 35 :attributes => { :href => '/workflows/edit?role_id=1&amp;tracker_id=2' }
36 36 end
37 37
38 38 def test_get_edit
39 39 get :edit
40 40 assert_response :success
41 41 assert_template 'edit'
42 42 assert_not_nil assigns(:roles)
43 43 assert_not_nil assigns(:trackers)
44 44 end
45 45
46 46 def test_get_edit_with_role_and_tracker
47 47 WorkflowTransition.delete_all
48 48 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
49 49 WorkflowTransition.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
50 50
51 51 get :edit, :role_id => 2, :tracker_id => 1
52 52 assert_response :success
53 53 assert_template 'edit'
54 54
55 55 # used status only
56 56 assert_not_nil assigns(:statuses)
57 57 assert_equal [2, 3, 5], assigns(:statuses).collect(&:id)
58 58
59 59 # allowed transitions
60 60 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
61 61 :name => 'issue_status[3][5][]',
62 62 :value => 'always',
63 63 :checked => 'checked' }
64 64 # not allowed
65 65 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
66 66 :name => 'issue_status[3][2][]',
67 67 :value => 'always',
68 68 :checked => nil }
69 69 # unused
70 70 assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
71 71 :name => 'issue_status[1][1][]' }
72 72 end
73 73
74 74 def test_get_edit_with_role_and_tracker_and_all_statuses
75 75 WorkflowTransition.delete_all
76 76
77 77 get :edit, :role_id => 2, :tracker_id => 1, :used_statuses_only => '0'
78 78 assert_response :success
79 79 assert_template 'edit'
80 80
81 81 assert_not_nil assigns(:statuses)
82 82 assert_equal IssueStatus.count, assigns(:statuses).size
83 83
84 84 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
85 85 :name => 'issue_status[1][1][]',
86 86 :value => 'always',
87 87 :checked => nil }
88 88 end
89 89
90 90 def test_post_edit
91 91 post :edit, :role_id => 2, :tracker_id => 1,
92 92 :issue_status => {
93 93 '4' => {'5' => ['always']},
94 94 '3' => {'1' => ['always'], '2' => ['always']}
95 95 }
96 96 assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1'
97 97
98 98 assert_equal 3, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
99 99 assert_not_nil WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
100 100 assert_nil WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4).first
101 101 end
102 102
103 103 def test_post_edit_with_additional_transitions
104 104 post :edit, :role_id => 2, :tracker_id => 1,
105 105 :issue_status => {
106 106 '4' => {'5' => ['always']},
107 107 '3' => {'1' => ['author'], '2' => ['assignee'], '4' => ['author', 'assignee']}
108 108 }
109 109 assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1'
110 110
111 111 assert_equal 4, WorkflowTransition.where(:tracker_id => 1, :role_id => 2).count
112 112
113 113 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 4, :new_status_id => 5).first
114 114 assert ! w.author
115 115 assert ! w.assignee
116 116 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 1).first
117 117 assert w.author
118 118 assert ! w.assignee
119 119 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2).first
120 120 assert ! w.author
121 121 assert w.assignee
122 122 w = WorkflowTransition.where(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 4).first
123 123 assert w.author
124 124 assert w.assignee
125 125 end
126 126
127 127 def test_clear_workflow
128 128 assert WorkflowTransition.count(:conditions => {:tracker_id => 1, :role_id => 2}) > 0
129 129
130 130 post :edit, :role_id => 2, :tracker_id => 1
131 131 assert_equal 0, WorkflowTransition.count(:conditions => {:tracker_id => 1, :role_id => 2})
132 132 end
133 133
134 134 def test_get_permissions
135 135 get :permissions
136 136
137 137 assert_response :success
138 138 assert_template 'permissions'
139 139 assert_not_nil assigns(:roles)
140 140 assert_not_nil assigns(:trackers)
141 141 end
142 142
143 143 def test_get_permissions_with_role_and_tracker
144 144 WorkflowPermission.delete_all
145 145 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'assigned_to_id', :rule => 'required')
146 146 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
147 147 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 3, :field_name => 'fixed_version_id', :rule => 'readonly')
148 148
149 149 get :permissions, :role_id => 1, :tracker_id => 2
150 150 assert_response :success
151 151 assert_template 'permissions'
152 152
153 153 assert_select 'input[name=role_id][value=1]'
154 154 assert_select 'input[name=tracker_id][value=2]'
155 155
156 156 # Required field
157 157 assert_select 'select[name=?]', 'permissions[assigned_to_id][2]' do
158 158 assert_select 'option[value=]'
159 159 assert_select 'option[value=][selected=selected]', 0
160 160 assert_select 'option[value=readonly]', :text => 'Read-only'
161 161 assert_select 'option[value=readonly][selected=selected]', 0
162 162 assert_select 'option[value=required]', :text => 'Required'
163 163 assert_select 'option[value=required][selected=selected]'
164 164 end
165 165
166 166 # Read-only field
167 167 assert_select 'select[name=?]', 'permissions[fixed_version_id][3]' do
168 168 assert_select 'option[value=]'
169 169 assert_select 'option[value=][selected=selected]', 0
170 170 assert_select 'option[value=readonly]', :text => 'Read-only'
171 171 assert_select 'option[value=readonly][selected=selected]'
172 172 assert_select 'option[value=required]', :text => 'Required'
173 173 assert_select 'option[value=required][selected=selected]', 0
174 174 end
175 175
176 176 # Other field
177 177 assert_select 'select[name=?]', 'permissions[due_date][3]' do
178 178 assert_select 'option[value=]'
179 179 assert_select 'option[value=][selected=selected]', 0
180 180 assert_select 'option[value=readonly]', :text => 'Read-only'
181 181 assert_select 'option[value=readonly][selected=selected]', 0
182 182 assert_select 'option[value=required]', :text => 'Required'
183 183 assert_select 'option[value=required][selected=selected]', 0
184 184 end
185 185 end
186 186
187 187 def test_get_permissions_with_required_custom_field_should_not_show_required_option
188 188 cf = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :tracker_ids => [1], :is_required => true)
189 189
190 190 get :permissions, :role_id => 1, :tracker_id => 1
191 191 assert_response :success
192 192 assert_template 'permissions'
193 193
194 194 # Custom field that is always required
195 195 # The default option is "(Required)"
196 196 assert_select 'select[name=?]', "permissions[#{cf.id}][3]" do
197 197 assert_select 'option[value=]'
198 198 assert_select 'option[value=readonly]', :text => 'Read-only'
199 199 assert_select 'option[value=required]', 0
200 200 end
201 201 end
202 202
203 203 def test_get_permissions_with_role_and_tracker_and_all_statuses
204 204 WorkflowTransition.delete_all
205 205
206 206 get :permissions, :role_id => 1, :tracker_id => 2, :used_statuses_only => '0'
207 207 assert_response :success
208 208 assert_equal IssueStatus.sorted.all, assigns(:statuses)
209 209 end
210 210
211 211 def test_post_permissions
212 212 WorkflowPermission.delete_all
213 213
214 214 post :permissions, :role_id => 1, :tracker_id => 2, :permissions => {
215 215 'assigned_to_id' => {'1' => '', '2' => 'readonly', '3' => ''},
216 216 'fixed_version_id' => {'1' => 'required', '2' => 'readonly', '3' => ''},
217 217 'due_date' => {'1' => '', '2' => '', '3' => ''},
218 218 }
219 219 assert_redirected_to '/workflows/permissions?role_id=1&tracker_id=2'
220 220
221 221 workflows = WorkflowPermission.all
222 222 assert_equal 3, workflows.size
223 223 workflows.each do |workflow|
224 224 assert_equal 1, workflow.role_id
225 225 assert_equal 2, workflow.tracker_id
226 226 end
227 227 assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'assigned_to_id' && wf.rule == 'readonly'}
228 228 assert workflows.detect {|wf| wf.old_status_id == 1 && wf.field_name == 'fixed_version_id' && wf.rule == 'required'}
229 229 assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'fixed_version_id' && wf.rule == 'readonly'}
230 230 end
231 231
232 232 def test_post_permissions_should_clear_permissions
233 233 WorkflowPermission.delete_all
234 234 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'assigned_to_id', :rule => 'required')
235 235 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
236 236 wf1 = WorkflowPermission.create!(:role_id => 1, :tracker_id => 3, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
237 237 wf2 = WorkflowPermission.create!(:role_id => 2, :tracker_id => 2, :old_status_id => 3, :field_name => 'fixed_version_id', :rule => 'readonly')
238 238
239 239 post :permissions, :role_id => 1, :tracker_id => 2
240 240 assert_redirected_to '/workflows/permissions?role_id=1&tracker_id=2'
241 241
242 242 workflows = WorkflowPermission.all
243 243 assert_equal 2, workflows.size
244 244 assert wf1.reload
245 245 assert wf2.reload
246 246 end
247 247
248 248 def test_get_copy
249 249 get :copy
250 250 assert_response :success
251 251 assert_template 'copy'
252 252 assert_select 'select[name=source_tracker_id]' do
253 253 assert_select 'option[value=1]', :text => 'Bug'
254 254 end
255 255 assert_select 'select[name=source_role_id]' do
256 256 assert_select 'option[value=2]', :text => 'Developer'
257 257 end
258 258 assert_select 'select[name=?]', 'target_tracker_ids[]' do
259 259 assert_select 'option[value=3]', :text => 'Support request'
260 260 end
261 261 assert_select 'select[name=?]', 'target_role_ids[]' do
262 262 assert_select 'option[value=1]', :text => 'Manager'
263 263 end
264 264 end
265 265
266 266 def test_post_copy_one_to_one
267 267 source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
268 268
269 269 post :copy, :source_tracker_id => '1', :source_role_id => '2',
270 270 :target_tracker_ids => ['3'], :target_role_ids => ['1']
271 271 assert_response 302
272 272 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
273 273 end
274 274
275 275 def test_post_copy_one_to_many
276 276 source_transitions = status_transitions(:tracker_id => 1, :role_id => 2)
277 277
278 278 post :copy, :source_tracker_id => '1', :source_role_id => '2',
279 279 :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
280 280 assert_response 302
281 281 assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 1)
282 282 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 1)
283 283 assert_equal source_transitions, status_transitions(:tracker_id => 2, :role_id => 3)
284 284 assert_equal source_transitions, status_transitions(:tracker_id => 3, :role_id => 3)
285 285 end
286 286
287 287 def test_post_copy_many_to_many
288 288 source_t2 = status_transitions(:tracker_id => 2, :role_id => 2)
289 289 source_t3 = status_transitions(:tracker_id => 3, :role_id => 2)
290 290
291 291 post :copy, :source_tracker_id => 'any', :source_role_id => '2',
292 292 :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
293 293 assert_response 302
294 294 assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 1)
295 295 assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 1)
296 296 assert_equal source_t2, status_transitions(:tracker_id => 2, :role_id => 3)
297 297 assert_equal source_t3, status_transitions(:tracker_id => 3, :role_id => 3)
298 298 end
299 299
300 def test_post_copy_with_incomplete_source_specification_should_fail
301 assert_no_difference 'WorkflowRule.count' do
302 post :copy,
303 :source_tracker_id => '', :source_role_id => '2',
304 :target_tracker_ids => ['2', '3'], :target_role_ids => ['1', '3']
305 assert_response 200
306 assert_select 'div.flash.error', :text => 'Please select a source tracker or role'
307 end
308 end
309
310 def test_post_copy_with_incomplete_target_specification_should_fail
311 assert_no_difference 'WorkflowRule.count' do
312 post :copy,
313 :source_tracker_id => '1', :source_role_id => '2',
314 :target_tracker_ids => ['2', '3']
315 assert_response 200
316 assert_select 'div.flash.error', :text => 'Please select target tracker(s) and role(s)'
317 end
318 end
319
300 320 # Returns an array of status transitions that can be compared
301 321 def status_transitions(conditions)
302 322 WorkflowTransition.
303 323 where(conditions).
304 324 order('tracker_id, role_id, old_status_id, new_status_id').
305 325 all.
306 326 collect {|w| [w.old_status, w.new_status_id]}
307 327 end
308 328 end
General Comments 0
You need to be logged in to leave comments. Login now