Commit b6c0f3e6 authored by Patrick Bajao's avatar Patrick Bajao Committed by Ash McKenzie

Public MR-level approval state API endpoint

This endpoint behaves the same way as the existing
private `/approval_settings` API endpoint.

The difference is that this endpoint responds with
`eligible_approvers` instead of `approvers`.

The private endpoint should be removed in
https://gitlab.com/gitlab-org/gitlab-ee/issues/13574 together
with the private project-level endpoints.
parent 324ec21a
...@@ -26,6 +26,12 @@ module API ...@@ -26,6 +26,12 @@ module API
render_api_error!(errors, 400) render_api_error!(errors, 400)
end end
def get_merge_request_approval_state(present_with:)
merge_request = find_merge_request_with_access(params[:merge_request_iid])
present merge_request.approval_state, with: present_with, current_user: current_user
end
end end
params do params do
...@@ -57,9 +63,14 @@ module API ...@@ -57,9 +63,14 @@ module API
hidden: true hidden: true
} }
get 'approval_settings' do get 'approval_settings' do
merge_request = find_merge_request_with_access(params[:merge_request_iid]) get_merge_request_approval_state(present_with: ::EE::API::Entities::MergeRequestApprovalSettings)
end
present merge_request.approval_state, with: ::EE::API::Entities::MergeRequestApprovalSettings, current_user: current_user desc 'Get approval state of merge request' do
success ::EE::API::Entities::MergeRequestApprovalState
end
get 'approval_state' do
get_merge_request_approval_state(present_with: ::EE::API::Entities::MergeRequestApprovalState)
end end
desc 'Change approval-related configuration' do desc 'Change approval-related configuration' do
......
...@@ -330,14 +330,6 @@ module EE ...@@ -330,14 +330,6 @@ module EE
expose :contains_hidden_groups?, as: :contains_hidden_groups expose :contains_hidden_groups?, as: :contains_hidden_groups
end end
# Being used in private project-level approvals API.
# This overrides the `eligible_approvers` to be exposed as `approvers`.
#
# To be removed in https://gitlab.com/gitlab-org/gitlab-ee/issues/13574.
class ApprovalSettingRule < ApprovalRule
expose :approvers, using: ::API::Entities::UserBasic, override: true
end
class MergeRequestApprovalRule < ApprovalRule class MergeRequestApprovalRule < ApprovalRule
class SourceRule < Grape::Entity class SourceRule < Grape::Entity
expose :approvals_required expose :approvals_required
...@@ -346,34 +338,52 @@ module EE ...@@ -346,34 +338,52 @@ module EE
expose :source_rule, using: SourceRule expose :source_rule, using: SourceRule
end end
# Being used in private MR-level approvals API. class MergeRequestApprovalStateRule < MergeRequestApprovalRule
# This overrides the `eligible_approvers` to be exposed as `approvers` and
# include additional properties.
#
# To be made public in https://gitlab.com/gitlab-org/gitlab-ee/issues/13712
# and the `approvers` override can be removed.
class MergeRequestApprovalSettingRule < MergeRequestApprovalRule
expose :approvers, using: ::API::Entities::UserBasic, override: true
expose :code_owner expose :code_owner
expose :approved_approvers, as: :approved_by, using: ::API::Entities::UserBasic expose :approved_approvers, as: :approved_by, using: ::API::Entities::UserBasic
expose :approved?, as: :approved expose :approved?, as: :approved
end end
# Decorates ApprovalState class MergeRequestApprovalState < Grape::Entity
class MergeRequestApprovalSettings < Grape::Entity
expose :approval_rules_overwritten do |approval_state| expose :approval_rules_overwritten do |approval_state|
approval_state.approval_rules_overwritten? approval_state.approval_rules_overwritten?
end end
expose :wrapped_approval_rules, as: :rules, using: MergeRequestApprovalSettingRule expose :wrapped_approval_rules, as: :rules, using: MergeRequestApprovalStateRule
end
# Being used in private project-level approvals API.
# This overrides the `eligible_approvers` to be exposed as `approvers`.
#
# To be removed in https://gitlab.com/gitlab-org/gitlab-ee/issues/13574.
class ApprovalSettingRule < ApprovalRule
expose :approvers, using: ::API::Entities::UserBasic, override: true
end end
# Decorates Project # Being used in private project-level approvals API.
#
# To be removed in https://gitlab.com/gitlab-org/gitlab-ee/issues/13574.
class ProjectApprovalSettings < Grape::Entity class ProjectApprovalSettings < Grape::Entity
expose :visible_approval_rules, as: :rules, using: ApprovalSettingRule expose :visible_approval_rules, as: :rules, using: ApprovalSettingRule
expose :min_fallback_approvals, as: :fallback_approvals_required expose :min_fallback_approvals, as: :fallback_approvals_required
end end
# Being used in private MR-level approvals API.
# This overrides the `eligible_approvers` to be exposed as `approvers`.
#
# To be removed in https://gitlab.com/gitlab-org/gitlab-ee/issues/13574.
class MergeRequestApprovalSettingRule < MergeRequestApprovalStateRule
expose :approvers, using: ::API::Entities::UserBasic, override: true
end
# Being used in private MR-level approvals API.
# This overrides the `rules` to be exposed using MergeRequestApprovalSettingRule.
#
# To be removed in https://gitlab.com/gitlab-org/gitlab-ee/issues/13574.
class MergeRequestApprovalSettings < MergeRequestApprovalState
expose :wrapped_approval_rules, as: :rules, using: MergeRequestApprovalSettingRule, override: true
end
# @deprecated # @deprecated
class Approver < Grape::Entity class Approver < Grape::Entity
expose :user, using: ::API::Entities::UserBasic expose :user, using: ::API::Entities::UserBasic
......
...@@ -10,6 +10,47 @@ describe API::MergeRequestApprovals do ...@@ -10,6 +10,47 @@ describe API::MergeRequestApprovals do
set(:approver) { create :user } set(:approver) { create :user }
set(:group) { create :group } set(:group) { create :group }
shared_examples_for 'an API endpoint for getting merge request approval state' do
context 'when source rule is present' do
let(:source_rule) { create(:approval_project_rule, project: project, approvals_required: 1, name: 'zoo') }
before do
rule.create_approval_merge_request_rule_source!(approval_project_rule: source_rule)
get api(url, user)
end
it 'returns source rule details' do
expect(response).to have_gitlab_http_status(200)
expect(json_response['rules'].size).to eq(1)
rule_response = json_response['rules'].first
expect(rule_response['source_rule']['approvals_required']).to eq(source_rule.approvals_required)
end
end
context 'when user cannot view a group included in groups' do
let(:private_group) { create(:group, :private) }
before do
rule.groups << private_group
get api(url, user)
end
it 'excludes private groups' do
expect(response).to have_gitlab_http_status(200)
expect(json_response['rules'].size).to eq(1)
rule_response = json_response['rules'].first
expect(rule_response['id']).to eq(rule.id)
expect(rule_response['groups'].size).to eq(0)
end
end
end
describe 'GET :id/merge_requests/:merge_request_iid/approvals' do describe 'GET :id/merge_requests/:merge_request_iid/approvals' do
let!(:rule) { create(:approval_merge_request_rule, merge_request: merge_request, approvals_required: 2, name: 'foo') } let!(:rule) { create(:approval_merge_request_rule, merge_request: merge_request, approvals_required: 2, name: 'foo') }
...@@ -96,14 +137,19 @@ describe API::MergeRequestApprovals do ...@@ -96,14 +137,19 @@ describe API::MergeRequestApprovals do
end end
describe 'GET :id/merge_requests/:merge_request_iid/approval_settings' do describe 'GET :id/merge_requests/:merge_request_iid/approval_settings' do
let!(:rule) { create(:approval_merge_request_rule, merge_request: merge_request, approvals_required: 2, name: 'foo') } let(:rule) { create(:approval_merge_request_rule, merge_request: merge_request, approvals_required: 2, name: 'foo') }
let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_settings" }
it 'retrieves the approval rules details' do before do
project.add_developer(approver) project.add_developer(approver)
merge_request.approvals.create(user: approver) merge_request.approvals.create(user: approver)
rule.users << approver rule.users << approver
end
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_settings", user) it_behaves_like 'an API endpoint for getting merge request approval state'
it 'retrieves the approval rules details' do
get api(url, user)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(json_response['rules'].size).to eq(1) expect(json_response['rules'].size).to eq(1)
...@@ -116,35 +162,22 @@ describe API::MergeRequestApprovals do ...@@ -116,35 +162,22 @@ describe API::MergeRequestApprovals do
expect(rule_response['approved_by'][0]['username']).to eq(approver.username) expect(rule_response['approved_by'][0]['username']).to eq(approver.username)
expect(rule_response['source_rule']).to eq(nil) expect(rule_response['source_rule']).to eq(nil)
end end
end
context 'when source rule is present' do describe 'GET :id/merge_requests/:merge_request_iid/approval_state' do
let!(:source_rule) { create(:approval_project_rule, project: project, approvals_required: 1, name: 'zoo') } let(:rule) { create(:approval_merge_request_rule, merge_request: merge_request, approvals_required: 2, name: 'foo') }
let!(:rule) { create(:approval_merge_request_rule, merge_request: merge_request, approvals_required: 2, name: 'foo') } let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_state" }
it 'returns source rule details' do
project.add_developer(approver)
merge_request.approvals.create(user: approver)
rule.users << approver
rule.create_approval_merge_request_rule_source!(approval_project_rule: source_rule)
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_settings", user)
expect(response).to have_gitlab_http_status(200)
expect(json_response['rules'].size).to eq(1)
rule_response = json_response['rules'].first
expect(rule_response['source_rule']['approvals_required']).to eq(source_rule.approvals_required) before do
end project.add_developer(approver)
merge_request.approvals.create(user: approver)
rule.users << approver
end end
it 'excludes private groups' do it_behaves_like 'an API endpoint for getting merge request approval state'
private_group = create(:group, :private)
rule.users << approver
rule.groups << private_group
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_settings", user) it 'retrieves the approval state details' do
get api(url, user)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(json_response['rules'].size).to eq(1) expect(json_response['rules'].size).to eq(1)
...@@ -152,7 +185,10 @@ describe API::MergeRequestApprovals do ...@@ -152,7 +185,10 @@ describe API::MergeRequestApprovals do
rule_response = json_response['rules'].first rule_response = json_response['rules'].first
expect(rule_response['id']).to eq(rule.id) expect(rule_response['id']).to eq(rule.id)
expect(rule_response['groups'].size).to eq(0) expect(rule_response['name']).to eq('foo')
expect(rule_response['eligible_approvers'][0]['username']).to eq(approver.username)
expect(rule_response['approved_by'][0]['username']).to eq(approver.username)
expect(rule_response['source_rule']).to eq(nil)
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment