From fdf6afea1b019503815f912fb76eecbd155bc207 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Tue, 24 Jan 2023 03:35:11 +0530 Subject: [PATCH 01/12] Adds squash options in project --- marge/project.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/marge/project.py b/marge/project.py index 42996bdd..0ef00ea2 100644 --- a/marge/project.py +++ b/marge/project.py @@ -89,6 +89,10 @@ def http_url_to_repo(self): def merge_requests_enabled(self): return self.info['merge_requests_enabled'] + @property + def squash_option(self): + return self.info['squash_option'] + @property def only_allow_merge_if_pipeline_succeeds(self): return self.info['only_allow_merge_if_pipeline_succeeds'] From 7919a9e79731b879b8517e11ed3c686c19bf57af Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Tue, 24 Jan 2023 03:35:37 +0530 Subject: [PATCH 02/12] Allows auto squash when the MR is squashable --- marge/job.py | 5 ++++- marge/merge_request.py | 6 +++++- marge/single_merge_job.py | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/marge/job.py b/marge/job.py index c93bf556..018d848f 100644 --- a/marge/job.py +++ b/marge/job.py @@ -39,6 +39,9 @@ def opts(self): def execute(self): raise NotImplementedError + def is_auto_squash_enabled(self, merge_request): + return self._project.squash_option == "always" or merge_request.squash + def ensure_mergeable_mr(self, merge_request): merge_request.refetch_info() log.info('Ensuring MR !%s is mergeable', merge_request.iid) @@ -47,7 +50,7 @@ def ensure_mergeable_mr(self, merge_request): if merge_request.work_in_progress: raise CannotMerge("Sorry, I can't merge requests marked as Work-In-Progress!") - if merge_request.squash and self._options.requests_commit_tagging: + if self.is_auto_squash_enabled(merge_request) and self._options.requests_commit_tagging: raise CannotMerge( "Sorry, merging requests marked as auto-squash would ruin my commit tagging!" ) diff --git a/marge/merge_request.py b/marge/merge_request.py index 030b79b8..982cf72a 100644 --- a/marge/merge_request.py +++ b/marge/merge_request.py @@ -159,6 +159,9 @@ def blocking_discussions_resolved(self): def force_remove_source_branch(self): return self.info['force_remove_source_branch'] + def auto_squash(self, project): + return project.squash_option == "always" or self.squash + def update_sha(self, sha): """record the updated sha. We don't use refetch_info instead as it may hit cache.""" self._info['sha'] = sha @@ -200,13 +203,14 @@ def rebase(self): raise TimeoutError('Waiting for merge request to be rebased by GitLab') - def accept(self, remove_branch=False, sha=None, merge_when_pipeline_succeeds=True): + def accept(self, remove_branch=False, sha=None, merge_when_pipeline_succeeds=True, auto_squash=False): return self._api.call(PUT( '/projects/{0.project_id}/merge_requests/{0.iid}/merge'.format(self), dict( should_remove_source_branch=remove_branch, merge_when_pipeline_succeeds=merge_when_pipeline_succeeds, sha=sha or self.sha, # if provided, ensures what is merged is what we want (or fails) + squash=auto_squash ), )) diff --git a/marge/single_merge_job.py b/marge/single_merge_job.py index 1f8155ba..e6e341a8 100644 --- a/marge/single_merge_job.py +++ b/marge/single_merge_job.py @@ -97,6 +97,7 @@ def update_merge_request_and_accept(self, approvals): remove_branch=merge_request.force_remove_source_branch, sha=actual_sha, merge_when_pipeline_succeeds=bool(target_project.only_allow_merge_if_pipeline_succeeds), + auto_squash=self.is_auto_squash_enabled(merge_request) ) log.info('merge_request.accept result: %s', ret) except gitlab.NotAcceptable as err: From 14302c19a46cf496e2577064704de65cc81071b4 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Tue, 24 Jan 2023 03:57:07 +0530 Subject: [PATCH 03/12] Adds default values breaking tests --- marge/merge_request.py | 2 +- tests/test_merge_request.py | 3 +++ tests/test_project.py | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/marge/merge_request.py b/marge/merge_request.py index 982cf72a..48cd7bed 100644 --- a/marge/merge_request.py +++ b/marge/merge_request.py @@ -203,7 +203,7 @@ def rebase(self): raise TimeoutError('Waiting for merge request to be rebased by GitLab') - def accept(self, remove_branch=False, sha=None, merge_when_pipeline_succeeds=True, auto_squash=False): + def accept(self, remove_branch=False, sha=None, merge_when_pipeline_succeeds=True, auto_squash=None): return self._api.call(PUT( '/projects/{0.project_id}/merge_requests/{0.iid}/merge'.format(self), dict( diff --git a/tests/test_merge_request.py b/tests/test_merge_request.py index 7259ea72..075a6e7a 100644 --- a/tests/test_merge_request.py +++ b/tests/test_merge_request.py @@ -172,6 +172,7 @@ def test_accept_remove_branch(self): merge_when_pipeline_succeeds=True, should_remove_source_branch=boolean, sha='badc0de', + squash=None, ) )) self.api.call.reset_mock() @@ -185,6 +186,7 @@ def test_accept_sha(self): merge_when_pipeline_succeeds=True, should_remove_source_branch=False, sha='g00dc0de', + squash=None, ) )) @@ -197,6 +199,7 @@ def test_accept_merge_when_pipeline_succeeds(self): merge_when_pipeline_succeeds=False, should_remove_source_branch=False, sha='badc0de', + squash=None, ) )) diff --git a/tests/test_project.py b/tests/test_project.py index fd963e91..f6b32123 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -13,6 +13,7 @@ 'default_branch': 'master', 'only_allow_merge_if_pipeline_succeeds': True, 'only_allow_merge_if_all_discussions_are_resolved': False, + 'squash_option': 'never', 'permissions': { 'project_access': { 'access_level': AccessLevel.developer.value, From c5903b868de42924e130eb35e25cda5ef8b0de58 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Tue, 24 Jan 2023 04:18:04 +0530 Subject: [PATCH 04/12] Prevents breaking existing test cases --- marge/merge_request.py | 17 ++++++++--------- marge/single_merge_job.py | 6 +++++- tests/test_merge_request.py | 3 --- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/marge/merge_request.py b/marge/merge_request.py index 48cd7bed..868c5805 100644 --- a/marge/merge_request.py +++ b/marge/merge_request.py @@ -204,15 +204,14 @@ def rebase(self): raise TimeoutError('Waiting for merge request to be rebased by GitLab') def accept(self, remove_branch=False, sha=None, merge_when_pipeline_succeeds=True, auto_squash=None): - return self._api.call(PUT( - '/projects/{0.project_id}/merge_requests/{0.iid}/merge'.format(self), - dict( - should_remove_source_branch=remove_branch, - merge_when_pipeline_succeeds=merge_when_pipeline_succeeds, - sha=sha or self.sha, # if provided, ensures what is merged is what we want (or fails) - squash=auto_squash - ), - )) + params = dict( + should_remove_source_branch=remove_branch, + merge_when_pipeline_succeeds=merge_when_pipeline_succeeds, + sha=sha or self.sha, # if provided, ensures what is merged is what we want (or fails) + ) + if auto_squash is not None: + params['squash'] = auto_squash + return self._api.call(PUT('/projects/{0.project_id}/merge_requests/{0.iid}/merge'.format(self), params)) def close(self): return self._api.call(PUT( diff --git a/marge/single_merge_job.py b/marge/single_merge_job.py index e6e341a8..79e8c8e4 100644 --- a/marge/single_merge_job.py +++ b/marge/single_merge_job.py @@ -92,12 +92,16 @@ def update_merge_request_and_accept(self, approvals): self.ensure_mergeable_mr(merge_request) + auto_squash = None + if self.is_auto_squash_enabled(merge_request): + auto_squash = True + try: ret = merge_request.accept( remove_branch=merge_request.force_remove_source_branch, sha=actual_sha, merge_when_pipeline_succeeds=bool(target_project.only_allow_merge_if_pipeline_succeeds), - auto_squash=self.is_auto_squash_enabled(merge_request) + auto_squash=auto_squash ) log.info('merge_request.accept result: %s', ret) except gitlab.NotAcceptable as err: diff --git a/tests/test_merge_request.py b/tests/test_merge_request.py index 075a6e7a..7259ea72 100644 --- a/tests/test_merge_request.py +++ b/tests/test_merge_request.py @@ -172,7 +172,6 @@ def test_accept_remove_branch(self): merge_when_pipeline_succeeds=True, should_remove_source_branch=boolean, sha='badc0de', - squash=None, ) )) self.api.call.reset_mock() @@ -186,7 +185,6 @@ def test_accept_sha(self): merge_when_pipeline_succeeds=True, should_remove_source_branch=False, sha='g00dc0de', - squash=None, ) )) @@ -199,7 +197,6 @@ def test_accept_merge_when_pipeline_succeeds(self): merge_when_pipeline_succeeds=False, should_remove_source_branch=False, sha='badc0de', - squash=None, ) )) From 00785b219760485428628937298300d5a958b033 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Tue, 24 Jan 2023 04:19:18 +0530 Subject: [PATCH 05/12] Fixes linting --- marge/merge_request.py | 5 ++++- pylintrc | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/marge/merge_request.py b/marge/merge_request.py index 868c5805..2d6d9f42 100644 --- a/marge/merge_request.py +++ b/marge/merge_request.py @@ -211,7 +211,10 @@ def accept(self, remove_branch=False, sha=None, merge_when_pipeline_succeeds=Tru ) if auto_squash is not None: params['squash'] = auto_squash - return self._api.call(PUT('/projects/{0.project_id}/merge_requests/{0.iid}/merge'.format(self), params)) + return self._api.call(PUT( + '/projects/{0.project_id}/merge_requests/{0.iid}/merge'.format(self), + params + )) def close(self): return self._api.call(PUT( diff --git a/pylintrc b/pylintrc index bc5347e1..62017c8b 100644 --- a/pylintrc +++ b/pylintrc @@ -30,7 +30,7 @@ max-line-length=110 [DESIGN] max-args=10 max-attributes=15 -max-public-methods=35 +max-public-methods=40 # Maximum number of locals for function / method body max-locals=25 From 0e4e82c180d6e5084119a41ae22f3ef3c06557b0 Mon Sep 17 00:00:00 2001 From: Anurag Agarwal Date: Tue, 24 Jan 2023 04:43:11 +0530 Subject: [PATCH 06/12] Uses only project enforced --- marge/job.py | 10 ++++++---- marge/merge_request.py | 3 --- marge/project.py | 6 +++++- marge/single_merge_job.py | 4 +--- pylintrc | 2 +- tests/test_project.py | 1 - 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/marge/job.py b/marge/job.py index 018d848f..6cb28880 100644 --- a/marge/job.py +++ b/marge/job.py @@ -39,9 +39,6 @@ def opts(self): def execute(self): raise NotImplementedError - def is_auto_squash_enabled(self, merge_request): - return self._project.squash_option == "always" or merge_request.squash - def ensure_mergeable_mr(self, merge_request): merge_request.refetch_info() log.info('Ensuring MR !%s is mergeable', merge_request.iid) @@ -50,7 +47,12 @@ def ensure_mergeable_mr(self, merge_request): if merge_request.work_in_progress: raise CannotMerge("Sorry, I can't merge requests marked as Work-In-Progress!") - if self.is_auto_squash_enabled(merge_request) and self._options.requests_commit_tagging: + auto_squash = ( + self._project.squash_enforced or + merge_request.squash + ) + + if auto_squash and self._options.requests_commit_tagging: raise CannotMerge( "Sorry, merging requests marked as auto-squash would ruin my commit tagging!" ) diff --git a/marge/merge_request.py b/marge/merge_request.py index 2d6d9f42..07956db1 100644 --- a/marge/merge_request.py +++ b/marge/merge_request.py @@ -159,9 +159,6 @@ def blocking_discussions_resolved(self): def force_remove_source_branch(self): return self.info['force_remove_source_branch'] - def auto_squash(self, project): - return project.squash_option == "always" or self.squash - def update_sha(self, sha): """record the updated sha. We don't use refetch_info instead as it may hit cache.""" self._info['sha'] = sha diff --git a/marge/project.py b/marge/project.py index 0ef00ea2..62aef04e 100644 --- a/marge/project.py +++ b/marge/project.py @@ -91,7 +91,7 @@ def merge_requests_enabled(self): @property def squash_option(self): - return self.info['squash_option'] + return self.info.get('squash_option', None) @property def only_allow_merge_if_pipeline_succeeds(self): @@ -116,6 +116,10 @@ def access_level(self): assert effective_access is not None, "GitLab failed to provide user permissions on project" return AccessLevel(effective_access['access_level']) + @property + def squash_enforced(self): + return self.squash_option == 'always' + # pylint: disable=invalid-name @unique diff --git a/marge/single_merge_job.py b/marge/single_merge_job.py index 79e8c8e4..602e06d4 100644 --- a/marge/single_merge_job.py +++ b/marge/single_merge_job.py @@ -92,9 +92,7 @@ def update_merge_request_and_accept(self, approvals): self.ensure_mergeable_mr(merge_request) - auto_squash = None - if self.is_auto_squash_enabled(merge_request): - auto_squash = True + auto_squash = True if target_project.squash_enforced else None try: ret = merge_request.accept( diff --git a/pylintrc b/pylintrc index 62017c8b..bc5347e1 100644 --- a/pylintrc +++ b/pylintrc @@ -30,7 +30,7 @@ max-line-length=110 [DESIGN] max-args=10 max-attributes=15 -max-public-methods=40 +max-public-methods=35 # Maximum number of locals for function / method body max-locals=25 diff --git a/tests/test_project.py b/tests/test_project.py index f6b32123..fd963e91 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -13,7 +13,6 @@ 'default_branch': 'master', 'only_allow_merge_if_pipeline_succeeds': True, 'only_allow_merge_if_all_discussions_are_resolved': False, - 'squash_option': 'never', 'permissions': { 'project_access': { 'access_level': AccessLevel.developer.value, From 75522844cb072f7183fcc9d7efc7343c38283290 Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Sat, 11 Feb 2023 19:44:24 +0000 Subject: [PATCH 07/12] Fix tests by adding pip constraint for importlib-metadata. See https://stackoverflow.com/a/73932581. It seems like importlib-metadata is only required for tests, not production code. --- .github/workflows/test.yml | 2 +- constraints.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 constraints.txt diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cbfc01c6..92cf9744 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,6 +23,6 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install requirements - run: pip install -r requirements_frozen.txt + run: pip install -c constraints.txt -r requirements_frozen.txt - name: Run tests run: pytest diff --git a/constraints.txt b/constraints.txt new file mode 100644 index 00000000..9428e642 --- /dev/null +++ b/constraints.txt @@ -0,0 +1 @@ +importlib-metadata<5.0 From b3b10a314d38fb9b37c9526d0e3582f4a8b08f82 Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Sun, 12 Feb 2023 01:01:41 +0000 Subject: [PATCH 08/12] reduce mocking, since squash check happens before approval check --- tests/test_job.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_job.py b/tests/test_job.py index 22036d10..7d033fd6 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -152,7 +152,6 @@ def test_ensure_mergeable_mr_squash_and_trailers(self): work_in_progress=False, squash=True, ) - merge_request.fetch_approvals.return_value.sufficient = True with pytest.raises(CannotMerge) as exc_info: merge_job.ensure_mergeable_mr(merge_request) From 4c98f7f5c61083a5971bf72c3bfefd12f9cc1909 Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Sat, 11 Feb 2023 21:11:13 +0000 Subject: [PATCH 09/12] add test around `ensure_mergeable_mr()` function's handling of needing `squash` --- tests/test_job.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_job.py b/tests/test_job.py index 7d033fd6..620d0dfc 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -160,6 +160,29 @@ def test_ensure_mergeable_mr_squash_and_trailers(self): "would ruin my commit tagging!" ) + def test_ensure_mergeable_mr_squash_needed_and_trailers(self): + merge_job = self.get_merge_job( + project=create_autospec( + marge.project.Project, + spec_set=True, + squash_option="always", + ), + options=MergeJobOptions.default(add_reviewers=True), + ) + merge_request = self._mock_merge_request( + assignee_ids=[merge_job._user.id], + state='opened', + work_in_progress=False, + squash=False, + ) + with pytest.raises(CannotMerge) as exc_info: + merge_job.ensure_mergeable_mr(merge_request) + + assert ( + exc_info.value.reason == "Sorry, merging requests marked as auto-squash " + "would ruin my commit tagging!" + ) + def test_unassign_from_mr(self): merge_job = self.get_merge_job() merge_request = self._mock_merge_request() From 8fd54b374c97e4164f9dbf9b823e3cbc15710df9 Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Sat, 11 Feb 2023 21:40:24 +0000 Subject: [PATCH 10/12] remove non-API property `squash_enforced` to reduce footprint (and simplify mocking) the only API calls made in marge-bot are `/projects` (with `simple` undefined) and `/projects/:id`, and both responses always contain the `squash_option` field to limit the scope of validation outside `Project`, convert `squash_option` into an enum --- marge/job.py | 4 ++-- marge/project.py | 16 ++++++++++------ marge/single_merge_job.py | 3 ++- tests/test_job.py | 2 +- tests/test_project.py | 4 +++- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/marge/job.py b/marge/job.py index 6cb28880..f2640104 100644 --- a/marge/job.py +++ b/marge/job.py @@ -9,7 +9,7 @@ from .branch import Branch from .interval import IntervalUnion from .merge_request import MergeRequestRebaseFailed -from .project import Project +from .project import Project, SquashOption from .user import User from .pipeline import Pipeline @@ -48,7 +48,7 @@ def ensure_mergeable_mr(self, merge_request): raise CannotMerge("Sorry, I can't merge requests marked as Work-In-Progress!") auto_squash = ( - self._project.squash_enforced or + self._project.squash_option is SquashOption.always or merge_request.squash ) diff --git a/marge/project.py b/marge/project.py index 62aef04e..29a656fc 100644 --- a/marge/project.py +++ b/marge/project.py @@ -1,5 +1,5 @@ import logging as log -from enum import IntEnum, unique +from enum import Enum, IntEnum, unique from functools import partial from . import gitlab @@ -91,7 +91,7 @@ def merge_requests_enabled(self): @property def squash_option(self): - return self.info.get('squash_option', None) + return SquashOption(self.info['squash_option']) @property def only_allow_merge_if_pipeline_succeeds(self): @@ -116,10 +116,6 @@ def access_level(self): assert effective_access is not None, "GitLab failed to provide user permissions on project" return AccessLevel(effective_access['access_level']) - @property - def squash_enforced(self): - return self.squash_option == 'always' - # pylint: disable=invalid-name @unique @@ -132,3 +128,11 @@ class AccessLevel(IntEnum): developer = 30 maintainer = 40 owner = 50 + + +@unique +class SquashOption(str, Enum): + always = "always" + default_off = "default_off" + default_on = "default_on" + never = "never" diff --git a/marge/single_merge_job.py b/marge/single_merge_job.py index 602e06d4..64377360 100644 --- a/marge/single_merge_job.py +++ b/marge/single_merge_job.py @@ -6,6 +6,7 @@ from . import git, gitlab from .commit import Commit from .job import CannotMerge, GitLabRebaseResultMismatch, MergeJob, SkipMerge +from .project import SquashOption class SingleMergeJob(MergeJob): @@ -92,7 +93,7 @@ def update_merge_request_and_accept(self, approvals): self.ensure_mergeable_mr(merge_request) - auto_squash = True if target_project.squash_enforced else None + auto_squash = True if target_project.squash_option is SquashOption.always else None try: ret = merge_request.accept( diff --git a/tests/test_job.py b/tests/test_job.py index 620d0dfc..c180e9d5 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -165,7 +165,7 @@ def test_ensure_mergeable_mr_squash_needed_and_trailers(self): project=create_autospec( marge.project.Project, spec_set=True, - squash_option="always", + squash_option=marge.project.SquashOption.always, ), options=MergeJobOptions.default(add_reviewers=True), ) diff --git a/tests/test_project.py b/tests/test_project.py index fd963e91..1bdec12b 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -20,7 +20,8 @@ 'group_access': { 'access_level': AccessLevel.developer.value, } - } + }, + 'squash_option': 'default_off', } GROUP_ACCESS = { @@ -109,6 +110,7 @@ def test_properties(self): assert project.merge_requests_enabled is True assert project.only_allow_merge_if_pipeline_succeeds is True assert project.only_allow_merge_if_all_discussions_are_resolved is False + assert project.squash_option == 'default_off' assert project.access_level == AccessLevel.developer def test_group_access(self): From 75a28354bb0f57ebcc42c3dfc8c4c77399af3167 Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Sat, 11 Feb 2023 19:05:35 +0000 Subject: [PATCH 11/12] pytest parametrize over enum iterator of project squash options also rename test to reflect wanting vs needing to squash --- tests/test_job.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/test_job.py b/tests/test_job.py index c180e9d5..54a78bbb 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -144,8 +144,16 @@ def test_ensure_mergeable_mr_unresolved_discussion(self): assert exc_info.value.reason == "Sorry, I can't merge requests which have unresolved discussions!" - def test_ensure_mergeable_mr_squash_and_trailers(self): - merge_job = self.get_merge_job(options=MergeJobOptions.default(add_reviewers=True)) + @pytest.mark.parametrize('squash_option', marge.project.SquashOption) + def test_ensure_mergeable_mr_squash_wanted_and_trailers(self, squash_option): + merge_job = self.get_merge_job( + project=create_autospec( + marge.project.Project, + spec_set=True, + squash_option=squash_option, + ), + options=MergeJobOptions.default(add_reviewers=True) + ) merge_request = self._mock_merge_request( assignee_ids=[merge_job._user.id], state='opened', From d528a86de2be6a0e5a0fec8c2df72b7c58612d5d Mon Sep 17 00:00:00 2001 From: Alan Ip Date: Sat, 11 Feb 2023 23:49:13 +0000 Subject: [PATCH 12/12] add tests around `accept()` function's `squash` arg --- tests/test_merge_request.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/test_merge_request.py b/tests/test_merge_request.py index 7259ea72..90dc84f7 100644 --- a/tests/test_merge_request.py +++ b/tests/test_merge_request.py @@ -161,6 +161,32 @@ def test_rebase_was_in_progress_no_error(self): self.merge_request.rebase() self.api.call.assert_has_calls([call(req) for (req, resp) in expected]) + @pytest.mark.parametrize('squash_wanted', [True, False]) + def test_accept_auto_squash_is_boolean(self, squash_wanted): + self._load(dict(INFO, sha='badc0de')) + self.merge_request.accept(auto_squash=squash_wanted) + self.api.call.assert_called_once_with(PUT( + '/projects/1234/merge_requests/54/merge', + dict( + merge_when_pipeline_succeeds=True, + should_remove_source_branch=False, + sha='badc0de', + squash=squash_wanted, + ) + )) + + def test_accept_auto_squash_is_none(self): + self._load(dict(INFO, sha='badc0de')) + self.merge_request.accept(auto_squash=None) + self.api.call.assert_called_once_with(PUT( + '/projects/1234/merge_requests/54/merge', + dict( + merge_when_pipeline_succeeds=True, + should_remove_source_branch=False, + sha='badc0de', + ) + )) + def test_accept_remove_branch(self): self._load(dict(INFO, sha='badc0de'))