@@ -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. |
|
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. |
|
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. |
|
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. |
|
228 | out << query_links(l(:label_my_queries), sidebar_queries.select(&:is_private?)) | |
229 |
out << query_links(l(:label_query_plural), sidebar_queries. |
|
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? || ( |
|
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 |
|
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 |
|
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', : |
|
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, : |
|
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), : |
|
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), : |
|
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), : |
|
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', : |
|
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', : |
|
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", " |
|
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", " |
|
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", " |
|
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 |
: |
|
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", " |
|
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", " |
|
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', : |
|
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', : |
|
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