import json import pytest from utils import seen, Commit, to_pr def test_no_duplicates(env): """ Should not have two override records for the same (context, repo) """ Overrides = env['res.partner.override'] Overrides.create({'context': 'a'}) with pytest.raises(Exception, match=r'already exists'): Overrides.create({'context': 'a'}) def name_search(Model, name): """ Convenience function to return a recordset instead of a craplist """ return Model.browse(id_ for id_, _ in Model.name_search(name)) def test_finding(env): project = env['runbot_merge.project'].create({ 'name': 'test', 'github_token': 'xxx', 'github_prefix': 'no', 'github_name': "xxx", 'github_email': "xxx@example.org", }) repo_1 = env['runbot_merge.repository'].create({'project_id': project.id, 'name': 'r1'}) repo_2 = env['runbot_merge.repository'].create({'project_id': project.id, 'name': 'r2'}) Overrides = env['res.partner.override'] a = Overrides.create({'context': 'ctx1'}) b = Overrides.create({'context': 'ctx1', 'repository_id': repo_1.id}) c = Overrides.create({'context': 'ctx1', 'repository_id': repo_2.id}) d = Overrides.create({'context': 'ctx2', 'repository_id': repo_2.id}) assert name_search(Overrides, 'ctx1') == a|b|c assert name_search(Overrides, 'ctx') == a|b|c|d assert name_search(Overrides, 'r2') == c|d def test_basic(env, project, make_repo, users, setreviewers, config): """ Test that we can override a status on a PR: * @mergebot override context=status * target url should be the comment (?) * description should be overridden by """ repo = make_repo('repo') repo_id = env['runbot_merge.repository'].create({ 'project_id': project.id, 'name': repo.name, 'status_ids': [(0, 0, {'context': 'l/int'})] }) setreviewers(*project.repo_ids) env['runbot_merge.events_sources'].create({'repository': repo.name}) # "other" can override the lint env['res.partner'].create({ 'name': config['role_other'].get('name', 'Other'), 'github_login': users['other'], 'override_rights': [(0, 0, { 'repository_id': repo_id.id, 'context': 'l/int', })] }) with repo: m = repo.make_commits(None, Commit('root', tree={'a': '1'}), ref='heads/master') repo.make_commits(m, Commit('pr', tree={'a': '2'}), ref='heads/change') pr = repo.make_pr(target='master', title='super change', head='change') pr.post_comment('hansen r+', config['role_reviewer']['token']) env.run_crons() pr_id = to_pr(env, pr) assert pr_id.state == 'approved' with repo: pr.post_comment('hansen override=l/int', config['role_reviewer']['token']) env.run_crons() assert pr_id.state == 'approved' with repo: pr.post_comment('hansen override=l/int', config['role_other']['token']) env.run_crons() assert pr_id.state == 'ready' comments = pr.comments assert comments == [ (users['reviewer'], 'hansen r+'), seen(env, pr, users), (users['reviewer'], 'hansen override=l/int'), (users['user'], "@{} you are not allowed to override 'l/int'.".format(users['reviewer'])), (users['other'], "hansen override=l/int"), ] assert pr_id.statuses == '{}' assert json.loads(pr_id.overrides) == {'l/int': { 'state': 'success', 'target_url': comments[-1]['html_url'], 'description': 'Overridden by @{}'.format(users['other']), }} def test_multiple(env, project, make_repo, users, setreviewers, config): """ Test that overriding multiple statuses in the same comment works """ repo = make_repo('repo') repo_id = env['runbot_merge.repository'].create({ 'project_id': project.id, 'name': repo.name, 'status_ids': [(0, 0, {'context': 'l/int'}), (0, 0, {'context': 'c/i'})] }) setreviewers(*project.repo_ids) env['runbot_merge.events_sources'].create({'repository': repo.name}) # "other" can override the lints env['res.partner'].create({ 'name': config['role_other'].get('name', 'Other'), 'github_login': users['other'], 'override_rights': [(0, 0, { 'repository_id': repo_id.id, 'context': 'l/int', }), (0, 0, { 'repository_id': repo_id.id, 'context': 'c/i', })] }) with repo: root = repo.make_commits(None, Commit('root', tree={'a': '0'}), ref='heads/master') for i, comment in enumerate([ # style 1: multiple commands inline 'hansen override=l/int override=c/i', # style 2: multiple parameters to command 'hansen override=l/int,c/i', # style 3: multiple commands each on its own line 'hansen override=l/int\nhansen override=c/i', ], start=1): with repo: repo.make_commits(root, Commit(f'pr{i}', tree={'a': f'{i}'}), ref=f'heads/change{i}') pr = repo.make_pr(target='master', title=f'super change {i}', head=f'change{i}') env.run_crons() pr_id = to_pr(env, pr) assert pr_id.state == 'opened' with repo: pr.post_comment(comment, config['role_other']['token']) env.run_crons() assert pr_id.state == 'validated' comments = pr.comments assert pr_id.statuses == '{}' assert json.loads(pr_id.overrides) == { 'l/int': { 'state': 'success', 'target_url': comments[-1]['html_url'], 'description': 'Overridden by @{}'.format(users['other']), }, 'c/i': { 'state': 'success', 'target_url': comments[-1]['html_url'], 'description': 'Overridden by @{}'.format(users['other']), }, } def test_no_repository(env, project, make_repo, users, setreviewers, config): """ A repo missing from an override allows overriding the status in every repo """ repo = make_repo('repo') env['runbot_merge.repository'].create({ 'project_id': project.id, 'name': repo.name, 'status_ids': [(0, 0, {'context': 'l/int'})] }) setreviewers(*project.repo_ids) env['runbot_merge.events_sources'].create({'repository': repo.name}) # "other" can override the lint env['res.partner'].create({ 'name': config['role_other'].get('name', 'Other'), 'github_login': users['other'], 'override_rights': [(0, 0, {'context': 'l/int'})] }) with repo: m = repo.make_commits(None, Commit('root', tree={'a': '1'}), ref='heads/master') repo.make_commits(m, Commit('pr', tree={'a': '2'}), ref='heads/change') pr = repo.make_pr(target='master', title='super change', head='change') pr.post_comment('hansen r+', config['role_reviewer']['token']) env.run_crons() pr_id = to_pr(env, pr) assert pr_id.state == 'approved' with repo: pr.post_comment('hansen override=l/int', config['role_other']['token']) env.run_crons() assert pr_id.state == 'ready' comments = pr.comments assert comments == [ (users['reviewer'], 'hansen r+'), seen(env, pr, users), (users['other'], "hansen override=l/int"), ] assert pr_id.statuses == '{}' assert json.loads(pr_id.overrides) == {'l/int': { 'state': 'success', 'target_url': comments[-1]['html_url'], 'description': 'Overridden by @{}'.format(users['other']), }}