Exemplo n.º 1
0
async def test_labeled_on_unmerged_pr_is_ignored():
    data = {"action": "labeled", "pull_request": {"merged": False}}
    event = sansio.Event(data, event="pull_request", delivery_id="1")
    gh = FakeGH()
    await backport_pr.router.dispatch(event, gh)
    assert gh.getitem_url is None
Exemplo n.º 2
0
async def test_check_run_completed_with_awaiting_merge_label_not_miss_islington_is_not_merged(
):
    sha = "f2393593c99dd2d3ab8bfab6fcc5ddee540518a9"
    data = {
        "action": "completed",
        "check_run": {
            "head_sha": sha
        },
        "sender": {
            "login": "******"
        },
    }
    event = sansio.Event(data, event="check_run", delivery_id="1")

    getitem = {
        f"/repos/python/cpython/commits/{sha}/status": {
            "state":
            "success",
            "statuses": [
                {
                    "state": "success",
                    "description": "Issue report skipped",
                    "context": "bedevere/issue-number",
                },
                {
                    "state": "success",
                    "description": "The Travis CI build passed",
                    "target_url":
                    "https://travis-ci.org/python/cpython/builds/340259685?utm_source=github_status&utm_medium=notification",
                    "context": "continuous-integration/travis-ci/pr",
                },
            ],
        },
        "/repos/python/cpython/pulls/5544": {
            "user": {
                "login": "******"
            },
            "merged_by": {
                "login": "******"
            },
        },
        "/repos/python/cpython/pulls/5547": {
            "labels": [{
                "name": "awaiting merge"
            }]
        },
        f"/search/issues?q=type:pr+repo:python/cpython+sha:{sha}": {
            "total_count":
            1,
            "items": [{
                "number": 5547,
                "title":
                "bpo-32720: Fixed the replacement field grammar documentation.",
                "body":
                "\n\n`arg_name` and `element_index` are defined as `digit`+ instead of `integer`.\n(cherry picked from commit 7a561afd2c79f63a6008843b83733911d07f0119)\n\nCo-authored-by: Mariatta <*****@*****.**>",
                "labels": [{
                    "name": "awaiting merge"
                }],
            }],
        },
    }

    gh = FakeGH(getitem=getitem)
    await check_run.router.dispatch(event, gh)
    assert not hasattr(gh, "post_data")  # does not leave a comment
    assert not hasattr(gh, "put_data")  # is not merged
Exemplo n.º 3
0
async def test_non_core_dev_does_not_downgrade():
    core_dev = "brettcannon"
    non_core_dev = "andreamcinnes"
    teams = [{"name": "python core", "id": 6}]
    items = {
        f"https://api.github.com/teams/6/memberships/{non_core_dev}":
        gidgethub.BadRequest(status_code=http.HTTPStatus(404)),
        f"https://api.github.com/teams/6/memberships/{core_dev}":
        True,
        "https://api.github.com/issue/42": {
            "labels": [],
            "labels_url": "https://api.github.com/labels/42",
        }
    }

    # Approval from a core dev changes the state to "Awaiting merge".
    data = {
        "action": "submitted",
        "review": {
            "state": "approved",
            "user": {
                "login": core_dev,
            },
        },
        "pull_request": {
            "url": "https://api.github.com/pr/42",
            "issue_url": "https://api.github.com/issue/42",
        },
    }
    event = sansio.Event(data,
                         event="pull_request_review",
                         delivery_id="12345")
    iterators = {
        "https://api.github.com/orgs/python/teams":
        teams,
        "https://api.github.com/pr/42/reviews": [{
            "user": {
                "login": core_dev
            },
            "state": "approved"
        }],
    }
    gh = FakeGH(getiter=iterators, getitem=items)
    await awaiting.router.dispatch(event, gh)
    assert len(gh.post_) == 1
    post_ = gh.post_[0]
    assert post_[0] == "https://api.github.com/labels/42"
    assert post_[1] == [awaiting.Blocker.merge.value]

    # Non-comment review from a non-core dev doesn't "downgrade" the PR's state.
    data = {
        "action": "submitted",
        "review": {
            "state": "approved",
            "user": {
                "login": non_core_dev,
            },
        },
        "pull_request": {
            "url": "https://api.github.com/pr/42",
            "issue_url": "https://api.github.com/issue/42",
        },
    }
    event = sansio.Event(data,
                         event="pull_request_review",
                         delivery_id="12345")
    iterators = {
        "https://api.github.com/orgs/python/teams":
        teams,
        "https://api.github.com/pr/42/reviews": [
            {
                "user": {
                    "login": core_dev
                },
                "state": "approved"
            },
            {
                "user": {
                    "login": non_core_dev
                },
                "state": "approved"
            },
        ],
    }
    gh = FakeGH(getiter=iterators, getitem=items)
    await awaiting.router.dispatch(event, gh)
    assert not gh.post_
Exemplo n.º 4
0
async def test_new_comment():
    # Comment not from PR author.
    data = {
        "action": "created",
        "issue": {
            "user": {
                "login": "******"
            }
        },
        "comment": {
            "user": {
                "login": "******"
            },
            "body": awaiting.BORING_TRIGGER_PHRASE,
        },
    }
    event = sansio.Event(data, event="issue_comment", delivery_id="12345")
    gh = FakeGH()
    await awaiting.router.dispatch(event, gh)
    assert not len(gh.post_)

    # Comment from PR author but missing trigger phrase.
    data = {
        "action": "created",
        "issue": {
            "user": {
                "login": "******"
            }
        },
        "comment": {
            "user": {
                "login": "******"
            },
            "body": "I DID expect the Spanish Inquisition",
        },
    }
    event = sansio.Event(data, event="issue_comment", delivery_id="12345")
    gh = FakeGH()
    await awaiting.router.dispatch(event, gh)
    assert not len(gh.post_)

    # Everything is right with the world.
    data = {
        "action": "created",
        "issue": {
            "user": {
                "login": "******"
            },
            "labels": [],
            "labels_url": "https://api.github.com/labels/42",
            "url": "https://api.github.com/issue/42",
            "pull_request": {
                "url": "https://api.github.com/pr/42"
            },
            "comments_url": "https://api.github.com/comments/42",
        },
        "comment": {
            "user": {
                "login": "******"
            },
            "body": awaiting.BORING_TRIGGER_PHRASE,
        },
    }
    event = sansio.Event(data, event="issue_comment", delivery_id="12345")
    items = {
        "https://api.github.com/teams/6/memberships/brettcannon":
        True,
        "https://api.github.com/teams/6/memberships/gvanrossum":
        True,
        "https://api.github.com/teams/6/memberships/not-core-dev":
        gidgethub.BadRequest(status_code=http.HTTPStatus(404)),
    }
    iterators = {
        "https://api.github.com/orgs/python/teams": [{
            "name": "python core",
            "id": 6
        }],
        "https://api.github.com/pr/42/reviews": [
            {
                "user": {
                    "login": "******"
                },
                "state": "approved"
            },
            {
                "user": {
                    "login": "******"
                },
                "state": "changes_requested"
            },
            {
                "user": {
                    "login": "******"
                },
                "state": "approved"
            },
        ],
    }
    gh = FakeGH(getitem=items, getiter=iterators)
    await awaiting.router.dispatch(event, gh)
    assert len(gh.post_) == 3
    labeling, comment, review_request = gh.post_
    assert labeling[0] == "https://api.github.com/labels/42"
    assert labeling[1] == [awaiting.Blocker.change_review.value]
    assert comment[0] == "https://api.github.com/comments/42"
    comment_body = comment[1]["body"]
    assert "@brettcannon" in comment_body
    assert "@gvanrossum" in comment_body
    assert "not-core-dev" not in comment_body
    assert review_request[
        0] == "https://api.github.com/pr/42/requested_reviewers"
    requested_reviewers = review_request[1]["reviewers"]
    assert "brettcannon" in requested_reviewers
    assert "gvanrossum" in requested_reviewers
    assert "not-core-dev" not in requested_reviewers

    # All is right with the Monty Python world.
    data = {
        "action": "created",
        "issue": {
            "user": {
                "login": "******"
            },
            "labels": [],
            "labels_url": "https://api.github.com/labels/42",
            "url": "https://api.github.com/issue/42",
            "pull_request": {
                "url": "https://api.github.com/pr/42"
            },
            "comments_url": "https://api.github.com/comments/42",
        },
        "comment": {
            "user": {
                "login": "******"
            },
            "body": awaiting.FUN_TRIGGER_PHRASE,
        },
    }
    event = sansio.Event(data, event="issue_comment", delivery_id="12345")
    gh = FakeGH(getitem=items, getiter=iterators)
    await awaiting.router.dispatch(event, gh)
    assert len(gh.post_) == 3
    labeling, comment, review_request = gh.post_
    assert labeling[0] == "https://api.github.com/labels/42"
    assert labeling[1] == [awaiting.Blocker.change_review.value]
    assert comment[0] == "https://api.github.com/comments/42"
    comment_body = comment[1]["body"]
    assert "@brettcannon" in comment_body
    assert "@gvanrossum" in comment_body
    assert "not-core-dev" not in comment_body
    assert review_request[
        0] == "https://api.github.com/pr/42/requested_reviewers"
    requested_reviewers = review_request[1]["reviewers"]
    assert "brettcannon" in requested_reviewers
    assert "gvanrossum" in requested_reviewers
    assert "not-core-dev" not in requested_reviewers
Exemplo n.º 5
0
async def test_ci_passed_automerge():
    sha = "f2393593c99dd2d3ab8bfab6fcc5ddee540518a9"
    data = {
        "action": "completed",
        "check_run": {
            "head_sha": sha
        },
        "sender": {
            "login": "******"
        },
    }
    event = sansio.Event(data, event="check_run", delivery_id="1")

    getitem = {
        f"/repos/python/cpython/commits/{sha}/status": {
            "state":
            "success",
            "statuses": [
                {
                    "state": "success",
                    "description": "Issue report skipped",
                    "context": "bedevere/issue-number",
                },
                {
                    "state": "success",
                    "description": "The Travis CI build passed",
                    "target_url":
                    "https://travis-ci.org/python/cpython/builds/340259685?utm_source=github_status&utm_medium=notification",
                    "context": "continuous-integration/travis-ci/pr",
                },
            ],
        },
        "/repos/python/cpython/pulls/5547": {
            "user": {
                "login": "******"
            },
            "merged_by": None,
            "labels": [
                {
                    "name": "awaiting merge"
                },
                {
                    "name": AUTOMERGE_LABEL
                },
            ],
        },
        f"/search/issues?q=type:pr+repo:python/cpython+sha:{sha}": {
            "total_count":
            1,
            "items": [{
                "number":
                5547,
                "title":
                "bpo-32720: Fixed the replacement field grammar documentation.",
                "body":
                "\n\n`arg_name` and `element_index` are defined as `digit`+ instead of `integer`.\n(cherry picked from commit 7a561afd2c79f63a6008843b83733911d07f0119)\n\nCo-authored-by: Mariatta <*****@*****.**>",
                "labels": [
                    {
                        "name": "awaiting merge"
                    },
                    {
                        "name": AUTOMERGE_LABEL
                    },
                ],
            }],
        },
        f"/repos/python/cpython/commits/{sha}/check-runs": {
            "check_runs": [{
                "conclusion": "success",
                "name": "Travis CI - Pull Request",
                "status": "completed",
            }],
            "total_count":
            1,
        },
    }

    getiter = {
        "/repos/python/cpython/pulls/5547/commits": [{
            "sha": "f2393593c99dd2d3ab8bfab6fcc5ddee540518a9",
            "commit": {
                "message":
                "bpo-32720: Fixed the replacement field grammar documentation."
            },
        }]
    }

    gh = FakeGH(getitem=getitem, getiter=getiter)
    await check_run.router.dispatch(event, gh)
    assert len(gh.post_data["body"]) is not None  # leaves a comment
    assert gh.put_data["sha"] == sha  # is merged
    assert gh.put_data["merge_method"] == "squash"
    assert (
        gh.put_data["commit_title"] ==
        "bpo-32720: Fixed the replacement field grammar documentation. (GH-5547)"
    )
Exemplo n.º 6
0
async def test_new_review():
    # First non-comment review from a non-core dev.
    username = "******"
    data = {
        "action": "submitted",
        "review": {
            "state": "approved",
            "user": {
                "login": username,
            },
        },
        "pull_request": {
            "url": "https://api.github.com/pr/42",
            "issue_url": "https://api.github.com/issue/42",
        },
    }
    event = sansio.Event(data,
                         event="pull_request_review",
                         delivery_id="12345")
    teams = [{"name": "python core", "id": 6}]
    items = {
        f"https://api.github.com/teams/6/memberships/{username}":
        gidgethub.BadRequest(status_code=http.HTTPStatus(404)),
        "https://api.github.com/teams/6/memberships/brettcannon":
        True,
        "https://api.github.com/issue/42": {
            "labels": [],
            "labels_url": "https://api.github.com/labels/42",
        }
    }
    iterators = {
        "https://api.github.com/orgs/python/teams":
        teams,
        "https://api.github.com/pr/42/reviews": [{
            "user": {
                "login": "******"
            },
            "state": "commented"
        }],
    }
    gh = FakeGH(getiter=iterators, getitem=items)
    await awaiting.router.dispatch(event, gh)
    assert len(gh.post_) == 1
    post_ = gh.post_[0]
    assert post_[0] == "https://api.github.com/labels/42"
    assert post_[1] == [awaiting.Blocker.core_review.value]

    # First and second review from a non-core dev.
    items = {
        f"https://api.github.com/teams/6/memberships/{username}":
        gidgethub.BadRequest(status_code=http.HTTPStatus(404)),
        "https://api.github.com/teams/6/memberships/brettcannon":
        True,
        "https://api.github.com/issue/42": {
            "labels": [],
            "labels_url": "https://api.github.com/labels/42",
        }
    }
    iterators = {
        "https://api.github.com/orgs/python/teams":
        teams,
        "https://api.github.com/pr/42/reviews": [{
            "user": {
                "login": "******"
            },
            "state": "approved"
        }],
    }
    gh = FakeGH(getiter=iterators, getitem=items)
    await awaiting.router.dispatch(event, gh)
    assert not gh.post_

    # First comment review from a non-core dev.
    data = {
        "action": "submitted",
        "review": {
            "state": "comment",
            "user": {
                "login": username,
            },
        },
        "pull_request": {
            "url": "https://api.github.com/pr/42",
            "issue_url": "https://api.github.com/issue/42",
        },
    }
    event = sansio.Event(data,
                         event="pull_request_review",
                         delivery_id="12345")
    items = {
        f"https://api.github.com/teams/6/memberships/{username}":
        gidgethub.BadRequest(status_code=http.HTTPStatus(404)),
        "https://api.github.com/teams/6/memberships/brettcannon":
        True,
        "https://api.github.com/issue/42": {
            "labels": [],
            "labels_url": "https://api.github.com/labels/42",
        }
    }
    iterators = {
        "https://api.github.com/orgs/python/teams":
        teams,
        "https://api.github.com/pr/42/reviews": [{
            "user": {
                "login": "******"
            },
            "state": "approved"
        }],
    }
    gh = FakeGH(getiter=iterators, getitem=items)
    await awaiting.router.dispatch(event, gh)
    assert not gh.post_

    # Core dev submits an approving review.
    username = "******"
    data = {
        "action": "submitted",
        "review": {
            "user": {
                "login": username,
            },
            "state": "APPROVED",
        },
        "pull_request": {
            "url": "https://api.github.com/pr/42",
            "issue_url": "https://api.github.com/issue/42",
        },
    }
    event = sansio.Event(data,
                         event="pull_request_review",
                         delivery_id="12345")
    teams = [{"name": "python core", "id": 6}]
    items = {
        f"https://api.github.com/teams/6/memberships/{username}": True,
        "https://api.github.com/issue/42": {
            "labels": [{
                "name": awaiting.Blocker.changes.value
            }],
            "labels_url": "https://api.github.com/labels/42",
        }
    }
    iterators = {
        "https://api.github.com/orgs/python/teams": teams,
        "https://api.github.com/pr/42/reviews": [],
    }
    gh = FakeGH(getiter=iterators, getitem=items)
    await awaiting.router.dispatch(event, gh)
    assert len(gh.post_) == 1
    post_ = gh.post_[0]
    assert post_[0] == "https://api.github.com/labels/42"
    assert post_[1] == [awaiting.Blocker.merge.value]

    # Core dev requests changes.
    data = {
        "action": "submitted",
        "review": {
            "user": {
                "login": username,
            },
            "state": "changes_requested".upper(),
        },
        "pull_request": {
            "url": "https://api.github.com/pr/42",
            "issue_url": "https://api.github.com/issue/42",
            "comments_url": "https://api.github.com/comment/42",
            "user": {
                "login": "******"
            }
        },
    }
    event = sansio.Event(data,
                         event="pull_request_review",
                         delivery_id="12345")
    items = {
        f"https://api.github.com/teams/6/memberships/{username}":
        True,
        f"https://api.github.com/teams/6/memberships/miss-islington":
        gidgethub.BadRequest(status_code=http.HTTPStatus(404)),
        "https://api.github.com/issue/42": {
            "labels": [],
            "labels_url": "https://api.github.com/labels/42",
        }
    }
    gh = FakeGH(getiter=iterators, getitem=items)
    await awaiting.router.dispatch(event, gh)
    assert len(gh.post_) == 2
    labeling = gh.post_[0]
    assert labeling[0] == "https://api.github.com/labels/42"
    assert labeling[1] == [awaiting.Blocker.changes.value]
    message = gh.post_[1]
    assert message[0] == "https://api.github.com/comment/42"
    assert awaiting.BORING_TRIGGER_PHRASE in message[1]["body"]

    # Comment reviews do nothing.
    data = {
        "action": "submitted",
        "review": {
            "user": {
                "login": username,
            },
            "state": "commented".upper(),
        },
        "pull_request": {
            "url": "https://api.github.com/pr/42",
            "issue_url": "https://api.github.com/issue/42",
            "comments_url": "https://api.github.com/comment/42",
        },
    }
    event = sansio.Event(data,
                         event="pull_request_review",
                         delivery_id="12345")
    gh = FakeGH(getiter=iterators, getitem=items)
    await awaiting.router.dispatch(event, gh)
    assert not len(gh.post_)

    # Skip commenting if "awaiting changes" is already set.
    data = {
        "action": "submitted",
        "review": {
            "user": {
                "login": username,
            },
            "state": "changes_requested".upper(),
        },
        "pull_request": {
            "url": "https://api.github.com/pr/42",
            "issue_url": "https://api.github.com/issue/42",
            "comments_url": "https://api.github.com/comment/42",
        },
    }
    event = sansio.Event(data,
                         event="pull_request_review",
                         delivery_id="12345")
    items = {
        f"https://api.github.com/teams/6/memberships/{username}": True,
        "https://api.github.com/issue/42": {
            "labels": [{
                "name": awaiting.Blocker.changes.value
            }],
            "labels_url": "https://api.github.com/labels/42",
        }
    }
    gh = FakeGH(getiter=iterators, getitem=items)
    await awaiting.router.dispatch(event, gh)
    assert not len(gh.post_)
Exemplo n.º 7
0
async def test_travis_not_done():
    sha = "f2393593c99dd2d3ab8bfab6fcc5ddee540518a9"
    data = {
        "sha": sha,
        "commit": {
            "committer": {
                "login": "******",
            },
        }
    }
    event = sansio.Event(data, event='status', delivery_id='1')

    getitem = {
        f'/repos/python/cpython/commits/{sha}/status': {
            "state":
            "success",
            "statuses": [{
                "state": "success",
                "description": "Issue report skipped",
                "context": "bedevere/issue-number",
            }]
        },
        "/repos/python/cpython/pulls/5544": {
            "user": {
                "login": "******"
            },
            "merged_by": {
                "login": "******"
            }
        },
        "/teams/42/memberships/Mariatta": True
    }

    getiter = {
        '/repos/miss-islington/cpython/git/refs/heads/': [{
            "ref": f"refs/heads/backport-{sha[0:7]}-3.6",
            "object": {
                "sha": sha,
            }
        }, {
            "ref": "refs/heads/backport-63ae044-3.6",
            "object": {
                "sha":
                "67a2b0b7713e40dea7762b7d7764ae18fe967561",
                "type":
                "commit",
                "url":
                "https://api.github.com/repos/miss-islington/cpython/git/commits/67a2b0b7713e40dea7762b7d7764ae18fe967561"
            }
        }],
        f'/repos/python/cpython/pulls?state=open&head=miss-islington:backport-{sha[0:7]}-3.6':
        [
            {
                "number":
                5547,
                "title":
                "[3.6] bpo-32720: Fixed the replacement field grammar documentation. (GH-5544)",
                "body":
                "\n\n`arg_name` and `element_index` are defined as `digit`+ instead of `integer`.\n(cherry picked from commit 7a561afd2c79f63a6008843b83733911d07f0119)\n\nCo-authored-by: Mariatta <*****@*****.**>"
            },
        ],
        '/repos/python/cpython/pulls/5547/reviews': [{
            "user": {
                "login": "******"
            },
            "state": "APPROVED"
        }],
        '/repos/python/cpython/pulls/5547/commits': [{
            "sha": "f2393593c99dd2d3ab8bfab6fcc5ddee540518a9",
            "commit": {
                "message":
                "bpo-32720: Fixed the replacement field grammar documentation. (GH-5544)\n\n`arg_name` and `element_index` are defined as `digit`+ instead of `integer`.\n(cherry picked from commit 7a561afd2c79f63a6008843b83733911d07f0119)\n\nCo-authored-by: Mariatta <*****@*****.**>"
            }
        }],
        "/orgs/python/teams": [{
            "name": "Python core",
            "id": 42
        }],
    }

    gh = FakeGH(getitem=getitem, getiter=getiter)
    await status_change.router.dispatch(event, gh)
    assert not hasattr(gh, 'post_data')  # does not leave a comment
    assert not hasattr(gh, 'put_data')  # is not merged
Exemplo n.º 8
0
async def test_branch_sha_not_matched_pr_not_merged():
    sha = "f2393593c99dd2d3ab8bfab6fcc5ddee540518a9"
    data = {"sha": sha, "commit": {"committer": {"login": "******"}}}
    event = sansio.Event(data, event="status", delivery_id="1")

    getitem = {
        f"/repos/python/cpython/commits/{sha}/status": {
            "state":
            "success",
            "statuses": [
                {
                    "state": "success",
                    "description": "Issue report skipped",
                    "context": "bedevere/issue-number",
                },
                {
                    "state": "success",
                    "description": "The Travis CI build passed",
                    "target_url":
                    "https://travis-ci.org/python/cpython/builds/340259685?utm_source=github_status&utm_medium=notification",
                    "context": "continuous-integration/travis-ci/pr",
                },
            ],
        },
        "/repos/python/cpython/pulls/5544": {
            "user": {
                "login": "******"
            },
            "merged_by": {
                "login": "******"
            },
        },
        "/repos/python/cpython/pulls/5547": {
            "labels": [{
                "name": "awaiting merge"
            }]
        },
    }

    getiter = {
        "/repos/miss-islington/cpython/git/refs/heads/": [
            {
                "ref": f"refs/heads/backport-{sha[0:7]}-3.6",
                "object": {
                    "sha": sha
                }
            },
            {
                "ref": "refs/heads/backport-63ae044-3.6",
                "object": {
                    "sha":
                    "67a2b0b7713e40dea7762b7d7764ae18fe967561",
                    "type":
                    "commit",
                    "url":
                    "https://api.github.com/repos/miss-islington/cpython/git/commits/67a2b0b7713e40dea7762b7d7764ae18fe967561",
                },
            },
        ],
        f"/repos/python/cpython/pulls?state=open&head=miss-islington:backport-{sha[0:7]}-3.6":
        [{
            "number":
            5547,
            "title":
            "[3.6] bpo-32720: Fixed the replacement field grammar documentation. (GH-5544)",
            "body":
            "\n\n`arg_name` and `element_index` are defined as `digit`+ instead of `integer`.\n(cherry picked from commit 7a561afd2c79f63a6008843b83733911d07f0119)\n\nCo-authored-by: Mariatta <*****@*****.**>",
        }],
        "/repos/python/cpython/pulls/5547/commits": [{
            "sha": "f2393593c99dd2d3",
            "commit": {
                "message":
                "bpo-32720: Fixed the replacement field grammar documentation. (GH-5544)\n\n`arg_name` and `element_index` are defined as `digit`+ instead of `integer`.\n(cherry picked from commit 7a561afd2c79f63a6008843b83733911d07f0119)\n\nCo-authored-by: Mariatta <*****@*****.**>"
            },
        }],
    }

    gh = FakeGH(getitem=getitem, getiter=getiter)
    await status_change.router.dispatch(event, gh)
    assert not hasattr(gh, "put_data")  # is not merged
Exemplo n.º 9
0
async def test_check_run_completed_failing_with_label():
    data = {
        "action": "completed",
        "check_run": {
            "head_sha": sha,
            "status": "completed",
            "conclusion": "timed_out",
        },
        "name": "Travis CI - Pull Request",
        "repository": {
            "full_name": repository
        },
        "installation": {
            "id": MOCK_INSTALLATION_ID
        },
    }
    event = sansio.Event(data, event="check_run", delivery_id="7")
    getitem = {
        search_url: {
            "total_count":
            1,
            "items": [{
                "number":
                number,
                "state":
                "open",
                "labels": [
                    {
                        "name": "Status: awaiting reviews"
                    },
                    {
                        "name": Label.FAILED_TEST
                    },
                ],
                "labels_url":
                check_run_url,
            }],
        },
        check_run_url: {
            "total_count":
            2,
            "check_runs": [
                {
                    "status": "completed",
                    "conclusion": "timed_out",
                    "name": "Travis CI - Pull Request",
                },
                {
                    "status": "completed",
                    "conclusion": "success",
                    "name": "pre-commit",
                },
            ],
        },
    }
    gh = MockGitHubAPI(getitem=getitem)
    result = await check_runs.router.dispatch(event, gh)
    assert result is None
    assert len(gh.getitem_url) == 2
    assert gh.getitem_url == [search_url, check_run_url]
    assert gh.post_data == []  # does not add any label
    assert gh.post_url == []
    assert gh.delete_url == []  # does not delete any label
Exemplo n.º 10
0
async def test_pr_reviewed_webhook_ci_passed_pr_is_merged():
    sha = "f2393593c99dd2d3ab8bfab6fcc5ddee540518a9"
    data = {
        "action": "submitted",
        "pull_request": {
            "user": {
                "login": "******"
            }
        },
        "review": {
            "commit_id": sha,
            "user": {
                "login": "******"
            },
            "state": "approved"
        }
    }

    event = sansio.Event(data, event='pull_request_review', delivery_id='1')

    getitem = {
        f'/repos/python/cpython/commits/{sha}/status': {
            "state":
            "success",
            "statuses": [{
                "state": "success",
                "description": "Issue report skipped",
                "context": "bedevere/issue-number",
            }, {
                "state": "success",
                "description": "The Travis CI build passed",
                "target_url":
                "https://travis-ci.org/python/cpython/builds/340259685?utm_source=github_status&utm_medium=notification",
                "context": "continuous-integration/travis-ci/pr",
            }]
        },
        "/teams/42/memberships/Mariatta": True
    }

    getiter = {
        '/repos/miss-islington/cpython/git/refs/heads/': [{
            "ref": f"refs/heads/backport-{sha[0:7]}-3.6",
            "object": {
                "sha": sha,
            }
        }, {
            "ref": f"refs/heads/backport-{sha[0:7]}-3.6",
            "object": {
                "sha":
                sha,
                "type":
                "commit",
                "url":
                f"https://api.github.com/repos/miss-islington/cpython/git/commits/{sha}"
            }
        }],
        f'/repos/python/cpython/pulls?state=open&head=miss-islington:backport-{sha[0:7]}-3.6':
        [
            {
                "number":
                5547,
                "title":
                "[3.6] bpo-32720: Fixed the replacement field grammar documentation. (GH-5544)",
                "body":
                "\n\n`arg_name` and `element_index` are defined as `digit`+ instead of `integer`.\n(cherry picked from commit 7a561afd2c79f63a6008843b83733911d07f0119)\n\nCo-authored-by: Mariatta <*****@*****.**>"
            },
        ],
        "/orgs/python/teams": [{
            "name": "Python core",
            "id": 42
        }],
        '/repos/python/cpython/pulls/5547/reviews': [{
            "user": {
                "login": "******"
            },
            "state": "APPROVED"
        }],
        '/repos/python/cpython/pulls/5547/commits': [{
            "sha": "f2393593c99dd2d3ab8bfab6fcc5ddee540518a9",
            "commit": {
                "message":
                "bpo-32720: Fixed the replacement field grammar documentation. (GH-5544)\n\n`arg_name` and `element_index` are defined as `digit`+ instead of `integer`.\n(cherry picked from commit 7a561afd2c79f63a6008843b83733911d07f0119)\n\nCo-authored-by: Mariatta <*****@*****.**>"
            }
        }],
    }

    gh = FakeGH(getitem=getitem, getiter=getiter)
    await status_change.router.dispatch(event, gh)
    assert not hasattr(gh, 'post_data')  # does not leave a comment
    assert gh.put_data["sha"] == sha  # is merged
    assert gh.put_data["merge_method"] == "squash"
    assert gh.put_data[
        "commit_title"] == "bpo-32720: Fixed the replacement field grammar documentation. (GH-5544)"
Exemplo n.º 11
0
async def test_check_run_completed_passing_with_label():
    rm_labels_url = f"{labels_url}/{urllib.parse.quote(Label.FAILED_TEST)}"
    data = {
        "action": "completed",
        "check_run": {
            "head_sha": sha,
            "status": "completed",
            "conclusion": "action_required",
        },
        "name": "validate-solutions",
        "repository": {
            "full_name": repository
        },
        "installation": {
            "id": MOCK_INSTALLATION_ID
        },
    }
    event = sansio.Event(data, event="check_run", delivery_id="5")
    getitem = {
        search_url: {
            "total_count":
            1,
            "items": [{
                "number":
                number,
                "state":
                "open",
                "labels": [
                    {
                        "name": "Status: awaiting reviews"
                    },
                    {
                        "name": Label.FAILED_TEST
                    },
                ],
                "labels_url":
                labels_url,
            }],
        },
        check_run_url: {
            "total_count":
            2,
            "check_runs": [
                {
                    "status": "completed",
                    "conclusion": "action_required",
                    "name": "validate-solutions",
                },
                {
                    "status": "completed",
                    "conclusion": "success",
                    "name": "pre-commit",
                },
            ],
        },
    }
    delete = {rm_labels_url: [{"name": "Status: awaiting reviews"}]}
    gh = MockGitHubAPI(getitem=getitem, delete=delete)
    result = await check_runs.router.dispatch(event, gh)
    assert result is None
    assert len(gh.getitem_url) == 2
    assert gh.getitem_url == [search_url, check_run_url]
    assert gh.post_url == []
    assert gh.post_data == []  # does not add any label
    assert gh.delete_url[0] == rm_labels_url
Exemplo n.º 12
0
async def test_new_commit_pushed_to_approved_pr():
    # There is new commit on approved PR
    username = "******"
    sha = "f2393593c99dd2d3ab8bfab6fcc5ddee540518a9"
    data = {"commits": [{"id": sha}]}
    event = sansio.Event(data, event="push", delivery_id="12345")
    teams = [{"name": "python core", "id": 6}]
    items = {
        f"https://api.github.com/teams/6/memberships/{username}": "OK",
        f"https://api.github.com/search/issues?q=type:pr+repo:python/cpython+sha:{sha}":
        {
            "total_count":
            1,
            "items": [{
                "number":
                5547,
                "title":
                "[3.6] bpo-32720: Fixed the replacement field grammar documentation. (GH-5544)",
                "body":
                "\n\n`arg_name` and `element_index` are defined as `digit`+ instead of `integer`.\n(cherry picked from commit 7a561afd2c79f63a6008843b83733911d07f0119)\n\nCo-authored-by: Mariatta <*****@*****.**>",
                "labels": [{
                    "name": "CLA signed",
                }, {
                    "name": "awaiting merge",
                }],
                "issue_url":
                "/repos/python/cpython/issues/5547",
            }],
        },
        "https://api.github.com/repos/python/cpython/issues/5547": {
            "labels": [{
                "name": "awaiting merge"
            }],
            "labels_url":
            "https://api.github.com/repos/python/cpython/issues/5547/labels{/name}",
            "pull_request": {
                "url":
                "https://api.github.com/repos/python/cpython/pulls/5547",
            },
            "comments_url":
            "https://api.github.com/repos/python/cpython/issues/5547/comments",
        },
    }
    gh = FakeGH(
        getiter={
            "https://api.github.com/orgs/python/teams":
            teams,
            "https://api.github.com/repos/python/cpython/pulls/5547/reviews":
            [{
                "user": {
                    "login": "******"
                },
                "state": "approved"
            }],
        },
        getitem=items,
    )
    await awaiting.router.dispatch(event, gh)

    # 3 posts:
    # - change the label
    # - leave a comment
    # - re-request review
    assert len(gh.post_) == 3

    assert (gh.post_[0][0] ==
            "https://api.github.com/repos/python/cpython/issues/5547/labels")
    assert gh.post_[0][1] == [awaiting.Blocker.core_review.value]

    assert (gh.post_[1][0] ==
            "https://api.github.com/repos/python/cpython/issues/5547/comments")
    assert gh.post_[1][1] == {
        "body":
        ACK.format(
            greeting="There's a new commit after the PR has been approved.",
            core_devs="@brettcannon",
        )
    }
Exemplo n.º 13
0
async def test_pr_with_remove_all_require_labels():
    # This case will only be true when the action is `synchronize`
    test_label_url = labels_url + f"/{urllib.parse.quote(Label.REQUIRE_TEST)}"
    names_label_url = labels_url + f"/{urllib.parse.quote(Label.DESCRIPTIVE_NAMES)}"
    annotation_label_url = labels_url + f"/{urllib.parse.quote(Label.ANNOTATIONS)}"
    data = {
        "action": "synchronize",
        "number": number,
        "pull_request": {
            "number":
            number,
            "url":
            pr_url,
            "body":
            CHECKBOX_TICKED,
            "labels": [
                {
                    "name": Label.REQUIRE_TEST
                },
                {
                    "name": Label.DESCRIPTIVE_NAMES
                },
                {
                    "name": Label.ANNOTATIONS
                },
            ],
            "user": {
                "login": user
            },
            "author_association":
            "NONE",
            "comments_url":
            comments_url,
            "issue_url":
            issue_url,
            "html_url":
            html_pr_url,
            "requested_reviewers": [{
                "login": "******"
            }, {
                "login": "******"
            }],
            "draft":
            False,
        },
        "repository": {
            "full_name": repository
        },
        "installation": {
            "id": MOCK_INSTALLATION_ID
        },
    }
    event = sansio.Event(data, event="pull_request", delivery_id="1")
    getiter = {
        files_url: [
            {
                "filename": "no_errors.py",
                "contents_url": "",
                "status": "added"
            },
            {
                "filename": "algorithm.py",
                "contents_url": "",
                "status": "added"
            },
        ],
    }
    delete = {
        test_label_url: {},
        names_label_url: {},
        annotation_label_url: {}
    }
    gh = MockGitHubAPI(getiter=getiter, delete=delete)
    await pull_requests.router.dispatch(event, gh)
    assert len(gh.getiter_url) == 1
    assert gh.getiter_url[0] == files_url
    # No labels are added
    assert gh.post_url == []
    assert gh.post_data == []
    # All labels are deleted
    assert gh.delete_url == [
        test_label_url, names_label_url, annotation_label_url
    ]
    assert gh.delete_data == [{}, {}, {}]
Exemplo n.º 14
0
async def test_max_pr_reached():
    data = {
        "action": "opened",
        "number": number,
        "pull_request": {
            "number": number,
            "url": pr_url,
            "body": CHECKBOX_TICKED,
            "head": {
                "sha": sha
            },
            "labels": [],
            "user": {
                "login": user
            },
            "author_association": "NONE",
            "comments_url": comments_url,
            "issue_url": issue_url,
            "html_url": html_pr_url,
            "requested_reviewers": [{
                "login": "******"
            }, {
                "login": "******"
            }],
            "draft": False,
        },
        "repository": {
            "full_name": repository
        },
        "installation": {
            "id": MOCK_INSTALLATION_ID
        },
    }
    event = sansio.Event(data, event="pull_request", delivery_id="1")
    getiter = {
        pr_user_search_url: {
            "total_count":
            2,
            "items": [
                {
                    "number": 1,
                    "state": "opened"
                },
                {
                    "number": 2,
                    "state": "opened"
                },
            ],
        },
        files_url: [],  # for check_pr_files function
    }
    post = {comments_url: {}}
    patch = {pr_url: {}}
    delete = {reviewers_url: {}}
    gh = MockGitHubAPI(getiter=getiter, post=post, patch=patch, delete=delete)
    await pull_requests.router.dispatch(event, gh)
    assert gh.getiter_url[0] == pr_user_search_url
    assert gh.post_url[0] == comments_url
    assert gh.post_data[0] == {
        "body": MAX_PR_REACHED_COMMENT.format(user_login=user,
                                              pr_number="#1, #2")
    }
    assert gh.patch_url[0] == pr_url
    assert gh.delete_url[0] == reviewers_url
    assert gh.delete_data[0] == {"reviewers": ["test1", "test2"]}
Exemplo n.º 15
0
async def test_label_on_ready_for_review_pr():
    # Open a PR in draft
    # Convert the draft PR to ready for review PR
    # Tests are failing on the latest commit, so test that it adds the label
    data = {
        "action": "ready_for_review",
        "number": number,
        "pull_request": {
            "number": number,
            "url": pr_url,
            "body": CHECKBOX_TICKED,
            "head": {
                "sha": sha
            },
            "labels": [],
            "user": {
                "login": user
            },
            "author_association": "NONE",
            "comments_url": comments_url,
            "issue_url": issue_url,
            "html_url": html_pr_url,
            "requested_reviewers": [{
                "login": "******"
            }, {
                "login": "******"
            }],
            "draft": False,
        },
        "repository": {
            "full_name": repository
        },
        "installation": {
            "id": MOCK_INSTALLATION_ID
        },
    }
    event = sansio.Event(data, event="pull_request", delivery_id="1")
    getitem = {
        check_run_url: {
            "total_count":
            2,
            "check_runs": [
                {
                    "status": "completed",
                    "conclusion": "success",
                    "name": "validate-solutions",
                },
                {
                    "status": "completed",
                    "conclusion": "failure",
                    "name": "pre-commit",
                },
            ],
        },
    }
    getiter = {
        files_url: {},
    }
    post = {labels_url: {}}
    gh = MockGitHubAPI(getitem=getitem, getiter=getiter, post=post)
    await pull_requests.router.dispatch(event, gh)
    assert len(gh.getitem_url) == 1
    assert check_run_url in gh.getitem_url
    assert len(gh.getiter_url) == 1
    assert files_url in gh.getiter_url
    assert labels_url in gh.post_url
    assert {"labels": [Label.FAILED_TEST]} in gh.post_data
    assert gh.delete_url == []