summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Van Landuyt <bob@vanlanduyt.co>2018-02-23 18:30:37 +0100
committerBob Van Landuyt <bob@vanlanduyt.co>2018-03-07 15:12:31 +0100
commit792ab0631c85098fbf92e727b77158fb9dae5219 (patch)
tree390bd2b69c2de7f229f4d073ad60282b473312d7
parent9ba0052cdd5ae12ea6b1edd8d25867e0fef25afc (diff)
downloadgitlab-ce-792ab0631c85098fbf92e727b77158fb9dae5219.tar.gz
Allow a user to select `allow maintainer to push`
When a project is not private, and the source branch not protected the user can now select the option to allow maintainers to push to this branch
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_maintainer_edit.vue19
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/dependencies.js1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js7
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js1
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss3
-rw-r--r--app/controllers/projects/merge_requests/application_controller.rb1
-rw-r--r--app/helpers/merge_requests_helper.rb13
-rw-r--r--app/models/merge_request.rb18
-rw-r--r--app/serializers/merge_request_widget_entity.rb1
-rw-r--r--app/services/merge_requests/base_service.rb8
-rw-r--r--app/services/merge_requests/build_service.rb1
-rw-r--r--app/views/shared/issuable/_form.html.haml2
-rw-r--r--app/views/shared/issuable/form/_contribution.html.haml19
-rw-r--r--changelogs/unreleased/bvl-allow-maintainer-to-push.yml5
-rw-r--r--spec/features/merge_request/user_allows_a_maintainer_to_push_spec.rb85
-rw-r--r--spec/fixtures/api/schemas/entities/merge_request_basic.json3
-rw-r--r--spec/fixtures/api/schemas/entities/merge_request_widget.json1
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_maintainer_edit_spec.js23
-rw-r--r--spec/javascripts/vue_mr_widget/mr_widget_options_spec.js1
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/models/merge_request_spec.rb78
-rw-r--r--spec/services/merge_requests/update_service_spec.rb37
22 files changed, 324 insertions, 4 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_maintainer_edit.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_maintainer_edit.vue
new file mode 100644
index 00000000000..7a69cce695e
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_maintainer_edit.vue
@@ -0,0 +1,19 @@
+<script>
+ export default {
+ name: 'MRWidgetMaintainerEdit',
+ props: {
+ maintainerEditAllowed: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
+ },
+ };
+</script>
+<template>
+ <section class="mr-info-list mr-maintainer-edit">
+ <p v-if="maintainerEditAllowed">
+ {{ s__("mrWidget|Allows edits from maintainers") }}
+ </p>
+ </section>
+</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/dependencies.js b/app/assets/javascripts/vue_merge_request_widget/dependencies.js
index edb3baa39e4..a1bc28873df 100644
--- a/app/assets/javascripts/vue_merge_request_widget/dependencies.js
+++ b/app/assets/javascripts/vue_merge_request_widget/dependencies.js
@@ -15,6 +15,7 @@ export { default as WidgetHeader } from './components/mr_widget_header.vue';
export { default as WidgetMergeHelp } from './components/mr_widget_merge_help.vue';
export { default as WidgetPipeline } from './components/mr_widget_pipeline.vue';
export { default as WidgetDeployment } from './components/mr_widget_deployment';
+export { default as WidgetMaintainerEdit } from './components/mr_widget_maintainer_edit.vue';
export { default as WidgetRelatedLinks } from './components/mr_widget_related_links.vue';
export { default as MergedState } from './components/states/mr_widget_merged.vue';
export { default as FailedToMerge } from './components/states/mr_widget_failed_to_merge.vue';
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js
index 797f0f6ec0f..df3eb86f35c 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js
@@ -6,6 +6,7 @@ import {
WidgetMergeHelp,
WidgetPipeline,
WidgetDeployment,
+ WidgetMaintainerEdit,
WidgetRelatedLinks,
MergedState,
ClosedState,
@@ -211,6 +212,7 @@ export default {
'mr-widget-merge-help': WidgetMergeHelp,
'mr-widget-pipeline': WidgetPipeline,
'mr-widget-deployment': WidgetDeployment,
+ 'mr-widget-maintainer-edit': WidgetMaintainerEdit,
'mr-widget-related-links': WidgetRelatedLinks,
'mr-widget-merged': MergedState,
'mr-widget-closed': ClosedState,
@@ -251,11 +253,12 @@ export default {
:is="componentName"
:mr="mr"
:service="service" />
+ <mr-widget-maintainer-edit
+ :maintainerEditAllowed="mr.maintainerEditAllowed" />
<mr-widget-related-links
v-if="shouldRenderRelatedLinks"
:state="mr.state"
- :related-links="mr.relatedLinks"
- />
+ :related-links="mr.relatedLinks" />
</div>
<div
class="mr-widget-footer"
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index 9a750ce42bd..5d07bcf1bb9 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -76,6 +76,7 @@ export default class MergeRequestStore {
this.canBeMerged = data.can_be_merged || false;
this.isMergeAllowed = data.mergeable || false;
this.mergeOngoing = data.merge_ongoing;
+ this.maintainerEditAllowed = data.allow_maintainer_to_push;
// Cherry-pick and Revert actions related
this.canCherryPickInCurrentMR = currentUser.can_cherry_pick_on_current_merge_request || false;
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index f887a11004f..f8708a2c0a3 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -453,7 +453,8 @@
}
}
-.mr-links {
+.mr-links,
+.mr-maintainer-edit {
padding-left: $status-icon-size + $status-icon-margin;
}
diff --git a/app/controllers/projects/merge_requests/application_controller.rb b/app/controllers/projects/merge_requests/application_controller.rb
index 793ae03fb88..67d4ea2ca8f 100644
--- a/app/controllers/projects/merge_requests/application_controller.rb
+++ b/app/controllers/projects/merge_requests/application_controller.rb
@@ -15,6 +15,7 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont
def merge_request_params_attributes
[
+ :allow_maintainer_to_push,
:assignee_id,
:description,
:force_remove_source_branch,
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index ce57422f45d..fb4fe1c40b7 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -125,6 +125,19 @@ module MergeRequestsHelper
link_to(url[merge_request.project, merge_request], data: data_attrs, &block)
end
+ def allow_maintainer_push_unavailable_reason(merge_request)
+ return if merge_request.can_allow_maintainer_to_push?(current_user)
+
+ minimum_visibility = [merge_request.target_project.visibility_level,
+ merge_request.source_project.visibility_level].min
+
+ if minimum_visibility < Gitlab::VisibilityLevel::INTERNAL
+ _('Not available for private projects')
+ elsif ProtectedBranch.protected?(merge_request.source_project, merge_request.source_branch)
+ _('Not available for protected branches')
+ end
+ end
+
def merge_params_ee(merge_request)
{}
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 9a7e66a9cbb..59fd2d4e4a0 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1087,4 +1087,22 @@ class MergeRequest < ActiveRecord::Base
project.merge_requests.merged.where(author_id: author_id).empty?
end
+
+ def allow_maintainer_to_push
+ maintainer_push_possible? && super
+ end
+
+ alias_method :allow_maintainer_to_push?, :allow_maintainer_to_push
+
+ def maintainer_push_possible?
+ source_project.present? && for_fork? &&
+ target_project.visibility_level > Gitlab::VisibilityLevel::PRIVATE &&
+ source_project.visibility_level > Gitlab::VisibilityLevel::PRIVATE &&
+ !ProtectedBranch.protected?(source_project, source_branch)
+ end
+
+ def can_allow_maintainer_to_push?(user)
+ maintainer_push_possible? &&
+ Ability.allowed?(user, :push_code, source_project)
+ end
end
diff --git a/app/serializers/merge_request_widget_entity.rb b/app/serializers/merge_request_widget_entity.rb
index a3ebec0efc6..89b49613a41 100644
--- a/app/serializers/merge_request_widget_entity.rb
+++ b/app/serializers/merge_request_widget_entity.rb
@@ -11,6 +11,7 @@ class MergeRequestWidgetEntity < IssuableEntity
expose :source_project_id
expose :target_branch
expose :target_project_id
+ expose :allow_maintainer_to_push
expose :should_be_rebased?, as: :should_be_rebased
expose :ff_only_enabled do |merge_request|
diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb
index 23262b62615..231ab76fde4 100644
--- a/app/services/merge_requests/base_service.rb
+++ b/app/services/merge_requests/base_service.rb
@@ -35,6 +35,14 @@ module MergeRequests
end
end
+ def filter_params(merge_request)
+ super
+
+ unless merge_request.can_allow_maintainer_to_push?(current_user)
+ params.delete(:allow_maintainer_to_push)
+ end
+ end
+
def merge_request_metrics_service(merge_request)
MergeRequestMetricsService.new(merge_request.metrics)
end
diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb
index 4b186d93772..a98bbdf74dd 100644
--- a/app/services/merge_requests/build_service.rb
+++ b/app/services/merge_requests/build_service.rb
@@ -6,6 +6,7 @@ module MergeRequests
@params_issue_iid = params.delete(:issue_iid)
self.merge_request = MergeRequest.new(params)
+ merge_request.author = current_user
merge_request.compare_commits = []
merge_request.source_project = find_source_project
merge_request.target_project = find_target_project
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index 6dfabd7ba4c..4c8f03f1498 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -33,6 +33,8 @@
= render 'shared/issuable/form/merge_params', issuable: issuable
+= render 'shared/issuable/form/contribution', issuable: issuable, form: form
+
- if @merge_request_to_resolve_discussions_of
.form-group
.col-sm-10.col-sm-offset-2
diff --git a/app/views/shared/issuable/form/_contribution.html.haml b/app/views/shared/issuable/form/_contribution.html.haml
new file mode 100644
index 00000000000..11474ebc9d9
--- /dev/null
+++ b/app/views/shared/issuable/form/_contribution.html.haml
@@ -0,0 +1,19 @@
+- issuable = local_assigns.fetch(:issuable)
+- form = local_assigns.fetch(:form)
+
+- return unless issuable.is_a?(MergeRequest)
+- return unless issuable.for_fork?
+- return unless can?(current_user, :push_code, issuable.source_project)
+
+%hr
+
+.form-group
+ .control-label
+ = _('Contribution')
+ .col-sm-10
+ .checkbox
+ = form.label :allow_maintainer_to_push do
+ = form.check_box :allow_maintainer_to_push, disabled: !issuable.can_allow_maintainer_to_push?(current_user)
+ = _('Allow edits from maintainers')
+ .help-block
+ = allow_maintainer_push_unavailable_reason(issuable)
diff --git a/changelogs/unreleased/bvl-allow-maintainer-to-push.yml b/changelogs/unreleased/bvl-allow-maintainer-to-push.yml
new file mode 100644
index 00000000000..a3fefc2889a
--- /dev/null
+++ b/changelogs/unreleased/bvl-allow-maintainer-to-push.yml
@@ -0,0 +1,5 @@
+---
+title: Allow maintainers to push to forks of their projects when a merge request is open
+merge_request: 17395
+author:
+type: added
diff --git a/spec/features/merge_request/user_allows_a_maintainer_to_push_spec.rb b/spec/features/merge_request/user_allows_a_maintainer_to_push_spec.rb
new file mode 100644
index 00000000000..eb41d7de8ed
--- /dev/null
+++ b/spec/features/merge_request/user_allows_a_maintainer_to_push_spec.rb
@@ -0,0 +1,85 @@
+require 'spec_helper'
+
+describe 'create a merge request that allows maintainers to push', :js do
+ include ProjectForksHelper
+ let(:user) { create(:user) }
+ let(:target_project) { create(:project, :public, :repository) }
+ let(:source_project) { fork_project(target_project, user, repository: true, namespace: user.namespace) }
+
+ def visit_new_merge_request
+ visit project_new_merge_request_path(
+ source_project,
+ merge_request: {
+ source_project_id: source_project.id,
+ target_project_id: target_project.id,
+ source_branch: 'fix',
+ target_branch: 'master'
+ })
+ end
+
+ before do
+ sign_in(user)
+ end
+
+ it 'allows setting maintainer push possible' do
+ visit_new_merge_request
+
+ check 'Allow edits from maintainers'
+
+ click_button 'Submit merge request'
+
+ wait_for_requests
+
+ expect(page).to have_content('Allows edits from maintainers')
+ end
+
+ it 'shows a message when one of the projects is private' do
+ source_project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+
+ visit_new_merge_request
+
+ expect(page).to have_content('Not available for private projects')
+ end
+
+ it 'shows a message when the source branch is protected' do
+ create(:protected_branch, project: source_project, name: 'fix')
+
+ visit_new_merge_request
+
+ expect(page).to have_content('Not available for protected branches')
+ end
+
+ context 'when the merge request is being created within the same project' do
+ let(:source_project) { target_project }
+
+ it 'hides the checkbox if the merge request is being created within the same project' do
+ target_project.add_developer(user)
+
+ visit_new_merge_request
+
+ expect(page).not_to have_content('Allows edits from maintainers')
+ end
+ end
+
+ context 'when a maintainer tries to edit the option' do
+ let(:maintainer) { create(:user) }
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: source_project,
+ target_project: target_project,
+ source_branch: 'fixes')
+ end
+
+ before do
+ target_project.add_master(maintainer)
+
+ sign_in(maintainer)
+ end
+
+ it 'it hides the option from maintainers' do
+ visit edit_project_merge_request_path(target_project, merge_request)
+
+ expect(page).not_to have_content('Allows edits from maintainers')
+ end
+ end
+end
diff --git a/spec/fixtures/api/schemas/entities/merge_request_basic.json b/spec/fixtures/api/schemas/entities/merge_request_basic.json
index f1199468d53..46031961cca 100644
--- a/spec/fixtures/api/schemas/entities/merge_request_basic.json
+++ b/spec/fixtures/api/schemas/entities/merge_request_basic.json
@@ -12,7 +12,8 @@
"rebase_in_progress": { "type": "boolean" },
"assignee_id": { "type": ["integer", "null"] },
"subscribed": { "type": ["boolean", "null"] },
- "participants": { "type": "array" }
+ "participants": { "type": "array" },
+ "allow_maintainer_to_push": { "type": "boolean"}
},
"additionalProperties": false
}
diff --git a/spec/fixtures/api/schemas/entities/merge_request_widget.json b/spec/fixtures/api/schemas/entities/merge_request_widget.json
index cfbeec58a45..a622bf88b13 100644
--- a/spec/fixtures/api/schemas/entities/merge_request_widget.json
+++ b/spec/fixtures/api/schemas/entities/merge_request_widget.json
@@ -30,6 +30,7 @@
"source_project_id": { "type": "integer" },
"target_branch": { "type": "string" },
"target_project_id": { "type": "integer" },
+ "allow_maintainer_to_push": { "type": "boolean"},
"metrics": {
"oneOf": [
{ "type": "null" },
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_maintainer_edit_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_maintainer_edit_spec.js
new file mode 100644
index 00000000000..65b3f721281
--- /dev/null
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_maintainer_edit_spec.js
@@ -0,0 +1,23 @@
+import Vue from 'vue';
+import maintainerEditComponent from '~/vue_merge_request_widget/components/mr_widget_maintainer_edit.vue';
+import mountComponent from 'spec/helpers/vue_mount_component_helper';
+
+describe('MRWidgetAuthor', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(maintainerEditComponent);
+
+ vm = mountComponent(Component, {
+ maintainerEditAllowed: true,
+ });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders the message when maintainers are allowed to edit', () => {
+ expect(vm.$el.textContent.trim()).toEqual('Allows edits from maintainers');
+ });
+});
diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
index 18ba34b55a5..ebe151ac3b1 100644
--- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
@@ -349,6 +349,7 @@ describe('mrWidgetOptions', () => {
expect(comps['mr-widget-pipeline-blocked']).toBeDefined();
expect(comps['mr-widget-pipeline-failed']).toBeDefined();
expect(comps['mr-widget-merge-when-pipeline-succeeds']).toBeDefined();
+ expect(comps['mr-widget-maintainer-edit']).toBeDefined();
});
});
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index ddcbb7a0033..0b938892da5 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -168,6 +168,7 @@ MergeRequest:
- last_edited_by_id
- head_pipeline_id
- discussion_locked
+- allow_maintainer_to_push
MergeRequestDiff:
- id
- state
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 243eeddc7a8..7986aa31e16 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -2084,4 +2084,82 @@ describe MergeRequest do
it_behaves_like 'checking whether a rebase is in progress'
end
end
+
+ describe '#allow_maintainer_to_push' do
+ let(:merge_request) do
+ build(:merge_request, source_branch: 'fixes', allow_maintainer_to_push: true)
+ end
+
+ it 'is false when pushing by a maintainer is not possible' do
+ expect(merge_request).to receive(:maintainer_push_possible?) { false }
+
+ expect(merge_request.allow_maintainer_to_push).to be_falsy
+ end
+
+ it 'is true when pushing by a maintainer is possible' do
+ expect(merge_request).to receive(:maintainer_push_possible?) { true }
+
+ expect(merge_request.allow_maintainer_to_push).to be_truthy
+ end
+ end
+
+ describe '#maintainer_push_possible?' do
+ let(:merge_request) do
+ build(:merge_request, source_branch: 'fixes')
+ end
+
+ before do
+ allow(ProtectedBranch).to receive(:protected?) { false }
+ end
+
+ it 'does not allow maintainer to push if the source project is the same as the target' do
+ merge_request.target_project = merge_request.source_project = create(:project, :public)
+
+ expect(merge_request.maintainer_push_possible?).to be_falsy
+ end
+
+ it 'allows maintainer to push when both source and target are public' do
+ merge_request.target_project = build(:project, :public)
+ merge_request.source_project = build(:project, :public)
+
+ expect(merge_request.maintainer_push_possible?).to be_truthy
+ end
+
+ it 'is not available for protected branches' do
+ merge_request.target_project = build(:project, :public)
+ merge_request.source_project = build(:project, :public)
+
+ expect(ProtectedBranch).to receive(:protected?)
+ .with(merge_request.source_project, 'fixes')
+ .and_return(true)
+
+ expect(merge_request.maintainer_push_possible?).to be_falsy
+ end
+ end
+
+ describe '#can_allow_maintainer_to_push?' do
+ let(:target_project) { create(:project, :public) }
+ let(:source_project) { fork_project(target_project) }
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: source_project,
+ source_branch: 'fixes',
+ target_project: target_project)
+ end
+ let(:user) { create(:user) }
+
+ before do
+ allow(merge_request).to receive(:maintainer_push_possible?) { true }
+ end
+
+ it 'is false if the user does not have push access to the source project' do
+ expect(merge_request.can_allow_maintainer_to_push?(user)).to be_falsy
+ end
+
+ it 'is true when the user has push access to the source project' do
+ source_project.add_developer(user)
+
+ expect(merge_request.can_allow_maintainer_to_push?(user)).to be_truthy
+ end
+ end
end
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index c31259239ee..5279ea6164e 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe MergeRequests::UpdateService, :mailer do
+ include ProjectForksHelper
+
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:user2) { create(:user) }
@@ -538,5 +540,40 @@ describe MergeRequests::UpdateService, :mailer do
let(:open_issuable) { merge_request }
let(:closed_issuable) { create(:closed_merge_request, source_project: project) }
end
+
+ context 'setting `allow_maintainer_to_push`' do
+ let(:target_project) { create(:project, :public) }
+ let(:source_project) { fork_project(target_project) }
+ let(:user) { create(:user) }
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: source_project,
+ source_branch: 'fixes',
+ target_project: target_project)
+ end
+
+ before do
+ allow(ProtectedBranch).to receive(:protected?).with(source_project, 'fixes') { false }
+ end
+
+ it 'does not allow a maintainer of the target project to set `allow_maintainer_to_push`' do
+ target_project.add_developer(user)
+
+ update_merge_request(allow_maintainer_to_push: true, title: 'Updated title')
+
+ expect(merge_request.title).to eq('Updated title')
+ expect(merge_request.allow_maintainer_to_push).to be_falsy
+ end
+
+ it 'is allowed by a user that can push to the source and can update the merge request' do
+ merge_request.update!(assignee: user)
+ source_project.add_developer(user)
+
+ update_merge_request(allow_maintainer_to_push: true, title: 'Updated title')
+
+ expect(merge_request.title).to eq('Updated title')
+ expect(merge_request.allow_maintainer_to_push).to be_truthy
+ end
+ end
end
end