##// END OF EJS Templates
Role based custom queries (#1019)....
Jean-Philippe Lang -
r11764:888c3581eb0f
parent child
Show More
@@ -0,0 +1,13
1 class CreateQueriesRoles < ActiveRecord::Migration
2 def self.up
3 create_table :queries_roles, :id => false do |t|
4 t.column :query_id, :integer, :null => false
5 t.column :role_id, :integer, :null => false
6 end
7 add_index :queries_roles, [:query_id, :role_id], :unique => true, :name => :queries_roles_ids
8 end
9
10 def self.down
11 drop_table :queries_roles
12 end
13 end
@@ -0,0 +1,13
1 class AddQueriesVisibility < ActiveRecord::Migration
2 def up
3 add_column :queries, :visibility, :integer, :default => 0
4 Query.where(:is_public => true).update_all(:visibility => 2)
5 remove_column :queries, :is_public
6 end
7
8 def down
9 add_column :queries, :is_public, :boolean, :default => true, :null => false
10 Query.where('visibility <> ?', 2).update_all(:is_public => false)
11 remove_column :queries, :visibility
12 end
13 end
@@ -45,7 +45,7 class QueriesController < ApplicationController
45 @query = IssueQuery.new
45 @query = IssueQuery.new
46 @query.user = User.current
46 @query.user = User.current
47 @query.project = @project
47 @query.project = @project
48 @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
48 @query.visibility = IssueQuery::VISIBILITY_PRIVATE unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
49 @query.build_from_params(params)
49 @query.build_from_params(params)
50 end
50 end
51
51
@@ -53,7 +53,7 class QueriesController < ApplicationController
53 @query = IssueQuery.new(params[:query])
53 @query = IssueQuery.new(params[:query])
54 @query.user = User.current
54 @query.user = User.current
55 @query.project = params[:query_is_for_all] ? nil : @project
55 @query.project = params[:query_is_for_all] ? nil : @project
56 @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
56 @query.visibility = IssueQuery::VISIBILITY_PRIVATE unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
57 @query.build_from_params(params)
57 @query.build_from_params(params)
58 @query.column_names = nil if params[:default_columns]
58 @query.column_names = nil if params[:default_columns]
59
59
@@ -71,7 +71,7 class QueriesController < ApplicationController
71 def update
71 def update
72 @query.attributes = params[:query]
72 @query.attributes = params[:query]
73 @query.project = nil if params[:query_is_for_all]
73 @query.project = nil if params[:query_is_for_all]
74 @query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
74 @query.visibility = IssueQuery::VISIBILITY_PRIVATE unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
75 @query.build_from_params(params)
75 @query.build_from_params(params)
76 @query.column_names = nil if params[:default_columns]
76 @query.column_names = nil if params[:default_columns]
77
77
@@ -225,8 +225,8 module IssuesHelper
225
225
226 def render_sidebar_queries
226 def render_sidebar_queries
227 out = ''.html_safe
227 out = ''.html_safe
228 out << query_links(l(:label_my_queries), sidebar_queries.reject(&:is_public?))
228 out << query_links(l(:label_my_queries), sidebar_queries.select(&:is_private?))
229 out << query_links(l(:label_query_plural), sidebar_queries.select(&:is_public?))
229 out << query_links(l(:label_query_plural), sidebar_queries.reject(&:is_private?))
230 out
230 out
231 end
231 end
232
232
@@ -45,9 +45,25 class IssueQuery < Query
45 scope :visible, lambda {|*args|
45 scope :visible, lambda {|*args|
46 user = args.shift || User.current
46 user = args.shift || User.current
47 base = Project.allowed_to_condition(user, :view_issues, *args)
47 base = Project.allowed_to_condition(user, :view_issues, *args)
48 user_id = user.logged? ? user.id : 0
48 scope = includes(:project).where("#{table_name}.project_id IS NULL OR (#{base})")
49
49
50 includes(:project).where("(#{table_name}.project_id IS NULL OR (#{base})) AND (#{table_name}.is_public = ? OR #{table_name}.user_id = ?)", true, user_id)
50 if user.admin?
51 scope.where("#{table_name}.visibility <> ? OR #{table_name}.user_id = ?", VISIBILITY_PRIVATE, user.id)
52 elsif user.memberships.any?
53 scope.where("#{table_name}.visibility = ?" +
54 " OR (#{table_name}.visibility = ? AND #{table_name}.id IN (" +
55 "SELECT DISTINCT q.id FROM #{table_name} q" +
56 " INNER JOIN #{table_name_prefix}queries_roles#{table_name_suffix} qr on qr.query_id = q.id" +
57 " INNER JOIN #{MemberRole.table_name} mr ON mr.role_id = qr.role_id" +
58 " INNER JOIN #{Member.table_name} m ON m.id = mr.member_id AND m.user_id = ?" +
59 " WHERE q.project_id IS NULL OR q.project_id = m.project_id))" +
60 " OR #{table_name}.user_id = ?",
61 VISIBILITY_PUBLIC, VISIBILITY_ROLES, user.id, user.id)
62 elsif user.logged?
63 scope.where("#{table_name}.visibility = ? OR #{table_name}.user_id = ?", VISIBILITY_PUBLIC, user.id)
64 else
65 scope.where("#{table_name}.visibility = ?", VISIBILITY_PUBLIC)
66 end
51 }
67 }
52
68
53 def initialize(attributes=nil, *args)
69 def initialize(attributes=nil, *args)
@@ -57,7 +73,28 class IssueQuery < Query
57
73
58 # Returns true if the query is visible to +user+ or the current user.
74 # Returns true if the query is visible to +user+ or the current user.
59 def visible?(user=User.current)
75 def visible?(user=User.current)
60 (project.nil? || user.allowed_to?(:view_issues, project)) && (self.is_public? || self.user_id == user.id)
76 return true if user.admin?
77 return false unless project.nil? || user.allowed_to?(:view_issues, project)
78 case visibility
79 when VISIBILITY_PUBLIC
80 true
81 when VISIBILITY_ROLES
82 if project
83 (user.roles_for_project(project) & roles).any?
84 else
85 Member.where(:user_id => user.id).joins(:roles).where(:member_roles => {:role_id => roles.map(&:id)}).any?
86 end
87 else
88 user == self.user
89 end
90 end
91
92 def is_private?
93 visibility == VISIBILITY_PRIVATE
94 end
95
96 def is_public?
97 !is_private?
61 end
98 end
62
99
63 def initialize_available_filters
100 def initialize_available_filters
@@ -116,8 +116,13 class Query < ActiveRecord::Base
116 class StatementInvalid < ::ActiveRecord::StatementInvalid
116 class StatementInvalid < ::ActiveRecord::StatementInvalid
117 end
117 end
118
118
119 VISIBILITY_PRIVATE = 0
120 VISIBILITY_ROLES = 1
121 VISIBILITY_PUBLIC = 2
122
119 belongs_to :project
123 belongs_to :project
120 belongs_to :user
124 belongs_to :user
125 has_and_belongs_to_many :roles, :join_table => "#{table_name_prefix}queries_roles#{table_name_suffix}", :foreign_key => "query_id"
121 serialize :filters
126 serialize :filters
122 serialize :column_names
127 serialize :column_names
123 serialize :sort_criteria, Array
128 serialize :sort_criteria, Array
@@ -126,7 +131,17 class Query < ActiveRecord::Base
126
131
127 validates_presence_of :name
132 validates_presence_of :name
128 validates_length_of :name, :maximum => 255
133 validates_length_of :name, :maximum => 255
134 validates :visibility, :inclusion => { :in => [VISIBILITY_PUBLIC, VISIBILITY_ROLES, VISIBILITY_PRIVATE] }
129 validate :validate_query_filters
135 validate :validate_query_filters
136 validate do |query|
137 errors.add(:base, l(:label_role_plural) + ' ' + l('activerecord.errors.messages.blank')) if query.visibility == VISIBILITY_ROLES && roles.blank?
138 end
139
140 after_save do |query|
141 if query.visibility_changed? && query.visibility != VISIBILITY_ROLES
142 query.roles.clear
143 end
144 end
130
145
131 class_attribute :operators
146 class_attribute :operators
132 self.operators = {
147 self.operators = {
@@ -245,9 +260,9 class Query < ActiveRecord::Base
245 def editable_by?(user)
260 def editable_by?(user)
246 return false unless user
261 return false unless user
247 # Admin can edit them all and regular users can edit their private queries
262 # Admin can edit them all and regular users can edit their private queries
248 return true if user.admin? || (!is_public && self.user_id == user.id)
263 return true if user.admin? || (is_private? && self.user_id == user.id)
249 # Members can not edit public queries that are for all project (only admin is allowed to)
264 # Members can not edit public queries that are for all project (only admin is allowed to)
250 is_public && !@is_for_all && user.allowed_to?(:manage_public_queries, project)
265 is_public? && !@is_for_all && user.allowed_to?(:manage_public_queries, project)
251 end
266 end
252
267
253 def trackers
268 def trackers
@@ -669,7 +669,7 class User < Principal
669 Message.update_all ['author_id = ?', substitute.id], ['author_id = ?', id]
669 Message.update_all ['author_id = ?', substitute.id], ['author_id = ?', id]
670 News.update_all ['author_id = ?', substitute.id], ['author_id = ?', id]
670 News.update_all ['author_id = ?', substitute.id], ['author_id = ?', id]
671 # Remove private queries and keep public ones
671 # Remove private queries and keep public ones
672 ::Query.delete_all ['user_id = ? AND is_public = ?', id, false]
672 ::Query.delete_all ['user_id = ? AND visibility = ?', id, ::Query::VISIBILITY_PRIVATE]
673 ::Query.update_all ['user_id = ?', substitute.id], ['user_id = ?', id]
673 ::Query.update_all ['user_id = ?', substitute.id], ['user_id = ?', id]
674 TimeEntry.update_all ['user_id = ?', substitute.id], ['user_id = ?', id]
674 TimeEntry.update_all ['user_id = ?', substitute.id], ['user_id = ?', id]
675 Token.delete_all ['user_id = ?', id]
675 Token.delete_all ['user_id = ?', id]
@@ -6,15 +6,22
6 <%= text_field 'query', 'name', :size => 80 %></p>
6 <%= text_field 'query', 'name', :size => 80 %></p>
7
7
8 <% if User.current.admin? || User.current.allowed_to?(:manage_public_queries, @project) %>
8 <% if User.current.admin? || User.current.allowed_to?(:manage_public_queries, @project) %>
9 <p><label for="query_is_public"><%=l(:field_is_public)%></label>
9 <p><label><%=l(:field_visible)%></label>
10 <%= check_box 'query', 'is_public',
10 <label class="block"><%= radio_button 'query', 'visibility', Query::VISIBILITY_PRIVATE %> <%= l(:label_visibility_private) %></label>
11 :onchange => (User.current.admin? ? nil : 'if (this.checked) {$("#query_is_for_all").removeAttr("checked"); $("#query_is_for_all").attr("disabled", true);} else {$("#query_is_for_all").removeAttr("disabled");}') %></p>
11 <label class="block"><%= radio_button 'query', 'visibility', Query::VISIBILITY_ROLES %> <%= l(:label_visibility_roles) %>:</label>
12 <% Role.givable.sorted.each do |role| %>
13 <label class="block role-visibility"><%= check_box_tag 'query[role_ids][]', role.id, @query.roles.include?(role), :id => nil %> <%= role.name %></label>
14 <% end %>
15 <label class="block"><%= radio_button 'query', 'visibility', Query::VISIBILITY_PUBLIC %> <%= l(:label_visibility_public) %></label>
16 <%= hidden_field_tag 'query[role_ids][]', '' %>
17 </p>
12 <% end %>
18 <% end %>
13
19
14 <p><label for="query_is_for_all"><%=l(:field_is_for_all)%></label>
20 <p><label for="query_is_for_all"><%=l(:field_is_for_all)%></label>
15 <%= check_box_tag 'query_is_for_all', 1, @query.project.nil?,
21 <%= check_box_tag 'query_is_for_all', 1, @query.project.nil?,
16 :disabled => (!@query.new_record? && (@query.project.nil? || (@query.is_public? && !User.current.admin?))) %></p>
22 :disabled => (!@query.new_record? && (@query.project.nil? || (@query.is_public? && !User.current.admin?))) %></p>
17
23
24 <fieldset><legend><%= l(:label_options) %></legend>
18 <p><label for="query_default_columns"><%=l(:label_default_columns)%></label>
25 <p><label for="query_default_columns"><%=l(:label_default_columns)%></label>
19 <%= check_box_tag 'default_columns', 1, @query.has_default_columns?, :id => 'query_default_columns',
26 <%= check_box_tag 'default_columns', 1, @query.has_default_columns?, :id => 'query_default_columns',
20 :onclick => 'if (this.checked) {$("#columns").hide();} else {$("#columns").show();}' %></p>
27 :onclick => 'if (this.checked) {$("#columns").hide();} else {$("#columns").show();}' %></p>
@@ -24,6 +31,7
24
31
25 <p><label><%= l(:button_show) %></label>
32 <p><label><%= l(:button_show) %></label>
26 <%= available_block_columns_tags(@query) %></p>
33 <%= available_block_columns_tags(@query) %></p>
34 </fieldset>
27 </div>
35 </div>
28
36
29 <fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend>
37 <fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend>
@@ -53,3 +61,12
53 <% end %>
61 <% end %>
54
62
55 </div>
63 </div>
64
65 <%= javascript_tag do %>
66 $(document).ready(function(){
67 $("input[name='query[visibility]']").change(function(){
68 var checked = $('#query_visibility_1').is(':checked');
69 $("input[name='query[role_ids][]'][type=checkbox]").attr('disabled', !checked);
70 }).trigger('change');
71 });
72 <% end %>
@@ -3,7 +3,7 api.array :queries, api_meta(:total_count => @query_count, :offset => @offset, :
3 api.query do
3 api.query do
4 api.id query.id
4 api.id query.id
5 api.name query.name
5 api.name query.name
6 api.is_public query.is_public
6 api.is_public query.is_public?
7 api.project_id query.project_id
7 api.project_id query.project_id
8 end
8 end
9 end
9 end
@@ -896,6 +896,9 en:
896 label_cross_project_hierarchy: With project hierarchy
896 label_cross_project_hierarchy: With project hierarchy
897 label_cross_project_system: With all projects
897 label_cross_project_system: With all projects
898 label_gantt_progress_line: Progress line
898 label_gantt_progress_line: Progress line
899 label_visibility_private: to me only
900 label_visibility_roles: to these roles only
901 label_visibility_public: to any users
899
902
900 button_login: Login
903 button_login: Login
901 button_submit: Submit
904 button_submit: Submit
@@ -872,6 +872,9 fr:
872 label_cross_project_hierarchy: Avec toute la hiérarchie
872 label_cross_project_hierarchy: Avec toute la hiérarchie
873 label_cross_project_system: Avec tous les projets
873 label_cross_project_system: Avec tous les projets
874 label_gantt_progress_line: Ligne de progression
874 label_gantt_progress_line: Ligne de progression
875 label_visibility_private: par moi uniquement
876 label_visibility_roles: par ces roles uniquement
877 label_visibility_public: par tout le monde
875
878
876 button_login: Connexion
879 button_login: Connexion
877 button_submit: Soumettre
880 button_submit: Soumettre
@@ -584,6 +584,8 input.autocomplete.ajax-loading {
584 background-image: url(../images/loading.gif);
584 background-image: url(../images/loading.gif);
585 }
585 }
586
586
587 .role-visibility {padding-left:2em;}
588
587 /***** Flash & error messages ****/
589 /***** Flash & error messages ****/
588 #errorExplanation, div.flash, .nodata, .warning, .conflict {
590 #errorExplanation, div.flash, .nodata, .warning, .conflict {
589 padding: 4px 4px 4px 30px;
591 padding: 4px 4px 4px 30px;
@@ -3,7 +3,7 queries_001:
3 id: 1
3 id: 1
4 type: IssueQuery
4 type: IssueQuery
5 project_id: 1
5 project_id: 1
6 is_public: true
6 visibility: 2
7 name: Multiple custom fields query
7 name: Multiple custom fields query
8 filters: |
8 filters: |
9 ---
9 ---
@@ -26,7 +26,7 queries_002:
26 id: 2
26 id: 2
27 type: IssueQuery
27 type: IssueQuery
28 project_id: 1
28 project_id: 1
29 is_public: false
29 visibility: 0
30 name: Private query for cookbook
30 name: Private query for cookbook
31 filters: |
31 filters: |
32 ---
32 ---
@@ -45,7 +45,7 queries_003:
45 id: 3
45 id: 3
46 type: IssueQuery
46 type: IssueQuery
47 project_id:
47 project_id:
48 is_public: false
48 visibility: 0
49 name: Private query for all projects
49 name: Private query for all projects
50 filters: |
50 filters: |
51 ---
51 ---
@@ -60,7 +60,7 queries_004:
60 id: 4
60 id: 4
61 type: IssueQuery
61 type: IssueQuery
62 project_id:
62 project_id:
63 is_public: true
63 visibility: 2
64 name: Public query for all projects
64 name: Public query for all projects
65 filters: |
65 filters: |
66 ---
66 ---
@@ -75,7 +75,7 queries_005:
75 id: 5
75 id: 5
76 type: IssueQuery
76 type: IssueQuery
77 project_id:
77 project_id:
78 is_public: true
78 visibility: 2
79 name: Open issues by priority and tracker
79 name: Open issues by priority and tracker
80 filters: |
80 filters: |
81 ---
81 ---
@@ -96,7 +96,7 queries_006:
96 id: 6
96 id: 6
97 type: IssueQuery
97 type: IssueQuery
98 project_id:
98 project_id:
99 is_public: true
99 visibility: 2
100 name: Open issues grouped by tracker
100 name: Open issues grouped by tracker
101 filters: |
101 filters: |
102 ---
102 ---
@@ -116,7 +116,7 queries_007:
116 id: 7
116 id: 7
117 type: IssueQuery
117 type: IssueQuery
118 project_id: 2
118 project_id: 2
119 is_public: true
119 visibility: 2
120 name: Public query for project 2
120 name: Public query for project 2
121 filters: |
121 filters: |
122 ---
122 ---
@@ -131,7 +131,7 queries_008:
131 id: 8
131 id: 8
132 type: IssueQuery
132 type: IssueQuery
133 project_id: 2
133 project_id: 2
134 is_public: false
134 visibility: 0
135 name: Private query for project 2
135 name: Private query for project 2
136 filters: |
136 filters: |
137 ---
137 ---
@@ -146,7 +146,7 queries_009:
146 id: 9
146 id: 9
147 type: IssueQuery
147 type: IssueQuery
148 project_id:
148 project_id:
149 is_public: true
149 visibility: 2
150 name: Open issues grouped by list custom field
150 name: Open issues grouped by list custom field
151 filters: |
151 filters: |
152 ---
152 ---
@@ -34,7 +34,7 class CalendarsControllerTest < ActionController::TestCase
34 end
34 end
35
35
36 def test_show_should_run_custom_queries
36 def test_show_should_run_custom_queries
37 @query = IssueQuery.create!(:name => 'Calendar', :is_public => true)
37 @query = IssueQuery.create!(:name => 'Calendar', :visibility => IssueQuery::VISIBILITY_PUBLIC)
38
38
39 get :show, :query_id => @query.id
39 get :show, :query_id => @query.id
40 assert_response :success
40 assert_response :success
@@ -327,7 +327,7 class IssuesControllerTest < ActionController::TestCase
327 end
327 end
328
328
329 def test_index_with_cross_project_query_in_session_should_show_project_issues
329 def test_index_with_cross_project_query_in_session_should_show_project_issues
330 q = IssueQuery.create!(:name => "test", :user_id => 2, :is_public => false, :project => nil)
330 q = IssueQuery.create!(:name => "test", :user_id => 2, :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
331 @request.session[:query] = {:id => q.id, :project_id => 1}
331 @request.session[:query] = {:id => q.id, :project_id => 1}
332
332
333 with_settings :display_subprojects_issues => '0' do
333 with_settings :display_subprojects_issues => '0' do
@@ -341,7 +341,7 class IssuesControllerTest < ActionController::TestCase
341 end
341 end
342
342
343 def test_private_query_should_not_be_available_to_other_users
343 def test_private_query_should_not_be_available_to_other_users
344 q = IssueQuery.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
344 q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
345 @request.session[:user_id] = 3
345 @request.session[:user_id] = 3
346
346
347 get :index, :query_id => q.id
347 get :index, :query_id => q.id
@@ -349,7 +349,7 class IssuesControllerTest < ActionController::TestCase
349 end
349 end
350
350
351 def test_private_query_should_be_available_to_its_user
351 def test_private_query_should_be_available_to_its_user
352 q = IssueQuery.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
352 q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
353 @request.session[:user_id] = 2
353 @request.session[:user_id] = 2
354
354
355 get :index, :query_id => q.id
355 get :index, :query_id => q.id
@@ -357,7 +357,7 class IssuesControllerTest < ActionController::TestCase
357 end
357 end
358
358
359 def test_public_query_should_be_available_to_other_users
359 def test_public_query_should_be_available_to_other_users
360 q = IssueQuery.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
360 q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => nil)
361 @request.session[:user_id] = 3
361 @request.session[:user_id] = 3
362
362
363 get :index, :query_id => q.id
363 get :index, :query_id => q.id
@@ -1151,7 +1151,7 class IssuesControllerTest < ActionController::TestCase
1151 end
1151 end
1152
1152
1153 def test_show_should_display_prev_next_links_with_saved_query_in_session
1153 def test_show_should_display_prev_next_links_with_saved_query_in_session
1154 query = IssueQuery.create!(:name => 'test', :is_public => true, :user_id => 1,
1154 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1,
1155 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1155 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1156 :sort_criteria => [['id', 'asc']])
1156 :sort_criteria => [['id', 'asc']])
1157 @request.session[:query] = {:id => query.id, :project_id => nil}
1157 @request.session[:query] = {:id => query.id, :project_id => nil}
@@ -1243,7 +1243,7 class IssuesControllerTest < ActionController::TestCase
1243 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
1243 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
1244 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
1244 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
1245
1245
1246 query = IssueQuery.create!(:name => 'test', :is_public => true, :user_id => 1, :filters => {},
1246 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1, :filters => {},
1247 :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
1247 :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
1248 @request.session[:query] = {:id => query.id, :project_id => nil}
1248 @request.session[:query] = {:id => query.id, :project_id => nil}
1249
1249
@@ -35,9 +35,7 class QueriesControllerTest < ActionController::TestCase
35 get :new, :project_id => 1
35 get :new, :project_id => 1
36 assert_response :success
36 assert_response :success
37 assert_template 'new'
37 assert_template 'new'
38 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
38 assert_select 'input[name=?][value=0][checked=checked]', 'query[visibility]'
39 :name => 'query[is_public]',
40 :checked => nil }
41 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
39 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
42 :name => 'query_is_for_all',
40 :name => 'query_is_for_all',
43 :checked => nil,
41 :checked => nil,
@@ -53,8 +51,7 class QueriesControllerTest < ActionController::TestCase
53 get :new
51 get :new
54 assert_response :success
52 assert_response :success
55 assert_template 'new'
53 assert_template 'new'
56 assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
54 assert_select 'input[name=?]', 'query[visibility]', 0
57 :name => 'query[is_public]' }
58 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
55 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
59 :name => 'query_is_for_all',
56 :name => 'query_is_for_all',
60 :checked => 'checked',
57 :checked => 'checked',
@@ -75,7 +72,7 class QueriesControllerTest < ActionController::TestCase
75 :f => ["status_id", "assigned_to_id"],
72 :f => ["status_id", "assigned_to_id"],
76 :op => {"assigned_to_id" => "=", "status_id" => "o"},
73 :op => {"assigned_to_id" => "=", "status_id" => "o"},
77 :v => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
74 :v => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
78 :query => {"name" => "test_new_project_public_query", "is_public" => "1"}
75 :query => {"name" => "test_new_project_public_query", "visibility" => "2"}
79
76
80 q = Query.find_by_name('test_new_project_public_query')
77 q = Query.find_by_name('test_new_project_public_query')
81 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
78 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
@@ -92,7 +89,7 class QueriesControllerTest < ActionController::TestCase
92 :fields => ["status_id", "assigned_to_id"],
89 :fields => ["status_id", "assigned_to_id"],
93 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
90 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
94 :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
91 :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
95 :query => {"name" => "test_new_project_private_query", "is_public" => "1"}
92 :query => {"name" => "test_new_project_private_query", "visibility" => "2"}
96
93
97 q = Query.find_by_name('test_new_project_private_query')
94 q = Query.find_by_name('test_new_project_private_query')
98 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
95 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
@@ -107,7 +104,7 class QueriesControllerTest < ActionController::TestCase
107 :fields => ["status_id", "assigned_to_id"],
104 :fields => ["status_id", "assigned_to_id"],
108 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
105 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
109 :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
106 :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
110 :query => {"name" => "test_new_global_private_query", "is_public" => "1"},
107 :query => {"name" => "test_new_global_private_query", "visibility" => "2"},
111 :c => ["", "tracker", "subject", "priority", "category"]
108 :c => ["", "tracker", "subject", "priority", "category"]
112
109
113 q = Query.find_by_name('test_new_global_private_query')
110 q = Query.find_by_name('test_new_global_private_query')
@@ -140,7 +137,7 class QueriesControllerTest < ActionController::TestCase
140 :operators => {"status_id" => "o"},
137 :operators => {"status_id" => "o"},
141 :values => {"status_id" => ["1"]},
138 :values => {"status_id" => ["1"]},
142 :query => {:name => "test_new_with_sort",
139 :query => {:name => "test_new_with_sort",
143 :is_public => "1",
140 :visibility => "2",
144 :sort_criteria => {"0" => ["due_date", "desc"], "1" => ["tracker", ""]}}
141 :sort_criteria => {"0" => ["due_date", "desc"], "1" => ["tracker", ""]}}
145
142
146 query = Query.find_by_name("test_new_with_sort")
143 query = Query.find_by_name("test_new_with_sort")
@@ -163,9 +160,7 class QueriesControllerTest < ActionController::TestCase
163 get :edit, :id => 4
160 get :edit, :id => 4
164 assert_response :success
161 assert_response :success
165 assert_template 'edit'
162 assert_template 'edit'
166 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
163 assert_select 'input[name=?][value=2][checked=checked]', 'query[visibility]'
167 :name => 'query[is_public]',
168 :checked => 'checked' }
169 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
164 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
170 :name => 'query_is_for_all',
165 :name => 'query_is_for_all',
171 :checked => 'checked',
166 :checked => 'checked',
@@ -177,8 +172,7 class QueriesControllerTest < ActionController::TestCase
177 get :edit, :id => 3
172 get :edit, :id => 3
178 assert_response :success
173 assert_response :success
179 assert_template 'edit'
174 assert_template 'edit'
180 assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
175 assert_select 'input[name=?]', 'query[visibility]', 0
181 :name => 'query[is_public]' }
182 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
176 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
183 :name => 'query_is_for_all',
177 :name => 'query_is_for_all',
184 :checked => 'checked',
178 :checked => 'checked',
@@ -190,8 +184,7 class QueriesControllerTest < ActionController::TestCase
190 get :edit, :id => 2
184 get :edit, :id => 2
191 assert_response :success
185 assert_response :success
192 assert_template 'edit'
186 assert_template 'edit'
193 assert_no_tag :tag => 'input', :attributes => { :type => 'checkbox',
187 assert_select 'input[name=?]', 'query[visibility]', 0
194 :name => 'query[is_public]' }
195 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
188 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
196 :name => 'query_is_for_all',
189 :name => 'query_is_for_all',
197 :checked => nil,
190 :checked => nil,
@@ -203,10 +196,7 class QueriesControllerTest < ActionController::TestCase
203 get :edit, :id => 1
196 get :edit, :id => 1
204 assert_response :success
197 assert_response :success
205 assert_template 'edit'
198 assert_template 'edit'
206 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
199 assert_select 'input[name=?][value=2][checked=checked]', 'query[visibility]'
207 :name => 'query[is_public]',
208 :checked => 'checked'
209 }
210 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
200 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
211 :name => 'query_is_for_all',
201 :name => 'query_is_for_all',
212 :checked => nil,
202 :checked => nil,
@@ -240,7 +230,7 class QueriesControllerTest < ActionController::TestCase
240 :fields => ["status_id", "assigned_to_id"],
230 :fields => ["status_id", "assigned_to_id"],
241 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
231 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
242 :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
232 :values => { "assigned_to_id" => ["me"], "status_id" => ["1"]},
243 :query => {"name" => "test_edit_global_private_query", "is_public" => "1"}
233 :query => {"name" => "test_edit_global_private_query", "visibility" => "2"}
244
234
245 assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 3
235 assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 3
246 q = Query.find_by_name('test_edit_global_private_query')
236 q = Query.find_by_name('test_edit_global_private_query')
@@ -257,7 +247,7 class QueriesControllerTest < ActionController::TestCase
257 :fields => ["status_id", "assigned_to_id"],
247 :fields => ["status_id", "assigned_to_id"],
258 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
248 :operators => {"assigned_to_id" => "=", "status_id" => "o"},
259 :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
249 :values => { "assigned_to_id" => ["1"], "status_id" => ["1"]},
260 :query => {"name" => "test_edit_global_public_query", "is_public" => "1"}
250 :query => {"name" => "test_edit_global_public_query", "visibility" => "2"}
261
251
262 assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 4
252 assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 4
263 q = Query.find_by_name('test_edit_global_public_query')
253 q = Query.find_by_name('test_edit_global_public_query')
@@ -28,6 +28,24 class QueryTest < ActiveSupport::TestCase
28 :projects_trackers,
28 :projects_trackers,
29 :custom_fields_trackers
29 :custom_fields_trackers
30
30
31 def test_query_with_roles_visibility_should_validate_roles
32 set_language_if_valid 'en'
33 query = IssueQuery.new(:name => 'Query', :visibility => IssueQuery::VISIBILITY_ROLES)
34 assert !query.save
35 assert_include "Roles can't be blank", query.errors.full_messages
36 query.role_ids = [1, 2]
37 assert query.save
38 end
39
40 def test_changing_roles_visibility_should_clear_roles
41 query = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_ROLES, :role_ids => [1, 2])
42 assert_equal 2, query.roles.count
43
44 query.visibility = IssueQuery::VISIBILITY_PUBLIC
45 query.save!
46 assert_equal 0, query.roles.count
47 end
48
31 def test_available_filters_should_be_ordered
49 def test_available_filters_should_be_ordered
32 set_language_if_valid 'en'
50 set_language_if_valid 'en'
33 query = IssueQuery.new
51 query = IssueQuery.new
@@ -1089,6 +1107,54 class QueryTest < ActiveSupport::TestCase
1089 assert !query_ids.include?(7), 'public query on private project was visible'
1107 assert !query_ids.include?(7), 'public query on private project was visible'
1090 end
1108 end
1091
1109
1110 def test_query_with_public_visibility_should_be_visible_to_anyone
1111 q = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_PUBLIC)
1112
1113 assert q.visible?(User.anonymous)
1114 assert IssueQuery.visible(User.anonymous).find_by_id(q.id)
1115
1116 assert q.visible?(User.find(7))
1117 assert IssueQuery.visible(User.find(7)).find_by_id(q.id)
1118
1119 assert q.visible?(User.find(2))
1120 assert IssueQuery.visible(User.find(2)).find_by_id(q.id)
1121
1122 assert q.visible?(User.find(1))
1123 assert IssueQuery.visible(User.find(1)).find_by_id(q.id)
1124 end
1125
1126 def test_query_with_roles_visibility_should_be_visible_to_user_with_role
1127 q = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_ROLES, :role_ids => [1,2])
1128
1129 assert !q.visible?(User.anonymous)
1130 assert_nil IssueQuery.visible(User.anonymous).find_by_id(q.id)
1131
1132 assert !q.visible?(User.find(7))
1133 assert_nil IssueQuery.visible(User.find(7)).find_by_id(q.id)
1134
1135 assert q.visible?(User.find(2))
1136 assert IssueQuery.visible(User.find(2)).find_by_id(q.id)
1137
1138 assert q.visible?(User.find(1))
1139 assert IssueQuery.visible(User.find(1)).find_by_id(q.id)
1140 end
1141
1142 def test_query_with_private_visibility_should_be_visible_to_owner
1143 q = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_PRIVATE, :user => User.find(7))
1144
1145 assert !q.visible?(User.anonymous)
1146 assert_nil IssueQuery.visible(User.anonymous).find_by_id(q.id)
1147
1148 assert q.visible?(User.find(7))
1149 assert IssueQuery.visible(User.find(7)).find_by_id(q.id)
1150
1151 assert !q.visible?(User.find(2))
1152 assert_nil IssueQuery.visible(User.find(2)).find_by_id(q.id)
1153
1154 assert q.visible?(User.find(1))
1155 assert_nil IssueQuery.visible(User.find(1)).find_by_id(q.id)
1156 end
1157
1092 test "#available_filters should include users of visible projects in cross-project view" do
1158 test "#available_filters should include users of visible projects in cross-project view" do
1093 users = IssueQuery.new.available_filters["assigned_to_id"]
1159 users = IssueQuery.new.available_filters["assigned_to_id"]
1094 assert_not_nil users
1160 assert_not_nil users
@@ -291,7 +291,7 class UserTest < ActiveSupport::TestCase
291 end
291 end
292
292
293 def test_destroy_should_delete_private_queries
293 def test_destroy_should_delete_private_queries
294 query = Query.new(:name => 'foo', :is_public => false)
294 query = Query.new(:name => 'foo', :visibility => Query::VISIBILITY_PRIVATE)
295 query.project_id = 1
295 query.project_id = 1
296 query.user_id = 2
296 query.user_id = 2
297 query.save!
297 query.save!
@@ -302,7 +302,7 class UserTest < ActiveSupport::TestCase
302 end
302 end
303
303
304 def test_destroy_should_update_public_queries
304 def test_destroy_should_update_public_queries
305 query = Query.new(:name => 'foo', :is_public => true)
305 query = Query.new(:name => 'foo', :visibility => Query::VISIBILITY_PUBLIC)
306 query.project_id = 1
306 query.project_id = 1
307 query.user_id = 2
307 query.user_id = 2
308 query.save!
308 query.save!
General Comments 0
You need to be logged in to leave comments. Login now