Backport was neccessary to implement missing categories filter without adding more technical debt. These changes will be merged into 4.1 and following branches and vanish in that merge (merge-strategy "ours") YOU SHOULD NOT SEE ANY CONTENTS FROM THIS COMMIT ANYWHERE AFTER 4.0.x! This commit was built from the commits of the GitHub-PR mentioned below, as well as some code dependencies for that. The GitHub-PR was https://github.com/opf/openproject/pull/2505pull/2908/head
parent
8007ad5638
commit
900b2a4c45
@ -0,0 +1,55 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'representable' |
||||
|
||||
module OpenProject::RepresentablePatch |
||||
def self.included(base) |
||||
base.class_eval do |
||||
def self.as_strategy=(strategy) |
||||
raise 'The :as_strategy option should respond to #call?' unless strategy.respond_to?(:call) |
||||
|
||||
@as_strategy = strategy |
||||
end |
||||
|
||||
def self.as_strategy |
||||
@as_strategy |
||||
end |
||||
|
||||
def self.property(name, options = {}, &block) |
||||
options = { as: as_strategy.call(name.to_s) }.merge(options) if as_strategy |
||||
|
||||
super |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
unless Representable::Decorator.included_modules.include?(OpenProject::RepresentablePatch) |
||||
Representable::Decorator.send(:include, OpenProject::RepresentablePatch) |
||||
end |
@ -0,0 +1,84 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'roar/decorator' |
||||
require 'roar/json/hal' |
||||
|
||||
module API |
||||
module Decorators |
||||
# This class is purely used for backporting categories to OP4.0. It should not be present in |
||||
# OpenProject 4.1 (you can use API::Decorators::Collection there) |
||||
class CollectionFourDotOne < Roar::Decorator |
||||
include Roar::JSON::HAL |
||||
include Roar::Hypermedia |
||||
include API::Utilities::UrlHelper |
||||
|
||||
def initialize(models, total, self_link, context: {}) |
||||
@total = total |
||||
@self_link = self_link |
||||
@context = context |
||||
|
||||
super(models) |
||||
end |
||||
|
||||
class_attribute :element_decorator_class |
||||
|
||||
def self.element_decorator(klass) |
||||
self.element_decorator_class = klass |
||||
end |
||||
|
||||
def element_decorator |
||||
self.class.element_decorator_class |
||||
end |
||||
|
||||
as_strategy = API::Utilities::CamelCasingStrategy.new |
||||
|
||||
link :self do |
||||
{ href: @self_link } |
||||
end |
||||
|
||||
property :_type, getter: -> (*) { 'Collection' } |
||||
property :total, getter: -> (*) { @total }, exec_context: :decorator |
||||
property :count, getter: -> (*) { empty? ? 0 : count } |
||||
|
||||
collection :elements, |
||||
getter: -> (*) { |
||||
represented.map { |model| |
||||
element_decorator.new(model, context) |
||||
} |
||||
}, |
||||
exec_context: :decorator, |
||||
embedded: true |
||||
|
||||
private |
||||
|
||||
attr_reader :context |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,126 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'roar/decorator' |
||||
require 'roar/hypermedia' |
||||
require 'roar/json/hal' |
||||
|
||||
require 'api/v3/utilities/path_helper' |
||||
|
||||
module API |
||||
module Decorators |
||||
class Single < ::Roar::Decorator |
||||
include ::Roar::JSON::HAL |
||||
include ::Roar::Hypermedia |
||||
include ::API::V3::Utilities::PathHelper |
||||
|
||||
attr_reader :context |
||||
class_attribute :as_strategy |
||||
self.as_strategy = ::API::Utilities::CamelCasingStrategy.new |
||||
|
||||
def initialize(model, context = {}) |
||||
@context = context |
||||
|
||||
super(model) |
||||
end |
||||
|
||||
property :_type, |
||||
exec_context: :decorator, |
||||
render_nil: false |
||||
|
||||
def self.self_link(path: nil, title_getter: -> (*) { represented.name }) |
||||
link :self do |
||||
path = _type.underscore unless path |
||||
link_object = { href: api_v3_paths.send(path, represented.id) } |
||||
title = instance_eval(&title_getter) |
||||
link_object[:title] = title if title |
||||
|
||||
link_object |
||||
end |
||||
end |
||||
|
||||
def self.linked_property(property, |
||||
path: property, |
||||
getter: property, |
||||
title_getter: -> (*) { call_or_send_to_represented(getter).name }, |
||||
show_if: -> (*) { true }, |
||||
embed_as: nil) |
||||
link property.to_s.camelize(:lower) do |
||||
next unless instance_eval(&show_if) |
||||
|
||||
value = call_or_send_to_represented(getter) |
||||
link_object = { href: (api_v3_paths.send(path, value.id) if value) } |
||||
if value |
||||
title = instance_eval(&title_getter) |
||||
link_object[:title] = title if title |
||||
end |
||||
link_object |
||||
end |
||||
|
||||
if embed_as |
||||
embed_property property, |
||||
getter: getter, |
||||
decorator: embed_as, |
||||
show_if: show_if |
||||
end |
||||
end |
||||
|
||||
def self.embed_property(property, getter: property, decorator:, show_if: true) |
||||
property property, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { call_or_send_to_represented(getter) }, |
||||
embedded: true, |
||||
decorator: decorator, |
||||
if: show_if |
||||
end |
||||
|
||||
protected |
||||
|
||||
def current_user |
||||
context[:current_user] |
||||
end |
||||
|
||||
private |
||||
|
||||
def call_or_send_to_represented(callable_or_name) |
||||
if callable_or_name.respond_to? :call |
||||
instance_exec(&callable_or_name) |
||||
else |
||||
represented.send(callable_or_name) |
||||
end |
||||
end |
||||
|
||||
def datetime_formatter |
||||
::API::V3::Utilities::DateTimeFormatter |
||||
end |
||||
|
||||
def _type; end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,50 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Categories |
||||
class CategoriesByProjectAPI < Grape::API |
||||
resources :categories do |
||||
before do |
||||
@categories = @project.categories |
||||
end |
||||
|
||||
get do |
||||
self_link = api_v3_paths.categories(@project.identifier) |
||||
|
||||
CategoryCollectionRepresenter.new(@categories, |
||||
@categories.count, |
||||
self_link) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,178 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module Utilities |
||||
module PathHelper |
||||
include API::Utilities::UrlHelper |
||||
|
||||
class ApiV3Path |
||||
def self.root |
||||
"#{root_path}api/v3" |
||||
end |
||||
|
||||
def self.activity(id) |
||||
"#{root}/activities/#{id}" |
||||
end |
||||
|
||||
def self.attachment(id) |
||||
"#{root}/attachments/#{id}" |
||||
end |
||||
|
||||
def self.available_assignees(project_id) |
||||
"#{project(project_id)}/available_assignees" |
||||
end |
||||
|
||||
def self.available_responsibles(project_id) |
||||
"#{project(project_id)}/available_responsibles" |
||||
end |
||||
|
||||
def self.available_watchers(work_package_id) |
||||
"#{work_package(work_package_id)}/available_watchers" |
||||
end |
||||
|
||||
def self.categories(project_id) |
||||
"#{project(project_id)}/categories" |
||||
end |
||||
|
||||
def self.category(id) |
||||
"#{root}/categories/#{id}" |
||||
end |
||||
|
||||
def self.preview_textile(link) |
||||
preview_markup(:textile, link) |
||||
end |
||||
|
||||
def self.priorities |
||||
"#{root}/priorities" |
||||
end |
||||
|
||||
def self.projects |
||||
"#{root}/projects" |
||||
end |
||||
|
||||
def self.project(id) |
||||
"#{projects}/#{id}" |
||||
end |
||||
|
||||
def self.query(id) |
||||
"#{root}/queries/#{id}" |
||||
end |
||||
|
||||
def self.relation(id) |
||||
"#{root}/relations/#{id}" |
||||
end |
||||
|
||||
def self.statuses |
||||
"#{root}/statuses" |
||||
end |
||||
|
||||
def self.status(id) |
||||
"#{statuses}/#{id}" |
||||
end |
||||
|
||||
def self.users |
||||
"#{root}/users" |
||||
end |
||||
|
||||
def self.user(id) |
||||
"#{users}/#{id}" |
||||
end |
||||
|
||||
def self.user_lock(id) |
||||
"#{user(id)}/lock" |
||||
end |
||||
|
||||
def self.version(version_id) |
||||
"#{root}/versions/#{version_id}" |
||||
end |
||||
|
||||
def self.versions(project_id) |
||||
"#{project(project_id)}/versions" |
||||
end |
||||
|
||||
def self.versions_projects(version_id) |
||||
"#{version(version_id)}/projects" |
||||
end |
||||
|
||||
def self.watcher(id, work_package_id) |
||||
"#{work_package(work_package_id)}/watchers/#{id}" |
||||
end |
||||
|
||||
def self.work_packages |
||||
"#{root}/work_packages" |
||||
end |
||||
|
||||
def self.work_package(id) |
||||
"#{work_packages}/#{id}" |
||||
end |
||||
|
||||
def self.work_package_activities(id) |
||||
"#{work_package(id)}/activities" |
||||
end |
||||
|
||||
def self.work_package_relations(id) |
||||
"#{work_package(id)}/relations" |
||||
end |
||||
|
||||
def self.work_package_relation(id, work_package_id) |
||||
"#{work_package_relations(work_package_id)}/#{id}" |
||||
end |
||||
|
||||
def self.work_package_form(id) |
||||
"#{work_package(id)}/form" |
||||
end |
||||
|
||||
def self.work_package_watchers(id) |
||||
"#{work_package(id)}/watchers" |
||||
end |
||||
|
||||
def self.root_path |
||||
@@root_path ||= Class.new.tap do |c| |
||||
c.extend(::API::V3::Utilities::PathHelper) |
||||
end.root_path |
||||
end |
||||
|
||||
def self.preview_markup(method, link) |
||||
path = "#{root}/render/#{method}" |
||||
|
||||
path += "?#{link}" unless link.nil? |
||||
|
||||
path |
||||
end |
||||
end |
||||
|
||||
def api_v3_paths |
||||
ApiV3Path |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,51 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
shared_examples_for 'API V3 collection decorated' do |total, count, self_link, type| |
||||
it { expect(collection).to be_json_eql('Collection'.to_json).at_path('_type') } |
||||
|
||||
describe 'elements' do |
||||
it { expect(collection).to be_json_eql(type.to_json).at_path('_embedded/elements/0/_type') } |
||||
end |
||||
|
||||
describe 'quantities' do |
||||
it { expect(collection).to be_json_eql(total.to_json).at_path('total') } |
||||
|
||||
it { expect(collection).to be_json_eql(count.to_json).at_path('count') } |
||||
|
||||
it { expect(collection).to have_json_size(count).at_path('_embedded/elements') } |
||||
end |
||||
|
||||
describe '_links' do |
||||
let(:href) { "/api/v3/#{self_link}".to_json } |
||||
|
||||
it { expect(collection).to be_json_eql(href).at_path('_links/self/href') } |
||||
end |
||||
end |
@ -0,0 +1,279 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Utilities::PathHelper do |
||||
let(:helper) { Class.new.tap { |c| c.extend(::API::V3::Utilities::PathHelper) }.api_v3_paths } |
||||
|
||||
shared_examples_for 'api v3 path' do |
||||
it { is_expected.to match(/^\/api\/v3/) } |
||||
end |
||||
|
||||
describe '#root' do |
||||
subject { helper.root } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
end |
||||
|
||||
describe '#activity' do |
||||
subject { helper.activity 1 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/activities\/1/) } |
||||
end |
||||
|
||||
describe '#attachment' do |
||||
subject { helper.attachment 1 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/attachments\/1/) } |
||||
end |
||||
|
||||
describe '#available_assignees' do |
||||
subject { helper.available_assignees 42 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/projects\/42\/available_assignees/) } |
||||
end |
||||
|
||||
describe '#available_responsibles' do |
||||
subject { helper.available_responsibles 42 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/projects\/42\/available_responsibles/) } |
||||
end |
||||
|
||||
describe '#available_watchers' do |
||||
subject { helper.available_watchers 42 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/work_packages\/42\/available_watchers/) } |
||||
end |
||||
|
||||
describe '#categories' do |
||||
subject { helper.categories 42 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/projects\/42\/categories/) } |
||||
end |
||||
|
||||
describe '#category' do |
||||
subject { helper.category 42 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/categories\/42/) } |
||||
end |
||||
|
||||
describe '#preview_textile' do |
||||
subject { helper.preview_textile '/api/v3/work_packages/42' } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/render\/textile/) } |
||||
|
||||
it { is_expected.to match(/\?\/api\/v3\/work_packages\/42$/) } |
||||
end |
||||
|
||||
describe '#priorities' do |
||||
subject { helper.priorities } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/priorities/) } |
||||
end |
||||
|
||||
describe 'projects paths' do |
||||
describe '#projects' do |
||||
subject { helper.projects } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/projects/) } |
||||
end |
||||
|
||||
describe '#project' do |
||||
subject { helper.project 1 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/projects\/1/) } |
||||
end |
||||
end |
||||
|
||||
describe '#query' do |
||||
subject { helper.query 1 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/queries\/1/) } |
||||
end |
||||
|
||||
describe 'relations paths' do |
||||
describe '#relation' do |
||||
subject { helper.relation 1 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/relations/) } |
||||
end |
||||
|
||||
describe '#relation' do |
||||
subject { helper.relation 1 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/relations\/1/) } |
||||
end |
||||
end |
||||
|
||||
describe 'statuses paths' do |
||||
describe '#statuses' do |
||||
subject { helper.statuses } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/statuses/) } |
||||
end |
||||
|
||||
describe '#status' do |
||||
subject { helper.status 1 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/statuses\/1/) } |
||||
end |
||||
end |
||||
|
||||
describe '#user' do |
||||
subject { helper.user 1 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/users\/1/) } |
||||
end |
||||
|
||||
describe '#version' do |
||||
subject { helper.version 42 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/versions\/42/) } |
||||
end |
||||
|
||||
describe '#versions' do |
||||
subject { helper.versions 42 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/projects\/42\/versions/) } |
||||
end |
||||
|
||||
describe '#versions_projects' do |
||||
subject { helper.versions_projects 42 } |
||||
|
||||
it_behaves_like 'api v3 path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/versions\/42\/projects/) } |
||||
end |
||||
|
||||
describe 'work packages paths' do |
||||
shared_examples_for 'api v3 work packages path' do |
||||
it { is_expected.to match(/^\/api\/v3\/work_packages/) } |
||||
end |
||||
|
||||
describe '#work_packages' do |
||||
subject { helper.work_packages } |
||||
|
||||
it_behaves_like 'api v3 work packages path' |
||||
end |
||||
|
||||
describe '#work_package' do |
||||
subject { helper.work_package 1 } |
||||
|
||||
it_behaves_like 'api v3 work packages path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/work_packages\/1/) } |
||||
end |
||||
|
||||
describe '#work_package_activities' do |
||||
subject { helper.work_package_activities 42 } |
||||
|
||||
it_behaves_like 'api v3 work packages path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/work_packages\/42\/activities/) } |
||||
end |
||||
|
||||
describe '#work_package_relations' do |
||||
subject { helper.work_package_relations 42 } |
||||
|
||||
it_behaves_like 'api v3 work packages path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/work_packages\/42\/relations/) } |
||||
end |
||||
|
||||
describe '#work_package_relation' do |
||||
subject { helper.work_package_relation 1, 42 } |
||||
|
||||
it_behaves_like 'api v3 work packages path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/work_packages\/42\/relations\/1/) } |
||||
end |
||||
|
||||
describe '#work_package_form' do |
||||
subject { helper.work_package_form 1 } |
||||
|
||||
it_behaves_like 'api v3 work packages path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/work_packages\/1\/form/) } |
||||
end |
||||
|
||||
describe '#work_package_watchers' do |
||||
subject { helper.work_package_watchers 1 } |
||||
|
||||
it_behaves_like 'api v3 work packages path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/work_packages\/1\/watchers/) } |
||||
end |
||||
|
||||
describe '#watcher' do |
||||
subject { helper.watcher 1, 42 } |
||||
|
||||
it_behaves_like 'api v3 work packages path' |
||||
|
||||
it { is_expected.to match(/^\/api\/v3\/work_packages\/42\/watchers\/1/) } |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,49 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
shared_examples_for 'API V3 collection response' do |total, count, type| |
||||
subject { response.body } |
||||
|
||||
it { expect(response.status).to eql(200) } |
||||
|
||||
it { is_expected.to be_json_eql('Collection'.to_json).at_path('_type') } |
||||
|
||||
it { is_expected.to be_json_eql(count.to_json).at_path('count') } |
||||
|
||||
it { is_expected.to be_json_eql(total.to_json).at_path('total') } |
||||
|
||||
it { is_expected.to have_json_size(count) .at_path('_embedded/elements') } |
||||
|
||||
it 'has element of specified type if elements exist' do |
||||
if count > 0 |
||||
is_expected.to be_json_eql(type.to_json).at_path('_embedded/elements/0/_type') |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue