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
render_api_error!(errors, 400)
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
params do
......@@ -57,9 +63,14 @@ module API
hidden: true
}
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
desc 'Change approval-related configuration' do
......
......@@ -330,14 +330,6 @@ module EE
expose :contains_hidden_groups?, as: :contains_hidden_groups
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 SourceRule < Grape::Entity
expose :approvals_required
......@@ -346,34 +338,52 @@ module EE
expose :source_rule, using: SourceRule
end
# Being used in private MR-level approvals API.
# 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
class MergeRequestApprovalStateRule < MergeRequestApprovalRule
expose :code_owner
expose :approved_approvers, as: :approved_by, using: ::API::Entities::UserBasic
expose :approved?, as: :approved
end
# Decorates ApprovalState
class MergeRequestApprovalSettings < Grape::Entity
class MergeRequestApprovalState < Grape::Entity
expose :approval_rules_overwritten do |approval_state|
approval_state.approval_rules_overwritten?
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
# 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
expose :visible_approval_rules, as: :rules, using: ApprovalSettingRule
expose :min_fallback_approvals, as: :fallback_approvals_required
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
class Approver < Grape::Entity
expose :user, using: ::API::Entities::UserBasic
......
......@@ -10,6 +10,47 @@ describe API::MergeRequestApprovals do
set(:approver) { create :user }
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
let!(:rule) { create(:approval_merge_request_rule, merge_request: merge_request, approvals_required: 2, name: 'foo') }
......@@ -96,14 +137,19 @@ describe API::MergeRequestApprovals do
end
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)
merge_request.approvals.create(user: 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(json_response['rules'].size).to eq(1)
......@@ -116,35 +162,22 @@ describe API::MergeRequestApprovals do
expect(rule_response['approved_by'][0]['username']).to eq(approver.username)
expect(rule_response['source_rule']).to eq(nil)
end
end
context 'when source rule is present' 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') }
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
describe 'GET :id/merge_requests/:merge_request_iid/approval_state' do
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" }
expect(rule_response['source_rule']['approvals_required']).to eq(source_rule.approvals_required)
end
before do
project.add_developer(approver)
merge_request.approvals.create(user: approver)
rule.users << approver
end
it 'excludes private groups' do
private_group = create(:group, :private)
rule.users << approver
rule.groups << private_group
it_behaves_like 'an API endpoint for getting merge request approval state'
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(json_response['rules'].size).to eq(1)
......@@ -152,7 +185,10 @@ describe API::MergeRequestApprovals do
rule_response = json_response['rules'].first
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
......
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