Feature #7360 » default_custom_query_trunk_r15273.patch
| app/controllers/default_custom_query_setting_controller.rb | ||
|---|---|---|
| 1 | # Redmine - project management software | |
| 2 | # Copyright (C) 2006-2015 Jean-Philippe Lang | |
| 3 | # | |
| 4 | # This program is free software; you can redistribute it and/or | |
| 5 | # modify it under the terms of the GNU General Public License | |
| 6 | # as published by the Free Software Foundation; either version 2 | |
| 7 | # of the License, or (at your option) any later version. | |
| 8 | # | |
| 9 | # This program is distributed in the hope that it will be useful, | |
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 12 | # GNU General Public License for more details. | |
| 13 | # | |
| 14 | # You should have received a copy of the GNU General Public License | |
| 15 | # along with this program; if not, write to the Free Software | |
| 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
| 17 | ||
| 18 | class DefaultCustomQuerySettingController < ApplicationController | |
| 19 | before_filter :find_project_by_project_id | |
| 20 | before_filter :authorize | |
| 21 | ||
| 22 | helper :default_custom_query | |
| 23 | ||
| 24 | def update | |
| 25 | settings = params[:settings] | |
| 26 | ||
| 27 | @default_query = ProjectsDefaultQuery.initialize_for(@project.id) | |
| 28 | @default_query.query_id = settings[:query_id] | |
| 29 | ||
| 30 | if @default_query.save | |
| 31 | session[:query] = nil | |
| 32 | end | |
| 33 | ||
| 34 | render partial: 'form' | |
| 35 | end | |
| 36 | end | |
| app/controllers/issues_controller.rb | ||
|---|---|---|
| 24 | 24 | before_filter :authorize, :except => [:index, :new, :create] | 
| 25 | 25 | before_filter :find_optional_project, :only => [:index, :new, :create] | 
| 26 | 26 | before_filter :build_new_issue_from_params, :only => [:new, :create] | 
| 27 | before_filter :with_default_query, only: [:index], if: :default_query_module_enabled? | |
| 27 | 28 | accept_rss_auth :index, :show | 
| 28 | 29 | accept_api_auth :index, :show, :create, :update, :destroy | 
| 29 | 30 | |
| ... | ... | |
| 353 | 354 | |
| 354 | 355 | private | 
| 355 | 356 | |
| 357 | def with_default_query | |
| 358 | case | |
| 359 | when params[:query_id].present? | |
| 360 | # Nothing to do | |
| 361 | when api_request? | |
| 362 | # Nothing to do | |
| 363 | # when show_all_issues? | |
| 364 | when params[:without_default] | |
| 365 | params[:set_filter] = 1 | |
| 366 | # when filter_applied? | |
| 367 | when params[:set_filter] && params.key?(:op) && params.key?(:f) | |
| 368 | # Nothing to do | |
| 369 | # when filter_cleared? | |
| 370 |     when params[:set_filter] && [:op, :f].all? {|k| !params.key?(k) } | |
| 371 | apply_default_query! | |
| 372 | when session[:query] | |
| 373 | query_id, project_id = session[:query].values_at(:id, :project_id) | |
| 374 | unless query_id && (project_id == @project.id) && IssueQuery.available_query?(@project.id, query_id) | |
| 375 | apply_default_query! | |
| 376 | end | |
| 377 | else | |
| 378 | apply_default_query! | |
| 379 | end | |
| 380 | end | |
| 381 | ||
| 382 | def apply_default_query! | |
| 383 | default_query = find_default_query | |
| 384 | if default_query | |
| 385 | params[:query_id] = default_query.id | |
| 386 | end | |
| 387 | end | |
| 388 | ||
| 356 | 389 | def retrieve_previous_and_next_issue_ids | 
| 357 | 390 | if params[:prev_issue_id].present? || params[:next_issue_id].present? | 
| 358 | 391 | @prev_issue_id = params[:prev_issue_id].presence.try(:to_i) | 
| app/controllers/projects_controller.rb | ||
|---|---|---|
| 38 | 38 | helper :queries | 
| 39 | 39 | helper :repositories | 
| 40 | 40 | helper :members | 
| 41 | helper :default_custom_query | |
| 41 | 42 | |
| 42 | 43 | # Lists visible projects | 
| 43 | 44 | def index | 
| app/helpers/default_custom_query_helper.rb | ||
|---|---|---|
| 1 | module DefaultCustomQueryHelper | |
| 2 | def options_for_selectable_queries(project) | |
| 3 | options_groups = [] | |
| 4 | ||
| 5 | queries = IssueQuery.only_public.where(project_id: nil) | |
| 6 | if queries.any? | |
| 7 |       options_groups << [l('default_custom_query.label_queries_for_all_projects'), queries] | |
| 8 | end | |
| 9 | ||
| 10 | queries = project.queries.only_public | |
| 11 | if queries.any? | |
| 12 |       options_groups << [l('default_custom_query.label_queries_for_current_project'), queries] | |
| 13 | end | |
| 14 | ||
| 15 | options_groups.map do |group, options| | |
| 16 |       [group, options.collect {|o| [o.name, o.id] }] | |
| 17 | end | |
| 18 | end | |
| 19 | end | |
| app/helpers/projects_helper.rb | ||
|---|---|---|
| 27 | 27 |             {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki}, | 
| 28 | 28 |             {:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural}, | 
| 29 | 29 |             {:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural}, | 
| 30 |             {:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities} | |
| 30 |             {:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities}, | |
| 31 |             {:name => 'default_custom_query', :action => :manage_default_query, :partial => 'default_custom_query_setting/form', :label => :'default_custom_query.label_setting'} | |
| 31 | 32 | ] | 
| 32 |     tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)} | |
| 33 |     tabs = tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)} | |
| 33 | 34 | end | 
| 34 | 35 | |
| 35 | 36 | def parent_project_select_tag(project) | 
| app/helpers/queries_helper.rb | ||
|---|---|---|
| 241 | 241 | @query.project = @project | 
| 242 | 242 | end | 
| 243 | 243 | @query | 
| 244 | else | |
| 245 | @query = find_default_query | |
| 244 | 246 | end | 
| 245 | 247 | end | 
| 246 | 248 | |
| 249 | private | |
| 250 | ||
| 251 | def find_default_query | |
| 252 | @project.default_query if @project.is_a?(Project) | |
| 253 | end | |
| 254 | ||
| 255 | def default_query_module_enabled? | |
| 256 | @project && @project.module_enabled?(:default_custom_query) | |
| 257 | end | |
| 258 | ||
| 247 | 259 | # Returns the query definition as hidden field tags | 
| 248 | 260 | def query_as_hidden_field_tags(query) | 
| 249 | 261 |     tags = hidden_field_tag("set_filter", "1", :id => nil) | 
| app/models/issue_query.rb | ||
|---|---|---|
| 16 | 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
| 17 | 17 | |
| 18 | 18 | class IssueQuery < Query | 
| 19 | has_many :projects_default_queries, dependent: :nullify, foreign_key: :query_id | |
| 19 | 20 | |
| 20 | 21 | self.queried_class = Issue | 
| 21 | 22 | |
| ... | ... | |
| 71 | 72 | end | 
| 72 | 73 | } | 
| 73 | 74 | |
| 75 |   scope :only_public, -> { | |
| 76 | where(:visibility => VISIBILITY_PUBLIC) | |
| 77 | } | |
| 78 | ||
| 79 | def self.available_query?(project_id, query_id) | |
| 80 | self.only_public | |
| 81 |         .where('project_id is null or project_id = ?', project_id) | |
| 82 | .where(id: query_id).exists? | |
| 83 | end | |
| 84 | ||
| 74 | 85 | def initialize(attributes=nil, *args) | 
| 75 | 86 | super attributes | 
| 76 | 87 |     self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} } | 
| ... | ... | |
| 102 | 113 | !is_private? | 
| 103 | 114 | end | 
| 104 | 115 | |
| 116 | def public_visibility? | |
| 117 | visibility == VISIBILITY_PUBLIC | |
| 118 | end | |
| 119 | ||
| 105 | 120 | def draw_relations | 
| 106 | 121 | r = options[:draw_relations] | 
| 107 | 122 | r.nil? || r == '1' | 
| app/models/project.rb | ||
|---|---|---|
| 55 | 55 | :class_name => 'IssueCustomField', | 
| 56 | 56 |                           :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", | 
| 57 | 57 | :association_foreign_key => 'custom_field_id' | 
| 58 | # Default Custom Queries | |
| 59 | has_many :default_queries, dependent: :delete_all, :class_name => 'ProjectsDefaultQuery' | |
| 58 | 60 | |
| 59 | 61 | acts_as_attachable :view_permission => :view_files, | 
| 60 | 62 | :edit_permission => :manage_files, | 
| ... | ... | |
| 790 | 792 | end | 
| 791 | 793 | end | 
| 792 | 794 | |
| 795 | def default_query | |
| 796 | default_queries.first.try :query | |
| 797 | end | |
| 798 | ||
| 799 | def init_default_query | |
| 800 | default_queries.first || default_queries.new | |
| 801 | end | |
| 802 | ||
| 793 | 803 | private | 
| 794 | 804 | |
| 795 | 805 | def update_inherited_members | 
| app/models/projects_default_query.rb | ||
|---|---|---|
| 1 | # Redmine - project management software | |
| 2 | # Copyright (C) 2006-2015 Jean-Philippe Lang | |
| 3 | # | |
| 4 | # This program is free software; you can redistribute it and/or | |
| 5 | # modify it under the terms of the GNU General Public License | |
| 6 | # as published by the Free Software Foundation; either version 2 | |
| 7 | # of the License, or (at your option) any later version. | |
| 8 | # | |
| 9 | # This program is distributed in the hope that it will be useful, | |
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 12 | # GNU General Public License for more details. | |
| 13 | # | |
| 14 | # You should have received a copy of the GNU General Public License | |
| 15 | # along with this program; if not, write to the Free Software | |
| 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
| 17 | ||
| 18 | class ProjectsDefaultQuery < ActiveRecord::Base | |
| 19 | belongs_to :project | |
| 20 | belongs_to :query, class_name: 'IssueQuery' | |
| 21 | ||
| 22 |   validates :project_id, :query_id, numericality: { allow_nil: true } | |
| 23 | validates :project_id, uniqueness: true, presence: true | |
| 24 | validate :query_must_be_selectable | |
| 25 | ||
| 26 | def self.initialize_for(project_id) | |
| 27 | default_query = where(:project_id => project_id).first | |
| 28 | ||
| 29 | unless default_query | |
| 30 | default_query = self.new | |
| 31 | default_query.project_id = project_id | |
| 32 | end | |
| 33 | default_query | |
| 34 | end | |
| 35 | ||
| 36 | def query | |
| 37 | return unless super | |
| 38 | ||
| 39 | unless new_record? || selectable_query?(super) | |
| 40 | update_attribute :query_id, nil | |
| 41 | end | |
| 42 | super | |
| 43 | end | |
| 44 | ||
| 45 | private | |
| 46 | ||
| 47 | def query_must_be_selectable | |
| 48 | return if errors.any? || query_id.blank? || !query_id_changed? | |
| 49 | ||
| 50 | issue_query = IssueQuery.where(:id => query_id).first | |
| 51 | ||
| 52 | unless selectable_query?(issue_query) | |
| 53 | errors.add :query_id, :invalid | |
| 54 | end | |
| 55 | end | |
| 56 | ||
| 57 | def selectable_query?(query) | |
| 58 | query && query.public_visibility? && | |
| 59 | (query.project.nil? || query.project == project) | |
| 60 | end | |
| 61 | end | |
| app/views/default_custom_query_setting/_form.html.erb | ||
|---|---|---|
| 1 | <%= labelled_form_for @default_query ||= @project.init_default_query, | |
| 2 | as: :settings, | |
| 3 | url: default_custom_query_setting_update_path(@project), | |
| 4 |                       remote: true, method: :put, html: { id: 'default-query-setting' } do |f| %> | |
| 5 | ||
| 6 | <%= error_messages_for @default_query %> | |
| 7 | ||
| 8 | <div class="box tabular"> | |
| 9 | <p> | |
| 10 | <%= f.select :query_id, options_for_selectable_queries(@project), include_blank: true %><br> | |
| 11 | <em><%=l 'default_custom_query.text_allowed_queries' %></em> | |
| 12 | </p> | |
| 13 | </div> | |
| 14 | <%= submit_tag l(:button_save) %> | |
| 15 | <% end %> | |
| 16 | ||
| 17 | <script> | |
| 18 |   $('#default-query-setting').on('ajax:success', function(data, result, xhr) { | |
| 19 |     $('#tab-content-default_custom_query').html(result); | |
| 20 | }); | |
| 21 | </script> | |
| app/views/issues/_sidebar.html.erb | ||
|---|---|---|
| 1 | 1 | <h3><%= l(:label_issue_plural) %></h3> | 
| 2 | 2 | |
| 3 | 3 | <ul> | 
| 4 | <li><%= link_to l(:label_issue_view_all), _project_issues_path(@project, :set_filter => 1) %></li> | |
| 4 | <% if @project && @project.module_enabled?(:default_custom_query) && @project.default_query.present? %> | |
| 5 | <li><%= link_to l('default_custom_query.label_view_default_issues'), project_issues_path(@project, :set_filter => 1) %><li> | |
| 6 | <% end %> | |
| 7 | <li><%= link_to l(:label_issue_view_all), _project_issues_path(@project, :set_filter => 1, :without_default => 1) %></li> | |
| 5 | 8 | <% if @project %> | 
| 6 | 9 | <li><%= link_to l(:field_summary), project_issues_report_path(@project) %></li> | 
| 7 | 10 | <% end %> | 
| config/locales/en.yml | ||
|---|---|---|
| 1181 | 1181 | description_date_from: Enter start date | 
| 1182 | 1182 | description_date_to: Enter end date | 
| 1183 | 1183 | text_repository_identifier_info: 'Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.' | 
| 1184 |  | |
| 1185 | project_module_default_custom_query: Default custom query | |
| 1186 | permission_manage_default_query: Manage default query | |
| 1187 | ||
| 1188 | # Labels for projects_default_queries column | |
| 1189 | field_query: Default custom query | |
| 1190 | ||
| 1191 | default_custom_query: | |
| 1192 | label_setting: Default custom query | |
| 1193 | label_view_default_issues: View default issues | |
| 1194 | label_queries_for_all_projects: For all projects | |
| 1195 | label_queries_for_current_project: For current project | |
| 1196 | ||
| 1197 | text_allowed_queries: Public (to any users) queries only selectable | |
| config/locales/fr.yml | ||
|---|---|---|
| 1201 | 1201 |   mail_body_security_notification_notify_enabled: Les notifications ont été activées pour l'adresse %{value} | 
| 1202 | 1202 |   mail_body_security_notification_notify_disabled: Les notifications ont été désactivées pour l'adresse %{value} | 
| 1203 | 1203 | field_remote_ip: Adresse IP | 
| 1204 | ||
| 1205 | project_module_default_custom_query: Rapport par défaut | |
| 1206 | permission_manage_default_query: Gérer le rapport par défaut | |
| 1207 | ||
| 1208 | # Labels for projects_default_queries column | |
| 1209 | field_query: Rapport par défaut | |
| 1210 | ||
| 1211 | default_custom_query: | |
| 1212 | label_setting: Rapport par défaut | |
| 1213 | label_view_default_issues: Voir les demandes par défaut | |
| 1214 | label_queries_for_all_projects: Pour tous les projets | |
| 1215 | label_queries_for_current_project: Pour le projet en cours | |
| 1216 | ||
| 1217 | text_allowed_queries: Seuls les rapports publics (pour tous les utilisateurs) sont sélectionnables | |
| config/locales/ja.yml | ||
|---|---|---|
| 1209 | 1209 | receives notifications. | 
| 1210 | 1210 | mail_body_settings_updated: ! 'The following settings were changed:' | 
| 1211 | 1211 | field_remote_ip: IP address | 
| 1212 | ||
| 1213 | project_module_default_custom_query: デフォルトカスタムクエリ | |
| 1214 | permission_manage_default_query: デフォルトカスタムクエリの管理 | |
| 1215 | ||
| 1216 | # Labels for projects_default_queries column | |
| 1217 | field_query: デフォルトクエリ | |
| 1218 | ||
| 1219 | default_custom_query: | |
| 1220 | label_setting: デフォルトカスタムクエリ | |
| 1221 | label_view_default_issues: デフォルトチケット一覧を見る | |
| 1222 | label_queries_for_all_projects: 全プロジェクト向け | |
| 1223 | label_queries_for_current_project: 現在プロジェクト | |
| 1224 | ||
| 1225 | text_allowed_queries: 公開クエリ(すべてのユーザ)のみ選択可能 | |
| config/locales/ru.yml | ||
|---|---|---|
| 1297 | 1297 | receives notifications. | 
| 1298 | 1298 | mail_body_settings_updated: ! 'The following settings were changed:' | 
| 1299 | 1299 | field_remote_ip: IP address | 
| 1300 | ||
| 1301 | project_module_default_custom_query: Выбор запроса по умолчанию (фильтр задач) | |
| 1302 | permission_manage_default_query: Manage default query | |
| 1303 | ||
| 1304 | # Labels for projects_default_queries column | |
| 1305 | field_query: Выбор запроса по умолчанию | |
| 1306 | ||
| 1307 | default_custom_query: | |
| 1308 | label_setting: Выбор запроса по умолчанию | |
| 1309 | label_view_default_issues: Просматривать запросы по умолчанию | |
| 1310 | label_queries_for_all_projects: Для всех проектов | |
| 1311 | label_queries_for_current_project: Для текущего прооекта | |
| 1312 | ||
| 1313 | text_allowed_queries: Для выбора доступны только публичные запросы (фильтры задач) | |
| config/locales/tr.yml | ||
|---|---|---|
| 1203 | 1203 | receives notifications. | 
| 1204 | 1204 | mail_body_settings_updated: ! 'The following settings were changed:' | 
| 1205 | 1205 | field_remote_ip: IP address | 
| 1206 | ||
| 1207 | project_module_default_custom_query: Öntanımlı özel sorgu | |
| 1208 | permission_manage_default_query: Öntanımlı sorguyu yönet | |
| 1209 | ||
| 1210 | # Labels for projects_default_queries column | |
| 1211 | field_query: Öntanımlı özel sorgu | |
| 1212 | ||
| 1213 | default_custom_query: | |
| 1214 | label_setting: Öntanımlı özel sorgu | |
| 1215 | label_view_default_issues: Öntanımlı işleri gör | |
| 1216 | label_queries_for_all_projects: Tüm birimler için | |
| 1217 | label_queries_for_current_project: Simdiki birim için | |
| 1218 | ||
| 1219 | text_allowed_queries: Herkese açık (tüm kullanıcılar) sorgular sadece seçilebilir | |
| config/routes.rb | ||
|---|---|---|
| 363 | 363 | |
| 364 | 364 | match 'uploads', :to => 'attachments#upload', :via => :post | 
| 365 | 365 | |
| 366 | controller :default_custom_query_setting, as: 'default_custom_query_setting' do | |
| 367 | put ':project_id/default_custom_query/update', action: 'update', as: 'update' | |
| 368 | end | |
| 369 | ||
| 366 | 370 | get 'robots.txt', :to => 'welcome#robots' | 
| 367 | 371 | |
| 368 | 372 |   Dir.glob File.expand_path("plugins/*", Rails.root) do |plugin_dir| | 
| config/settings.yml | ||
|---|---|---|
| 219 | 219 | - boards | 
| 220 | 220 | - calendar | 
| 221 | 221 | - gantt | 
| 222 | - default_custom_query | |
| 222 | 223 | default_projects_tracker_ids: | 
| 223 | 224 | serialized: true | 
| 224 | 225 | default: | 
| db/migrate/20160307180800_create_projects_default_queries.rb | ||
|---|---|---|
| 1 | class CreateProjectsDefaultQueries < ActiveRecord::Migration | |
| 2 | def change | |
| 3 | create_table :projects_default_queries do |t| | |
| 4 | t.belongs_to :project | |
| 5 | t.belongs_to :query | |
| 6 | ||
| 7 | t.timestamps null: false | |
| 8 | end | |
| 9 | add_index :projects_default_queries, :project_id, unique: true | |
| 10 | add_index :projects_default_queries, :query_id | |
| 11 | end | |
| 12 | end | |
| lib/redmine.rb | ||
|---|---|---|
| 183 | 183 | map.project_module :gantt do |map| | 
| 184 | 184 |     map.permission :view_gantt, {:gantts => [:show, :update]}, :read => true | 
| 185 | 185 | end | 
| 186 | ||
| 187 | map.project_module :default_custom_query do |map| | |
| 188 |     map.permission :manage_default_query, { :default_custom_query_setting =>  [:update] }, :require => :member | |
| 189 | end | |
| 186 | 190 | end | 
| 187 | 191 | |
| 188 | 192 | Redmine::MenuManager.map :top_menu do |menu| | 
| test/functional/default_custom_query_setting_controller.rb | ||
|---|---|---|
| 1 | # Redmine - project management software | |
| 2 | # Copyright (C) 2006-2015 Jean-Philippe Lang | |
| 3 | # | |
| 4 | # This program is free software; you can redistribute it and/or | |
| 5 | # modify it under the terms of the GNU General Public License | |
| 6 | # as published by the Free Software Foundation; either version 2 | |
| 7 | # of the License, or (at your option) any later version. | |
| 8 | # | |
| 9 | # This program is distributed in the hope that it will be useful, | |
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 12 | # GNU General Public License for more details. | |
| 13 | # | |
| 14 | # You should have received a copy of the GNU General Public License | |
| 15 | # along with this program; if not, write to the Free Software | |
| 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
| 17 | ||
| 18 | require File.expand_path('../../test_helper', __FILE__) | |
| 19 | ||
| 20 | class DefaultCustomQuerySettingControllerTest < ActionController::TestCase | |
| 21 | fixtures :projects, | |
| 22 | :users, | |
| 23 | :roles, | |
| 24 | :members, | |
| 25 | :member_roles, | |
| 26 | :issues | |
| 27 | ||
| 28 | def setup | |
| 29 | User.current = nil | |
| 30 | @request.session[:user_id] = nil | |
| 31 | ||
| 32 | @project = Project.generate_with_parent! | |
| 33 | @project.enable_module!(:default_custom_query) | |
| 34 | ||
| 35 | @permitted_user = User.generate! | |
| 36 | User.add_to_project(@permitted_user, @project, Role.generate!(:permissions => [:edit_project, :manage_default_query])) | |
| 37 | @not_permitted_user = User.generate! | |
| 38 | User.add_to_project(@not_permitted_user, @project, Role.generate!(:permissions => [:edit_project, :add_subprojects])) | |
| 39 | ||
| 40 | @stored_query = IssueQuery.create!(:name => "test", :user_id => 1, :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => @project) | |
| 41 |     @session_query_value = {:id => @stored_query.id, :project_id => @project.id} | |
| 42 | @request.session[:query] = @session_query_value | |
| 43 | end | |
| 44 | ||
| 45 | def test_update_should_success_when_module_is_enabled_on_project_and_logged_user_has_permission | |
| 46 | public_query = IssueQuery.create!(:name => "test", :user_id => 1, :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => @project) | |
| 47 | @request.session[:user_id] = @permitted_user.id | |
| 48 | ||
| 49 |     xhr :put, :update, :project_id => @project.id, :settings => {:query_id => public_query.id} | |
| 50 | ||
| 51 | assert_response :success | |
| 52 | assert_nil @request.session[:query] | |
| 53 | assert_template partial: 'default_custom_query_setting/_form' | |
| 54 | ||
| 55 | assert_equal public_query, @project.default_query | |
| 56 | end | |
| 57 | ||
| 58 | def test_update_should_success_and_clear_query_when_module_is_enabled_on_project_and_logged_user_has_permission | |
| 59 | @request.session[:user_id] = @permitted_user.id | |
| 60 | ||
| 61 |     xhr :put, :update, :project_id => @project.id, :settings => {:query_id => nil} | |
| 62 | ||
| 63 | assert_response :success | |
| 64 | assert_equal nil, @request.session[:query] | |
| 65 | assert_template partial: 'default_custom_query_setting/_form' | |
| 66 | ||
| 67 | assert_nil @project.default_query | |
| 68 | end | |
| 69 | ||
| 70 | def test_update_should_failure_when_module_is_enabled_on_project_but_logged_user_does_not_have_permission | |
| 71 | public_query = IssueQuery.create!(:name => "test", :user_id => 1, :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => @project) | |
| 72 | @request.session[:user_id] = @not_permitted_user.id | |
| 73 | ||
| 74 |     xhr :put, :update, :project_id => @project.identifier, :settings => {:query_id => public_query.id} | |
| 75 | ||
| 76 | assert_response :forbidden | |
| 77 | assert_equal @session_query_value, @request.session[:query] | |
| 78 | end | |
| 79 | ||
| 80 | def test_update_should_failure_when_module_is_enabled_on_project_but_spacified_unselectable_query | |
| 81 | private_query = IssueQuery.create!(:name => "test", :user_id => 1, :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => @project) | |
| 82 | @request.session[:user_id] = @permitted_user.id | |
| 83 | ||
| 84 |     xhr :put, :update, :project_id => @project.id, :settings => {:query_id => private_query.id} | |
| 85 | ||
| 86 | assert_response :success | |
| 87 | assert_equal @session_query_value, @request.session[:query] | |
| 88 | assert_template partial: 'default_custom_query_setting/_form' | |
| 89 | assert_select '#errorExplanation li', 1 | |
| 90 | end | |
| 91 | ||
| 92 | def test_update_should_failure_when_module_is_disabled | |
| 93 | @project.disable_module!(:default_custom_query) | |
| 94 | public_query = IssueQuery.create!(:name => "test", :user_id => 1, :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => @project) | |
| 95 | @request.session[:user_id] = @permitted_user.id | |
| 96 | ||
| 97 |     xhr :put, :update, :project_id => @project.id, :settings => {:query_id => public_query.id} | |
| 98 | ||
| 99 | assert_response :forbidden | |
| 100 | assert_equal @session_query_value, @request.session[:query] | |
| 101 | end | |
| 102 | end | |
| test/functional/issues_controller_test.rb | ||
|---|---|---|
| 431 | 431 | assert_response :success | 
| 432 | 432 | end | 
| 433 | 433 | |
| 434 | def test_default_query_should_be_available_when_default_query_module_enabled | |
| 435 | project = Project.find(1) | |
| 436 | project.enable_module!(:default_custom_query) | |
| 437 | ||
| 438 | q = IssueQuery.create!(:name => "default_custom_query", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => nil) | |
| 439 | dq = ProjectsDefaultQuery.initialize_for(project.id) | |
| 440 | dq.query = q | |
| 441 | dq.save! | |
| 442 | ||
| 443 | @request.session[:user_id] = 3 | |
| 444 | ||
| 445 | get :index, :project_id => 1 | |
| 446 | assert_response :success | |
| 447 | assert_select 'h2', text: q.name | |
| 448 | assert_select 'ul.queries a.selected', text: q.name | |
| 449 | end | |
| 450 | ||
| 451 | def test_default_query_should_be_unavailable_when_default_query_module_disabled | |
| 452 | project = Project.find(1) | |
| 453 | project.disable_module!(:default_custom_query) | |
| 454 | ||
| 455 | @request.session[:user_id] = 3 | |
| 456 | ||
| 457 | get :index, :project_id => 1 | |
| 458 | assert_response :success | |
| 459 | assert_select 'h2', text: l(:label_issue_plural) | |
| 460 | assert_select 'ul.queries a.selected', false | |
| 461 | end | |
| 462 | ||
| 463 | def test_default_query_should_be_unavailable_when_param_without_default_spacified | |
| 464 | project = Project.find(1) | |
| 465 | project.enable_module!(:default_custom_query) | |
| 466 | ||
| 467 | q = IssueQuery.create!(:name => "default_custom_query", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => nil) | |
| 468 | dq = ProjectsDefaultQuery.initialize_for(project.id) | |
| 469 | dq.query = q | |
| 470 | dq.save! | |
| 471 | ||
| 472 | @request.session[:user_id] = 3 | |
| 473 | ||
| 474 | get :index, :project_id => 1, :without_default => 1 | |
| 475 | assert_response :success | |
| 476 | assert_select 'h2', text: l(:label_issue_plural) | |
| 477 | assert_select 'ul.queries a.selected', false | |
| 478 | end | |
| 479 | ||
| 480 | def test_default_query_should_be_unavailable_when_filter_condition_op_and_f_spacified | |
| 481 | project = Project.find(1) | |
| 482 | project.enable_module!(:default_custom_query) | |
| 483 | ||
| 484 | q = IssueQuery.create!(:name => "default_custom_query", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => nil) | |
| 485 | dq = ProjectsDefaultQuery.initialize_for(project.id) | |
| 486 | dq.query = q | |
| 487 | dq.save! | |
| 488 | ||
| 489 | @request.session[:user_id] = 3 | |
| 490 | ||
| 491 | get :index, :project_id => 1, :set_filter => 1, :op => 'op', :f => 'f' | |
| 492 | assert_response :success | |
| 493 | assert_select 'h2', text: l(:label_issue_plural) | |
| 494 | assert_select 'ul.queries a.selected', false | |
| 495 | end | |
| 496 | ||
| 434 | 497 | def test_index_should_omit_page_param_in_export_links | 
| 435 | 498 | get :index, :page => 2 | 
| 436 | 499 | assert_response :success | 
| test/unit/helpers/default_custom_query_helper_test.rb | ||
|---|---|---|
| 1 | # Redmine - project management software | |
| 2 | # Copyright (C) 2006-2015 Jean-Philippe Lang | |
| 3 | # | |
| 4 | # This program is free software; you can redistribute it and/or | |
| 5 | # modify it under the terms of the GNU General Public License | |
| 6 | # as published by the Free Software Foundation; either version 2 | |
| 7 | # of the License, or (at your option) any later version. | |
| 8 | # | |
| 9 | # This program is distributed in the hope that it will be useful, | |
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 12 | # GNU General Public License for more details. | |
| 13 | # | |
| 14 | # You should have received a copy of the GNU General Public License | |
| 15 | # along with this program; if not, write to the Free Software | |
| 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
| 17 | ||
| 18 | require File.expand_path('../../../test_helper', __FILE__) | |
| 19 | ||
| 20 | class DefaultCustomQueryHelperTest < ActionView::TestCase | |
| 21 | include ApplicationHelper | |
| 22 | include DefaultCustomQueryHelper | |
| 23 | include Redmine::I18n | |
| 24 | include ERB::Util | |
| 25 | include Rails.application.routes.url_helpers | |
| 26 | ||
| 27 | fixtures :projects, :queries | |
| 28 | ||
| 29 | def setup | |
| 30 | super | |
| 31 |     set_language_if_valid('en') | |
| 32 | end | |
| 33 | ||
| 34 | def test_options_for_selectable_queries | |
| 35 | project = Project.find(2) | |
| 36 | ||
| 37 | options = options_for_selectable_queries(project) | |
| 38 | ||
| 39 | assert_equal 2, options.count | |
| 40 |     assert_includes options.first, l('default_custom_query.label_queries_for_all_projects') | |
| 41 |     assert_includes options.first, IssueQuery.only_public.where(:project_id => nil).collect {|o| [o.name, o.id]} | |
| 42 |     assert_includes options.last, l('default_custom_query.label_queries_for_current_project') | |
| 43 |     assert_includes options.last, project.queries.only_public.collect {|o| [o.name, o.id]} | |
| 44 | end | |
| 45 | end | |
| test/unit/project_test.rb | ||
|---|---|---|
| 1000 | 1000 | Project.uniq.visible.to_a | 
| 1001 | 1001 | end | 
| 1002 | 1002 | end | 
| 1003 | ||
| 1004 | def test_default_query | |
| 1005 | project = Project.find(1) | |
| 1006 | query = IssueQuery.create!(:name => "test", :user_id => 1, :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => @project) | |
| 1007 | ProjectsDefaultQuery.create!(:project_id => project.id, :query_id => query.id) | |
| 1008 | default_queries = ProjectsDefaultQuery.where(:project_id => project.id) | |
| 1009 | assert_equal query, project.default_query | |
| 1010 | end | |
| 1011 | ||
| 1012 | def test_init_default_query | |
| 1013 | project = Project.find(1) | |
| 1014 | query = IssueQuery.create!(:name => "test", :user_id => 1, :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => @project) | |
| 1015 | default_query = ProjectsDefaultQuery.create!(:project_id => project.id, :query_id => query.id) | |
| 1016 | assert_equal default_query, project.init_default_query | |
| 1017 | ||
| 1018 | default_query.destroy! | |
| 1019 | assert_kind_of ProjectsDefaultQuery, project.init_default_query | |
| 1020 | assert project.init_default_query.new_record? | |
| 1021 | end | |
| 1003 | 1022 | end | 
| test/unit/projects_default_query_test.rb | ||
|---|---|---|
| 1 | # Redmine - project management software | |
| 2 | # Copyright (C) 2006-2016 Jean-Philippe Lang | |
| 3 | # | |
| 4 | # This program is free software; you can redistribute it and/or | |
| 5 | # modify it under the terms of the GNU General Public License | |
| 6 | # as published by the Free Software Foundation; either version 2 | |
| 7 | # of the License, or (at your option) any later version. | |
| 8 | # | |
| 9 | # This program is distributed in the hope that it will be useful, | |
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 12 | # GNU General Public License for more details. | |
| 13 | # | |
| 14 | # You should have received a copy of the GNU General Public License | |
| 15 | # along with this program; if not, write to the Free Software | |
| 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
| 17 | ||
| 18 | require File.expand_path('../../test_helper', __FILE__) | |
| 19 | ||
| 20 | class ProjectsDefaultQueryTest < ActiveSupport::TestCase | |
| 21 | include Redmine::I18n | |
| 22 | ||
| 23 | fixtures :projects, :queries | |
| 24 | ||
| 25 | def setup | |
| 26 | User.current = nil | |
| 27 | @project = Project.find(1) | |
| 28 | @issue_query = IssueQuery.create!(:name => "test", :user_id => 1, :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => @project) | |
| 29 | end | |
| 30 | ||
| 31 | def test_initialize_for_should_return_new_record_object | |
| 32 | ProjectsDefaultQuery.where(:project_id => @project.id).destroy_all | |
| 33 | default_query = ProjectsDefaultQuery.initialize_for(@project.id) | |
| 34 | ||
| 35 | assert_equal ProjectsDefaultQuery, default_query.class | |
| 36 | assert_equal @project.id, default_query.project_id | |
| 37 | assert_equal true, default_query.new_record? | |
| 38 | end | |
| 39 | ||
| 40 | def test_initialize_for_should_return_presisted_object | |
| 41 | ProjectsDefaultQuery.create!(:project_id => @project.id) | |
| 42 | default_query = ProjectsDefaultQuery.initialize_for(@project.id) | |
| 43 | ||
| 44 | assert_equal ProjectsDefaultQuery, default_query.class | |
| 45 | assert_equal @project.id, default_query.project_id | |
| 46 | assert_equal true, default_query.persisted? | |
| 47 | end | |
| 48 | ||
| 49 | def test_validate_query_must_be_selectable | |
| 50 | set_language_if_valid 'en' | |
| 51 | default_query = ProjectsDefaultQuery.initialize_for(@project.id) | |
| 52 |  | |
| 53 | private_query = IssueQuery.create!(:name => "test", :user_id => 1, :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => @project) | |
| 54 | default_query.query_id = private_query.id | |
| 55 | assert_not default_query.valid? | |
| 56 | assert_includes default_query.errors[:query_id], "is invalid" | |
| 57 |  | |
| 58 | other_project_query = IssueQuery.create!(:name => "test", :user_id => 1, :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => Project.find(2)) | |
| 59 | default_query.query_id = other_project_query.id | |
| 60 | assert_not default_query.valid? | |
| 61 | assert_includes default_query.errors[:query_id], "is invalid" | |
| 62 | end | |
| 63 | ||
| 64 | def test_query_should_return_issue_query_object_when_associated_query_exist_and_visibility_public | |
| 65 | default_query = ProjectsDefaultQuery.create!(:project_id => @project.id, :query_id => @issue_query.id) | |
| 66 | ||
| 67 | assert_equal @issue_query, default_query.query | |
| 68 | ||
| 69 | @issue_query.update_attribute :project_id, nil | |
| 70 | default_query.reload | |
| 71 | ||
| 72 | assert_equal @issue_query, default_query.query | |
| 73 | end | |
| 74 | ||
| 75 | def test_query_should_return_nil_when_associated_query_exist_and_visibility_private | |
| 76 | default_query = ProjectsDefaultQuery.create!(:project_id => @project.id, :query_id => @issue_query.id) | |
| 77 |  | |
| 78 | @issue_query.update_attribute :visibility, IssueQuery::VISIBILITY_PRIVATE | |
| 79 | default_query.reload | |
| 80 | ||
| 81 | assert_nil default_query.query | |
| 82 | end | |
| 83 | ||
| 84 | def test_query_should_return_nil_when_associated_query_exist_and_difarent_project_query | |
| 85 | default_query = ProjectsDefaultQuery.create!(:project_id => @project.id, :query_id => @issue_query.id) | |
| 86 | ||
| 87 | @issue_query.update_attribute :project_id, 2 | |
| 88 | default_query.reload | |
| 89 | ||
| 90 | assert_nil default_query.query | |
| 91 | end | |
| 92 | ||
| 93 | def test_query_should_return_nil_when_associated_query_does_not_exist | |
| 94 | default_query = ProjectsDefaultQuery.create!(:project_id => @project.id, :query_id => @issue_query.id) | |
| 95 | ||
| 96 | @issue_query.destroy! | |
| 97 | default_query.reload | |
| 98 | ||
| 99 | assert_nil default_query.query | |
| 100 | end | |
| 101 | end | |
| test/unit/query_test.rb | ||
|---|---|---|
| 999 | 999 | end | 
| 1000 | 1000 | end | 
| 1001 | 1001 | |
| 1002 | def test_available_query_should_return_true_when_public_query_existed_on_project | |
| 1003 | project = Project.find(1) | |
| 1004 | IssueQuery.only_public.destroy_all | |
| 1005 | public_issue_query_on_project = IssueQuery.create!(:name => "q", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => project) | |
| 1006 | public_issue_query_nil_project = IssueQuery.create!(:name => "q", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => nil) | |
| 1007 | assert IssueQuery.available_query?(project.id, public_issue_query_on_project.id) | |
| 1008 | assert IssueQuery.available_query?(project.id, public_issue_query_nil_project.id) | |
| 1009 | end | |
| 1010 | ||
| 1011 | def test_available_query_should_return_false_when_public_query_does_not_existed_on_project | |
| 1012 | project = Project.find(1) | |
| 1013 | IssueQuery.only_public.destroy_all | |
| 1014 | private_issue_query_on_project = IssueQuery.create!(:name => "q", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => project) | |
| 1015 | public_issue_query_on_other = IssueQuery.create!(:name => "q", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => Project.find(2)) | |
| 1016 | assert_equal false, IssueQuery.available_query?(project.id, private_issue_query_on_project.id) | |
| 1017 | assert_equal false, IssueQuery.available_query?(project.id, public_issue_query_on_other.id) | |
| 1018 | end | |
| 1019 | ||
| 1002 | 1020 | def test_default_columns | 
| 1003 | 1021 | q = IssueQuery.new | 
| 1004 | 1022 | assert q.columns.any? |