Ejemplo n.º 1
0
async def test_client_user_token(respx_mock: respx.MockRouter) -> None:
    respx_mock.get("/user/12345/installation").respond(
        200,
        json={
            "id": 12345,
            "target_type": "User",
            "permissions": {
                "checks": "write",
                "contents": "write",
                "pull_requests": "write",
            },
            "account": {
                "login": "******",
                "id": 12345
            },
        },
    )

    respx_mock.get("/",
                   headers__contains={
                       "Authorization": "token <user-token>"
                   }).respond(200, json={"work": True})

    installation_json = await github.get_installation_from_account_id(
        github_types.GitHubAccountIdType(12345))
    async with github.AsyncGithubInstallationClient(
            github.GithubAppInstallationAuth(installation_json)) as client:
        ret = await client.get(
            "/",
            oauth_token=github_types.GitHubOAuthToken("<user-token>"),
        )
        assert ret.json()["work"]
Ejemplo n.º 2
0
async def test_client_abuse_403_no_header(
        respx_mock: respx.MockRouter) -> None:

    abuse_message = ("You have triggered an abuse detection mechanism. "
                     "Please wait a few minutes before you try again.")
    respx_mock.get("/user/12345/installation").respond(
        200,
        json={
            "id": 12345,
            "target_type": "User",
            "permissions": {
                "checks": "write",
                "contents": "write",
                "pull_requests": "write",
            },
            "account": {
                "login": "******",
                "id": 12345
            },
        },
    )
    respx_mock.post("/app/installations/12345/access_tokens").respond(
        200, json={
            "token": "<token>",
            "expires_at": "2100-12-31T23:59:59Z"
        })
    respx_mock.get("/").respond(
        403,
        json={"message": abuse_message},
    )

    installation_json = await github.get_installation_from_account_id(
        github_types.GitHubAccountIdType(12345))
    async with github.AsyncGithubInstallationClient(
            github.GithubAppInstallationAuth(installation_json)) as client:
        with pytest.raises(http.HTTPClientSideError) as exc_info:
            await client.get("/")

    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) == f"{config.GITHUB_REST_API_URL}/"
Ejemplo n.º 3
0
async def test_client_installation_token_with_owner_id(
    respx_mock: respx.MockRouter, ) -> None:
    respx_mock.get("/user/12345/installation").respond(
        200,
        json={
            "id": 12345,
            "target_type": "User",
            "permissions": {
                "checks": "write",
                "contents": "write",
                "pull_requests": "write",
            },
            "account": {
                "login": "******",
                "id": 12345
            },
        },
    )

    respx_mock.post("/app/installations/12345/access_tokens").respond(
        200,
        json={
            "token": "<installation-token>",
            "expires_at": "2100-12-31T23:59:59Z"
        },
    )

    respx_mock.get("/",
                   headers__contains={
                       "Authorization": "token <installation-token>"
                   }).respond(200, json={"work": True})

    installation_json = await github.get_installation_from_account_id(
        github_types.GitHubAccountIdType(12345))
    async with github.AsyncGithubInstallationClient(
            github.GithubAppInstallationAuth(installation_json)) as client:
        ret = await client.get("/")
        assert ret.json()["work"]
        assert isinstance(client.auth, github.GithubAppInstallationAuth)
        assert client.auth._installation is not None
        assert client.auth._installation["account"]["login"] == "testing"
        assert client.auth._installation["account"]["id"] == 12345
Ejemplo n.º 4
0
async def test_client_access_token_HTTP_500(
        respx_mock: respx.MockRouter) -> None:
    respx_mock.get("/user/12345/installation").respond(
        200,
        json={
            "id": 12345,
            "target_type": "User",
            "permissions": {
                "checks": "write",
                "contents": "write",
                "pull_requests": "write",
            },
            "account": {
                "login": "******",
                "id": 12345
            },
        },
    )
    retries = [0]

    def error_500_tracker(_):
        retries[0] += 1
        return httpx.Response(500, text="This is a 5XX error")

    respx_mock.post("/app/installations/12345/access_tokens").mock(
        side_effect=error_500_tracker)

    installation_json = await github.get_installation_from_account_id(
        github_types.GitHubAccountIdType(12345))
    async with github.AsyncGithubInstallationClient(
            github.GithubAppInstallationAuth(installation_json)) as client:
        with pytest.raises(http.HTTPServerSideError) as exc_info:
            await client.get("/")

    assert exc_info.value.message == "This is a 5XX error"
    assert exc_info.value.status_code == 500
    assert exc_info.value.response.status_code == 500
    assert (str(
        exc_info.value.request.url
    ) == f"{config.GITHUB_REST_API_URL}/app/installations/12345/access_tokens")
Ejemplo n.º 5
0
async def test_configuration_check_not_needed_with_configuration_deleted(
    github_server: respx.MockRouter, redis_cache: utils.RedisCache
) -> None:
    github_server.get("/user/12345/installation").respond(
        200,
        json={
            "id": 12345,
            "permissions": {
                "checks": "write",
                "contents": "write",
                "pull_requests": "write",
            },
            "target_type": GH_OWNER["type"],
            "account": GH_OWNER,
        },
    )
    github_server.get(f"{BASE_URL}/pulls/1",).respond(
        200,
        json=typing.cast(typing.Dict[typing.Any, typing.Any], GH_PULL),
    )
    github_server.get(f"{BASE_URL}/contents/.mergify.yml").respond(
        200,
        json=typing.cast(
            typing.Dict[typing.Any, typing.Any],
            github_types.GitHubContentFile(
                {
                    "type": "file",
                    "content": FAKE_MERGIFY_CONTENT,
                    "path": ".mergify.yml",
                    "sha": github_types.SHAType(
                        "739e5ec79e358bae7a150941a148b4131233ce2c"
                    ),
                }
            ),
        ),
    )

    # Summary is present, no need to redo the check
    github_server.get(
        f"{BASE_URL}/commits/{GH_PULL['head']['sha']}/check-runs"
    ).respond(
        200,
        json={"check_runs": [SUMMARY_CHECK, CONFIGURATION_DELETED_CHECK]},
    )

    installation_json = await github.get_installation_from_account_id(GH_OWNER["id"])
    async with github.AsyncGithubInstallationClient(
        github.GithubAppInstallationAuth(installation_json)
    ) as client:
        installation = context.Installation(
            installation_json,
            subscription.Subscription(
                redis_cache,
                0,
                "",
                frozenset([subscription.Features.PUBLIC_REPOSITORY]),
                0,
            ),
            client,
            redis_cache,
            mock.Mock(),
        )
        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()
        changed = await engine._check_configuration_changes(ctxt, main_config_file)
        assert changed
Ejemplo n.º 6
0
async def test_configuration_initial(
    github_server: respx.MockRouter, redis_cache: utils.RedisCache
) -> None:
    github_server.get("/user/12345/installation").respond(
        200,
        json={
            "id": 12345,
            "permissions": {
                "checks": "write",
                "contents": "write",
                "pull_requests": "write",
            },
            "target_type": GH_OWNER["type"],
            "account": GH_OWNER,
        },
    )
    github_server.get(f"{BASE_URL}/pulls/1",).respond(
        200,
        json=typing.cast(typing.Dict[typing.Any, typing.Any], GH_PULL),
    )

    github_server.route(
        respx.patterns.M(method="GET", path=f"{BASE_URL}/contents/.mergify.yml")
        & ~respx.patterns.M(params__contains={"ref": GH_PULL["merge_commit_sha"]})
    ).respond(404)

    github_server.route(
        respx.patterns.M(method="GET", path=f"{BASE_URL}/contents/.mergify/config.yml")
        & ~respx.patterns.M(params__contains={"ref": GH_PULL["merge_commit_sha"]})
    ).respond(404)

    github_server.route(
        respx.patterns.M(method="GET", path=f"{BASE_URL}/contents/.github/mergify.yml")
        & ~respx.patterns.M(params__contains={"ref": GH_PULL["merge_commit_sha"]})
    ).respond(404)

    github_server.route(
        respx.patterns.M(method="GET", path=f"{BASE_URL}/contents/.mergify.yml")
        & respx.patterns.M(params__contains={"ref": GH_PULL["merge_commit_sha"]})
    ).respond(
        200,
        json=typing.cast(
            typing.Dict[typing.Any, typing.Any],
            github_types.GitHubContentFile(
                {
                    "type": "file",
                    "content": FAKE_MERGIFY_CONTENT,
                    "path": ".mergify.yml",
                    "sha": github_types.SHAType(
                        "739e5ec79e358bae7a150941a148b4131233ce2c"
                    ),
                }
            ),
        ),
    )
    github_server.route(
        respx.patterns.M(method="GET", path=f"{BASE_URL}/contents/.github/mergify.yml")
        & respx.patterns.M(params__contains={"ref": GH_PULL["merge_commit_sha"]})
    ).respond(404)
    github_server.route(
        respx.patterns.M(method="GET", path=f"{BASE_URL}/contents/.mergify/config.yml")
        & respx.patterns.M(params__contains={"ref": GH_PULL["merge_commit_sha"]})
    ).respond(404)

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

    github_server.post(f"{BASE_URL}/check-runs").respond(
        200, json=typing.cast(typing.Dict[typing.Any, typing.Any], CHECK_RUN)
    )

    installation_json = await github.get_installation_from_account_id(GH_OWNER["id"])
    async with github.AsyncGithubInstallationClient(
        github.GithubAppInstallationAuth(installation_json)
    ) as client:
        installation = context.Installation(
            installation_json,
            subscription.Subscription(
                redis_cache,
                0,
                "",
                frozenset([subscription.Features.PUBLIC_REPOSITORY]),
                0,
            ),
            client,
            redis_cache,
            mock.Mock(),
        )
        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