Merge pull request #5156 from opf/feature/adapt_query_representer
adapt query representerpull/5177/head
commit
596e82ff2f
@ -0,0 +1,167 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
class ParseQueryParamsService |
||||
def call(params) |
||||
parsed_params = {} |
||||
|
||||
parsed_params[:group_by] = group_by_from_params(params) |
||||
|
||||
error_result = with_service_error_on_json_parse_error do |
||||
parsed_params[:filters] = filters_from_params(params) |
||||
|
||||
parsed_params[:sort_by] = sort_by_from_params(params) |
||||
end |
||||
return error_result if error_result |
||||
|
||||
parsed_params[:columns] = columns_from_params(params) |
||||
|
||||
parsed_params[:display_sums] = sums_from_params(params) |
||||
|
||||
ServiceResult.new(success: true, |
||||
result: without_empty(parsed_params)) |
||||
end |
||||
|
||||
def group_by_from_params(params) |
||||
convert_attribute(params[:group_by] || params[:groupBy] || params[:g]) |
||||
end |
||||
|
||||
def sort_by_from_params(params) |
||||
return unless params[:sortBy] |
||||
|
||||
parse_sorting_from_json(params[:sortBy]) |
||||
end |
||||
|
||||
# Expected format looks like: |
||||
# [ |
||||
# { |
||||
# "filtered_field_name": { |
||||
# "operator": "a name for a filter operation", |
||||
# "values": ["values", "for the", "operation"] |
||||
# } |
||||
# }, |
||||
# { /* more filters if needed */} |
||||
# ] |
||||
def filters_from_params(params) |
||||
return unless params[:filters] |
||||
|
||||
filters = JSON.parse(params[:filters]) |
||||
filters.each_with_object([]) do |filter, array| |
||||
attribute = filter.keys.first # there should only be one attribute per filter |
||||
operator = filter[attribute]['operator'] |
||||
values = filter[attribute]['values'] |
||||
ar_attribute = convert_filter_attribute attribute, append_id: true |
||||
|
||||
internal_representation = { field: ar_attribute, |
||||
operator: operator, |
||||
values: values } |
||||
array << internal_representation |
||||
end |
||||
end |
||||
|
||||
def columns_from_params(params) |
||||
columns = params[:columns] || params[:c] || params[:column_names] |
||||
|
||||
return unless columns |
||||
|
||||
columns.map do |column| |
||||
convert_attribute(column) |
||||
end |
||||
end |
||||
|
||||
def sums_from_params(params) |
||||
if params[:showSums] == 'true' |
||||
true |
||||
elsif params[:showSums] == 'false' |
||||
false |
||||
end |
||||
end |
||||
|
||||
## |
||||
# Maps given field names coming from the frontend to the actual names |
||||
# as expected by the query. This works slightly different to what happens |
||||
# in #column_names_from_params. For instance while they column name is |
||||
# :type the expected field name is :type_id. |
||||
# |
||||
# Examples: |
||||
# * status => status_id |
||||
# * progresssDone => done_ratio |
||||
# * assigned => assigned_to |
||||
# * customField1 => cf_1 |
||||
# |
||||
# @param query [Query] Query for which to get the correct field names. |
||||
# @param field_names [Array] Field names as read from the params. |
||||
# @return [Array] Returns a list of fixed field names. The list may contain nil values |
||||
# for fields which could not be found. |
||||
def fix_field_array(field_names) |
||||
return [] if field_names.nil? |
||||
|
||||
field_names |
||||
.map { |name| convert_attribute name, append_id: true } |
||||
end |
||||
|
||||
def parse_sorting_from_json(json) |
||||
JSON.parse(json).map do |order| |
||||
attribute, direction = if order.is_a?(Array) |
||||
[order.first, order.last] |
||||
elsif order.is_a?(String) |
||||
order.split(':') |
||||
end |
||||
|
||||
[convert_attribute(attribute), direction] |
||||
end |
||||
end |
||||
|
||||
def convert_attribute(attribute, append_id: false) |
||||
::API::Utilities::WpPropertyNameConverter.to_ar_name(attribute, |
||||
refer_to_ids: append_id) |
||||
end |
||||
|
||||
def convert_filter_attribute(attribute, append_id: false) |
||||
::API::Utilities::QueryFiltersNameConverter.to_ar_name(attribute, |
||||
refer_to_ids: append_id) |
||||
end |
||||
|
||||
def with_service_error_on_json_parse_error |
||||
yield |
||||
|
||||
nil |
||||
rescue ::JSON::ParserError => error |
||||
result = ServiceResult.new |
||||
result.errors.add(:base, error.message) |
||||
return result |
||||
end |
||||
|
||||
def without_empty(hash) |
||||
hash.select { |_, v| v.present? || v == false } |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,55 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
class UpdateQueryFromV3ParamsService |
||||
def initialize(query, user) |
||||
self.query = query |
||||
self.current_user = user |
||||
end |
||||
|
||||
def call(params) |
||||
parsed = ::API::V3::ParseQueryParamsService |
||||
.new |
||||
.call(params) |
||||
|
||||
if parsed.success? |
||||
::UpdateQueryFromParamsService |
||||
.new(query, current_user) |
||||
.call(parsed.result) |
||||
else |
||||
parsed |
||||
end |
||||
end |
||||
|
||||
attr_accessor :query, |
||||
:current_user |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,49 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
class WorkPackageCollectionFromQueryParamsService |
||||
def initialize(user) |
||||
self.current_user = user |
||||
end |
||||
|
||||
def call(params = {}) |
||||
query = Query.new(name: '_', project: params[:project], sort_criteria: [['parent', 'desc']]) |
||||
|
||||
WorkPackageCollectionFromQueryService |
||||
.new(query, current_user) |
||||
.call(params) |
||||
end |
||||
|
||||
private |
||||
|
||||
attr_accessor :current_user |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,155 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
class WorkPackageCollectionFromQueryService |
||||
include Utilities::PathHelper |
||||
|
||||
def initialize(query, user) |
||||
self.query = query |
||||
self.current_user = user |
||||
end |
||||
|
||||
def call(params = {}) |
||||
update = UpdateQueryFromV3ParamsService |
||||
.new(query, current_user) |
||||
.call(params) |
||||
|
||||
if update.success? |
||||
representer = results_to_representer(params) |
||||
|
||||
ServiceResult.new(success: true, result: representer) |
||||
else |
||||
update |
||||
end |
||||
end |
||||
|
||||
private |
||||
|
||||
def results_to_representer(params) |
||||
collection_representer(query.results.sorted_work_packages, |
||||
params: params, |
||||
project: query.project, |
||||
groups: generate_groups, |
||||
sums: generate_total_sums) |
||||
end |
||||
|
||||
attr_accessor :query, |
||||
:current_user |
||||
|
||||
def representer |
||||
::API::V3::WorkPackages::WorkPackageCollectionRepresenter |
||||
end |
||||
|
||||
def calculate_resulting_params(provided_params) |
||||
calculate_default_params |
||||
.merge(provided_params.slice('offset', 'pageSize').symbolize_keys) |
||||
end |
||||
|
||||
def calculate_default_params |
||||
::API::V3::Queries::QueryParamsRepresenter |
||||
.new(query) |
||||
.to_h |
||||
end |
||||
|
||||
def generate_groups |
||||
return unless query.grouped? |
||||
|
||||
results = query.results |
||||
|
||||
results.work_package_count_by_group.map do |group, count| |
||||
sums = if query.display_sums? |
||||
format_query_sums results.all_sums_for_group(group) |
||||
end |
||||
|
||||
::API::Decorators::AggregationGroup.new(group, count, sums: sums) |
||||
end |
||||
end |
||||
|
||||
def generate_total_sums |
||||
return unless query.display_sums? |
||||
|
||||
format_query_sums query.results.all_total_sums |
||||
end |
||||
|
||||
def format_query_sums(sums) |
||||
OpenStruct.new(format_column_keys(sums)) |
||||
end |
||||
|
||||
def format_column_keys(hash_by_column) |
||||
::Hash[ |
||||
hash_by_column.map do |column, value| |
||||
match = /cf_(\d+)/.match(column.name.to_s) |
||||
|
||||
column_name = if match |
||||
"custom_field_#{match[1]}" |
||||
else |
||||
column.name.to_s |
||||
end |
||||
|
||||
[column_name, value] |
||||
end |
||||
] |
||||
end |
||||
|
||||
def collection_representer(work_packages, params:, project:, groups:, sums:) |
||||
resulting_params = calculate_resulting_params(params) |
||||
|
||||
::API::V3::WorkPackages::WorkPackageCollectionRepresenter.new( |
||||
work_packages, |
||||
self_link(project), |
||||
project: project, |
||||
query: resulting_params, |
||||
page: to_i_or_nil(resulting_params[:offset]), |
||||
per_page: to_i_or_nil(resulting_params[:pageSize]), |
||||
groups: groups, |
||||
total_sums: sums, |
||||
embed_schemas: true, |
||||
current_user: current_user |
||||
) |
||||
end |
||||
|
||||
def to_i_or_nil(value) |
||||
value ? value.to_i : nil |
||||
end |
||||
|
||||
def self_link(project) |
||||
if project |
||||
api_v3_paths.work_packages_by_project(project.id) |
||||
else |
||||
api_v3_paths.work_packages |
||||
end |
||||
end |
||||
|
||||
def convert_to_v3(attribute) |
||||
::API::Utilities::PropertyNameConverter.from_ar_name(attribute).to_sym |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,84 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class UpdateQueryFromParamsService |
||||
def initialize(query, user) |
||||
self.query = query |
||||
self.current_user = user |
||||
end |
||||
|
||||
def call(params) |
||||
apply_group_by(params) |
||||
|
||||
apply_sort_by(params) |
||||
|
||||
apply_filters(params) |
||||
|
||||
apply_columns(params) |
||||
|
||||
apply_sums(params) |
||||
|
||||
if query.valid? |
||||
ServiceResult.new(success: true, |
||||
result: query) |
||||
else |
||||
ServiceResult.new(errors: query.errors) |
||||
end |
||||
end |
||||
|
||||
private |
||||
|
||||
def apply_group_by(params) |
||||
query.group_by = params[:group_by] if params[:group_by] |
||||
end |
||||
|
||||
def apply_sort_by(params) |
||||
query.sort_criteria = params[:sort_by] if params[:sort_by] |
||||
end |
||||
|
||||
def apply_filters(params) |
||||
return unless params[:filters] |
||||
query.filters = [] |
||||
|
||||
params[:filters].each do |filter| |
||||
query.add_filter(filter[:field], filter[:operator], filter[:values]) |
||||
end |
||||
end |
||||
|
||||
def apply_columns(params) |
||||
query.column_names = params[:columns] if params[:columns] |
||||
end |
||||
|
||||
def apply_sums(params) |
||||
query.display_sums = params[:display_sums] if params[:display_sums] |
||||
end |
||||
|
||||
attr_accessor :query, |
||||
:current_user, |
||||
:params |
||||
end |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,38 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
# The sole purpose of this is to have a work package |
||||
# that is inexpensive to initialize by overriding the after_initialize hook |
||||
|
||||
module API |
||||
module Utilities |
||||
class PropertyNameConverterWorkPackageDummy < ::WorkPackage |
||||
def set_default_values; end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,47 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'api/utilities/property_name_converter' |
||||
require 'api/utilities/query_filters_name_converter_context' |
||||
|
||||
module API |
||||
module Utilities |
||||
class QueryFiltersNameConverter |
||||
class << self |
||||
def to_ar_name(attribute, refer_to_ids: false) |
||||
conversion_wp = ::API::Utilities::QueryFiltersNameConverterContext.new |
||||
|
||||
::API::Utilities::PropertyNameConverter.to_ar_name(attribute, |
||||
context: conversion_wp, |
||||
refer_to_ids: refer_to_ids) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,9 @@ |
||||
module API |
||||
module Utilities |
||||
class QueryFiltersNameConverterContext |
||||
def respond_to?(method_name, include_private = false) |
||||
Query.registered_filters.map(&:key).include?(method_name.to_sym) || super |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,47 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'api/utilities/property_name_converter' |
||||
require 'api/utilities/property_name_converter_work_package_dummy' |
||||
|
||||
module API |
||||
module Utilities |
||||
class WpPropertyNameConverter |
||||
class << self |
||||
def to_ar_name(attribute, refer_to_ids: false) |
||||
conversion_wp = ::API::Utilities::PropertyNameConverterWorkPackageDummy.new |
||||
|
||||
::API::Utilities::PropertyNameConverter.to_ar_name(attribute, |
||||
context: conversion_wp, |
||||
refer_to_ids: refer_to_ids) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,67 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module Columns |
||||
class QueryColumnRepresenter < ::API::Decorators::Single |
||||
self_link id_attribute: ->(*) { converted_name }, |
||||
title_getter: ->(*) { represented.caption } |
||||
|
||||
def initialize(model) |
||||
super(model, current_user: nil, embed_links: true) |
||||
end |
||||
|
||||
property :id, |
||||
exec_context: :decorator |
||||
|
||||
property :caption, |
||||
as: :name |
||||
|
||||
private |
||||
|
||||
def converted_name |
||||
convert_attribute(represented.name) |
||||
end |
||||
|
||||
alias :id :converted_name |
||||
|
||||
def _type |
||||
'QueryColumn' |
||||
end |
||||
|
||||
def convert_attribute(attribute) |
||||
::API::Utilities::PropertyNameConverter.from_ar_name(attribute) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,66 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module Columns |
||||
class QueryColumnsAPI < ::API::OpenProjectAPI |
||||
resource :columns do |
||||
helpers do |
||||
def convert_to_ar(attribute) |
||||
::API::Utilities::WpPropertyNameConverter.to_ar_name(attribute) |
||||
end |
||||
end |
||||
|
||||
params do |
||||
requires :id, desc: 'Column id' |
||||
end |
||||
|
||||
before do |
||||
authorize(:view_work_packages, global: true, user: current_user) |
||||
end |
||||
|
||||
route_param :id do |
||||
get do |
||||
ar_id = convert_to_ar(params[:id]).to_sym |
||||
column = Query.all_columns.detect { |candidate| candidate.name == ar_id } |
||||
|
||||
if column |
||||
::API::V3::Queries::Columns::QueryColumnRepresenter.new(column) |
||||
else |
||||
raise API::Errors::NotFound |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,46 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module Filters |
||||
class QueryFilterDecorator |
||||
def initialize(filter) |
||||
self.filter = filter |
||||
end |
||||
|
||||
private |
||||
|
||||
attr_accessor :filter |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,96 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module Filters |
||||
class QueryFilterInstanceRepresenter < ::API::Decorators::Single |
||||
def initialize(model) |
||||
super(model, current_user: nil, embed_links: true) |
||||
end |
||||
|
||||
link :filter do |
||||
{ |
||||
href: api_v3_paths.query_filter(converted_name), |
||||
title: name |
||||
} |
||||
end |
||||
|
||||
link :operator do |
||||
{ |
||||
href: api_v3_paths.query_operator(represented.operator), |
||||
title: operator_name |
||||
} |
||||
end |
||||
|
||||
links :values do |
||||
next unless represented.ar_object_filter? |
||||
|
||||
represented.value_objects.map do |value_object| |
||||
{ |
||||
href: api_v3_paths.send(value_object.class.name.downcase, value_object.id), |
||||
title: value_object.name |
||||
} |
||||
end |
||||
end |
||||
|
||||
property :name, |
||||
exec_context: :decorator |
||||
|
||||
property :values, |
||||
if: ->(*) { !ar_object_filter? }, |
||||
show_nil: true |
||||
|
||||
private |
||||
|
||||
def name |
||||
represented.human_name |
||||
end |
||||
|
||||
def _type |
||||
"#{converted_name.camelize}QueryFilter" |
||||
end |
||||
|
||||
def converted_name |
||||
convert_attribute(represented.name) |
||||
end |
||||
|
||||
def operator_name |
||||
I18n.t(represented.class.operators[represented.operator.to_sym]) |
||||
end |
||||
|
||||
def convert_attribute(attribute) |
||||
::API::Utilities::PropertyNameConverter.from_ar_name(attribute) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,65 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module Filters |
||||
class QueryFilterRepresenter < ::API::Decorators::Single |
||||
self_link id_attribute: ->(*) { converted_key }, |
||||
title_getter: ->(*) { represented.human_name }, |
||||
path: :query_filter |
||||
|
||||
def initialize(model) |
||||
super(model, current_user: nil, embed_links: true) |
||||
end |
||||
|
||||
property :id, |
||||
exec_context: :decorator |
||||
|
||||
private |
||||
|
||||
def converted_key |
||||
convert_attribute(represented.name) |
||||
end |
||||
|
||||
alias :id :converted_key |
||||
|
||||
def _type |
||||
'QueryFilter' |
||||
end |
||||
|
||||
def convert_attribute(attribute) |
||||
::API::Utilities::PropertyNameConverter.from_ar_name(attribute) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,71 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module Filters |
||||
class QueryFiltersAPI < ::API::OpenProjectAPI |
||||
resource :filters do |
||||
helpers do |
||||
def convert_to_ar(attribute) |
||||
::API::Utilities::QueryFiltersNameConverter.to_ar_name(attribute, |
||||
refer_to_ids: true) |
||||
end |
||||
end |
||||
|
||||
params do |
||||
requires :id, desc: 'Filter id' |
||||
end |
||||
|
||||
before do |
||||
authorize(:view_work_packages, global: true, user: current_user) |
||||
end |
||||
|
||||
route_param :id do |
||||
get do |
||||
ar_id = convert_to_ar(params[:id]) |
||||
|
||||
filter_class = Query.find_registered_filter(ar_id) |
||||
|
||||
if filter_class |
||||
filter = filter_class.new |
||||
filter.name = ar_id |
||||
|
||||
::API::V3::Queries::Filters::QueryFilterRepresenter.new(filter) |
||||
else |
||||
raise API::Errors::NotFound |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,67 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module GroupBys |
||||
class QueryGroupByRepresenter < ::API::Decorators::Single |
||||
self_link id_attribute: ->(*) { converted_name }, |
||||
title_getter: ->(*) { represented.caption } |
||||
|
||||
def initialize(model) |
||||
super(model, current_user: nil, embed_links: true) |
||||
end |
||||
|
||||
property :id, |
||||
exec_context: :decorator |
||||
|
||||
property :caption, |
||||
as: :name |
||||
|
||||
private |
||||
|
||||
def converted_name |
||||
convert_attribute(represented.name) |
||||
end |
||||
|
||||
alias :id :converted_name |
||||
|
||||
def _type |
||||
'QueryGroupBy' |
||||
end |
||||
|
||||
def convert_attribute(attribute) |
||||
::API::Utilities::PropertyNameConverter.from_ar_name(attribute) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,66 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module GroupBys |
||||
class QueryGroupBysAPI < ::API::OpenProjectAPI |
||||
resource :group_bys do |
||||
helpers do |
||||
def convert_to_ar(attribute) |
||||
::API::Utilities::WpPropertyNameConverter.to_ar_name(attribute) |
||||
end |
||||
end |
||||
|
||||
params do |
||||
requires :id, desc: 'Group by id' |
||||
end |
||||
|
||||
before do |
||||
authorize(:view_work_packages, global: true, user: current_user) |
||||
end |
||||
|
||||
route_param :id do |
||||
get do |
||||
ar_id = convert_to_ar(params[:id]).to_sym |
||||
column = Query.groupable_columns.detect { |candidate| candidate.name == ar_id } |
||||
|
||||
if column |
||||
::API::V3::Queries::GroupBys::QueryGroupByRepresenter.new(column) |
||||
else |
||||
raise API::Errors::NotFound |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,63 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module Operators |
||||
class QueryOperatorRepresenter < ::API::Decorators::Single |
||||
self_link id_attribute: ->(*) { represented }, |
||||
title_getter: ->(*) { name } |
||||
|
||||
def initialize(model) |
||||
super(model.to_sym, current_user: nil, embed_links: true) |
||||
end |
||||
|
||||
property :id, |
||||
exec_context: :decorator |
||||
|
||||
property :name, |
||||
exec_context: :decorator |
||||
|
||||
private |
||||
|
||||
def name |
||||
I18n.t(::Queries::BaseFilter.operators[represented]) |
||||
end |
||||
|
||||
alias :id :represented |
||||
|
||||
def _type |
||||
'QueryOperator' |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,57 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module Operators |
||||
class QueryOperatorsAPI < ::API::OpenProjectAPI |
||||
resource :operators do |
||||
params do |
||||
requires :id, desc: 'Operator id' |
||||
end |
||||
|
||||
before do |
||||
authorize(:view_work_packages, global: true, user: current_user) |
||||
end |
||||
|
||||
route_param :id do |
||||
get do |
||||
if ::Queries::BaseFilter.operators[params[:id].to_sym] |
||||
::API::V3::Queries::Operators::QueryOperatorRepresenter.new(params[:id]) |
||||
else |
||||
raise API::Errors::NotFound |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,90 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
# Other than the Roar based representers of the api v3, this |
||||
# representer is only responsible for transforming a query's |
||||
# attributes into a hash which in turn can be used e.g. to be displayed |
||||
# in a url |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
class QueryParamsRepresenter |
||||
def initialize(query) |
||||
self.query = query |
||||
end |
||||
|
||||
def to_h |
||||
p = default_hash |
||||
|
||||
p[:showSums] = 'true' if query.display_sums? |
||||
p[:groupBy] = query.group_by if query.group_by? |
||||
p[:sortBy] = sort_criteria_to_v3 if query.sorted? |
||||
p[:filters] = filters_to_v3 if query.filtered? |
||||
|
||||
p |
||||
end |
||||
|
||||
def self_link |
||||
if query.project |
||||
api_v3_paths.work_packages_by_project(query.project.id) |
||||
else |
||||
api_v3_paths.work_packages |
||||
end |
||||
end |
||||
|
||||
private |
||||
|
||||
def sort_criteria_to_v3 |
||||
converted = query.sort_criteria.map { |first, last| [convert_to_v3(first), last] } |
||||
|
||||
JSON::dump(converted) |
||||
end |
||||
|
||||
def filters_to_v3 |
||||
converted = query.filters.map do |filter| |
||||
{ convert_to_v3(filter.name) => { operator: filter.operator, values: filter.values } } |
||||
end |
||||
|
||||
JSON::dump(converted) |
||||
end |
||||
|
||||
def convert_to_v3(attribute) |
||||
::API::Utilities::PropertyNameConverter.from_ar_name(attribute).to_sym |
||||
end |
||||
|
||||
def default_hash |
||||
{ offset: 1, pageSize: Setting.per_page_options_array.first } |
||||
end |
||||
|
||||
attr_accessor :query |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,73 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module SortBys |
||||
class QuerySortByRepresenter < ::API::Decorators::Single |
||||
self_link id_attribute: ->(*) { self_link_params }, |
||||
title_getter: ->(*) { represented.name } |
||||
|
||||
def initialize(model) |
||||
super(model, current_user: nil, embed_links: true) |
||||
end |
||||
|
||||
link :column do |
||||
{ |
||||
href: api_v3_paths.query_column(represented.converted_name), |
||||
title: represented.column_caption |
||||
} |
||||
end |
||||
|
||||
link :direction do |
||||
{ |
||||
href: represented.direction_uri, |
||||
title: represented.direction_l10n |
||||
} |
||||
end |
||||
|
||||
property :id |
||||
|
||||
property :name |
||||
|
||||
private |
||||
|
||||
def self_link_params |
||||
[represented.converted_name, represented.direction_name] |
||||
end |
||||
|
||||
def _type |
||||
'QuerySortBy' |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,68 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module SortBys |
||||
class QuerySortBysAPI < ::API::OpenProjectAPI |
||||
resource :sort_bys do |
||||
helpers do |
||||
def convert_to_ar(attribute) |
||||
::API::Utilities::WpPropertyNameConverter.to_ar_name(attribute) |
||||
end |
||||
end |
||||
|
||||
params do |
||||
requires :id, desc: 'Group by id' |
||||
requires :direction, desc: 'Direction of sorting' |
||||
end |
||||
|
||||
before do |
||||
authorize(:view_work_packages, global: true, user: current_user) |
||||
end |
||||
|
||||
namespace ':id-:direction' do |
||||
get do |
||||
ar_id = convert_to_ar(params[:id]) |
||||
|
||||
begin |
||||
decorator = ::API::V3::Queries::SortBys::SortByDecorator.new(ar_id, |
||||
params[:direction]) |
||||
::API::V3::Queries::SortBys::QuerySortByRepresenter.new(decorator) |
||||
rescue ArgumentError |
||||
raise API::Errors::NotFound |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,99 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Queries |
||||
module SortBys |
||||
class SortByDecorator |
||||
def initialize(column_name, direction) |
||||
if !['asc', 'desc'].include?(direction) |
||||
raise ArgumentError, "Invalid direction. Only 'asc' and 'desc' are supported." |
||||
end |
||||
|
||||
self.direction = direction |
||||
|
||||
column_sym = column_name.to_sym |
||||
column = Query |
||||
.sortable_columns |
||||
.detect { |candidate| candidate.name == column_sym } |
||||
|
||||
if column.nil? |
||||
raise ArgumentError, "Invalid column name." |
||||
end |
||||
|
||||
self.column = column |
||||
end |
||||
|
||||
def id |
||||
"#{converted_name}-#{direction_name}" |
||||
end |
||||
|
||||
def name |
||||
I18n.t('query.attribute_and_direction', |
||||
attribute: column_caption, |
||||
direction: direction_l10n) |
||||
end |
||||
|
||||
def converted_name |
||||
convert_attribute(column_name) |
||||
end |
||||
|
||||
def direction_name |
||||
direction |
||||
end |
||||
|
||||
def direction_uri |
||||
"urn:openproject-org:api:v3:queries:directions:#{direction}" |
||||
end |
||||
|
||||
def direction_l10n |
||||
I18n.t(direction == 'desc' ? :label_descending : :label_ascending) |
||||
end |
||||
|
||||
def column_name |
||||
column.name |
||||
end |
||||
|
||||
def column_caption |
||||
column.caption |
||||
end |
||||
|
||||
private |
||||
|
||||
def convert_attribute(attribute) |
||||
::API::Utilities::PropertyNameConverter.from_ar_name(attribute) |
||||
end |
||||
|
||||
attr_accessor :direction, :column |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -1,210 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
module WorkPackageListHelpers |
||||
extend Grape::API::Helpers |
||||
include QueriesHelper |
||||
|
||||
def work_packages_by_params(project: nil) |
||||
query = Query.new(name: '_', project: project) |
||||
query_params = {} |
||||
|
||||
begin |
||||
apply_filters query, query_params |
||||
apply_sorting query, query_params |
||||
groups = apply_and_generate_groups query, query_params |
||||
|
||||
total_sums = generate_total_sums query.results, query_params |
||||
rescue ::JSON::ParserError => error |
||||
raise ::API::Errors::InvalidQuery.new(error.message) |
||||
end |
||||
|
||||
work_packages = query |
||||
.results |
||||
.sorted_work_packages |
||||
|
||||
collection_representer(work_packages, |
||||
project: project, |
||||
query_params: query_params, |
||||
groups: groups, |
||||
sums: total_sums) |
||||
end |
||||
|
||||
def apply_filters(query, query_params) |
||||
if params[:filters] |
||||
filters = parse_filters_from_json(params[:filters]) |
||||
set_filters(query, filters) |
||||
query_params[:filters] = params[:filters] |
||||
end |
||||
end |
||||
|
||||
# Expected format looks like: |
||||
# [ |
||||
# { |
||||
# "filtered_field_name": { |
||||
# "operator": "a name for a filter operation", |
||||
# "values": ["values", "for the", "operation"] |
||||
# } |
||||
# }, |
||||
# { /* more filters if needed */} |
||||
# ] |
||||
def parse_filters_from_json(json) |
||||
filters = JSON.parse(json) |
||||
operators = {} |
||||
values = {} |
||||
filters.each do |filter| |
||||
attribute = filter.keys.first # there should only be one attribute per filter |
||||
operators[attribute] = filter[attribute]['operator'] |
||||
values[attribute] = filter[attribute]['values'] |
||||
end |
||||
|
||||
{ |
||||
fields: values.keys, |
||||
operators: operators, |
||||
values: values |
||||
} |
||||
end |
||||
|
||||
def set_filters(query, filters) |
||||
add_filter_from_params(query, filters: filters) |
||||
|
||||
bad_filter = query.filters.detect(&:invalid?) |
||||
if bad_filter |
||||
raise_invalid_query(bad_filter.errors) |
||||
end |
||||
end |
||||
|
||||
def apply_sorting(query, query_params) |
||||
if params[:sortBy] |
||||
query.sort_criteria = parse_sorting_from_json(params[:sortBy]) |
||||
query_params[:sortBy] = params[:sortBy] |
||||
else |
||||
query.sort_criteria = [['parent', 'desc']] |
||||
query_params[:sortBy] = 'parent:desc' |
||||
end |
||||
end |
||||
|
||||
def parse_sorting_from_json(json) |
||||
JSON.parse(json).map do |(attribute, order)| |
||||
[convert_attribute(attribute), order] |
||||
end |
||||
end |
||||
|
||||
def apply_and_generate_groups(query, query_params) |
||||
if params[:groupBy] |
||||
query.group_by = convert_attribute params[:groupBy] |
||||
query_params[:groupBy] = params[:groupBy] |
||||
|
||||
generate_groups query.results |
||||
end |
||||
end |
||||
|
||||
def generate_groups(results) |
||||
results.work_package_count_by_group.map do |group, count| |
||||
sums = nil |
||||
if params[:showSums] == 'true' |
||||
sums = format_query_sums results.all_sums_for_group(group) |
||||
end |
||||
|
||||
::API::Decorators::AggregationGroup.new(group, count, sums: sums) |
||||
end |
||||
end |
||||
|
||||
def generate_total_sums(results, query_params) |
||||
if params[:showSums] == 'true' |
||||
query_params[:showSums] = 'true' |
||||
format_query_sums results.all_total_sums |
||||
end |
||||
end |
||||
|
||||
def format_query_sums(sums) |
||||
OpenStruct.new(format_column_keys(sums)) |
||||
end |
||||
|
||||
def format_column_keys(hash_by_column) |
||||
::Hash[ |
||||
hash_by_column.map do |column, value| |
||||
match = /cf_(\d+)/.match(column.name.to_s) |
||||
|
||||
column_name = if match |
||||
"custom_field_#{match[1]}" |
||||
else |
||||
column.name.to_s |
||||
end |
||||
|
||||
[column_name, value] |
||||
end |
||||
] |
||||
end |
||||
|
||||
def collection_representer(work_packages, project:, query_params:, groups:, sums:) |
||||
self_link = if project |
||||
api_v3_paths.work_packages_by_project(project.id) |
||||
else |
||||
api_v3_paths.work_packages |
||||
end |
||||
|
||||
::API::V3::WorkPackages::WorkPackageCollectionRepresenter.new( |
||||
work_packages, |
||||
self_link, |
||||
project: project, |
||||
query: query_params, |
||||
page: to_i_or_nil(params[:offset]), |
||||
per_page: to_i_or_nil(params[:pageSize]), |
||||
groups: groups, |
||||
total_sums: sums, |
||||
embed_schemas: true, |
||||
current_user: current_user |
||||
) |
||||
end |
||||
|
||||
def convert_attribute(attribute, append_id: false) |
||||
@@conversion_wp ||= ::API::Utilities::PropertyNameConverterQueryContext.new |
||||
::API::Utilities::PropertyNameConverter.to_ar_name(attribute, |
||||
context: @@conversion_wp, |
||||
refer_to_ids: append_id) |
||||
end |
||||
|
||||
def raise_invalid_query(errors) |
||||
api_errors = errors.full_messages.map do |message| |
||||
::API::Errors::InvalidQuery.new(message) |
||||
end |
||||
|
||||
raise ::API::Errors::MultipleErrors.create_if_many api_errors |
||||
end |
||||
|
||||
def to_i_or_nil(value) |
||||
value ? value.to_i : nil |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,90 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Queries::Columns::QueryColumnRepresenter do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
let(:column) { Query.available_columns.detect { |column| column.name == :status } } |
||||
let(:representer) { described_class.new(column) } |
||||
|
||||
subject { representer.to_json } |
||||
|
||||
describe 'generation' do |
||||
describe '_links' do |
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'self' } |
||||
let(:href) { api_v3_paths.query_column 'status' } |
||||
let(:title) { 'Status' } |
||||
end |
||||
end |
||||
|
||||
it 'has _type QueryColumn' do |
||||
is_expected |
||||
.to be_json_eql('QueryColumn'.to_json) |
||||
.at_path('_type') |
||||
end |
||||
|
||||
it 'has id attribute' do |
||||
is_expected |
||||
.to be_json_eql('status'.to_json) |
||||
.at_path('id') |
||||
end |
||||
|
||||
it 'has name attribute' do |
||||
is_expected |
||||
.to be_json_eql('Status'.to_json) |
||||
.at_path('name') |
||||
end |
||||
|
||||
context 'for a translated column' do |
||||
let(:column) { Query.available_columns.detect { |column| column.name == :assigned_to } } |
||||
|
||||
describe '_links' do |
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'self' } |
||||
let(:href) { api_v3_paths.query_column 'assignee' } |
||||
let(:title) { 'Assignee' } |
||||
end |
||||
end |
||||
|
||||
it 'has id attribute' do |
||||
is_expected |
||||
.to be_json_eql('assignee'.to_json) |
||||
.at_path('id') |
||||
end |
||||
|
||||
it 'has name attribute' do |
||||
is_expected |
||||
.to be_json_eql('Assignee'.to_json) |
||||
.at_path('name') |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,111 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Queries::Filters::QueryFilterInstanceRepresenter do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
let(:operator) { '=' } |
||||
let(:values) { [status.id.to_s] } |
||||
|
||||
let(:status) { FactoryGirl.build_stubbed(:status) } |
||||
|
||||
let(:filter) do |
||||
Queries::WorkPackages::Filter::StatusFilter.new(operator: operator, values: values) |
||||
end |
||||
|
||||
let(:representer) { described_class.new(filter) } |
||||
|
||||
before do |
||||
allow(filter) |
||||
.to receive(:value_objects) |
||||
.and_return([status]) |
||||
end |
||||
|
||||
describe 'generation' do |
||||
subject { representer.to_json } |
||||
|
||||
describe '_links' do |
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'filter' } |
||||
let(:href) { api_v3_paths.query_filter 'status' } |
||||
let(:title) { 'Status' } |
||||
end |
||||
|
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'operator' } |
||||
let(:href) { api_v3_paths.query_operator '=' } |
||||
let(:title) { 'is' } |
||||
end |
||||
|
||||
it "has a 'values' collection" do |
||||
expected = { |
||||
href: api_v3_paths.status(status.id.to_s), |
||||
title: status.name |
||||
} |
||||
|
||||
is_expected |
||||
.to be_json_eql([expected].to_json) |
||||
.at_path('_links/values') |
||||
end |
||||
end |
||||
|
||||
it 'has _type StatusQueryFilter' do |
||||
is_expected |
||||
.to be_json_eql('StatusQueryFilter'.to_json) |
||||
.at_path('_type') |
||||
end |
||||
|
||||
it 'has name Status' do |
||||
is_expected |
||||
.to be_json_eql('Status'.to_json) |
||||
.at_path('name') |
||||
end |
||||
|
||||
context 'with a non ar object filter' do |
||||
let(:values) { ['lorem ipsum'] } |
||||
let(:filter) do |
||||
Queries::WorkPackages::Filter::SubjectFilter.new(operator: operator, values: values) |
||||
end |
||||
|
||||
describe '_links' do |
||||
it 'has no values link' do |
||||
is_expected |
||||
.not_to have_json_path('_links/values') |
||||
end |
||||
end |
||||
|
||||
it "has a 'values' array property" do |
||||
is_expected |
||||
.to be_json_eql(values.to_json) |
||||
.at_path('values') |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,106 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Queries::Filters::QueryFilterRepresenter do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
let(:filter) { Queries::WorkPackages::Filter::SubjectFilter.new } |
||||
let(:representer) { described_class.new(filter) } |
||||
|
||||
subject { representer.to_json } |
||||
|
||||
describe 'generation' do |
||||
describe '_links' do |
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'self' } |
||||
let(:href) { api_v3_paths.query_filter 'subject' } |
||||
let(:title) { 'Subject' } |
||||
end |
||||
end |
||||
|
||||
it 'has _type QueryFilter' do |
||||
is_expected |
||||
.to be_json_eql('QueryFilter'.to_json) |
||||
.at_path('_type') |
||||
end |
||||
|
||||
it 'has id attribute' do |
||||
is_expected |
||||
.to be_json_eql('subject'.to_json) |
||||
.at_path('id') |
||||
end |
||||
|
||||
context 'for a translated filter' do |
||||
let(:filter) { Queries::WorkPackages::Filter::AssignedToFilter.new } |
||||
|
||||
describe '_links' do |
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'self' } |
||||
let(:href) { api_v3_paths.query_filter 'assignee' } |
||||
let(:title) { 'Assignee' } |
||||
end |
||||
end |
||||
|
||||
it 'has id attribute' do |
||||
is_expected |
||||
.to be_json_eql('assignee'.to_json) |
||||
.at_path('id') |
||||
end |
||||
end |
||||
|
||||
context 'for a custom field filter' do |
||||
let(:custom_field) { FactoryGirl.build_stubbed(:list_wp_custom_field) } |
||||
let(:filter) { Queries::WorkPackages::Filter::CustomFieldFilter.new } |
||||
|
||||
before do |
||||
allow(WorkPackageCustomField) |
||||
.to receive(:find_by_id) |
||||
.with(custom_field.id) |
||||
.and_return custom_field |
||||
|
||||
filter.name = "cf_#{custom_field.id}" |
||||
end |
||||
|
||||
describe '_links' do |
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'self' } |
||||
let(:href) { api_v3_paths.query_filter "customField#{custom_field.id}" } |
||||
let(:title) { custom_field.name } |
||||
end |
||||
end |
||||
|
||||
it 'has id attribute' do |
||||
is_expected |
||||
.to be_json_eql("customField#{custom_field.id}".to_json) |
||||
.at_path('id') |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,90 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Queries::GroupBys::QueryGroupByRepresenter do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
let(:column) { Query.available_columns.detect { |column| column.name == :status } } |
||||
let(:representer) { described_class.new(column) } |
||||
|
||||
subject { representer.to_json } |
||||
|
||||
describe 'generation' do |
||||
describe '_links' do |
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'self' } |
||||
let(:href) { api_v3_paths.query_group_by 'status' } |
||||
let(:title) { 'Status' } |
||||
end |
||||
end |
||||
|
||||
it 'has _type QueryGroupBy' do |
||||
is_expected |
||||
.to be_json_eql('QueryGroupBy'.to_json) |
||||
.at_path('_type') |
||||
end |
||||
|
||||
it 'has id attribute' do |
||||
is_expected |
||||
.to be_json_eql('status'.to_json) |
||||
.at_path('id') |
||||
end |
||||
|
||||
it 'has name attribute' do |
||||
is_expected |
||||
.to be_json_eql('Status'.to_json) |
||||
.at_path('name') |
||||
end |
||||
|
||||
context 'for a translated column' do |
||||
let(:column) { Query.available_columns.detect { |column| column.name == :assigned_to } } |
||||
|
||||
describe '_links' do |
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'self' } |
||||
let(:href) { api_v3_paths.query_group_by 'assignee' } |
||||
let(:title) { 'Assignee' } |
||||
end |
||||
end |
||||
|
||||
it 'has id attribute' do |
||||
is_expected |
||||
.to be_json_eql('assignee'.to_json) |
||||
.at_path('id') |
||||
end |
||||
|
||||
it 'has name attribute' do |
||||
is_expected |
||||
.to be_json_eql('Assignee'.to_json) |
||||
.at_path('name') |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,66 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Queries::Operators::QueryOperatorRepresenter do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
let(:operator) { '!~' } |
||||
let(:representer) { described_class.new(operator) } |
||||
|
||||
subject { representer.to_json } |
||||
|
||||
describe 'generation' do |
||||
describe '_links' do |
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'self' } |
||||
let(:href) { api_v3_paths.query_operator operator } |
||||
let(:title) { I18n.t(:label_not_contains) } |
||||
end |
||||
end |
||||
|
||||
it 'has _type QueryOperator' do |
||||
is_expected |
||||
.to be_json_eql('QueryOperator'.to_json) |
||||
.at_path('_type') |
||||
end |
||||
|
||||
it 'has id attribute' do |
||||
is_expected |
||||
.to be_json_eql(operator.to_json) |
||||
.at_path('id') |
||||
end |
||||
|
||||
it 'has name attribute' do |
||||
is_expected |
||||
.to be_json_eql(I18n.t(:label_not_contains).to_json) |
||||
.at_path('name') |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,130 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Queries::SortBys::QuerySortByRepresenter do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
let(:column) { 'status' } |
||||
let(:direction) { 'desc' } |
||||
let(:representer) do |
||||
described_class |
||||
.new(::API::V3::Queries::SortBys::SortByDecorator.new(column, direction)) |
||||
end |
||||
|
||||
subject { representer.to_json } |
||||
|
||||
describe 'generation' do |
||||
describe '_links' do |
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'self' } |
||||
let(:href) { api_v3_paths.query_sort_by 'status', 'desc' } |
||||
let(:title) { 'Status (Descending)' } |
||||
end |
||||
end |
||||
|
||||
it 'has _type QuerySortBy' do |
||||
is_expected |
||||
.to be_json_eql('QuerySortBy'.to_json) |
||||
.at_path('_type') |
||||
end |
||||
|
||||
it 'has id attribute' do |
||||
is_expected |
||||
.to be_json_eql('status-desc'.to_json) |
||||
.at_path('id') |
||||
end |
||||
|
||||
it 'has name attribute' do |
||||
is_expected |
||||
.to be_json_eql('Status (Descending)'.to_json) |
||||
.at_path('name') |
||||
end |
||||
|
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'column' } |
||||
let(:href) { api_v3_paths.query_column 'status' } |
||||
let(:title) { 'Status' } |
||||
end |
||||
|
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'direction' } |
||||
let(:href) { "urn:openproject-org:api:v3:queries:directions:#{direction}" } |
||||
let(:title) { 'Descending' } |
||||
end |
||||
|
||||
context 'when providing an unsupported sort direction' do |
||||
let(:direction) { 'bogus' } |
||||
|
||||
it 'raises error' do |
||||
expect { subject }.to raise_error(ArgumentError) |
||||
end |
||||
end |
||||
|
||||
context 'when sorting differently' do |
||||
let(:direction) { 'asc' } |
||||
|
||||
it 'has id attribute' do |
||||
is_expected |
||||
.to be_json_eql('status-asc'.to_json) |
||||
.at_path('id') |
||||
end |
||||
|
||||
it 'has name attribute' do |
||||
is_expected |
||||
.to be_json_eql('Status (Ascending)'.to_json) |
||||
.at_path('name') |
||||
end |
||||
end |
||||
|
||||
context 'for a translated column' do |
||||
let(:column) { 'assigned_to' } |
||||
|
||||
describe '_links' do |
||||
it_behaves_like 'has a titled link' do |
||||
let(:link) { 'self' } |
||||
let(:href) { api_v3_paths.query_sort_by 'assignee', 'desc' } |
||||
let(:title) { 'Assignee (Descending)' } |
||||
end |
||||
end |
||||
|
||||
it 'has id attribute' do |
||||
is_expected |
||||
.to be_json_eql('assignee-desc'.to_json) |
||||
.at_path('id') |
||||
end |
||||
|
||||
it 'has name attribute' do |
||||
is_expected |
||||
.to be_json_eql('Assignee (Descending)'.to_json) |
||||
.at_path('name') |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,82 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
require 'rack/test' |
||||
|
||||
describe 'API v3 Query Column resource', type: :request do |
||||
include Rack::Test::Methods |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
describe '#get queries/columns/:id' do |
||||
let(:path) { api_v3_paths.query_column(column_name) } |
||||
let(:column_name) { 'status' } |
||||
let(:project) { FactoryGirl.create(:project) } |
||||
let(:role) { FactoryGirl.create(:role, permissions: permissions) } |
||||
let(:permissions) { [:view_work_packages] } |
||||
let(:user) do |
||||
FactoryGirl.create(:user, |
||||
member_in_project: project, |
||||
member_through_role: role) |
||||
end |
||||
|
||||
before do |
||||
allow(User) |
||||
.to receive(:current) |
||||
.and_return(user) |
||||
|
||||
get path |
||||
end |
||||
|
||||
it 'succeeds' do |
||||
expect(last_response.status) |
||||
.to eq(200) |
||||
end |
||||
|
||||
it 'returns the column' do |
||||
expect(last_response.body) |
||||
.to be_json_eql(path.to_json) |
||||
.at_path('_links/self/href') |
||||
end |
||||
|
||||
context 'user not allowed' do |
||||
let(:permissions) { [] } |
||||
|
||||
it_behaves_like 'unauthorized access' |
||||
end |
||||
|
||||
context 'non existing group by' do |
||||
let(:path) { api_v3_paths.query_column('bogus') } |
||||
|
||||
it 'returns 404' do |
||||
expect(last_response.status) |
||||
.to eql(404) |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,98 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
require 'rack/test' |
||||
|
||||
describe 'API v3 Query Filter resource', type: :request do |
||||
include Rack::Test::Methods |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
describe '#get queries/filters/:id' do |
||||
let(:path) { api_v3_paths.query_filter(filter_name) } |
||||
let(:filter_name) { 'assignee' } |
||||
let(:project) { FactoryGirl.create(:project) } |
||||
let(:role) { FactoryGirl.create(:role, permissions: permissions) } |
||||
let(:permissions) { [:view_work_packages] } |
||||
let(:user) do |
||||
FactoryGirl.create(:user, |
||||
member_in_project: project, |
||||
member_through_role: role) |
||||
end |
||||
|
||||
before do |
||||
allow(User) |
||||
.to receive(:current) |
||||
.and_return(user) |
||||
|
||||
get path |
||||
end |
||||
|
||||
it 'succeeds' do |
||||
expect(last_response.status) |
||||
.to eq(200) |
||||
end |
||||
|
||||
it 'returns the filter' do |
||||
expect(last_response.body) |
||||
.to be_json_eql(path.to_json) |
||||
.at_path('_links/self/href') |
||||
end |
||||
|
||||
context 'user not allowed' do |
||||
let(:permissions) { [] } |
||||
|
||||
it_behaves_like 'unauthorized access' |
||||
end |
||||
|
||||
context 'non existing filter' do |
||||
let(:filter_name) { 'bogus' } |
||||
|
||||
it 'returns 404' do |
||||
expect(last_response.status) |
||||
.to eql(404) |
||||
end |
||||
end |
||||
|
||||
context 'custom field filter' do |
||||
let(:list_wp_custom_field) { FactoryGirl.create(:list_wp_custom_field) } |
||||
let(:filter_name) { "customField#{list_wp_custom_field.id}" } |
||||
|
||||
it 'succeeds' do |
||||
expect(last_response.status) |
||||
.to eq(200) |
||||
end |
||||
|
||||
it 'returns the filter' do |
||||
expect(last_response.body) |
||||
.to be_json_eql(path.to_json) |
||||
.at_path('_links/self/href') |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,91 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
require 'rack/test' |
||||
|
||||
describe 'API v3 Query Group By resource', type: :request do |
||||
include Rack::Test::Methods |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
describe '#get queries/group_bys/:id' do |
||||
let(:path) { api_v3_paths.query_group_by(group_by_name) } |
||||
let(:group_by_name) { 'status' } |
||||
let(:project) { FactoryGirl.create(:project) } |
||||
let(:role) { FactoryGirl.create(:role, permissions: permissions) } |
||||
let(:permissions) { [:view_work_packages] } |
||||
let(:user) do |
||||
FactoryGirl.create(:user, |
||||
member_in_project: project, |
||||
member_through_role: role) |
||||
end |
||||
|
||||
before do |
||||
allow(User) |
||||
.to receive(:current) |
||||
.and_return(user) |
||||
|
||||
get path |
||||
end |
||||
|
||||
it 'succeeds' do |
||||
expect(last_response.status) |
||||
.to eql(200) |
||||
end |
||||
|
||||
it 'returns the group_by' do |
||||
expect(last_response.body) |
||||
.to be_json_eql(path.to_json) |
||||
.at_path('_links/self/href') |
||||
end |
||||
|
||||
context 'user not allowed' do |
||||
let(:permissions) { [] } |
||||
|
||||
it_behaves_like 'unauthorized access' |
||||
end |
||||
|
||||
context 'non existing group by' do |
||||
let(:path) { api_v3_paths.query_group_by('bogus') } |
||||
|
||||
it 'returns 404' do |
||||
expect(last_response.status) |
||||
.to eql(404) |
||||
end |
||||
end |
||||
|
||||
context 'non groupable group by' do |
||||
let(:path) { api_v3_paths.query_group_by('id') } |
||||
|
||||
it 'returns 404' do |
||||
expect(last_response.status) |
||||
.to eql(404) |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,82 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
require 'rack/test' |
||||
|
||||
describe 'API v3 Query Operator resource', type: :request do |
||||
include Rack::Test::Methods |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
describe '#get queries/operators/:id' do |
||||
let(:path) { api_v3_paths.query_operator(operator) } |
||||
let(:operator) { '=' } |
||||
let(:project) { FactoryGirl.create(:project) } |
||||
let(:role) { FactoryGirl.create(:role, permissions: permissions) } |
||||
let(:permissions) { [:view_work_packages] } |
||||
let(:user) do |
||||
FactoryGirl.create(:user, |
||||
member_in_project: project, |
||||
member_through_role: role) |
||||
end |
||||
|
||||
before do |
||||
allow(User) |
||||
.to receive(:current) |
||||
.and_return(user) |
||||
|
||||
get path |
||||
end |
||||
|
||||
it 'succeeds' do |
||||
expect(last_response.status) |
||||
.to eq(200) |
||||
end |
||||
|
||||
it 'returns the operator' do |
||||
expect(last_response.body) |
||||
.to be_json_eql(path.to_json) |
||||
.at_path('_links/self/href') |
||||
end |
||||
|
||||
context 'user not allowed' do |
||||
let(:permissions) { [] } |
||||
|
||||
it_behaves_like 'unauthorized access' |
||||
end |
||||
|
||||
context 'non existing operator' do |
||||
let(:operator) { 'bogus' } |
||||
|
||||
it 'returns 404' do |
||||
expect(last_response.status) |
||||
.to eql(404) |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,101 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
require 'rack/test' |
||||
|
||||
describe 'API v3 Query Sort Bys resource', type: :request do |
||||
include Rack::Test::Methods |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
describe '#get queries/sort_bys/:id' do |
||||
let(:path) { api_v3_paths.query_sort_by(column_name, direction) } |
||||
let(:column_name) { 'status' } |
||||
let(:direction) { 'desc' } |
||||
let(:project) { FactoryGirl.create(:project) } |
||||
let(:role) { FactoryGirl.create(:role, permissions: permissions) } |
||||
let(:permissions) { [:view_work_packages] } |
||||
let(:user) do |
||||
FactoryGirl.create(:user, |
||||
member_in_project: project, |
||||
member_through_role: role) |
||||
end |
||||
|
||||
before do |
||||
allow(User) |
||||
.to receive(:current) |
||||
.and_return(user) |
||||
|
||||
get path |
||||
end |
||||
|
||||
it 'succeeds' do |
||||
expect(last_response.status) |
||||
.to eq(200) |
||||
end |
||||
|
||||
it 'returns the sort by' do |
||||
expect(last_response.body) |
||||
.to be_json_eql(path.to_json) |
||||
.at_path('_links/self/href') |
||||
end |
||||
|
||||
context 'user not allowed' do |
||||
let(:permissions) { [] } |
||||
|
||||
it_behaves_like 'unauthorized access' |
||||
end |
||||
|
||||
context 'non existing sort by' do |
||||
let(:path) { api_v3_paths.query_sort_by('bogus', direction) } |
||||
|
||||
it 'returns 404' do |
||||
expect(last_response.status) |
||||
.to eql(404) |
||||
end |
||||
end |
||||
|
||||
context 'non existing direction' do |
||||
let(:path) { api_v3_paths.query_sort_by(column_name, 'bogus') } |
||||
|
||||
it 'returns 404' do |
||||
expect(last_response.status) |
||||
.to eql(404) |
||||
end |
||||
end |
||||
|
||||
context 'non sortable sort by' do |
||||
let(:path) { api_v3_paths.query_sort_by('spent_time', direction) } |
||||
|
||||
it 'returns 404' do |
||||
expect(last_response.status) |
||||
.to eql(404) |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,231 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::ParseQueryParamsService, |
||||
type: :model do |
||||
|
||||
let(:instance) { described_class.new } |
||||
let(:params) { {} } |
||||
|
||||
describe '#call' do |
||||
subject { instance.call(params) } |
||||
|
||||
shared_examples_for 'transforms' do |
||||
it 'is success' do |
||||
expect(subject) |
||||
.to be_success |
||||
end |
||||
|
||||
it 'is transformed' do |
||||
expect(subject.result) |
||||
.to eql(expected) |
||||
end |
||||
end |
||||
|
||||
context 'with group by' do |
||||
context 'as groupBy' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) { { groupBy: 'status' } } |
||||
let(:expected) { { group_by: 'status' } } |
||||
end |
||||
end |
||||
|
||||
context 'as group_by' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) { { group_by: 'status' } } |
||||
let(:expected) { { group_by: 'status' } } |
||||
end |
||||
end |
||||
|
||||
context 'as "g"' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) { { g: 'status' } } |
||||
let(:expected) { { group_by: 'status' } } |
||||
end |
||||
end |
||||
|
||||
context 'with an attribute called differently in v3' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) { { groupBy: 'assignee' } } |
||||
let(:expected) { { group_by: 'assigned_to' } } |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with columns' do |
||||
context 'as columns' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) { { columns: ['status', 'assignee'] } } |
||||
let(:expected) { { columns: ['status', 'assigned_to'] } } |
||||
end |
||||
end |
||||
|
||||
context 'as "c"' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) { { c: ['status', 'assignee'] } } |
||||
let(:expected) { { columns: ['status', 'assigned_to'] } } |
||||
end |
||||
end |
||||
|
||||
context 'as column_names' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) { { column_names: ['status', 'assignee'] } } |
||||
let(:expected) { { columns: ['status', 'assigned_to'] } } |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with sort' do |
||||
context 'as sortBy in comma separated value' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) { { sortBy: JSON::dump([['status', 'desc']]) } } |
||||
let(:expected) { { sort_by: [['status', 'desc']] } } |
||||
end |
||||
end |
||||
|
||||
context 'as sortBy in colon concatenated value' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) { { sortBy: JSON::dump(['status:desc']) } } |
||||
let(:expected) { { sort_by: [['status', 'desc']] } } |
||||
end |
||||
end |
||||
|
||||
context 'with an invalid JSON' do |
||||
let(:params) { { sortBy: 'faulty' + JSON::dump(['status:desc']) } } |
||||
|
||||
it 'is not success' do |
||||
expect(subject) |
||||
.to_not be_success |
||||
end |
||||
|
||||
it 'returns the error' do |
||||
message = 'unexpected token at \'faulty["status:desc"]\'' |
||||
|
||||
expect(subject.errors.messages[:base].length) |
||||
.to eql(1) |
||||
expect(subject.errors.messages[:base][0]) |
||||
.to end_with(message) |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with filters' do |
||||
context 'as filters in dumped json' do |
||||
context 'with a filter named internally' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) do |
||||
{ filters: JSON::dump([{ 'status_id' => { 'operator' => '=', |
||||
'values' => ['1', '2'] } }]) } |
||||
end |
||||
let(:expected) do |
||||
{ filters: [{ field: 'status_id', operator: '=', values: ['1', '2'] }] } |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with a filter named according to v3' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) do |
||||
{ filters: JSON::dump([{ 'status' => { 'operator' => '=', |
||||
'values' => ['1', '2'] } }]) } |
||||
end |
||||
let(:expected) do |
||||
{ filters: [{ field: 'status_id', operator: '=', values: ['1', '2'] }] } |
||||
end |
||||
end |
||||
|
||||
it_behaves_like 'transforms' do |
||||
let(:params) do |
||||
{ filters: JSON::dump([{ 'subprojectId' => { 'operator' => '=', |
||||
'values' => ['1', '2'] } }]) } |
||||
end |
||||
let(:expected) do |
||||
{ filters: [{ field: 'subproject_id', operator: '=', values: ['1', '2'] }] } |
||||
end |
||||
end |
||||
|
||||
it_behaves_like 'transforms' do |
||||
let(:params) do |
||||
{ filters: JSON::dump([{ 'watcher' => { 'operator' => '=', |
||||
'values' => ['1', '2'] } }]) } |
||||
end |
||||
let(:expected) do |
||||
{ filters: [{ field: 'watcher_id', operator: '=', values: ['1', '2'] }] } |
||||
end |
||||
end |
||||
|
||||
it_behaves_like 'transforms' do |
||||
let(:params) do |
||||
{ filters: JSON::dump([{ 'custom_field_1' => { 'operator' => '=', |
||||
'values' => ['1', '2'] } }]) } |
||||
end |
||||
let(:expected) do |
||||
{ filters: [{ field: 'cf_1', operator: '=', values: ['1', '2'] }] } |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with an invalid JSON' do |
||||
let(:params) do |
||||
{ filters: 'faulty' + JSON::dump([{ 'status' => { 'operator' => '=', |
||||
'values' => ['1', '2'] } }]) } |
||||
end |
||||
|
||||
it 'is not success' do |
||||
expect(subject) |
||||
.to_not be_success |
||||
end |
||||
|
||||
it 'returns the error' do |
||||
message = 'unexpected token at ' + |
||||
"'faulty[{\"status\":{\"operator\":\"=\",\"values\":[\"1\",\"2\"]}}]'" |
||||
|
||||
expect(subject.errors.messages[:base].length) |
||||
.to eql(1) |
||||
expect(subject.errors.messages[:base][0]) |
||||
.to end_with(message) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with showSums' do |
||||
it_behaves_like 'transforms' do |
||||
let(:params) { { showSums: 'true' } } |
||||
let(:expected) { { display_sums: true } } |
||||
end |
||||
|
||||
it_behaves_like 'transforms' do |
||||
let(:params) { { showSums: 'false' } } |
||||
let(:expected) { { display_sums: false } } |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,114 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::UpdateQueryFromV3ParamsService, |
||||
type: :model do |
||||
|
||||
let(:user) { FactoryGirl.build_stubbed(:user) } |
||||
let(:query) { FactoryGirl.build_stubbed(:query) } |
||||
|
||||
let(:params) { double('params') } |
||||
let(:parsed_params) { double('parsed_params') } |
||||
|
||||
let(:mock_parse_query_service) do |
||||
mock = double('ParseQueryParamsService') |
||||
|
||||
allow(mock) |
||||
.to receive(:call) |
||||
.with(params) |
||||
.and_return(mock_parse_query_service_response) |
||||
|
||||
mock |
||||
end |
||||
|
||||
let(:mock_parse_query_service_response) do |
||||
ServiceResult.new(success: mock_parse_query_service_success, |
||||
errors: mock_parse_query_service_errors, |
||||
result: mock_parse_query_service_result) |
||||
end |
||||
|
||||
let(:mock_parse_query_service_success) { true } |
||||
let(:mock_parse_query_service_errors) { nil } |
||||
let(:mock_parse_query_service_result) { parsed_params } |
||||
|
||||
let(:mock_update_query_service) do |
||||
mock = double('UpdateQueryFromParamsService') |
||||
|
||||
allow(mock) |
||||
.to receive(:call) |
||||
.with(parsed_params) |
||||
.and_return(mock_update_query_service_response) |
||||
|
||||
mock |
||||
end |
||||
|
||||
let(:mock_update_query_service_response) do |
||||
ServiceResult.new(success: mock_update_query_service_success, |
||||
errors: mock_update_query_service_errors, |
||||
result: mock_update_query_service_result) |
||||
end |
||||
|
||||
let(:mock_update_query_service_success) { true } |
||||
let(:mock_update_query_service_errors) { nil } |
||||
let(:mock_update_query_service_result) { query } |
||||
|
||||
let(:instance) { described_class.new(query, user) } |
||||
|
||||
before do |
||||
allow(UpdateQueryFromParamsService) |
||||
.to receive(:new) |
||||
.with(query, user) |
||||
.and_return(mock_update_query_service) |
||||
allow(::API::V3::ParseQueryParamsService) |
||||
.to receive(:new) |
||||
.with(no_args) |
||||
.and_return(mock_parse_query_service) |
||||
end |
||||
|
||||
describe '#call' do |
||||
subject { instance.call(params) } |
||||
|
||||
it 'returns the update result' do |
||||
is_expected |
||||
.to eql(mock_update_query_service_response) |
||||
end |
||||
|
||||
context 'when parsing fails' do |
||||
let(:mock_parse_query_service_success) { false } |
||||
let(:mock_parse_query_service_errors) { double 'error' } |
||||
let(:mock_parse_query_service_result) { nil } |
||||
|
||||
it 'returns the parse result' do |
||||
is_expected |
||||
.to eql(mock_parse_query_service_response) |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,89 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::WorkPackageCollectionFromQueryParamsService, |
||||
type: :model do |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
let(:mock_wp_collection_from_query_service) do |
||||
mock = double('WorkPackageCollectionFromQueryService') |
||||
|
||||
allow(mock) |
||||
.to receive(:call) |
||||
.with(params) |
||||
.and_return(mock_wp_collection_service_response) |
||||
|
||||
mock |
||||
end |
||||
|
||||
let(:mock_wp_collection_service_response) do |
||||
ServiceResult.new(success: mock_wp_collection_service_success, |
||||
errors: mock_wp_collection_service_errors, |
||||
result: mock_wp_collection_service_result) |
||||
end |
||||
|
||||
let(:mock_wp_collection_service_success) { true } |
||||
let(:mock_wp_collection_service_errors) { nil } |
||||
let(:mock_wp_collection_service_result) { double('result') } |
||||
|
||||
let(:query) { FactoryGirl.build_stubbed(:query) } |
||||
let(:project) { FactoryGirl.build_stubbed(:project) } |
||||
let(:user) { FactoryGirl.build_stubbed(:user) } |
||||
|
||||
let(:instance) { described_class.new(user) } |
||||
|
||||
before do |
||||
stub_const('::API::V3::WorkPackageCollectionFromQueryService', |
||||
mock_wp_collection_from_query_service) |
||||
|
||||
allow(::API::V3::WorkPackageCollectionFromQueryService) |
||||
.to receive(:new) |
||||
.with(query, user) |
||||
.and_return(mock_wp_collection_from_query_service) |
||||
end |
||||
|
||||
describe '#call' do |
||||
let(:params) { { project: project } } |
||||
|
||||
subject { instance.call(params) } |
||||
|
||||
before do |
||||
allow(Query) |
||||
.to receive(:new) |
||||
.with(name: '_', project: project, sort_criteria: [['parent', 'desc']]) |
||||
.and_return(query) |
||||
end |
||||
|
||||
it 'is successful' do |
||||
is_expected |
||||
.to eql(mock_wp_collection_service_response) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,383 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::WorkPackageCollectionFromQueryService, |
||||
type: :model do |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
let(:query) do |
||||
query = FactoryGirl.build_stubbed(:query) |
||||
allow(query) |
||||
.to receive(:results) |
||||
.and_return(results) |
||||
|
||||
query |
||||
end |
||||
|
||||
let(:results) do |
||||
results = double('results') |
||||
|
||||
allow(results) |
||||
.to receive(:sorted_work_packages) |
||||
.and_return([work_package]) |
||||
|
||||
allow(results) |
||||
.to receive(:all_total_sums) |
||||
.and_return(OpenStruct.new(name: :estimated_hours) => 0.0) |
||||
|
||||
allow(results) |
||||
.to receive(:work_package_count_by_group) |
||||
.and_return(1 => 5, 2 => 10) |
||||
|
||||
allow(results) |
||||
.to receive(:all_sums_for_group) |
||||
.with(1) |
||||
.and_return(OpenStruct.new(name: :status_id) => 50) |
||||
|
||||
allow(results) |
||||
.to receive(:all_sums_for_group) |
||||
.with(2) |
||||
.and_return(OpenStruct.new(name: :status_id) => 100) |
||||
|
||||
results |
||||
end |
||||
|
||||
let(:user) { FactoryGirl.build_stubbed(:user) } |
||||
let(:project) { FactoryGirl.build_stubbed(:project) } |
||||
let(:mock_wp_representer) do |
||||
Struct.new(:work_packages, |
||||
:self_link, |
||||
:query, |
||||
:project, |
||||
:groups, |
||||
:total_sums, |
||||
:page, |
||||
:per_page, |
||||
:embed_schemas, |
||||
:current_user) do |
||||
|
||||
def initialize(work_packages, |
||||
self_link, |
||||
query:, |
||||
project:, |
||||
groups:, |
||||
total_sums:, |
||||
page:, |
||||
per_page:, |
||||
embed_schemas:, |
||||
current_user:) |
||||
super(work_packages, |
||||
self_link, |
||||
query, |
||||
project, |
||||
groups, |
||||
total_sums, |
||||
page, |
||||
per_page, |
||||
embed_schemas, |
||||
current_user) |
||||
end |
||||
end |
||||
end |
||||
|
||||
let(:mock_aggregation_representer) do |
||||
Struct.new(:group, |
||||
:count, |
||||
:sums) do |
||||
|
||||
def initialize(group, |
||||
count, |
||||
sums:) |
||||
super(group, |
||||
count, |
||||
sums) |
||||
end |
||||
end |
||||
end |
||||
|
||||
let(:params) { {} } |
||||
|
||||
let(:mock_update_query_service) do |
||||
mock = double('UpdateQueryFromV3ParamsService') |
||||
|
||||
allow(mock) |
||||
.to receive(:call) |
||||
.with(params) |
||||
.and_return(mock_update_query_service_response) |
||||
|
||||
mock |
||||
end |
||||
|
||||
let(:mock_update_query_service_response) do |
||||
ServiceResult.new(success: update_query_service_success, |
||||
errors: update_query_service_errors, |
||||
result: update_query_service_result) |
||||
end |
||||
|
||||
let(:update_query_service_success) { true } |
||||
let(:update_query_service_errors) { nil } |
||||
let(:update_query_service_result) { query } |
||||
|
||||
let(:work_package) { FactoryGirl.build_stubbed(:work_package) } |
||||
|
||||
let(:instance) { described_class.new(query, user) } |
||||
|
||||
describe '#call' do |
||||
subject { instance.call(params) } |
||||
|
||||
it 'is successful' do |
||||
is_expected |
||||
.to be_success |
||||
end |
||||
|
||||
before do |
||||
stub_const('::API::V3::WorkPackages::WorkPackageCollectionRepresenter', mock_wp_representer) |
||||
stub_const('::API::Decorators::AggregationGroup', mock_aggregation_representer) |
||||
|
||||
allow(::API::V3::UpdateQueryFromV3ParamsService) |
||||
.to receive(:new) |
||||
.with(query, user) |
||||
.and_return(mock_update_query_service) |
||||
end |
||||
|
||||
context 'result' do |
||||
subject { instance.call(params).result } |
||||
|
||||
it 'is a WorkPackageCollectionRepresenter' do |
||||
is_expected |
||||
.to be_a(::API::V3::WorkPackages::WorkPackageCollectionRepresenter) |
||||
end |
||||
|
||||
context 'work_packages' do |
||||
it "has the querie's work_package results set" do |
||||
expect(subject.work_packages) |
||||
.to match_array([work_package]) |
||||
end |
||||
end |
||||
|
||||
context 'current_user' do |
||||
it 'has the provided user set' do |
||||
expect(subject.current_user) |
||||
.to eq(user) |
||||
end |
||||
end |
||||
|
||||
context 'project' do |
||||
it 'has the queries project set' do |
||||
expect(subject.project) |
||||
.to eq(query.project) |
||||
end |
||||
end |
||||
|
||||
context 'self_link' do |
||||
context 'if the project is nil' do |
||||
let(:query) { FactoryGirl.build_stubbed(:query, project: nil) } |
||||
|
||||
it 'is the global work_package link' do |
||||
expect(subject.self_link) |
||||
.to eq(api_v3_paths.work_packages) |
||||
end |
||||
end |
||||
|
||||
context 'if the project is set' do |
||||
let(:query) { FactoryGirl.build_stubbed(:query, project: project) } |
||||
|
||||
it 'is the global work_package link' do |
||||
expect(subject.self_link) |
||||
.to eq(api_v3_paths.work_packages_by_project(project.id)) |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'embed_schemas' do |
||||
it 'is true' do |
||||
expect(subject.embed_schemas) |
||||
.to be_truthy |
||||
end |
||||
end |
||||
|
||||
context 'total_sums' do |
||||
context 'with query.display_sums? being false' do |
||||
it 'is nil' do |
||||
query.display_sums = false |
||||
|
||||
expect(subject.total_sums) |
||||
.to be_nil |
||||
end |
||||
end |
||||
|
||||
context 'with query.display_sums? being true' do |
||||
it 'has a struct containg the sums' do |
||||
query.display_sums = true |
||||
|
||||
expected = OpenStruct.new(estimated_hours: 0.0) |
||||
|
||||
expect(subject.total_sums) |
||||
.to eq(expected) |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'groups' do |
||||
context 'with query.grouped? being false' do |
||||
it 'is nil' do |
||||
query.group_by = nil |
||||
|
||||
expect(subject.groups) |
||||
.to be_nil |
||||
end |
||||
end |
||||
|
||||
context 'with query.group_by being empty' do |
||||
it 'is nil' do |
||||
query.group_by = '' |
||||
|
||||
expect(subject.groups) |
||||
.to be_nil |
||||
end |
||||
end |
||||
|
||||
context 'with query.grouped? being true' do |
||||
it 'has the groups' do |
||||
query.group_by = 'status' |
||||
|
||||
expect(subject.groups[0].group) |
||||
.to eq(1) |
||||
expect(subject.groups[0].count) |
||||
.to eq(5) |
||||
expect(subject.groups[1].group) |
||||
.to eq(2) |
||||
expect(subject.groups[1].count) |
||||
.to eq(10) |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'query (in the url)' do |
||||
context 'when displaying sums' do |
||||
it 'is represented' do |
||||
query.display_sums = true |
||||
|
||||
expect(subject.query[:showSums]) |
||||
.to eq('true') |
||||
end |
||||
end |
||||
|
||||
context 'when grouping' do |
||||
it 'is represented' do |
||||
query.group_by = 'status_id' |
||||
|
||||
expect(subject.query[:groupBy]) |
||||
.to eq('status_id') |
||||
end |
||||
end |
||||
|
||||
context 'when sorting' do |
||||
it 'is represented' do |
||||
query.sort_criteria = [['status_id', 'desc']] |
||||
|
||||
expected_sort = JSON::dump [['status', 'desc']] |
||||
|
||||
expect(subject.query[:sortBy]) |
||||
.to eq(expected_sort) |
||||
end |
||||
end |
||||
|
||||
context 'filters' do |
||||
it 'is represented' do |
||||
query.add_filter('status_id', '=', ['1', '2']) |
||||
query.add_filter('subproject_id', '=', ['3', '4']) |
||||
|
||||
expected_filters = JSON::dump([ |
||||
{ status: { operator: '=', values: ['1', '2'] } }, |
||||
{ subprojectId: { operator: '=', values: ['3', '4'] } } |
||||
]) |
||||
|
||||
expect(subject.query[:filters]) |
||||
.to eq(expected_filters) |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'offset' do |
||||
it 'is 1 as default' do |
||||
expect(subject.query[:offset]) |
||||
.to be(1) |
||||
end |
||||
|
||||
context 'with a provided value' do |
||||
# It is imporant for the keys to be strings |
||||
# as that is what will come from the client |
||||
let(:params) { { 'offset' => 3 } } |
||||
|
||||
it 'is that value' do |
||||
expect(subject.query[:offset]) |
||||
.to be(3) |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'pageSize' do |
||||
before do |
||||
allow(Setting) |
||||
.to receive(:per_page_options_array) |
||||
.and_return([25, 50]) |
||||
end |
||||
|
||||
it 'is nil' do |
||||
expect(subject.query[:pageSize]) |
||||
.to be(25) |
||||
end |
||||
|
||||
context 'with a provided value' do |
||||
# It is imporant for the keys to be strings |
||||
# as that is what will come from the client |
||||
let(:params) { { 'pageSize' => 100 } } |
||||
|
||||
it 'is that value' do |
||||
expect(subject.query[:pageSize]) |
||||
.to be(100) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'when the update query service fails' do |
||||
let(:update_query_service_success) { false } |
||||
let(:update_query_service_errors) { double('errors') } |
||||
let(:update_query_service_result) { nil } |
||||
|
||||
it 'returns the update service response' do |
||||
is_expected |
||||
.to eql(mock_update_query_service_response) |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,104 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe UpdateQueryFromParamsService, |
||||
type: :model do |
||||
|
||||
let(:user) { FactoryGirl.build_stubbed(:user) } |
||||
let(:query) { FactoryGirl.build_stubbed(:query) } |
||||
|
||||
let(:instance) { described_class.new(query, user) } |
||||
|
||||
let(:params) { {} } |
||||
|
||||
describe '#call' do |
||||
subject { instance.call(params) } |
||||
|
||||
context 'group_by' do |
||||
context 'for an existing value' do |
||||
let(:params) { { group_by: 'status' } } |
||||
|
||||
it 'sets the value' do |
||||
subject |
||||
|
||||
expect(query.group_by) |
||||
.to eql('status') |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'filters' do |
||||
let(:params) do |
||||
{ filters: [{ field: 'status_id', operator: '=', values: ['1', '2'] }] } |
||||
end |
||||
|
||||
context 'for a valid filter' do |
||||
it 'sets the filter' do |
||||
subject |
||||
|
||||
expect(query.filters.length) |
||||
.to eql(1) |
||||
expect(query.filters[0].name) |
||||
.to eql(:status_id) |
||||
expect(query.filters[0].operator) |
||||
.to eql('=') |
||||
expect(query.filters[0].values) |
||||
.to eql(['1', '2']) |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'sort_by' do |
||||
let(:params) do |
||||
{ sort_by: [['status_id', 'desc']] } |
||||
end |
||||
|
||||
it 'sets the order' do |
||||
subject |
||||
|
||||
expect(query.sort_criteria) |
||||
.to eql([['status_id', 'desc']]) |
||||
end |
||||
end |
||||
|
||||
context 'columns' do |
||||
let(:params) do |
||||
{ columns: ['assigned_to', 'author', 'category', 'subject'] } |
||||
end |
||||
|
||||
it 'sets the columns' do |
||||
subject |
||||
|
||||
expect(query.column_names) |
||||
.to match_array(params[:columns].map(&:to_sym)) |
||||
end |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue