import xmlrpc.client import pytest from utils import Commit, read_tracking_value, matches # basic udiff / show style patch, updates `b` from `1` to `2` BASIC_UDIFF = """\ commit 0000000000000000000000000000000000000000 Author: 3 Discos Down Date: 2021-04-24T17:09:14Z whop whop whop diff --git a/b b/b index 000000000000..000000000000 100644 --- a/b +++ b/b @@ -1,1 +1,1 @@ -1 +2 """ FORMAT_PATCH_XMO = """\ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: 3 Discos Down Date: Sat, 24 Apr 2021 17:09:14 +0000 Subject: [PATCH] [I18N] whop whop whop --- b | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b b/b index 000000000000..000000000000 100644 --- a/b +++ b/b @@ -1,1 +1,1 @@ -1 +2 -- 2.46.2 """ # slightly different format than the one I got, possibly because older? FORMAT_PATCH_MAT = """\ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: 3 Discos Down Date: Sat, 24 Apr 2021 17:09:14 +0000 Subject: [PATCH 1/1] [I18N] whop whop whop --- b | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git b b index 000000000000..000000000000 100644 --- b +++ b @@ -1,1 +1,1 @@ -1 +2 -- 2.34.1 """ @pytest.fixture(autouse=True) def _setup(repo): with repo: [c, _] = repo.make_commits( None, Commit("a", tree={"a": "1", "b": "1\n"}), Commit("b", tree={"a": "2"}), ref="heads/master", ) repo.make_ref("heads/x", c) @pytest.mark.parametrize("group,access", [ ('base.group_portal', False), ('base.group_user', False), ('runbot_merge.group_patcher', True), ('runbot_merge.group_admin', False), ('base.group_system', True), ]) def test_patch_acl(env, project, group, access): g = env.ref(group) assert g._name == 'res.groups' env['res.users'].create({ 'name': 'xxx', 'login': 'xxx', 'password': 'xxx', 'groups_id': [(6, 0, [g.id])], }) env2 = env.with_user('xxx', 'xxx') def create(): return env2['runbot_merge.patch'].create({ 'target': project.branch_ids.id, 'repository': project.repo_ids.id, 'patch': BASIC_UDIFF, }) if access: create() else: pytest.raises(xmlrpc.client.Fault, create)\ .match("You are not allowed to create") def test_apply_commit(env, project, repo, users): with repo: [c] = repo.make_commits("x", Commit("c", tree={"b": "2"}, author={ 'name': "Henry Hoover", "email": "dustsuckinghose@example.org", }), ref="heads/abranch") repo.delete_ref('heads/abranch') p = env['runbot_merge.patch'].create({ 'target': project.branch_ids.id, 'repository': project.repo_ids.id, 'commit': c, }) env.run_crons() HEAD = repo.commit('master') assert repo.read_tree(HEAD) == { 'a': '2', 'b': '2', } assert HEAD.message == "c" assert HEAD.author['name'] == "Henry Hoover" assert HEAD.author['email'] == "dustsuckinghose@example.org" assert not p.active def test_commit_conflict(env, project, repo, users): with repo: [c] = repo.make_commits("x", Commit("x", tree={"b": "3"})) repo.make_commits("master", Commit("c", tree={"b": "2"}), ref="heads/master", make=False) p = env['runbot_merge.patch'].create({ 'target': project.branch_ids.id, 'repository': project.repo_ids.id, 'commit': c, }) env.run_crons() HEAD = repo.commit('master') assert repo.read_tree(HEAD) == { 'a': '2', 'b': '2', } assert not p.active assert [( m.subject, m.body, list(map(read_tracking_value, m.tracking_value_ids)), ) for m in reversed(p.message_ids) ] == [ (False, '

Unstaged direct-application patch created

', []), ( "Unable to apply patch", """\

Auto-merging b
\ CONFLICT (content): Merge conflict in b

\ """, [], ), (False, '', [('active', 1, 0)]), ] def test_apply_udiff(env, project, repo, users): p = env['runbot_merge.patch'].create({ 'target': project.branch_ids.id, 'repository': project.repo_ids.id, 'patch': BASIC_UDIFF, }) env.run_crons() HEAD = repo.commit('master') assert repo.read_tree(HEAD) == { 'a': '2', 'b': '2\n', } assert HEAD.message == "whop\n\nwhop whop" assert HEAD.author['name'] == "3 Discos Down" assert HEAD.author['email'] == "bar@example.org" assert not p.active @pytest.mark.parametrize('patch', [ pytest.param(FORMAT_PATCH_XMO, id='xmo'), pytest.param(FORMAT_PATCH_MAT, id='mat'), pytest.param( FORMAT_PATCH_XMO.replace('\n', '\r\n'), id='windows', ), pytest.param( FORMAT_PATCH_XMO.rsplit('-- \n')[0], id='no-signature', ) ]) def test_apply_format_patch(env, project, repo, users, patch): p = env['runbot_merge.patch'].create({ 'target': project.branch_ids.id, 'repository': project.repo_ids.id, 'patch': patch, }) env.run_crons() bot = env['res.users'].browse((1,)) assert p.message_ids[::-1].mapped(lambda m: ( m.author_id.display_name, m.body, list(map(read_tracking_value, m.tracking_value_ids)), )) == [ (p.create_uid.partner_id.display_name, '

Unstaged direct-application patch created

', []), (bot.partner_id.display_name, "", [('active', 1, 0)]), ] HEAD = repo.commit('master') assert repo.read_tree(HEAD) == { 'a': '2', 'b': '2\n', } assert HEAD.message == "[I18N] whop\n\nwhop whop" assert HEAD.author['name'] == "3 Discos Down" assert HEAD.author['email'] == "bar@example.org" assert not p.active def test_patch_conflict(env, project, repo, users): p = env['runbot_merge.patch'].create({ 'target': project.branch_ids.id, 'repository': project.repo_ids.id, 'patch': BASIC_UDIFF, }) with repo: repo.make_commits('master', Commit('cccombo breaker', tree={'b': '3'}), ref='heads/master', make=False) env.run_crons() HEAD = repo.commit('master') assert HEAD.message == 'cccombo breaker' assert repo.read_tree(HEAD) == { 'a': '2', 'b': '3', } assert not p.active assert [( m.subject, m.body, list(map(read_tracking_value, m.tracking_value_ids)), ) for m in reversed(p.message_ids) ] == [( False, '

Unstaged direct-application patch created

', [], ), ( "Unable to apply patch", matches("$$"), # feedback from patch can vary [], ), ( False, '', [('active', 1, 0)] )]