Exemple #1
0
def test_client_user_token(httpserver: httpserver.HTTPServer) -> None:
    with mock.patch(
            "mergify_engine.config.GITHUB_API_URL",
            httpserver.url_for("/")[:-1],
    ):
        httpserver.expect_request("/users/owner").respond_with_json({
            "login":
            "******",
            "id":
            12345,
        })
        httpserver.expect_request("/",
                                  headers={
                                      "Authorization": "token <user-token>"
                                  }).respond_with_json({"work": True},
                                                       status=200)

        with github.GithubInstallationClient(
                github.get_auth("owner")) as client:
            ret = client.get(
                httpserver.url_for("/"),
                oauth_token="<user-token>")  # type: ignore[call-arg]
            assert ret.json()["work"]

    assert len(httpserver.log) == 2
def test_client_installation_HTTP_500(httpserver):
    httpserver.expect_request("/repos/owner/repo/installation").respond_with_data(
        "This is an 5XX error", status=500
    )
    with mock.patch(
        "mergify_engine.config.GITHUB_API_URL",
        httpserver.url_for("/")[:-1],
    ):
        with github.GithubInstallationClient(
            github.get_auth("owner", "repo")
        ) as client:
            with pytest.raises(http.HTTPServerSideError) as exc_info:
                client.get(httpserver.url_for("/"))

    # 5 retries
    assert len(httpserver.log) == 5

    assert exc_info.value.message == "This is an 5XX error"
    assert exc_info.value.status_code == 500
    assert exc_info.value.response.status_code == 500
    assert str(exc_info.value.request.url) == httpserver.url_for(
        "/repos/owner/repo/installation"
    )

    httpserver.check_assertions()
Exemple #3
0
def _sync_simulator(pull_request_rules, owner, repo, pull_number, token):
    try:
        if token:
            auth = github.GithubTokenAuth(owner, token)
        else:
            auth = github.get_auth(owner)

        with github.get_client(auth=auth) as client:
            try:
                data = client.item(
                    f"/repos/{owner}/{repo}/pulls/{pull_number}")
            except http.HTTPNotFound:
                raise PullRequestUrlInvalid(
                    message=
                    f"Pull request {owner}/{repo}/pulls/{pull_number} not found"
                )

            sub = asyncio.run(
                subscription.Subscription.get_subscription(
                    client.auth.owner_id))

            ctxt = context.Context(
                client,
                data,
                sub,
                [{
                    "event_type": "mergify-simulator",
                    "data": []
                }],
            )
            match = pull_request_rules.get_pull_request_rule(ctxt)
            return actions_runner.gen_summary(ctxt, match)
    except exceptions.MergifyNotInstalled:
        raise PullRequestUrlInvalid(
            message=f"Mergify not installed on repository '{owner}/{repo}'")
async def _simulator(redis_cache, pull_request_rules, owner, repo, pull_number, token):
    try:
        if token:
            auth = github.GithubTokenAuth(token)
        else:
            auth = github.get_auth(owner)

        async with github.aget_client(auth=auth) as client:
            try:
                data = await client.item(f"/repos/{owner}/{repo}/pulls/{pull_number}")
            except http.HTTPNotFound:
                raise PullRequestUrlInvalid(
                    message=f"Pull request {owner}/{repo}/pulls/{pull_number} not found"
                )

            sub = await subscription.Subscription.get_subscription(
                redis_cache, data["base"]["user"]["id"]
            )

            installation = context.Installation(
                data["base"]["user"]["id"],
                owner,
                sub,
                client,
                redis_cache,
            )
            repository = context.Repository(installation, data["base"]["repo"])
            ctxt = await repository.get_pull_request_context(data["number"], data)
            ctxt.sources = [{"event_type": "mergify-simulator", "data": []}]
            match = await pull_request_rules.get_pull_request_rule(ctxt)
            return await actions_runner.gen_summary(ctxt, pull_request_rules, match)
    except exceptions.MergifyNotInstalled:
        raise PullRequestUrlInvalid(
            message=f"Mergify not installed on repository '{owner}/{repo}'"
        )
Exemple #5
0
 def get_auth(owner=None, auth=None):
     if auth is None:
         auth = github.get_auth(owner)
         auth.installation = {
             "id": config.INSTALLATION_ID,
         }
         auth.permissions_need_to_be_updated = False
         auth.owner_id = config.TESTING_ORGANIZATION_ID
     return auth
Exemple #6
0
async def _do_test_client_installation_token(
    httpserver: httpserver.HTTPServer,
    endpoint: str,
    owner_name: typing.Optional[github_types.GitHubLogin] = None,
    owner_id: typing.Optional[github_types.GitHubAccountIdType] = None,
) -> None:

    with mock.patch(
            "mergify_engine.config.GITHUB_API_URL",
            httpserver.url_for("/")[:-1],
    ):

        httpserver.expect_request(endpoint).respond_with_json({
            "id": 12345,
            "target_type": "User",
            "permissions": {
                "checks": "write",
                "contents": "write",
                "pull_requests": "write",
            },
            "account": {
                "login": "******",
                "id": 12345
            },
        })

        httpserver.expect_request(
            "/app/installations/12345/access_tokens").respond_with_json({
                "token":
                "<app_token>",
                "expires_at":
                "2100-12-31T23:59:59Z"
            })

        httpserver.expect_request("/",
                                  headers={
                                      "Authorization":
                                      "token <installation-token>"
                                  }).respond_with_json({"work": True},
                                                       status=200)

        async with github.AsyncGithubInstallationClient(
                github.get_auth(owner_name=owner_name,
                                owner_id=owner_id)) as client:

            ret = await client.get(httpserver.url_for("/"))
            assert ret.json()["work"]
            assert client.auth.owner == "testing"
            assert client.auth.owner_id == 12345

    assert len(httpserver.log) == 3

    httpserver.check_assertions()
Exemple #7
0
async def test_client_abuse_403_no_header(
        httpserver: httpserver.HTTPServer) -> None:

    abuse_message = ("You have triggered an abuse detection mechanism. "
                     "Please wait a few minutes before you try again.")
    httpserver.expect_request("/users/owner/installation").respond_with_json({
        "id":
        12345,
        "target_type":
        "User",
        "permissions": {
            "checks": "write",
            "contents": "write",
            "pull_requests": "write",
        },
        "account": {
            "login": "******",
            "id": 12345
        },
    })
    httpserver.expect_request(
        "/app/installations/12345/access_tokens").respond_with_json({
            "token":
            "<token>",
            "expires_at":
            "2100-12-31T23:59:59Z"
        })

    httpserver.expect_oneshot_request("/").respond_with_json(
        {"message": abuse_message},
        status=403,
    )

    with mock.patch(
            "mergify_engine.config.GITHUB_API_URL",
            httpserver.url_for("/")[:-1],
    ):
        async with github.AsyncGithubInstallationClient(
                github.get_auth(github_types.GitHubLogin("owner"))) as client:
            with pytest.raises(http.HTTPClientSideError) as exc_info:
                await client.get(httpserver.url_for("/"))

    assert exc_info.value.message == abuse_message
    assert exc_info.value.status_code == 403
    assert exc_info.value.response.status_code == 403
    assert str(exc_info.value.request.url) == httpserver.url_for("/")
    assert len(httpserver.log) == 3

    httpserver.check_assertions()
Exemple #8
0
def test_client_installation_HTTP_404(httpserver):
    httpserver.expect_request("/users/owner/installation").respond_with_json(
        {"message": "Repository not found"}, status=404)
    with mock.patch(
            "mergify_engine.config.GITHUB_API_URL",
            httpserver.url_for("/")[:-1],
    ):
        with github.GithubInstallationClient(
                github.get_auth("owner")) as client:
            with pytest.raises(exceptions.MergifyNotInstalled):
                client.get(httpserver.url_for("/"))

    assert len(httpserver.log) == 1

    httpserver.check_assertions()
Exemple #9
0
def test_client_installation_token(httpserver):
    with mock.patch(
            "mergify_engine.config.GITHUB_API_URL",
            httpserver.url_for("/")[:-1],
    ):
        httpserver.expect_request(
            "/users/owner/installation").respond_with_json({
                "id": 12345,
                "target_type": "User",
                "permissions": {
                    "checks": "write",
                    "contents": "write",
                    "pull_requests": "write",
                },
                "account": {
                    "login": "******",
                    "id": 12345
                },
            })
        httpserver.expect_request(
            "/app/installations/12345/access_tokens").respond_with_json({
                "token":
                "<app_token>",
                "expires_at":
                "2100-12-31T23:59:59Z"
            })

        httpserver.expect_request("/",
                                  headers={
                                      "Authorization":
                                      "token <installation-token>"
                                  }).respond_with_json({"work": True},
                                                       status=200)

        with github.GithubInstallationClient(
                github.get_auth("owner")) as client:
            ret = client.get(httpserver.url_for("/"))
            assert ret.json()["work"]

    assert len(httpserver.log) == 3

    httpserver.check_assertions()
async def test_client_installation_HTTP_301(httpserver: httpserver.HTTPServer) -> None:
    httpserver.expect_request("/users/owner/installation").respond_with_data(
        status=301,
        headers={"Location": httpserver.url_for("/repositories/12345/installation")},
    )
    httpserver.expect_request("/repositories/12345/installation").respond_with_json(
        {"message": "Repository not found"}, status=404
    )
    with mock.patch(
        "mergify_engine.config.GITHUB_API_URL",
        httpserver.url_for("/")[:-1],
    ):
        async with github.AsyncGithubInstallationClient(
            github.get_auth(github_types.GitHubLogin("owner"))
        ) as client:
            with pytest.raises(exceptions.MergifyNotInstalled):
                await client.get(httpserver.url_for("/"))

    assert len(httpserver.log) == 2

    httpserver.check_assertions()
Exemple #11
0
async def test_client_access_token_HTTP_500(
        httpserver: httpserver.HTTPServer) -> None:
    httpserver.expect_request("/users/owner/installation").respond_with_json({
        "id":
        12345,
        "target_type":
        "User",
        "permissions": {
            "checks": "write",
            "contents": "write",
            "pull_requests": "write",
        },
        "account": {
            "login": "******",
            "id": 12345
        },
    })
    httpserver.expect_request(
        "/app/installations/12345/access_tokens").respond_with_data(
            "This is an 5XX error", status=500)

    with mock.patch(
            "mergify_engine.config.GITHUB_API_URL",
            httpserver.url_for("/")[:-1],
    ):
        async with github.AsyncGithubInstallationClient(
                github.get_auth(github_types.GitHubLogin("owner"))) as client:
            with pytest.raises(http.HTTPServerSideError) as exc_info:
                await client.get(httpserver.url_for("/"))

    # installation request + 5 retries
    assert len(httpserver.log) == 6

    assert exc_info.value.message == "This is an 5XX error"
    assert exc_info.value.status_code == 500
    assert exc_info.value.response.status_code == 500
    assert str(exc_info.value.request.url) == httpserver.url_for(
        "/app/installations/12345/access_tokens")

    httpserver.check_assertions()
Exemple #12
0
async def test_configuration_initial(
    github_server: httpserver.HTTPServer,
    redis_cache: utils.RedisCache,
) -> None:
    github_server.expect_oneshot_request(
        f"{BASE_URL}/pulls/1", ).respond_with_json(
            GH_PULL,
            status=200,
        )

    github_server.expect_oneshot_request(
        f"{BASE_URL}/contents/.mergify.yml", ).respond_with_data(status=404)

    github_server.expect_oneshot_request(
        f"{BASE_URL}/contents/.mergify/config.yml", ).respond_with_data(
            status=404)

    github_server.expect_oneshot_request(
        f"{BASE_URL}/contents/.github/mergify.yml", ).respond_with_data(
            status=404)

    github_server.expect_oneshot_request(
        f"{BASE_URL}/contents/.mergify.yml",
        query_string={
            "ref": GH_PULL["head"]["sha"]
        },
    ).respond_with_json(
        github_types.GitHubContentFile({
            "type":
            "file",
            "content":
            FAKE_MERGIFY_CONTENT,
            "path":
            ".mergify.yml",
            "sha":
            github_types.SHAType("739e5ec79e358bae7a150941a148b4131233ce2c"),
        }),
        status=200,
    )

    github_server.expect_oneshot_request(
        f"{BASE_URL}/commits/{GH_PULL['head']['sha']}/check-runs"
    ).respond_with_json({"check_runs": []}, status=200)

    github_server.expect_oneshot_request(f"{BASE_URL}/check-runs",
                                         method="POST").respond_with_json(
                                             {}, status=200)

    async with github.AsyncGithubInstallationClient(
            github.get_auth(GH_OWNER["login"])) as client:
        installation = context.Installation(
            GH_OWNER["id"],
            GH_OWNER["login"],
            subscription.Subscription(redis_cache, 0, False, "", frozenset(),
                                      0),
            client,
            redis_cache,
        )
        repository = context.Repository(installation, GH_REPO)
        ctxt = await repository.get_pull_request_context(
            github_types.GitHubPullRequestNumber(1))

        main_config_file = await repository.get_mergify_config_file()
        assert main_config_file is None

        changed = await engine._check_configuration_changes(
            ctxt, main_config_file)
        assert changed

    github_server.check_assertions()