Feature #29482 » 0001-Filters-for-Projects-page.patch
| app/controllers/projects_controller.rb | ||
|---|---|---|
| 33 | 33 |
helper :custom_fields |
| 34 | 34 |
helper :issues |
| 35 | 35 |
helper :queries |
| 36 |
include QueriesHelper |
|
| 36 | 37 |
helper :repositories |
| 37 | 38 |
helper :members |
| 38 | 39 |
helper :trackers |
| ... | ... | |
| 44 | 45 |
return |
| 45 | 46 |
end |
| 46 | 47 | |
| 47 |
scope = Project.visible.sorted |
|
| 48 |
retrieve_project_query |
|
| 49 |
scope = project_scope |
|
| 48 | 50 | |
| 49 | 51 |
respond_to do |format| |
| 50 | 52 |
format.html {
|
| 51 |
unless params[:closed] |
|
| 52 |
scope = scope.active |
|
| 53 |
end |
|
| 54 | 53 |
@projects = scope.to_a |
| 55 | 54 |
} |
| 56 | 55 |
format.api {
|
| ... | ... | |
| 257 | 256 |
# hide project in layout |
| 258 | 257 |
@project = nil |
| 259 | 258 |
end |
| 259 | ||
| 260 |
private |
|
| 261 | ||
| 262 |
# Returns the ProjectEntry scope for index |
|
| 263 |
def project_scope(options={})
|
|
| 264 |
@query.results_scope(options) |
|
| 265 |
end |
|
| 266 | ||
| 267 |
def retrieve_project_query |
|
| 268 |
retrieve_query(ProjectQuery, false) |
|
| 269 |
end |
|
| 260 | 270 |
end |
| app/controllers/queries_controller.rb | ||
|---|---|---|
| 126 | 126 |
@query.column_names = nil if params[:default_columns] |
| 127 | 127 |
@query.sort_criteria = (params[:query] && params[:query][:sort_criteria]) || @query.sort_criteria |
| 128 | 128 |
@query.name = params[:query] && params[:query][:name] |
| 129 |
if User.current.allowed_to?(:manage_public_queries, @query.project) || User.current.admin? |
|
| 129 |
if User.current.allowed_to?(:manage_public_queries, @query.project) || User.current.admin? || (@query.type == 'ProjectQuery' && User.current.allowed_to?(:manage_public_queries, @query.project, :global => true))
|
|
| 130 | 130 |
@query.visibility = (params[:query] && params[:query][:visibility]) || Query::VISIBILITY_PRIVATE |
| 131 | 131 |
@query.role_ids = params[:query] && params[:query][:role_ids] |
| 132 | 132 |
else |
| ... | ... | |
| 156 | 156 |
redirect_to _time_entries_path(@project, nil, options) |
| 157 | 157 |
end |
| 158 | 158 | |
| 159 |
def redirect_to_project_query(options) |
|
| 160 |
redirect_to projects_path(options) |
|
| 161 |
end |
|
| 162 | ||
| 159 | 163 |
# Returns the Query subclass, IssueQuery by default |
| 160 | 164 |
# for compatibility with previous behaviour |
| 161 | 165 |
def query_class |
| app/models/project_query.rb | ||
|---|---|---|
| 1 |
# frozen_string_literal: true |
|
| 2 | ||
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2017 Jean-Philippe Lang |
|
| 5 |
# |
|
| 6 |
# This program is free software; you can redistribute it and/or |
|
| 7 |
# modify it under the terms of the GNU General Public License |
|
| 8 |
# as published by the Free Software Foundation; either version 2 |
|
| 9 |
# of the License, or (at your option) any later version. |
|
| 10 |
# |
|
| 11 |
# This program is distributed in the hope that it will be useful, |
|
| 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 14 |
# GNU General Public License for more details. |
|
| 15 |
# |
|
| 16 |
# You should have received a copy of the GNU General Public License |
|
| 17 |
# along with this program; if not, write to the Free Software |
|
| 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 19 | ||
| 20 |
class ProjectQuery < Query |
|
| 21 | ||
| 22 |
self.queried_class = Project |
|
| 23 | ||
| 24 |
self.available_columns = [] |
|
| 25 | ||
| 26 |
def initialize(attributes=nil, *args) |
|
| 27 |
super attributes |
|
| 28 |
self.filters ||= { 'status' => {:operator => "=", :values => ['1']} }
|
|
| 29 |
end |
|
| 30 | ||
| 31 |
def initialize_available_filters |
|
| 32 |
add_available_filter "status", |
|
| 33 |
:type => :list, :values => lambda { project_statuses_values }
|
|
| 34 |
add_available_filter "name", :type => :text |
|
| 35 |
add_available_filter "description", :type => :text |
|
| 36 |
add_available_filter "is_public", |
|
| 37 |
:type => :list, |
|
| 38 |
:values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]] |
|
| 39 |
add_available_filter "created_on", :type => :date_past |
|
| 40 |
end |
|
| 41 | ||
| 42 |
def available_columns |
|
| 43 |
[] |
|
| 44 |
end |
|
| 45 | ||
| 46 |
def base_scope |
|
| 47 |
Project.visible.where(statement) |
|
| 48 |
end |
|
| 49 | ||
| 50 |
def results_scope(options={})
|
|
| 51 |
order_option = [group_by_sort_order, (options[:order] || sort_clause)].flatten.reject(&:blank?) |
|
| 52 | ||
| 53 |
order_option << "#{Project.table_name}.id ASC"
|
|
| 54 |
scope = base_scope. |
|
| 55 |
order(order_option). |
|
| 56 |
joins(joins_for_order_statement(order_option.join(',')))
|
|
| 57 | ||
| 58 |
if has_custom_field_column? |
|
| 59 |
scope = scope.preload(:custom_values) |
|
| 60 |
end |
|
| 61 | ||
| 62 |
if has_column?(:parent_id) |
|
| 63 |
scope = scope.preload(:parent) |
|
| 64 |
end |
|
| 65 | ||
| 66 |
scope |
|
| 67 |
end |
|
| 68 |
end |
|
| app/models/query.rb | ||
|---|---|---|
| 716 | 716 |
end |
| 717 | 717 | |
| 718 | 718 |
def columns |
| 719 |
return [] if available_columns.empty? |
|
| 719 | 720 |
# preserve the column_names order |
| 720 | 721 |
cols = (has_default_columns? ? default_columns_names : column_names).collect do |name| |
| 721 | 722 |
available_columns.find { |col| col.name == name }
|
| app/views/projects/_sidebar.html.erb | ||
|---|---|---|
| 1 |
<%= render_sidebar_queries(ProjectQuery, @project) %> |
|
| 2 |
<%= call_hook(:view_projects_sidebar_queries_bottom) %> |
|
| app/views/projects/index.html.erb | ||
|---|---|---|
| 1 |
<% content_for :header_tags do %> |
|
| 2 |
<%= auto_discovery_link_tag(:atom, {:action => 'index', :format => 'atom', :key => User.current.rss_key}) %>
|
|
| 3 |
<% end %> |
|
| 4 | ||
| 5 | 1 |
<div class="contextual"> |
| 6 | 2 |
<%= form_tag({}, :method => :get) do %>
|
| 7 |
<label for="closed"> |
|
| 8 |
<%= check_box_tag 'closed', 1, params[:closed], :onchange => "this.form.submit();" %> |
|
| 9 |
<%= l(:label_show_closed_projects) %> |
|
| 10 |
</label> |
|
| 11 | 3 |
<% end %> |
| 12 | 4 |
<%= render_project_action_links %> |
| 13 | 5 |
</div> |
| 14 | 6 | |
| 15 |
<h2><%= l(:label_project_plural) %></h2>
|
|
| 7 |
<h2><%= @query.new_record? ? l(:label_project_plural) : @query.name %></h2>
|
|
| 16 | 8 | |
| 17 |
<div id="projects-index"> |
|
| 18 |
<%= render_project_hierarchy(@projects) %> |
|
| 19 |
</div> |
|
| 9 |
<%= form_tag(projects_path(@project, nil), :method => :get, :id => 'query_form') do %> |
|
| 10 |
<%= render :partial => 'queries/query_form' %> |
|
| 11 |
<% end %> |
|
| 12 | ||
| 13 |
<% if @query.valid? %> |
|
| 14 |
<% if @projects.empty? %> |
|
| 15 |
<p class="nodata"><%= l(:label_no_data) %></p> |
|
| 16 |
<% else %> |
|
| 17 |
<div id="projects-index"> |
|
| 18 |
<%= render_project_hierarchy(@projects) %> |
|
| 19 |
</div> |
|
| 20 |
<% end %> |
|
| 21 |
<% end %> |
|
| 20 | 22 | |
| 21 | 23 |
<% if User.current.logged? %> |
| 22 | 24 |
<p style="text-align:right;"> |
| ... | ... | |
| 24 | 26 |
</p> |
| 25 | 27 |
<% end %> |
| 26 | 28 | |
| 29 |
<% content_for :sidebar do %> |
|
| 30 |
<%= render :partial => 'projects/sidebar' %> |
|
| 31 |
<% end %> |
|
| 32 | ||
| 27 | 33 |
<% other_formats_links do |f| %> |
| 28 | 34 |
<%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %>
|
| 29 | 35 |
<% end %> |
| app/views/queries/_form.html.erb | ||
|---|---|---|
| 7 | 7 |
<p><label for="query_name"><%=l(:field_name)%></label> |
| 8 | 8 |
<%= text_field 'query', 'name', :size => 80 %></p> |
| 9 | 9 | |
| 10 |
<% if User.current.admin? || User.current.allowed_to?(:manage_public_queries, @query.project) %> |
|
| 10 |
<% if User.current.admin? || |
|
| 11 |
User.current.allowed_to?(:manage_public_queries, @query.project) || |
|
| 12 |
@query.type == 'ProjectQuery' && User.current.allowed_to?(:manage_public_queries, @query.project, :global => true) %> |
|
| 11 | 13 |
<p><label><%=l(:field_visible)%></label> |
| 12 | 14 |
<label class="block"><%= radio_button 'query', 'visibility', Query::VISIBILITY_PRIVATE %> <%= l(:label_visibility_private) %></label> |
| 13 | 15 |
<label class="block"><%= radio_button 'query', 'visibility', Query::VISIBILITY_PUBLIC %> <%= l(:label_visibility_public) %></label> |
| 14 |
<label class="block"><%= radio_button 'query', 'visibility', Query::VISIBILITY_ROLES %> <%= l(:label_visibility_roles) %>:</label> |
|
| 15 |
<% Role.givable.sorted.each do |role| %> |
|
| 16 |
<label class="block role-visibility"><%= check_box_tag 'query[role_ids][]', role.id, @query.roles.include?(role), :id => nil %> <%= role.name %></label> |
|
| 16 |
<% unless @query.type == 'ProjectQuery' %> |
|
| 17 |
<label class="block"><%= radio_button 'query', 'visibility', Query::VISIBILITY_ROLES %> <%= l(:label_visibility_roles) %>:</label> |
|
| 18 |
<% Role.givable.sorted.each do |role| %> |
|
| 19 |
<label class="block role-visibility"><%= check_box_tag 'query[role_ids][]', role.id, @query.roles.include?(role), :id => nil %> <%= role.name %></label> |
|
| 20 |
<% end %> |
|
| 21 |
<%= hidden_field_tag 'query[role_ids][]', '' %> |
|
| 17 | 22 |
<% end %> |
| 18 |
<%= hidden_field_tag 'query[role_ids][]', '' %> |
|
| 19 | 23 |
</p> |
| 20 | 24 |
<% end %> |
| 21 | 25 | |
| 22 |
<p><label for="query_is_for_all"><%=l(:field_is_for_all)%></label> |
|
| 23 |
<%= check_box_tag 'query_is_for_all', 1, @query.project.nil?, :class => (User.current.admin? ? '' : 'disable-unless-private') %></p> |
|
| 26 |
<% unless @query.type == 'ProjectQuery' %> |
|
| 27 |
<p><label for="query_is_for_all"><%=l(:field_is_for_all)%></label> |
|
| 28 |
<%= check_box_tag 'query_is_for_all', 1, @query.project.nil?, :class => (User.current.admin? ? '' : 'disable-unless-private') %></p> |
|
| 29 |
<% end %> |
|
| 24 | 30 | |
| 25 | 31 |
<fieldset id="options"><legend><%= l(:label_options) %></legend> |
| 26 | 32 |
<p><label for="query_default_columns"><%=l(:label_default_columns)%></label> |
| ... | ... | |
| 28 | 34 |
:data => {:disables => "#columns, .block_columns input"} %></p>
|
| 29 | 35 | |
| 30 | 36 |
<% unless params[:gantt] %> |
| 31 |
<p><label for="query_group_by"><%= l(:field_group_by) %></label> |
|
| 32 |
<%= select 'query', 'group_by', @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]}, :include_blank => true %></p>
|
|
| 37 |
<p><label for="query_group_by"><%= l(:field_group_by) %></label>
|
|
| 38 |
<%= select 'query', 'group_by', @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]}, :include_blank => true %></p>
|
|
| 33 | 39 | |
| 34 |
<p class="block_columns"><label><%= l(:button_show) %></label> |
|
| 35 |
<%= available_block_columns_tags(@query) %></p> |
|
| 40 |
<% unless @query.available_block_columns.empty? %> |
|
| 41 |
<p class="block_columns"><label><%= l(:button_show) %></label> |
|
| 42 |
<%= available_block_columns_tags(@query) %></p> |
|
| 43 |
<% end %> |
|
| 36 | 44 | |
| 37 |
<p><label><%= l(:label_total_plural) %></label> |
|
| 38 |
<%= available_totalable_columns_tags(@query) %></p> |
|
| 45 |
<% unless @query.available_totalable_columns.empty? %> |
|
| 46 |
<p class="totable_columns"><label><%= l(:label_total_plural) %></label> |
|
| 47 |
<%= available_totalable_columns_tags(@query) %></p> |
|
| 48 |
<% end %> |
|
| 39 | 49 |
<% else %> |
| 40 | 50 |
<p><label><%= l(:button_show) %></label> |
| 41 | 51 |
<%= hidden_field_tag 'query[draw_relations]', '0' %> |
| ... | ... | |
| 54 | 64 |
</fieldset> |
| 55 | 65 | |
| 56 | 66 |
<% unless params[:gantt] %> |
| 57 |
<fieldset><legend><%= l(:label_sort) %></legend> |
|
| 67 |
<fieldset id="sort"><legend><%= l(:label_sort) %></legend>
|
|
| 58 | 68 |
<% 3.times do |i| %> |
| 59 | 69 |
<%= content_tag(:span, "#{i+1}:", :class => 'query_sort_criteria_count')%>
|
| 60 | 70 |
<%= label_tag "query_sort_criteria_attribute_" + i.to_s, |
| app/views/queries/_query_form.html.erb | ||
|---|---|---|
| 11 | 11 |
</div> |
| 12 | 12 |
</fieldset> |
| 13 | 13 | |
| 14 |
<fieldset id="options" class="collapsible collapsed"> |
|
| 15 |
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_options) %></legend> |
|
| 16 |
<div style="display: none;"> |
|
| 17 |
<table> |
|
| 18 |
<tr> |
|
| 19 |
<td class="field"><%= l(:field_column_names) %></td> |
|
| 20 |
<td><%= render_query_columns_selection(@query) %></td> |
|
| 21 |
</tr> |
|
| 22 |
<% if @query.groupable_columns.any? %> |
|
| 23 |
<tr> |
|
| 24 |
<td class="field"><label for='group_by'><%= l(:field_group_by) %></label></td> |
|
| 25 |
<td><%= group_by_column_select_tag(@query) %></td> |
|
| 26 |
</tr> |
|
| 27 |
<% end %> |
|
| 28 |
<% if @query.available_block_columns.any? %> |
|
| 29 |
<tr> |
|
| 30 |
<td class="field"><%= l(:button_show) %></td> |
|
| 31 |
<td><%= available_block_columns_tags(@query) %></td> |
|
| 32 |
</tr> |
|
| 33 |
<% end %> |
|
| 34 |
<% if @query.available_totalable_columns.any? %> |
|
| 35 |
<tr> |
|
| 36 |
<td><%= l(:label_total_plural) %></td> |
|
| 37 |
<td><%= available_totalable_columns_tags(@query) %></td> |
|
| 38 |
</tr> |
|
| 39 |
<% end %> |
|
| 40 |
</table> |
|
| 41 |
</div> |
|
| 42 |
</fieldset> |
|
| 14 |
<% if @query.available_columns.any? %> |
|
| 15 |
<fieldset id="options" class="collapsible collapsed"> |
|
| 16 |
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_options) %></legend> |
|
| 17 |
<div style="display: none;"> |
|
| 18 |
<table> |
|
| 19 |
<% if @query.available_columns.any? %> |
|
| 20 |
<tr> |
|
| 21 |
<td class="field"><%= l(:field_column_names) %></td> |
|
| 22 |
<td><%= render_query_columns_selection(@query) %></td> |
|
| 23 |
</tr> |
|
| 24 |
<% end %> |
|
| 25 |
<% if @query.groupable_columns.any? %> |
|
| 26 |
<tr> |
|
| 27 |
<td class="field"><label for='group_by'><%= l(:field_group_by) %></label></td> |
|
| 28 |
<td><%= group_by_column_select_tag(@query) %></td> |
|
| 29 |
</tr> |
|
| 30 |
<% end %> |
|
| 31 |
<% if @query.available_block_columns.any? %> |
|
| 32 |
<tr> |
|
| 33 |
<td class="field"><%= l(:button_show) %></td> |
|
| 34 |
<td><%= available_block_columns_tags(@query) %></td> |
|
| 35 |
</tr> |
|
| 36 |
<% end %> |
|
| 37 |
<% if @query.available_totalable_columns.any? %> |
|
| 38 |
<tr> |
|
| 39 |
<td><%= l(:label_total_plural) %></td> |
|
| 40 |
<td><%= available_totalable_columns_tags(@query) %></td> |
|
| 41 |
</tr> |
|
| 42 |
<% end %> |
|
| 43 |
</table> |
|
| 44 |
</div> |
|
| 45 |
</fieldset> |
|
| 46 |
<% end %> |
|
| 43 | 47 |
</div> |
| 44 | 48 | |
| 45 | 49 |
<p class="buttons"> |
| config/locales/en.yml | ||
|---|---|---|
| 977 | 977 |
label_completed_versions: Completed versions |
| 978 | 978 |
label_search_for_watchers: Search for watchers to add |
| 979 | 979 |
label_session_expiration: Session expiration |
| 980 |
label_show_closed_projects: View closed projects |
|
| 981 | 980 |
label_status_transitions: Status transitions |
| 982 | 981 |
label_fields_permissions: Fields permissions |
| 983 | 982 |
label_readonly: Read-only |
| public/stylesheets/application.css | ||
|---|---|---|
| 649 | 649 |
-moz-column-count: auto; |
| 650 | 650 |
-moz-column-width: 400px; |
| 651 | 651 |
-moz-column-gap : 0.5rem; |
| 652 |
margin-bottom: 1.2em; |
|
| 652 | 653 |
} |
| 653 | 654 |
#projects-index li.root ul.projects { border-left: 3px solid #e0e0e0; padding-left:1em;}
|
| 654 | 655 |
#projects-index ul.projects li.root {
|
| test/functional/queries_controller_test.rb | ||
|---|---|---|
| 69 | 69 |
assert_response 404 |
| 70 | 70 |
end |
| 71 | 71 | |
| 72 |
def test_new_should_not_render_show_inline_columns_option_for_query_without_available_inline_columns |
|
| 73 |
@request.session[:user_id] = 1 |
|
| 74 |
get :new, :params => {
|
|
| 75 |
:type => 'ProjectQuery' |
|
| 76 |
} |
|
| 77 | ||
| 78 |
assert_response :success |
|
| 79 |
assert_select 'p[class=?]', 'block_columns', 0 |
|
| 80 |
end |
|
| 81 | ||
| 82 |
def test_new_should_not_render_show_totals_option_for_query_without_totable_columns |
|
| 83 |
@request.session[:user_id] = 1 |
|
| 84 |
get :new, :params => {
|
|
| 85 |
:type => 'ProjectQuery' |
|
| 86 |
} |
|
| 87 | ||
| 88 |
assert_response :success |
|
| 89 |
assert_select 'p[class=?]', 'totables_columns', 0 |
|
| 90 |
end |
|
| 91 | ||
| 72 | 92 |
def test_new_time_entry_query |
| 73 | 93 |
@request.session[:user_id] = 2 |
| 74 | 94 |
get :new, :params => {
|
| ... | ... | |
| 77 | 97 |
} |
| 78 | 98 |
assert_response :success |
| 79 | 99 |
assert_select 'input[name=type][value=?]', 'TimeEntryQuery' |
| 100 |
assert_select 'p[class=?]', 'totable_columns', 1 |
|
| 101 |
assert_select 'p[class=?]', 'block_columns', 0 |
|
| 102 |
end |
|
| 103 | ||
| 104 |
def test_new_project_query_for_projects |
|
| 105 |
@request.session[:user_id] = 1 |
|
| 106 |
get :new, :params => {
|
|
| 107 |
:type => 'ProjectQuery' |
|
| 108 |
} |
|
| 109 |
assert_response :success |
|
| 110 |
assert_select 'input[name=type][value=?]', 'ProjectQuery' |
|
| 111 |
end |
|
| 112 | ||
| 113 |
def test_new_project_query_should_not_render_roles_visibility_options |
|
| 114 |
@request.session[:user_id] = 1 |
|
| 115 |
get :new, :params => {
|
|
| 116 |
:type => 'ProjectQuery' |
|
| 117 |
} |
|
| 118 | ||
| 119 |
assert_response :success |
|
| 120 |
assert_select 'input[id=?]', 'query_visibility_0', 1 |
|
| 121 |
assert_select 'input[id=?]', 'query_visibility_2', 1 |
|
| 122 |
assert_select 'input[id=?]', 'query_visibility_1', 0 |
|
| 123 |
end |
|
| 124 | ||
| 125 |
def test_new_project_query_should_not_render_for_all_projects_option |
|
| 126 |
@request.session[:user_id] = 1 |
|
| 127 |
get :new, :params => {
|
|
| 128 |
:type => 'ProjectQuery' |
|
| 129 |
} |
|
| 130 | ||
| 131 |
assert_response :success |
|
| 132 |
assert_select 'input[name=?]', 'for_all_projects', 0 |
|
| 80 | 133 |
end |
| 81 | 134 | |
| 82 | 135 |
def test_new_time_entry_query_should_select_spent_time_from_main_menu |
| ... | ... | |
| 441 | 494 |
assert q.valid? |
| 442 | 495 |
end |
| 443 | 496 | |
| 497 |
def test_create_public_project_query |
|
| 498 |
@request.session[:user_id] = 2 |
|
| 499 | ||
| 500 |
q = new_record(ProjectQuery) do |
|
| 501 |
post :create, :params => {
|
|
| 502 |
:type => 'ProjectQuery', |
|
| 503 |
:default_columns => '1', |
|
| 504 |
:f => ["status"], |
|
| 505 |
:op => {
|
|
| 506 |
"status" => "=" |
|
| 507 |
}, |
|
| 508 |
:v => {
|
|
| 509 |
"status" => ['1'] |
|
| 510 |
}, |
|
| 511 |
:query => {
|
|
| 512 |
"name" => "test_new_project_public_query", "visibility" => "2" |
|
| 513 |
} |
|
| 514 |
} |
|
| 515 |
end |
|
| 516 | ||
| 517 |
assert_redirected_to :controller => 'projects', :action => 'index', :query_id => q.id |
|
| 518 | ||
| 519 |
assert q.is_public? |
|
| 520 |
assert q.valid? |
|
| 521 |
end |
|
| 522 | ||
| 444 | 523 |
def test_edit_global_public_query |
| 445 | 524 |
@request.session[:user_id] = 1 |
| 446 | 525 |
get :edit, :params => {
|
| test/unit/project_query_test.rb | ||
|---|---|---|
| 1 |
# frozen_string_literal: true |
|
| 2 | ||
| 3 |
# Redmine - project management software |
|
| 4 |
# Copyright (C) 2006-2017 Jean-Philippe Lang |
|
| 5 |
# |
|
| 6 |
# This program is free software; you can redistribute it and/or |
|
| 7 |
# modify it under the terms of the GNU General Public License |
|
| 8 |
# as published by the Free Software Foundation; either version 2 |
|
| 9 |
# of the License, or (at your option) any later version. |
|
| 10 |
# |
|
| 11 |
# This program is distributed in the hope that it will be useful, |
|
| 12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 14 |
# GNU General Public License for more details. |
|
| 15 |
# |
|
| 16 |
# You should have received a copy of the GNU General Public License |
|
| 17 |
# along with this program; if not, write to the Free Software |
|
| 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 19 | ||
| 20 |
require File.expand_path('../../test_helper', __FILE__)
|
|
| 21 | ||
| 22 |
class ProjectQueryTest < ActiveSupport::TestCase |
|
| 23 |
fixtures :projects, :users, |
|
| 24 |
:members, :roles, :member_roles, |
|
| 25 |
:issue_categories, :enumerations, |
|
| 26 |
:groups_users, |
|
| 27 |
:enabled_modules |
|
| 28 | ||
| 29 |
def test_filter_values_be_arrays |
|
| 30 |
q = ProjectQuery.new |
|
| 31 |
assert_nil q.project |
|
| 32 | ||
| 33 |
q.available_filters.each do |name, filter| |
|
| 34 |
values = filter.values |
|
| 35 |
assert (values.nil? || values.is_a?(Array)), |
|
| 36 |
"#values for #{name} filter returned a #{values.class.name}"
|
|
| 37 |
end |
|
| 38 |
end |
|
| 39 | ||
| 40 |
def test_project_statuses_filter_should_return_project_statuses |
|
| 41 |
query = ProjectQuery.new(:name => '_') |
|
| 42 |
query.filters = {'status' => {:operator => '=', :values => []}}
|
|
| 43 | ||
| 44 |
values = query.available_filters['status'][:values] |
|
| 45 |
assert_equal ['active', 'closed'], values.map(&:first) |
|
| 46 |
assert_equal ['1', '5'], values.map(&:second) |
|
| 47 | ||
| 48 |
end |
|
| 49 |
end |
|