/ee/spec/requests/api/merge_request_approval_rules_spec.rb
Ruby | 370 lines | 291 code | 78 blank | 1 comment | 0 complexity | 17bcbbff65d92e6c4cb1e35e14380bc2 MD5 | raw file
- # frozen_string_literal: true
- require 'spec_helper'
- describe API::MergeRequestApprovalRules do
- set(:user) { create(:user) }
- set(:other_user) { create(:user) }
- set(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace) }
- let(:merge_request) { create(:merge_request, author: user, source_project: project, target_project: project) }
- shared_examples_for 'a protected API endpoint for merge request approval rule action' do
- context 'disable_overriding_approvers_per_merge_request is set to true' do
- before do
- project.update!(disable_overriding_approvers_per_merge_request: true)
- action
- end
- it 'responds with 403' do
- expect(response).to have_gitlab_http_status(403)
- end
- end
- context 'disable_overriding_approvers_per_merge_request is set to false' do
- before do
- project.update!(disable_overriding_approvers_per_merge_request: false)
- action
- end
- context 'user cannot update merge request' do
- let(:current_user) { other_user }
- it 'responds with 403' do
- expect(response).to have_gitlab_http_status(403)
- end
- end
- end
- end
- shared_examples_for 'a protected API endpoint that only allows action on regular merge request approval rule' do
- context 'approval rule is not a regular type' do
- let(:approval_rule) { create(:code_owner_rule, merge_request: merge_request) }
- it 'responds with 403' do
- expect(response).to have_gitlab_http_status(403)
- end
- end
- end
- describe 'GET /projects/:id/merge_requests/:merge_request_iid/approval_rules' do
- let(:current_user) { other_user }
- let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_rules" }
- context 'user cannot read merge request' do
- before do
- project.project_feature.update!(merge_requests_access_level: ProjectFeature::PRIVATE)
- get api(url, other_user)
- end
- it 'responds with 403' do
- expect(response).to have_gitlab_http_status(403)
- end
- end
- context 'use can read merge request' do
- let(:approver) { create(:user) }
- let(:group) { create(:group) }
- let(:source_rule) { nil }
- let(:users) { [approver] }
- let(:groups) { [group] }
- let!(:mr_approval_rule) do
- create(
- :approval_merge_request_rule,
- merge_request: merge_request,
- approval_project_rule: source_rule,
- users: users,
- groups: groups
- )
- end
- before do
- group.add_developer(approver)
- merge_request.approvals.create(user: approver)
- get api(url, current_user)
- end
- it 'matches the response schema' do
- expect(response).to have_gitlab_http_status(200)
- expect(response).to match_response_schema('public_api/v4/merge_request_approval_rules', dir: 'ee')
- rules = json_response
- expect(rules.size).to eq(1)
- expect(rules.first['name']).to eq(mr_approval_rule.name)
- expect(rules.first['approvals_required']).to eq(mr_approval_rule.approvals_required)
- expect(rules.first['rule_type']).to eq(mr_approval_rule.rule_type)
- expect(rules.first['contains_hidden_groups']).to eq(false)
- expect(rules.first['source_rule']).to be_nil
- expect(rules.first['eligible_approvers']).to match([hash_including('id' => approver.id)])
- expect(rules.first['users']).to match([hash_including('id' => approver.id)])
- expect(rules.first['groups']).to match([hash_including('id' => group.id)])
- end
- context 'groups contain private groups' do
- let(:group) { create(:group, :private) }
- context 'current_user cannot see private group' do
- it 'hides private group' do
- rules = json_response
- expect(rules.first['contains_hidden_groups']).to eq(true)
- expect(rules.first['groups']).to be_empty
- end
- end
- context 'current_user can see private group' do
- let(:current_user) { approver }
- it 'shows private group' do
- rules = json_response
- expect(rules.first['contains_hidden_groups']).to eq(false)
- expect(rules.first['groups']).to match([hash_including('id' => group.id)])
- end
- end
- end
- context 'has existing merge request rule that overrides a project-level rule' do
- let(:source_rule) { create(:approval_project_rule, project: project) }
- it 'includes source_rule' do
- expect(json_response.first['source_rule']['approvals_required']).to eq(source_rule.approvals_required)
- end
- end
- end
- end
- describe 'POST /projects/:id/merge_requests/:merge_request_iid/approval_rules' do
- let(:current_user) { user }
- let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_rules" }
- let(:approver) { create(:user) }
- let(:group) { create(:group) }
- let(:approval_project_rule_id) { nil }
- let(:user_ids) { [] }
- let(:group_ids) { [] }
- let(:params) do
- {
- name: 'Test',
- approvals_required: 1,
- approval_project_rule_id: approval_project_rule_id,
- user_ids: user_ids,
- group_ids: group_ids
- }
- end
- let(:action) { post api(url, current_user), params: params }
- it_behaves_like 'a protected API endpoint for merge request approval rule action'
- context 'when user can update merge request and approval rules can be overridden' do
- before do
- project.update!(disable_overriding_approvers_per_merge_request: false)
- project.add_developer(approver)
- group.add_developer(approver)
- action
- end
- it 'matches the response schema' do
- expect(response).to have_gitlab_http_status(201)
- expect(response).to match_response_schema('public_api/v4/merge_request_approval_rule', dir: 'ee')
- rule = json_response
- expect(rule['name']).to eq(params[:name])
- expect(rule['approvals_required']).to eq(params[:approvals_required])
- expect(rule['rule_type']).to eq('regular')
- expect(rule['contains_hidden_groups']).to eq(false)
- expect(rule['source_rule']).to be_nil
- expect(rule['eligible_approvers']).to be_empty
- expect(rule['users']).to be_empty
- expect(rule['groups']).to be_empty
- end
- context 'users are passed' do
- let(:user_ids) { [approver.id] }
- it 'includes users' do
- rule = json_response
- expect(rule['eligible_approvers']).to match([hash_including('id' => approver.id)])
- expect(rule['users']).to match([hash_including('id' => approver.id)])
- end
- end
- context 'groups are passed' do
- let(:group_ids) { [group.id] }
- it 'includes groups' do
- rule = json_response
- expect(rule['eligible_approvers']).to match([hash_including('id' => approver.id)])
- expect(rule['groups']).to match([hash_including('id' => group.id)])
- end
- end
- context 'approval_project_rule_id is passed' do
- let(:approval_project_rule) do
- create(
- :approval_project_rule,
- project: project,
- users: [approver],
- groups: [group]
- )
- end
- let(:approval_project_rule_id) { approval_project_rule.id }
- it 'copies the attributes from the project rule execpt approvals_required' do
- rule = json_response
- expect(rule['name']).to eq(approval_project_rule.name)
- expect(rule['approvals_required']).to eq(params[:approvals_required])
- expect(rule['source_rule']['approvals_required']).to eq(approval_project_rule.approvals_required)
- expect(rule['eligible_approvers']).to match([hash_including('id' => approver.id)])
- expect(rule['users']).to match([hash_including('id' => approver.id)])
- expect(rule['groups']).to match([hash_including('id' => group.id)])
- end
- end
- end
- end
- describe 'PUT /projects/:id/merge_requests/:merge_request_iid/approval_rules/:approval_rule_id' do
- let(:current_user) { user }
- let(:existing_approver) { create(:user) }
- let(:existing_group) { create(:group) }
- let(:approval_rule) do
- create(
- :approval_merge_request_rule,
- merge_request: merge_request,
- name: 'Old Name',
- approvals_required: 2,
- users: [existing_approver],
- groups: [existing_group]
- )
- end
- let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_rules/#{approval_rule.id}" }
- let(:new_approver) { create(:user) }
- let(:new_group) { create(:group) }
- let(:user_ids) { [] }
- let(:group_ids) { [] }
- let(:remove_hidden_groups) { nil }
- let(:params) do
- {
- name: 'Test',
- approvals_required: 1,
- user_ids: user_ids,
- group_ids: group_ids,
- remove_hidden_groups: remove_hidden_groups
- }
- end
- let(:action) { put api(url, current_user), params: params }
- it_behaves_like 'a protected API endpoint for merge request approval rule action'
- context 'when user can update merge request and approval rules can be overridden' do
- before do
- project.update!(disable_overriding_approvers_per_merge_request: false)
- project.add_developer(existing_approver)
- project.add_developer(new_approver)
- existing_group.add_developer(existing_approver)
- new_group.add_developer(new_approver)
- action
- end
- it_behaves_like 'a protected API endpoint that only allows action on regular merge request approval rule'
- it 'matches the response schema' do
- expect(response).to have_gitlab_http_status(200)
- expect(response).to match_response_schema('public_api/v4/merge_request_approval_rule', dir: 'ee')
- rule = json_response
- expect(rule['name']).to eq(params[:name])
- expect(rule['approvals_required']).to eq(params[:approvals_required])
- expect(rule['rule_type']).to eq(approval_rule.rule_type)
- expect(rule['contains_hidden_groups']).to eq(false)
- expect(rule['source_rule']).to be_nil
- expect(rule['eligible_approvers']).to be_empty
- expect(rule['users']).to be_empty
- expect(rule['groups']).to be_empty
- end
- context 'users are passed' do
- let(:user_ids) { [new_approver.id] }
- it 'changes users' do
- rule = json_response
- expect(rule['eligible_approvers']).to match([hash_including('id' => new_approver.id)])
- expect(rule['users']).to match([hash_including('id' => new_approver.id)])
- end
- end
- context 'groups are passed' do
- let(:group_ids) { [new_group.id] }
- it 'changes groups' do
- rule = json_response
- expect(rule['eligible_approvers']).to match([hash_including('id' => new_approver.id)])
- expect(rule['groups']).to match([hash_including('id' => new_group.id)])
- end
- end
- context 'remove_hidden_groups is passed' do
- let(:existing_group) { create(:group, :private) }
- context 'when set to true' do
- let(:remove_hidden_groups) { true }
- it 'removes the existing private group' do
- expect(approval_rule.reload.groups).not_to include(existing_group)
- end
- end
- context 'when set to false' do
- let(:remove_hidden_groups) { false }
- it 'does not remove the existing private group' do
- expect(approval_rule.reload.groups).to include(existing_group)
- end
- end
- end
- end
- end
- describe 'DELETE /projects/:id/merge_requests/:merge_request_iid/approval_rules/:approval_rule_id' do
- let(:current_user) { user }
- let(:approval_rule) { create(:approval_merge_request_rule, merge_request: merge_request) }
- let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_rules/#{approval_rule.id}" }
- let(:action) { delete api(url, current_user) }
- it_behaves_like 'a protected API endpoint for merge request approval rule action'
- context 'when user can update merge request and approval rules can be overridden' do
- before do
- project.update!(disable_overriding_approvers_per_merge_request: false)
- action
- end
- it_behaves_like 'a protected API endpoint that only allows action on regular merge request approval rule'
- it 'responds with 204' do
- expect(response).to have_gitlab_http_status(204)
- end
- end
- end
- end