summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOswaldo Ferreira <oswaldo@gitlab.com>2017-04-06 22:36:09 -0300
committerOswaldo Ferreira <oswaldo@gitlab.com>2017-06-06 17:07:57 -0300
commitb9bba9d39c38a17ac55fc60c5ac89cdbbfc6c2f5 (patch)
tree9689b856bd6554557f7d42835e82be813e78a330
parentd1c2d36f0325c79aed9b5ae2e6396591c6ced3be (diff)
downloadgitlab-ce-22600-related-resources-uris-using-grape-source-helpers.tar.gz
Declare related resource URI's for Issues API22600-related-resources-uris-using-grape-source-helpers
-rw-r--r--Gemfile1
-rw-r--r--Gemfile.lock11
-rw-r--r--changelogs/unreleased/22600-related-resources-uris-using-grape-source-helpers.yml4
-rw-r--r--config/routes/api.rb2
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/entities.rb24
-rw-r--r--lib/api/helpers/related_resources_helpers.rb31
-rw-r--r--lib/api/v3/entities.rb6
-rw-r--r--spec/requests/api/issues_spec.rb41
9 files changed, 120 insertions, 1 deletions
diff --git a/Gemfile b/Gemfile
index 56f5a8f6a41..9e0a6764b58 100644
--- a/Gemfile
+++ b/Gemfile
@@ -16,6 +16,7 @@ gem 'mysql2', '~> 0.3.16', group: :mysql
gem 'pg', '~> 0.18.2', group: :postgres
gem 'rugged', '~> 0.25.1.1'
+gem 'grape-route-helpers', github: 'oswaldoferreira/grape-route-helpers', branch: 'master'
gem 'faraday', '~> 0.11.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index be1f6555851..5418ed6cd24 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,3 +1,13 @@
+GIT
+ remote: git://github.com/oswaldoferreira/grape-route-helpers.git
+ revision: fe80756582958a40b87f53d7e257ae8c0a8aaccd
+ branch: master
+ specs:
+ grape-route-helpers (2.1.0)
+ activesupport
+ grape (>= 0.19.0)
+ rake
+
GEM
remote: https://rubygems.org/
specs:
@@ -944,6 +954,7 @@ DEPENDENCIES
google-api-client (~> 0.8.6)
grape (~> 0.19.0)
grape-entity (~> 0.6.0)
+ grape-route-helpers!
haml_lint (~> 0.21.0)
hamlit (~> 2.6.1)
hashie-forbidden_attributes
diff --git a/changelogs/unreleased/22600-related-resources-uris-using-grape-source-helpers.yml b/changelogs/unreleased/22600-related-resources-uris-using-grape-source-helpers.yml
new file mode 100644
index 00000000000..837a34bd067
--- /dev/null
+++ b/changelogs/unreleased/22600-related-resources-uris-using-grape-source-helpers.yml
@@ -0,0 +1,4 @@
+---
+title: Declare related resources into V4 API entities
+merge_request:
+author:
diff --git a/config/routes/api.rb b/config/routes/api.rb
index 69c8efc151c..ce7a7c88900 100644
--- a/config/routes/api.rb
+++ b/config/routes/api.rb
@@ -1,2 +1,2 @@
API::API.logger Rails.logger
-mount API::API => '/api'
+mount API::API => '/'
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 88f91c07194..981dda414f1 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -2,6 +2,7 @@ module API
class API < Grape::API
include APIGuard
+ prefix :api
version %w(v3 v4), using: :path
version 'v3', using: :path do
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index ded5c65e303..c80fa806084 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -287,6 +287,30 @@ module API
end
class Issue < IssueBasic
+ include ::API::Helpers::RelatedResourcesHelpers
+
+ expose :relationship_urls do
+ expose :self do |_, options|
+ expose_url(options)
+ end
+
+ expose :issues, if: @@issues_available do |issue, options|
+ expose_url(options, api_v4_issues_path)
+ end
+
+ expose :project_issues, if: @@issues_available do |issue, options|
+ expose_url(options, api_v4_projects_issues_path(id: issue.project.id))
+ end
+
+ expose :project_merge_requests, if: @@merge_requests_available do |issue, options|
+ expose_url(options, api_v4_projects_merge_requests_path(id: issue.project.id))
+ end
+
+ expose :project_repo_branches do |issue, options|
+ expose_url(options, api_v4_projects_repository_branches_path(id: issue.project.id))
+ end
+ end
+
expose :subscribed do |issue, options|
issue.subscribed?(options[:current_user], options[:project] || issue.project)
end
diff --git a/lib/api/helpers/related_resources_helpers.rb b/lib/api/helpers/related_resources_helpers.rb
new file mode 100644
index 00000000000..00a13c2ceb0
--- /dev/null
+++ b/lib/api/helpers/related_resources_helpers.rb
@@ -0,0 +1,31 @@
+module API
+ module Helpers
+ module RelatedResourcesHelpers
+ include GrapeRouteHelpers::NamedRouteMatcher
+
+ @@issues_available = -> (issue, options) do
+ available?(:issues, issue.project, options[:current_user])
+ end
+
+ @@merge_requests_available = -> (issue, options) do
+ available?(:merge_requests, issue.project, options[:current_user])
+ end
+
+ # Builds a full URL based on GrapeEntity env options
+ def expose_url(entity_options, path = nil)
+ env = entity_options[:env]
+ url_scheme = env['rack.url_scheme']
+ http_host = env['HTTP_HOST']
+ path_info = path || env['PATH_INFO']
+
+ URI::HTTP.build(scheme: url_scheme, host: http_host, path: path_info).to_s
+ end
+
+ private
+
+ def available?(feature, project, current_user)
+ project.feature_available?(feature, current_user)
+ end
+ end
+ end
+end
diff --git a/lib/api/v3/entities.rb b/lib/api/v3/entities.rb
index 7c5065dee90..734a4b6019e 100644
--- a/lib/api/v3/entities.rb
+++ b/lib/api/v3/entities.rb
@@ -100,6 +100,12 @@ module API
end
end
+ class Issue < ::API::Entities::IssueBasic
+ expose :subscribed do |issue, options|
+ issue.subscribed?(options[:current_user], options[:project] || issue.project)
+ end
+ end
+
class MergeRequest < Grape::Entity
expose :id, :iid
expose(:project_id) { |entity| entity.project.id }
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 79cac721202..4e1e1c29ce3 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -693,6 +693,47 @@ describe API::Issues do
expect(json_response['confidential']).to be_falsy
end
+ context 'related resource URIs exposure' do
+ context 'when issues feature available' do
+ it 'exposes related resources URIs' do
+ get api("/projects/#{project.id}/issues/#{issue.iid}", user)
+
+ relationship_urls = json_response['relationship_urls']
+
+ base_url = 'http://www.example.com/api/v4'
+
+ expect(relationship_urls['self']).to eq("#{base_url}/projects/#{project.id}/issues/#{issue.iid}")
+ expect(relationship_urls['issues']).to eq("#{base_url}/issues")
+ expect(relationship_urls['project_issues']).to eq("#{base_url}/projects/#{project.id}/issues")
+ expect(relationship_urls['project_merge_requests']).to eq("#{base_url}/projects/#{project.id}/merge_requests")
+ expect(relationship_urls['project_repo_branches']).to eq("#{base_url}/projects/#{project.id}/repository/branches")
+ end
+ end
+
+ context 'when merge requests feature not available' do
+ let(:project) do
+ create(:empty_project, :public,
+ :merge_requests_disabled,
+ creator_id: user.id,
+ namespace: user.namespace)
+ end
+
+ it 'excludes merge requests related URIs' do
+ get api("/projects/#{project.id}/issues/#{issue.iid}", user)
+
+ relationship_urls = json_response['relationship_urls']
+
+ base_url = 'http://www.example.com/api/v4'
+
+ expect(relationship_urls.has_key?('project_merge_requests')).to be_falsy
+ expect(relationship_urls['self']).to eq("#{base_url}/projects/#{project.id}/issues/#{issue.iid}")
+ expect(relationship_urls['issues']).to eq("#{base_url}/issues")
+ expect(relationship_urls['project_issues']).to eq("#{base_url}/projects/#{project.id}/issues")
+ expect(relationship_urls['project_repo_branches']).to eq("#{base_url}/projects/#{project.id}/repository/branches")
+ end
+ end
+ end
+
it "returns a project issue by internal id" do
get api("/projects/#{project.id}/issues/#{issue.iid}", user)