Merge pull request #10136 from opf/feature/40931-signaling-included-properties-of-the-projects-api
Feature/40931 signaling included properties of the projects apipull/10274/head
commit
8431743fb3
@ -0,0 +1,5 @@ |
||||
class ProjectsLftRgtIndex < ActiveRecord::Migration[6.1] |
||||
def change |
||||
add_index :projects, %i[lft rgt] |
||||
end |
||||
end |
@ -0,0 +1,83 @@ |
||||
--- |
||||
description: |- |
||||
Some endpoints, especially those returning `Collection` resources, support signaling desired properties. By signaling, the client |
||||
can convey to the server the properties to include in a response. |
||||
|
||||
Currently only `select` is supported which allows to specify the subset of properties a client is interested in. The benefit of using `select` |
||||
is reduced response time. Other signaling, especially expanding the embedded resources to include as well over multiple layers of embedding |
||||
are in consideration to be implemented (probably named `embed`) but as of now, they are not supported. Please also see |
||||
[the specification for OData that inspired this feature](https://www.odata.org/documentation/odata-version-2-0/uri-conventions/). |
||||
|
||||
For example, a resource `/api/v3/bogus` that without signaling returns: |
||||
|
||||
``` |
||||
{ |
||||
"_type": "Collection" |
||||
"count": 20, |
||||
"total": 554, |
||||
"_embedded": { |
||||
"elements": [ |
||||
{ |
||||
"id": 1, |
||||
"name": "Some name" |
||||
}, |
||||
{ |
||||
"id": 9, |
||||
"name": "Another name" |
||||
} |
||||
] |
||||
}, |
||||
"_links": { |
||||
"self": { |
||||
"href": "/api/v3/bogus", |
||||
"title": "A bogus collection" |
||||
}, |
||||
"bar": { |
||||
"href": "/api/v3/bar", |
||||
"title": "Foobar" |
||||
} |
||||
} |
||||
} |
||||
``` |
||||
|
||||
can via signaling `/api/v3/bogus?select=total,elements/name,bar` be instructed to return: |
||||
|
||||
``` |
||||
{ |
||||
"total": 554, |
||||
"_embedded": { |
||||
"elements": [ |
||||
{ |
||||
"name": "Some name" |
||||
}, |
||||
{ |
||||
"name": "Another name" |
||||
} |
||||
] |
||||
}, |
||||
"_links": { |
||||
"bar": { |
||||
"href": "/api/v3/bar", |
||||
"title": "Foobar" |
||||
} |
||||
} |
||||
} |
||||
``` |
||||
|
||||
The `select` query property is a comma separated list of the properties to include, e.g. `select=total,elements/name,bar`. |
||||
The API also accepts alternative styles of writing like `select=["total","elements/name","bar"]`. Each individual item in the list |
||||
is the path inside the resource. So while `total` refers to the property on the top level, `elements/name` refers to the property `name` within |
||||
the collection of `elements`. The full path has to be provided for every property, e.g. `select=elements/name,elements/id`. |
||||
The order of the list has no impact on the selection. There is also a wildcard `*` which will result in every property on that level to be selected. |
||||
To select every property in the example above, the client would have to signal `select=*,elements/*`. |
||||
|
||||
Please note that the nesting into `_embedded` and `_links` is not included in the query prop `select` as |
||||
links in the context of HAL can be considered properties of the resource just the same as unnested properties and forcing |
||||
clients to write the full nesting would not increase clarity. |
||||
|
||||
Link properties are considered to be a single value that cannot be split up further. Every property within a link will be returned |
||||
if the link is signaled to be selected. |
||||
|
||||
The `select` signaling flag has been introduced for performance reasons. Not every end point supports it and those that do oftentimes only |
||||
allow a subset of their resource's properties to be selected. End points supporting the `select` query prop are documented accordingly. |
||||
name: Signaling |
@ -0,0 +1,37 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module Groups |
||||
class GroupSqlCollectionRepresenter < API::Decorators::SqlCollectionRepresenter |
||||
self.embed_map = { |
||||
elements: GroupSqlRepresenter |
||||
}.with_indifferent_access |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,48 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module Groups |
||||
class GroupSqlRepresenter |
||||
include API::Decorators::Sql::Hal |
||||
|
||||
link :self, |
||||
path: { api: :group, params: %w(id) }, |
||||
column: -> { :id }, |
||||
title: -> { 'lastname' } |
||||
|
||||
property :_type, |
||||
representation: ->(*) { "'Group'" } |
||||
|
||||
property :id |
||||
|
||||
property :name, |
||||
column: :lastname |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,37 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module PlaceholderUsers |
||||
class PlaceholderUserSqlCollectionRepresenter < API::Decorators::SqlCollectionRepresenter |
||||
self.embed_map = { |
||||
elements: PlaceholderUserSqlRepresenter |
||||
}.with_indifferent_access |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,48 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module PlaceholderUsers |
||||
class PlaceholderUserSqlRepresenter |
||||
include API::Decorators::Sql::Hal |
||||
|
||||
link :self, |
||||
path: { api: :placeholder_user, params: %w(id) }, |
||||
column: -> { :id }, |
||||
title: -> { 'lastname' } |
||||
|
||||
property :_type, |
||||
representation: ->(*) { "'PlaceholderUser'" } |
||||
|
||||
property :id |
||||
|
||||
property :name, |
||||
column: :lastname |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,37 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
#-- encoding: UTF-8 |
||||
|
||||
# Exists to satisfy the expectations of the default end points. |
||||
module API |
||||
module V3 |
||||
module Principals |
||||
class PrincipalCollectionRepresenter < ::API::V3::Users::UserCollectionRepresenter |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,37 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module Principals |
||||
class PrincipalSqlCollectionRepresenter < API::Decorators::SqlCollectionRepresenter |
||||
self.embed_map = { |
||||
elements: PrincipalSqlRepresenter |
||||
}.with_indifferent_access |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,70 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module Principals |
||||
# This representer is able to render all the concrete classes of Principal: User, Group and PlaceholderUser. |
||||
class PrincipalSqlRepresenter |
||||
include API::Decorators::Sql::Hal |
||||
|
||||
class << self |
||||
def select_sql(select, walker_result) |
||||
<<~SELECT |
||||
json_strip_nulls( |
||||
CASE |
||||
WHEN type = 'Group' THEN json_build_object(#{group_select_sql(select, walker_result)}) |
||||
WHEN type = 'PlaceholderUser' THEN json_build_object(#{placeholder_user_select_sql(select, walker_result)}) |
||||
WHEN type = 'User' THEN json_build_object(#{user_select_sql(select, walker_result)}) |
||||
END |
||||
) |
||||
SELECT |
||||
end |
||||
|
||||
private |
||||
|
||||
def group_select_sql(select, walker_result) |
||||
API::V3::Groups::GroupSqlRepresenter.json_object_string(select, walker_result) |
||||
end |
||||
|
||||
def placeholder_user_select_sql(select, walker_result) |
||||
API::V3::PlaceholderUsers::PlaceholderUserSqlRepresenter.json_object_string(select, walker_result) |
||||
end |
||||
|
||||
def user_select_sql(select, walker_result) |
||||
API::V3::Users::UserSqlRepresenter.json_object_string(select, walker_result) |
||||
end |
||||
|
||||
def valid_selects |
||||
API::V3::Groups::GroupSqlRepresenter.valid_selects & |
||||
API::V3::PlaceholderUsers::PlaceholderUserSqlRepresenter.valid_selects & |
||||
API::V3::Users::UserSqlRepresenter.valid_selects |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,37 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module Projects |
||||
class ProjectSqlCollectionRepresenter < API::Decorators::SqlCollectionRepresenter |
||||
self.embed_map = { |
||||
elements: ProjectSqlRepresenter |
||||
}.with_indifferent_access |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,133 @@ |
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2020 the OpenProject GmbH |
||||
# |
||||
# 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 COPYRIGHT and LICENSE files for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Projects |
||||
class ProjectSqlRepresenter |
||||
include API::Decorators::Sql::Hal |
||||
|
||||
class << self |
||||
def ctes(walker_result) |
||||
{ |
||||
ancestors: ancestors_sql(walker_result) |
||||
} |
||||
end |
||||
|
||||
protected |
||||
|
||||
def ancestors_sql(walker_result) |
||||
<<-SQL.squish |
||||
SELECT id, CASE WHEN count(link) = 0 THEN '[]' ELSE json_agg(link) END ancestors |
||||
FROM |
||||
( |
||||
SELECT |
||||
origin.id, |
||||
#{ancestor_projection} link |
||||
FROM projects origin |
||||
LEFT OUTER JOIN projects ancestors |
||||
ON ancestors.lft < origin.lft AND ancestors.rgt > origin.rgt |
||||
#{visibility_join} |
||||
WHERE origin.id IN (#{origin_subselect(walker_result).select(:id).to_sql}) |
||||
ORDER by origin.id, ancestors.lft |
||||
) ancestors |
||||
GROUP BY id |
||||
SQL |
||||
end |
||||
|
||||
def origin_subselect(walker_result) |
||||
if walker_result.page_size |
||||
walker_result.filter_scope.limit(sql_limit(walker_result)).offset(sql_offset(walker_result)) |
||||
else |
||||
walker_result.filter_scope |
||||
end |
||||
end |
||||
|
||||
def ancestor_projection |
||||
if User.current.admin? |
||||
<<-SQL.squish |
||||
CASE |
||||
WHEN ancestors.id IS NOT NULL |
||||
THEN json_build_object('href', format('/api/v3/projects/%s', ancestors.id), 'title', ancestors.name) |
||||
ELSE NULL |
||||
END |
||||
SQL |
||||
else |
||||
<<-SQL.squish |
||||
CASE |
||||
WHEN ancestors.id IS NOT NULL AND visible_ancestors.id IS NOT NULL |
||||
THEN json_build_object('href', format('/api/v3/projects/%s', ancestors.id), 'title', ancestors.name) |
||||
WHEN ancestors.id IS NOT NULL AND visible_ancestors.id IS NULL |
||||
THEN json_build_object('href', '#{API::V3::URN_UNDISCLOSED}', 'title', '#{I18n.t(:'api_v3.undisclosed.ancestor')}') |
||||
ELSE NULL |
||||
END |
||||
SQL |
||||
end |
||||
end |
||||
|
||||
def visibility_join |
||||
if User.current.admin? |
||||
'' |
||||
else |
||||
<<-SQL.squish |
||||
LEFT OUTER JOIN (#{Project.visible.to_sql}) visible_ancestors |
||||
ON visible_ancestors.id = ancestors.id |
||||
SQL |
||||
end |
||||
end |
||||
end |
||||
|
||||
link :self, |
||||
path: { api: :project, params: %w(id) }, |
||||
column: -> { :id }, |
||||
title: -> { :name } |
||||
|
||||
link :ancestors, |
||||
sql: -> { 'ancestors' }, |
||||
join: { |
||||
table: :ancestors, |
||||
condition: 'ancestors.id = projects.id', |
||||
select: 'ancestors' |
||||
} |
||||
|
||||
property :_type, |
||||
representation: ->(*) { "'Project'" } |
||||
|
||||
property :id |
||||
|
||||
property :name |
||||
|
||||
property :identifier |
||||
|
||||
property :active |
||||
|
||||
property :public |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,37 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module Users |
||||
class UserSqlCollectionRepresenter < API::Decorators::SqlCollectionRepresenter |
||||
self.embed_map = { |
||||
elements: UserSqlRepresenter |
||||
}.with_indifferent_access |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,83 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module Users |
||||
class UserSqlRepresenter |
||||
include API::Decorators::Sql::Hal |
||||
|
||||
class << self |
||||
def user_name_projection(*) |
||||
case Setting.user_format |
||||
when :firstname_lastname |
||||
'concat(firstname, \' \', lastname)' |
||||
when :firstname |
||||
'firstname' |
||||
when :lastname_firstname |
||||
'concat(lastname, \' \', firstname)' |
||||
when :lastname_coma_firstname |
||||
'concat(lastname, \', \', firstname)' |
||||
when :lastname_n_firstname |
||||
'concat_ws(lastname, \'\', firstname)' |
||||
when :username |
||||
'login' |
||||
else |
||||
raise ArgumentError, "Invalid user format" |
||||
end |
||||
end |
||||
|
||||
def render_if_manage_user_or_self(*) |
||||
if User.current.allowed_to_globally?(:manage_user) |
||||
'TRUE' |
||||
else |
||||
"id = #{User.current.id}" |
||||
end |
||||
end |
||||
end |
||||
|
||||
link :self, |
||||
path: { api: :user, params: %w(id) }, |
||||
column: -> { :id }, |
||||
title: method(:user_name_projection) |
||||
|
||||
property :_type, |
||||
representation: ->(*) { "'User'" } |
||||
|
||||
property :id |
||||
|
||||
property :name, |
||||
representation: method(:user_name_projection) |
||||
|
||||
property :firstname, |
||||
render_if: method(:render_if_manage_user_or_self) |
||||
|
||||
property :lastname, |
||||
render_if: method(:render_if_manage_user_or_self) |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,69 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module Utilities |
||||
module Endpoints |
||||
class SqlFallbackedIndex < SqlIndex |
||||
private |
||||
|
||||
def render_paginated_success(results, query, params, self_path) |
||||
resulting_params = calculate_resulting_params(query, params) |
||||
|
||||
if resulting_params[:select] |
||||
::API::V3::Utilities::SqlRepresenterWalker |
||||
.new(results, |
||||
current_user: User.current, |
||||
self_path: self_path, |
||||
url_query: resulting_params) |
||||
.walk(deduce_render_representer) |
||||
else |
||||
deduce_fallback_render_representer |
||||
.new(results, |
||||
self_link: self_path, |
||||
query: resulting_params, |
||||
page: resulting_params[:offset], |
||||
per_page: resulting_params[:pageSize], |
||||
groups: calculate_groups(query), |
||||
current_user: User.current) |
||||
end |
||||
end |
||||
|
||||
def deduce_fallback_render_representer |
||||
"::API::V3::#{deduce_api_namespace}::#{api_name}CollectionRepresenter".constantize |
||||
end |
||||
|
||||
def calculate_resulting_params(query, provided_params) |
||||
super.tap do |params| |
||||
params.delete(:select) unless provided_params.has_key?(:select) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,37 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class WorkPackageSqlCollectionRepresenter < API::Decorators::SqlCollectionRepresenter |
||||
self.embed_map = { |
||||
elements: WorkPackageSqlRepresenter |
||||
}.with_indifferent_access |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,47 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class WorkPackageSqlRepresenter |
||||
include API::Decorators::Sql::Hal |
||||
|
||||
link :self, |
||||
path: { api: :work_package, params: %w(id) }, |
||||
column: -> { :id }, |
||||
title: -> { 'subject' } |
||||
|
||||
property :_type, |
||||
representation: ->(*) { "'WorkPackage'" } |
||||
|
||||
property :id |
||||
|
||||
property :subject |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,74 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Groups::GroupSqlRepresenter, 'rendering' do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
subject(:json) do |
||||
::API::V3::Utilities::SqlRepresenterWalker |
||||
.new(scope, |
||||
current_user: current_user, |
||||
url_query: { select: select }) |
||||
.walk(described_class) |
||||
.to_json |
||||
end |
||||
|
||||
let(:scope) do |
||||
Group |
||||
.where(id: group.id) |
||||
end |
||||
|
||||
let(:group) { create(:group) } |
||||
|
||||
let(:select) { { '*' => {} } } |
||||
|
||||
current_user do |
||||
create(:user) |
||||
end |
||||
|
||||
context 'when rendering all supported properties' do |
||||
let(:expected) do |
||||
{ |
||||
_type: "Group", |
||||
id: group.id, |
||||
name: group.name, |
||||
_links: { |
||||
self: { |
||||
href: api_v3_paths.group(group.id), |
||||
title: group.name |
||||
} |
||||
} |
||||
} |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql(expected.to_json) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,74 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::PlaceholderUsers::PlaceholderUserSqlRepresenter, 'rendering' do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
subject(:json) do |
||||
::API::V3::Utilities::SqlRepresenterWalker |
||||
.new(scope, |
||||
current_user: current_user, |
||||
url_query: { select: select }) |
||||
.walk(described_class) |
||||
.to_json |
||||
end |
||||
|
||||
let(:scope) do |
||||
PlaceholderUser |
||||
.where(id: placeholder_user.id) |
||||
end |
||||
|
||||
let(:placeholder_user) { create(:placeholder_user) } |
||||
|
||||
let(:select) { { '*' => {} } } |
||||
|
||||
current_user do |
||||
create(:user) |
||||
end |
||||
|
||||
context 'when rendering all supported properties' do |
||||
let(:expected) do |
||||
{ |
||||
_type: "PlaceholderUser", |
||||
id: placeholder_user.id, |
||||
name: placeholder_user.name, |
||||
_links: { |
||||
self: { |
||||
href: api_v3_paths.placeholder_user(placeholder_user.id), |
||||
title: placeholder_user.name |
||||
} |
||||
} |
||||
} |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql(expected.to_json) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,141 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Principals::PrincipalSqlRepresenter, 'rendering' do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
subject(:json) do |
||||
::API::V3::Utilities::SqlRepresenterWalker |
||||
.new(scope, |
||||
current_user: current_user, |
||||
url_query: { select: select }) |
||||
.walk(described_class) |
||||
.to_json |
||||
end |
||||
|
||||
let(:scope) do |
||||
Principal |
||||
.where(id: rendered_principal.id) |
||||
end |
||||
|
||||
let(:group) { create(:group) } |
||||
let(:placeholder_user) { create(:placeholder_user) } |
||||
|
||||
let(:select) { { '*' => {} } } |
||||
|
||||
current_user do |
||||
create(:user) |
||||
end |
||||
|
||||
context 'when rendering all supported properties for a group' do |
||||
let(:rendered_principal) { group } |
||||
|
||||
let(:expected) do |
||||
{ |
||||
_type: "Group", |
||||
id: group.id, |
||||
name: group.name, |
||||
_links: { |
||||
self: { |
||||
href: api_v3_paths.group(group.id), |
||||
title: group.name |
||||
} |
||||
} |
||||
} |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql(expected.to_json) |
||||
end |
||||
end |
||||
|
||||
context 'when rendering all supported properties for a placeholder user' do |
||||
let(:rendered_principal) { placeholder_user } |
||||
|
||||
let(:expected) do |
||||
{ |
||||
_type: "PlaceholderUser", |
||||
id: placeholder_user.id, |
||||
name: placeholder_user.name, |
||||
_links: { |
||||
self: { |
||||
href: api_v3_paths.placeholder_user(placeholder_user.id), |
||||
title: placeholder_user.name |
||||
} |
||||
} |
||||
} |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql(expected.to_json) |
||||
end |
||||
end |
||||
|
||||
context 'when rendering all supported properties for a user' do |
||||
let(:rendered_principal) { current_user } |
||||
|
||||
let(:expected) do |
||||
{ |
||||
_type: "User", |
||||
id: current_user.id, |
||||
name: current_user.name, |
||||
firstname: current_user.firstname, |
||||
lastname: current_user.lastname, |
||||
_links: { |
||||
self: { |
||||
href: api_v3_paths.user(current_user.id), |
||||
title: current_user.name |
||||
} |
||||
} |
||||
} |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql(expected.to_json) |
||||
end |
||||
end |
||||
|
||||
context 'when rendering only the name property for a user' do |
||||
let(:rendered_principal) { current_user } |
||||
let(:select) { { 'name' => {} } } |
||||
|
||||
let(:expected) do |
||||
{ |
||||
name: current_user.name |
||||
} |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql(expected.to_json) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,145 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Projects::ProjectSqlCollectionRepresenter, 'rendering' do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
subject(:json) do |
||||
::API::V3::Utilities::SqlRepresenterWalker |
||||
.new(scope, |
||||
current_user: current_user, |
||||
self_path: 'some_path', |
||||
url_query: { offset: 1, pageSize: 5, select: select }) |
||||
.walk(described_class) |
||||
.to_json |
||||
end |
||||
|
||||
let(:scope) do |
||||
Project |
||||
.where(id: project.id) |
||||
end |
||||
|
||||
let(:project) do |
||||
create(:project) |
||||
end |
||||
|
||||
let(:role) { create(:role) } |
||||
|
||||
let(:select) do |
||||
{ '*' => {}, 'elements' => { '*' => {} } } |
||||
end |
||||
|
||||
current_user do |
||||
create(:user, |
||||
member_in_project: project, |
||||
member_through_role: role) |
||||
end |
||||
|
||||
context 'when rendering everything' do |
||||
let(:expected) do |
||||
{ |
||||
_type: "Collection", |
||||
pageSize: 5, |
||||
total: 1, |
||||
count: 1, |
||||
offset: 1, |
||||
_embedded: { |
||||
elements: [ |
||||
{ |
||||
id: project.id, |
||||
_type: "Project", |
||||
name: project.name, |
||||
identifier: project.identifier, |
||||
active: true, |
||||
public: false, |
||||
_links: { |
||||
ancestors: [], |
||||
self: { |
||||
href: api_v3_paths.project(project.id), |
||||
title: project.name |
||||
} |
||||
} |
||||
} |
||||
] |
||||
}, |
||||
_links: { |
||||
self: { |
||||
href: "some_path?offset=1&pageSize=5&select=%2A%2Celements%2F%2A" |
||||
}, |
||||
changeSize: { |
||||
href: "some_path?offset=1&pageSize=%7Bsize%7D&select=%2A%2Celements%2F%2A", |
||||
templated: true |
||||
}, |
||||
jumpTo: { |
||||
href: "some_path?offset=%7Boffset%7D&pageSize=5&select=%2A%2Celements%2F%2A", |
||||
templated: true |
||||
} |
||||
} |
||||
}.to_json |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql(expected) |
||||
end |
||||
end |
||||
|
||||
context 'when rendering only collection attributes' do |
||||
let(:select) do |
||||
{ '*' => {} } |
||||
end |
||||
|
||||
let(:expected) do |
||||
{ |
||||
_type: "Collection", |
||||
pageSize: 5, |
||||
total: 1, |
||||
count: 1, |
||||
offset: 1, |
||||
_links: { |
||||
self: { |
||||
href: "some_path?offset=1&pageSize=5&select=%2A" |
||||
}, |
||||
changeSize: { |
||||
href: "some_path?offset=1&pageSize=%7Bsize%7D&select=%2A", |
||||
templated: true |
||||
}, |
||||
jumpTo: { |
||||
href: "some_path?offset=%7Boffset%7D&pageSize=5&select=%2A", |
||||
templated: true |
||||
} |
||||
} |
||||
}.to_json |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql(expected) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,200 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Projects::ProjectSqlRepresenter, 'rendering' do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
subject(:json) do |
||||
::API::V3::Utilities::SqlRepresenterWalker |
||||
.new(scope, |
||||
current_user: current_user, |
||||
url_query: { select: select }) |
||||
.walk(described_class) |
||||
.to_json |
||||
end |
||||
|
||||
let(:scope) do |
||||
Project |
||||
.where(id: project.id) |
||||
end |
||||
|
||||
let(:project) do |
||||
create(:project) |
||||
end |
||||
|
||||
let(:role) { create(:role) } |
||||
|
||||
let(:select) { { '*' => {} } } |
||||
|
||||
current_user do |
||||
create(:user, |
||||
member_in_project: project, |
||||
member_through_role: role) |
||||
end |
||||
|
||||
context 'when rendering all supported properties' do |
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql( |
||||
{ |
||||
id: project.id, |
||||
_type: "Project", |
||||
name: project.name, |
||||
identifier: project.identifier, |
||||
active: true, |
||||
public: false, |
||||
_links: { |
||||
ancestors: [], |
||||
self: { |
||||
href: api_v3_paths.project(project.id), |
||||
title: project.name |
||||
} |
||||
} |
||||
}.to_json |
||||
) |
||||
end |
||||
end |
||||
|
||||
context 'with an ancestor' do |
||||
let!(:parent) do |
||||
create(:project, members: { current_user => role }).tap do |parent| |
||||
project.parent = parent |
||||
project.save |
||||
end |
||||
end |
||||
|
||||
let!(:grandparent) do |
||||
create(:project, members: { current_user => role }).tap do |grandparent| |
||||
parent.parent = grandparent |
||||
parent.save |
||||
end |
||||
end |
||||
|
||||
let(:select) { { 'ancestors' => {} } } |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql( |
||||
{ |
||||
_links: { |
||||
ancestors: [ |
||||
{ |
||||
href: api_v3_paths.project(grandparent.id), |
||||
title: grandparent.name |
||||
}, |
||||
{ |
||||
href: api_v3_paths.project(parent.id), |
||||
title: parent.name |
||||
} |
||||
] |
||||
} |
||||
}.to_json |
||||
) |
||||
end |
||||
end |
||||
|
||||
context 'with an ancestor the user does not have permission to see' do |
||||
let!(:parent) do |
||||
create(:project).tap do |parent| |
||||
project.parent = parent |
||||
project.save |
||||
end |
||||
end |
||||
|
||||
let!(:grandparent) do |
||||
create(:project, members: { current_user => role }).tap do |grandparent| |
||||
parent.parent = grandparent |
||||
parent.save |
||||
end |
||||
end |
||||
|
||||
let(:select) { { 'ancestors' => {} } } |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql( |
||||
{ |
||||
_links: { |
||||
ancestors: [ |
||||
{ |
||||
href: api_v3_paths.project(grandparent.id), |
||||
title: grandparent.name |
||||
}, |
||||
{ |
||||
href: API::V3::URN_UNDISCLOSED, |
||||
title: I18n.t(:'api_v3.undisclosed.ancestor') |
||||
} |
||||
] |
||||
} |
||||
}.to_json |
||||
) |
||||
end |
||||
end |
||||
|
||||
context 'with an archived ancestor but with the user being admin' do |
||||
let!(:parent) do |
||||
create(:project, active: false).tap do |parent| |
||||
project.parent = parent |
||||
project.save |
||||
end |
||||
end |
||||
|
||||
let!(:grandparent) do |
||||
create(:project).tap do |grandparent| |
||||
parent.parent = grandparent |
||||
parent.save |
||||
end |
||||
end |
||||
|
||||
let(:select) { { 'ancestors' => {} } } |
||||
|
||||
current_user do |
||||
create(:admin) |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql( |
||||
{ |
||||
_links: { |
||||
ancestors: [ |
||||
{ |
||||
href: api_v3_paths.project(grandparent.id), |
||||
title: grandparent.name |
||||
}, |
||||
{ |
||||
href: api_v3_paths.project(parent.id), |
||||
title: parent.name |
||||
} |
||||
] |
||||
} |
||||
}.to_json |
||||
) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,189 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Users::UserSqlRepresenter, 'rendering' do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
subject(:json) do |
||||
::API::V3::Utilities::SqlRepresenterWalker |
||||
.new(scope, |
||||
current_user: current_user, |
||||
url_query: { select: select }) |
||||
.walk(described_class) |
||||
.to_json |
||||
end |
||||
|
||||
let(:scope) do |
||||
User |
||||
.where(id: rendered_user.id) |
||||
end |
||||
|
||||
let(:rendered_user) { current_user } |
||||
|
||||
let(:select) { { '*' => {} } } |
||||
|
||||
current_user do |
||||
create(:user) |
||||
end |
||||
|
||||
context 'when rendering all supported properties' do |
||||
let(:expected) do |
||||
{ |
||||
_type: "User", |
||||
id: current_user.id, |
||||
name: current_user.name, |
||||
firstname: current_user.firstname, |
||||
lastname: current_user.lastname, |
||||
_links: { |
||||
self: { |
||||
href: api_v3_paths.user(current_user.id), |
||||
title: current_user.name |
||||
} |
||||
} |
||||
} |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql(expected.to_json) |
||||
end |
||||
end |
||||
|
||||
describe 'name property' do |
||||
shared_examples_for 'name property depending on user format setting' do |
||||
let(:select) { { 'name' => {} } } |
||||
|
||||
let(:expected) do |
||||
{ |
||||
name: current_user.name |
||||
} |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql(expected.to_json) |
||||
end |
||||
end |
||||
|
||||
context 'when user_format is set to firstname', with_settings: { user_format: :firstname } do |
||||
it_behaves_like 'name property depending on user format setting' |
||||
end |
||||
|
||||
context 'when user_format is set to lastname_firstname', with_settings: { user_format: :lastname_firstname } do |
||||
it_behaves_like 'name property depending on user format setting' |
||||
end |
||||
|
||||
context 'when user_format is set to lastname_coma_firstname', with_settings: { user_format: :lastname_coma_firstname } do |
||||
it_behaves_like 'name property depending on user format setting' |
||||
end |
||||
|
||||
context 'when user_format is set to lastname_n_firstname', with_settings: { user_format: :lastname_n_firstname } do |
||||
it_behaves_like 'name property depending on user format setting' |
||||
end |
||||
|
||||
context 'when user_format is set to username', with_settings: { user_format: :username } do |
||||
it_behaves_like 'name property depending on user format setting' |
||||
end |
||||
end |
||||
|
||||
describe 'firstname property' do |
||||
let(:select) { { 'firstname' => {} } } |
||||
|
||||
context 'when the user is the current user' do |
||||
it 'renders the firstname' do |
||||
expect(json) |
||||
.to be_json_eql( |
||||
{ |
||||
firstname: rendered_user.firstname |
||||
}.to_json |
||||
) |
||||
end |
||||
end |
||||
|
||||
context 'when the user is a user not having manage_user permission' do |
||||
let(:rendered_user) { create(:user) } |
||||
|
||||
it 'hides the firstname' do |
||||
expect(json) |
||||
.to be_json_eql({}.to_json) |
||||
end |
||||
end |
||||
|
||||
context 'when the user is a user having manage_user permission' do |
||||
let(:current_user) { create(:user, global_permissions: [:manage_user]) } |
||||
let(:rendered_user) { create(:user) } |
||||
|
||||
it 'renders the firstname' do |
||||
expect(json) |
||||
.to be_json_eql( |
||||
{ |
||||
firstname: rendered_user.firstname |
||||
}.to_json |
||||
) |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe 'lastname property' do |
||||
let(:select) { { 'lastname' => {} } } |
||||
|
||||
context 'when the user is the current user' do |
||||
it 'renders the lastname' do |
||||
expect(json) |
||||
.to be_json_eql( |
||||
{ |
||||
lastname: rendered_user.lastname |
||||
}.to_json |
||||
) |
||||
end |
||||
end |
||||
|
||||
context 'when the user is a user not having manage_user permission' do |
||||
let(:rendered_user) { create(:user) } |
||||
|
||||
it 'hides the lastname' do |
||||
expect(json) |
||||
.to be_json_eql({}.to_json) |
||||
end |
||||
end |
||||
|
||||
context 'when the user is a user having manage_user permission' do |
||||
let(:current_user) { create(:user, global_permissions: [:manage_user]) } |
||||
let(:rendered_user) { create(:user) } |
||||
|
||||
it 'renders the lastname' do |
||||
expect(json) |
||||
.to be_json_eql( |
||||
{ |
||||
lastname: rendered_user.lastname |
||||
}.to_json |
||||
) |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,74 @@ |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2010-2022 the OpenProject GmbH |
||||
# |
||||
# 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-2013 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 COPYRIGHT and LICENSE files for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::WorkPackages::WorkPackageSqlRepresenter, 'rendering' do |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
subject(:json) do |
||||
::API::V3::Utilities::SqlRepresenterWalker |
||||
.new(scope, |
||||
current_user: current_user, |
||||
url_query: { select: select }) |
||||
.walk(described_class) |
||||
.to_json |
||||
end |
||||
|
||||
let(:scope) do |
||||
WorkPackage |
||||
.where(id: rendered_work_package.id) |
||||
end |
||||
|
||||
let(:rendered_work_package) { create(:work_package) } |
||||
|
||||
let(:select) { { '*' => {} } } |
||||
|
||||
current_user do |
||||
create(:user) |
||||
end |
||||
|
||||
context 'when rendering all supported properties' do |
||||
let(:expected) do |
||||
{ |
||||
_type: "WorkPackage", |
||||
id: rendered_work_package.id, |
||||
subject: rendered_work_package.subject, |
||||
_links: { |
||||
self: { |
||||
href: api_v3_paths.work_package(rendered_work_package.id), |
||||
title: rendered_work_package.subject |
||||
} |
||||
} |
||||
} |
||||
end |
||||
|
||||
it 'renders as expected' do |
||||
expect(json) |
||||
.to be_json_eql(expected.to_json) |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue