Ejemplo n.º 1
0
async def test_application_tokens_via_env(monkeypatch, redis_cache):
    api_access_key1 = "1" * 32
    api_secret_key1 = "1" * 32
    account_id1 = github_types.GitHubAccountIdType(12345)
    account_login1 = github_types.GitHubLogin("login1")

    api_access_key2 = "2" * 32
    api_secret_key2 = "2" * 32
    account_id2 = github_types.GitHubAccountIdType(67891)
    account_login2 = github_types.GitHubLogin("login2")

    with pytest.raises(application.ApplicationUserNotFound):
        await application.ApplicationOnPremise.get(
            redis_cache, api_access_key1, api_secret_key1, None
        )

    with pytest.raises(application.ApplicationUserNotFound):
        await application.ApplicationOnPremise.get(
            redis_cache, api_access_key2, api_secret_key2, None
        )

    monkeypatch.setattr(
        config,
        "APPLICATION_APIKEYS",
        config.ApplicationAPIKeys(
            f"{api_access_key1}{api_secret_key1}:{account_id1}:{account_login1},{api_access_key2}{api_secret_key2}:{account_id2}:{account_login2}"
        ),
    )

    app = await application.ApplicationOnPremise.get(
        redis_cache, api_access_key1, api_secret_key1, account_login1
    )
    assert app.account_scope["id"] == account_id1

    app = await application.ApplicationOnPremise.get(
        redis_cache, api_access_key2, api_secret_key2, account_login2
    )
    assert app.account_scope["id"] == account_id2

    app = await application.ApplicationOnPremise.get(
        redis_cache, api_access_key1, api_secret_key1, None
    )
    assert app.account_scope["id"] == account_id1

    app = await application.ApplicationOnPremise.get(
        redis_cache, api_access_key2, api_secret_key2, None
    )
    assert app.account_scope["id"] == account_id2

    # wrong scope
    with pytest.raises(application.ApplicationUserNotFound):
        await application.ApplicationOnPremise.get(
            redis_cache, api_access_key1, api_secret_key1, account_id2
        )
    with pytest.raises(application.ApplicationUserNotFound):
        await application.ApplicationOnPremise.get(
            redis_cache, api_access_key2, api_secret_key2, account_id1
        )
Ejemplo n.º 2
0
async def _refresh(
    owner: github_types.GitHubLogin,
    repo: str,
    action: github_types.GitHubEventRefreshActionType = "user",
    ref: typing.Optional[github_types.GitHubRefType] = None,
    pull_request: typing.Optional[github_types.GitHubPullRequest] = None,
) -> responses.Response:
    data = github_types.GitHubEventRefresh({
        "action": action,
        "organization": {
            "login": owner,
            "id": github_types.GitHubAccountIdType(0),
            "type": "Organization",
        },
        "installation": {
            "id": 0,
            "account": {
                "login": owner,
                "id": github_types.GitHubAccountIdType(0),
                "type": "Organization",
            },
        },
        "repository": {
            "default_branch": github_types.GitHubRefType(""),
            "id": github_types.GitHubRepositoryIdType(0),
            "private": False,
            "archived": False,
            "url": "",
            "name": repo,
            "owner": {
                "login": owner,
                "id": github_types.GitHubAccountIdType(0),
                "type": "Organization",
            },
            "full_name": f"{owner}/{repo}",
        },
        "sender": {
            "login": github_types.GitHubLogin("<internal>"),
            "id": github_types.GitHubAccountIdType(0),
            "type": "User",
        },
        "ref": ref,
        "pull_request": pull_request,
    })

    await github_events.filter_and_dispatch(_AREDIS_STREAM, "refresh",
                                            str(uuid.uuid4()), data)

    return responses.Response("Refresh queued", status_code=202)
Ejemplo n.º 3
0
async def test_get_mergify_config_location_from_cache(
    redis_cache: utils.RedisCache, ) -> None:
    client = mock.AsyncMock()
    client.auth.owner = "foo"
    client.item.side_effect = [
        http.HTTPNotFound("Not Found",
                          request=mock.Mock(),
                          response=mock.Mock()),
        http.HTTPNotFound("Not Found",
                          request=mock.Mock(),
                          response=mock.Mock()),
        github_types.GitHubContentFile({
            "content":
            encodebytes("whatever".encode()).decode(),
            "type":
            "file",
            "path":
            ".github/mergify.yml",
            "sha":
            github_types.SHAType("zeazeaze"),
        }),
    ]

    installation = context.Installation(
        github_types.GitHubAccountIdType(0),
        github_types.GitHubLogin("foo"),
        subscription.Subscription(redis_cache, 0, False, "", frozenset()),
        client,
        redis_cache,
    )
    repository = context.Repository(installation,
                                    github_types.GitHubRepositoryName("bar"))

    await repository.get_mergify_config_file()
    assert client.item.call_count == 3
    client.item.assert_has_calls([
        mock.call("/repos/foo/bar/contents/.mergify.yml"),
        mock.call("/repos/foo/bar/contents/.mergify/config.yml"),
        mock.call("/repos/foo/bar/contents/.github/mergify.yml"),
    ])

    client.item.reset_mock()
    client.item.side_effect = [
        github_types.GitHubContentFile({
            "content":
            encodebytes("whatever".encode()).decode(),
            "type":
            "file",
            "path":
            ".github/mergify.yml",
            "sha":
            github_types.SHAType("zeazeaze"),
        }),
    ]
    repository._cache = context.RepositoryCache()
    await repository.get_mergify_config_file()
    assert client.item.call_count == 1
    client.item.assert_has_calls([
        mock.call("/repos/foo/bar/contents/.github/mergify.yml"),
    ])
Ejemplo n.º 4
0
async def test_get_mergify_config_invalid(
        invalid: str, redis_cache: utils.RedisCache) -> None:
    with pytest.raises(InvalidRules):

        async def item(*args, **kwargs):
            return github_types.GitHubContentFile({
                "content":
                encodebytes(invalid.encode()).decode(),
                "path":
                ".mergify.yml",
                "type":
                "file",
                "sha":
                "azertyu",
            })

        client = mock.Mock()
        client.item.return_value = item()
        installation = context.Installation(
            github_types.GitHubAccountIdType(0),
            github_types.GitHubLogin("foobar"),
            subscription.Subscription(redis_cache, 0, False, "", frozenset()),
            client,
            redis_cache,
        )
        repository = context.Repository(
            installation,
            github_types.GitHubRepositoryName("xyz"),
            github_types.GitHubRepositoryIdType(0),
        )

        config_file = await repository.get_mergify_config_file()
        assert config_file is not None
        get_mergify_config(config_file)
Ejemplo n.º 5
0
async def test_client_installation_token_with_owner_id(
    httpserver: httpserver.HTTPServer, ) -> None:
    await _do_test_client_installation_token(
        httpserver,
        "/user/12345/installation",
        owner_id=github_types.GitHubAccountIdType(12345),
    )
Ejemplo n.º 6
0
async def test_get_already_merged_summary(
    merged_by: str,
    raw_config: str,
    result: str,
    context_getter: conftest.ContextGetterFixture,
) -> None:
    ctxt = await context_getter(
        github_types.GitHubPullRequestNumber(1),
        merged=True,
        merged_by=github_types.GitHubAccount({
            "id":
            github_types.GitHubAccountIdType(1),
            "login":
            github_types.GitHubLogin(merged_by),
            "type":
            "User",
            "avatar_url":
            "",
        }),
    )
    ctxt.repository._caches.branch_protections[github_types.GitHubRefType(
        "main")] = None

    file = context.MergifyConfigFile(
        type="file",
        content="whatever",
        sha=github_types.SHAType("azertyuiop"),
        path="whatever",
        decoded_content=raw_config,
    )

    config = rules.get_mergify_config(file)
    match = await config["pull_request_rules"].get_pull_request_rule(ctxt)
    assert result == await actions_runner.get_already_merged_summary(
        ctxt, match)
Ejemplo n.º 7
0
async def test_save_apikey_scoped(redis_cache):
    api_access_key = "a" * 32
    api_secret_key = "s" * 32
    account_id = github_types.GitHubAccountIdType(12345)
    account_login = github_types.GitHubLogin("login")
    app = application.Application(
        redis_cache,
        0,
        "app name",
        api_access_key,
        api_secret_key,
        {"id": account_id, "login": account_login},
    )

    await app.save_to_cache()
    rapp = await application.Application._retrieve_from_cache(
        redis_cache, api_access_key, api_secret_key, account_login
    )
    assert app == rapp

    # wrong scope
    app = await application.Application._retrieve_from_cache(
        redis_cache,
        api_access_key,
        api_secret_key,
        github_types.GitHubLogin("another login"),
    )
    assert app is None
    app = await application.Application._retrieve_from_cache(
        redis_cache,
        api_access_key,
        api_secret_key,
        None,
    )
    assert app is None
Ejemplo n.º 8
0
async def send_refresh(
    redis_cache: utils.RedisCache,
    redis_stream: utils.RedisStream,
    repository: github_types.GitHubRepository,
    pull_request_number: typing.Optional[
        github_types.GitHubPullRequestNumber] = None,
    ref: typing.Optional[github_types.GitHubRefType] = None,
    action: github_types.GitHubEventRefreshActionType = "user",
) -> None:
    data = github_types.GitHubEventRefresh({
        "action": action,
        "ref": ref,
        "repository": repository,
        "pull_request_number": pull_request_number,
        "sender": {
            "login": github_types.GitHubLogin("<internal>"),
            "id": github_types.GitHubAccountIdType(0),
            "type": "User",
            "avatar_url": "",
        },
        "organization": repository["owner"],
        "installation": {
            "id": github_types.GitHubInstallationIdType(0),
            "account": repository["owner"],
        },
    })
    await filter_and_dispatch(redis_cache, redis_stream, "refresh",
                              str(uuid.uuid4()), data)
Ejemplo n.º 9
0
 async def get(
     cls: typing.Type[ApplicationClassT],
     redis: redis_utils.RedisCache,
     api_access_key: str,
     api_secret_key: str,
     account_scope: typing.Optional[github_types.GitHubLogin],
 ) -> ApplicationClassT:
     data = config.APPLICATION_APIKEYS.get(api_access_key)
     if data is None or data["api_secret_key"] != api_secret_key:
         raise ApplicationUserNotFound()
     if account_scope is not None and account_scope != data["account_login"]:
         raise ApplicationUserNotFound()
     return cls(
         redis,
         0,
         "on-premise-app",
         api_access_key,
         api_secret_key,
         ApplicationAccountScope({
             "id":
             github_types.GitHubAccountIdType(data["account_id"]),
             "login":
             github_types.GitHubLogin(data["account_login"]),
         }),
     )
Ejemplo n.º 10
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.º 11
0
async def test_client_installation_HTTP_404(
        respx_mock: respx.MockRouter) -> None:
    respx_mock.get("/user/12345/installation").respond(
        404, json={"message": "Repository not found"})

    with pytest.raises(exceptions.MergifyNotInstalled):
        await github.get_installation_from_account_id(
            github_types.GitHubAccountIdType(12345))
Ejemplo n.º 12
0
 def __init__(self) -> None:
     self.permissions_need_to_be_updated = False
     self.installation = {
         "id": config.ACTION_ID,
     }
     # TODO(sileht): To be defined when we handle subscription for GitHub Action
     self.owner = None
     self.owner_id = github_types.GitHubAccountIdType(0)
Ejemplo n.º 13
0
 def _extract_owner(
     self, stream_name: StreamNameType
 ) -> typing.Tuple[github_types.GitHubLogin, github_types.GitHubAccountIdType]:
     stream_splitted = stream_name.split("~")[1:]
     return (
         github_types.GitHubLogin(stream_splitted[0]),
         github_types.GitHubAccountIdType(int(stream_splitted[1])),
     )
Ejemplo n.º 14
0
def test_seats_renamed_account_repo() -> None:
    user1 = count_seats.SeatAccount(
        github_types.GitHubAccountIdType(123),
        github_types.GitHubLogin("user1"),
    )
    user1bis = count_seats.SeatAccount(
        github_types.GitHubAccountIdType(123),
        github_types.GitHubLogin("user1bis"),
    )
    user2 = count_seats.SeatAccount(
        github_types.GitHubAccountIdType(456),
        github_types.GitHubLogin("user2"),
    )
    user2bis = count_seats.SeatAccount(
        github_types.GitHubAccountIdType(456),
        github_types.GitHubLogin("user2bis"),
    )

    users = {user1, user2, user2bis, user1bis}
    assert len(users) == 2
    assert list(users)[0].login == "user2"
    assert list(users)[1].login == "user1"

    repo1 = count_seats.SeatRepository(
        github_types.GitHubRepositoryIdType(123),
        github_types.GitHubRepositoryName("repo1"),
    )
    repo1bis = count_seats.SeatRepository(
        github_types.GitHubRepositoryIdType(123),
        github_types.GitHubRepositoryName("repo1bis"),
    )
    repo2 = count_seats.SeatRepository(
        github_types.GitHubRepositoryIdType(456),
        github_types.GitHubRepositoryName("repo2"),
    )
    repo2bis = count_seats.SeatRepository(
        github_types.GitHubRepositoryIdType(456),
        github_types.GitHubRepositoryName("repo2bis"),
    )

    repos = {repo1, repo2, repo2bis, repo1bis}
    assert repos == {repo1, repo2}
Ejemplo n.º 15
0
def repository(redis_cache, fake_client):
    gh_owner = github_types.GitHubAccount({
        "login":
        github_types.GitHubLogin("user"),
        "id":
        github_types.GitHubAccountIdType(0),
        "type":
        "User",
        "avatar_url":
        "",
    })

    gh_repo = github_types.GitHubRepository({
        "full_name":
        "user/name",
        "name":
        github_types.GitHubRepositoryName("name"),
        "private":
        False,
        "id":
        github_types.GitHubRepositoryIdType(0),
        "owner":
        gh_owner,
        "archived":
        False,
        "url":
        "",
        "html_url":
        "",
        "default_branch":
        github_types.GitHubRefType("ref"),
    })
    installation = context.Installation(
        github_types.GitHubAccountIdType(123),
        github_types.GitHubLogin("user"),
        subscription.Subscription(redis_cache, 0, False, "", frozenset()),
        fake_client,
        redis_cache,
    )
    return context.Repository(installation, gh_repo)
Ejemplo n.º 16
0
async def test_client_installation_HTTP_301(
        respx_mock: respx.MockRouter) -> None:
    url_prefix = parse.urlparse(config.GITHUB_REST_API_URL).path
    respx_mock.get("/user/12345/installation").respond(
        301,
        headers={"Location": f"{url_prefix}/repositories/12345/installation"},
    )

    respx_mock.get("/repositories/12345/installation").respond(
        404, json={"message": "Repository not found"})
    with pytest.raises(exceptions.MergifyNotInstalled):
        await github.get_installation_from_account_id(
            github_types.GitHubAccountIdType(12345))
Ejemplo n.º 17
0
def repository(redis_cache, fake_client):
    installation = context.Installation(
        github_types.GitHubAccountIdType(123),
        github_types.GitHubLogin("user"),
        subscription.Subscription(redis_cache, 0, False, "", frozenset()),
        fake_client,
        redis_cache,
    )
    return context.Repository(
        installation,
        github_types.GitHubRepositoryName("name"),
        github_types.GitHubRepositoryIdType(123),
    )
Ejemplo n.º 18
0
async def test_update_apikey(redis_cache):
    api_access_key = "a" * 32
    api_secret_key = "s" * 32
    account_id = github_types.GitHubAccountIdType(12345)
    account_login = github_types.GitHubLogin("login")

    app = application.Application(
        redis_cache,
        0,
        "app name",
        api_access_key,
        api_secret_key,
        {"id": account_id, "login": account_login},
    )

    await app.save_to_cache()
    rapp = await application.Application._retrieve_from_cache(
        redis_cache, api_access_key, api_secret_key, account_login
    )
    assert app == rapp

    await application.Application.update(
        redis_cache,
        api_access_key,
        application.ApplicationDashboardJSON(
            {
                "id": 1,
                "name": "new name",
                "github_account": {
                    "id": 424242,
                    "login": "******",
                    "type": "User",
                    "avatar_url": "",
                },
            }
        ),
    )
    rapp = await application.Application._retrieve_from_cache(
        redis_cache, api_access_key, api_secret_key, account_login
    )
    expected_app = application.Application(
        redis_cache,
        1,
        "new name",
        api_access_key,
        api_secret_key,
        {"id": 424242, "login": "******"},
        ttl=application.Application.RETENTION_SECONDS,
    )

    assert expected_app == rapp
Ejemplo n.º 19
0
async def send(
    redis_stream: utils.RedisStream,
    redis_cache: utils.RedisCache,
) -> None:
    score = date.utcnow().timestamp()
    keys = await redis_cache.zrangebyscore(DELAYED_REFRESH_KEY, "-inf", score)
    if not keys:
        return

    pipe = await redis_stream.pipeline()
    keys_to_delete = set()
    for subkey in keys:
        (
            owner_id_str,
            owner_login,
            repository_id_str,
            repository_name,
            pull_request_number_str,
        ) = subkey.split("~")
        owner_id = github_types.GitHubAccountIdType(int(owner_id_str))
        repository_id = github_types.GitHubRepositoryIdType(
            int(repository_id_str))
        pull_request_number = github_types.GitHubPullRequestNumber(
            int(pull_request_number_str))

        LOG.info(
            "sending delayed pull request refresh",
            gh_owner=owner_login,
            gh_repo=repository_name,
            action="internal",
            source="delayed-refresh",
        )

        await worker.push(
            pipe,
            owner_id,
            owner_login,
            repository_id,
            repository_name,
            pull_request_number,
            "refresh",
            {
                "action": "internal",
                "ref": None,
                "source": "delayed-refresh",
            },  # type: ignore[typeddict-item]
        )
        keys_to_delete.add(subkey)

    await pipe.execute()
    await redis_cache.zrem(DELAYED_REFRESH_KEY, *keys_to_delete)
Ejemplo n.º 20
0
def fake_repository(
    redis_links: redis_utils.RedisLinks,
    fake_subscription: subscription.Subscription,
) -> context.Repository:
    gh_owner = github_types.GitHubAccount({
        "login":
        github_types.GitHubLogin("Mergifyio"),
        "id":
        github_types.GitHubAccountIdType(0),
        "type":
        "User",
        "avatar_url":
        "",
    })

    gh_repo = github_types.GitHubRepository({
        "full_name":
        "Mergifyio/mergify-engine",
        "name":
        github_types.GitHubRepositoryName("mergify-engine"),
        "private":
        False,
        "id":
        github_types.GitHubRepositoryIdType(0),
        "owner":
        gh_owner,
        "archived":
        False,
        "url":
        "",
        "html_url":
        "",
        "default_branch":
        github_types.GitHubRefType("main"),
    })
    installation_json = github_types.GitHubInstallation({
        "id":
        github_types.GitHubInstallationIdType(12345),
        "target_type":
        gh_owner["type"],
        "permissions": {},
        "account":
        gh_owner,
    })

    fake_client = mock.Mock()
    installation = context.Installation(installation_json, fake_subscription,
                                        fake_client, redis_links)
    return context.Repository(installation, gh_repo)
Ejemplo n.º 21
0
async def send_refresh(
    pull: github_types.GitHubPullRequest,
    action: github_types.GitHubEventRefreshActionType = "user",
) -> None:
    data = github_types.GitHubEventRefresh({
        "action":
        action,
        "ref":
        None,
        "repository":
        pull["base"]["repo"],
        "pull_request":
        pull,
        "ref":
        None,
        "sender": {
            "login": github_types.GitHubLogin("<internal>"),
            "id": github_types.GitHubAccountIdType(0),
            "type": "User",
        },
        "organization":
        pull["base"]["repo"]["owner"],
        "installation": {
            "id": 0,
            "account": {
                "login": github_types.GitHubLogin(""),
                "id": github_types.GitHubAccountIdType(0),
                "type": "User",
            },
        },
    })
    redis = await utils.create_aredis_for_stream()
    try:
        await filter_and_dispatch(redis, "refresh", str(uuid.uuid4()), data)
    finally:
        redis.connection_pool.disconnect()
Ejemplo n.º 22
0
async def _send_refresh(
    redis_stream: "redis_utils.RedisStream",
    repository: github_types.GitHubRepository,
    action: github_types.GitHubEventRefreshActionType,
    source: str,
    pull_request_number: typing.Optional[
        github_types.GitHubPullRequestNumber] = None,
    ref: typing.Optional[github_types.GitHubRefType] = None,
    score: typing.Optional[str] = None,
) -> None:
    # TODO(sileht): move refresh stuff into it's own file
    # Break circular import
    from mergify_engine import github_events
    from mergify_engine import worker

    data = github_types.GitHubEventRefresh({
        "action": action,
        "source": source,
        "ref": ref,
        "pull_request_number": pull_request_number,
        "repository": repository,
        "sender": {
            "login": github_types.GitHubLogin("<internal>"),
            "id": github_types.GitHubAccountIdType(0),
            "type": "User",
            "avatar_url": "",
        },
        "organization": repository["owner"],
        "installation": {
            "id": github_types.GitHubInstallationIdType(0),
            "account": repository["owner"],
            "target_type": repository["owner"]["type"],
            "permissions": {},
        },
    })

    slim_event = github_events._extract_slim_event("refresh", data)
    await worker.push(
        redis_stream,
        repository["owner"]["id"],
        repository["owner"]["login"],
        repository["id"],
        repository["name"],
        pull_request_number,
        "refresh",
        slim_event,
        None,
    )
Ejemplo n.º 23
0
async def test_client_401_raise_ratelimit(
        respx_mock: respx.MockRouter) -> None:
    owner_id = github_types.GitHubAccountIdType(12345)
    owner_login = github_types.GitHubLogin("owner")
    repo = "repo"

    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"
        },
        headers={
            "X-RateLimit-Remaining": "5000",
            "X-RateLimit-Reset": "1234567890",
        },
    )

    respx_mock.get("/repos/owner/repo/pull/1").respond(
        403,
        json={"message": "quota !"},
        headers={
            "X-RateLimit-Remaining": "0",
            "X-RateLimit-Reset": "1234567890"
        },
    )

    installation_json = await github.get_installation_from_account_id(owner_id)
    async with github.aget_client(installation_json) as client:
        with pytest.raises(exceptions.RateLimited):
            await client.item(f"/repos/{owner_login}/{repo}/pull/1")
Ejemplo n.º 24
0
async def test_run_command_with_user(
    user_id: int,
    permission: str,
    comment: str,
    result: typing.Optional[str],
    context_getter: conftest.ContextGetterFixture,
) -> None:

    user = github_types.GitHubAccount(
        {
            "id": github_types.GitHubAccountIdType(user_id),
            "login": github_types.GitHubLogin("wall-e"),
            "type": "Bot",
            "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4",
        }, )

    client = mock.Mock()
    client.item = mock.AsyncMock()
    client.item.return_value = {
        "permission": permission,
        "user": user,
    }
    client.post = mock.AsyncMock()

    ctxt = await context_getter(github_types.GitHubPullRequestNumber(1))
    ctxt.repository.installation.client = client

    await commands_runner.handle(
        ctxt=ctxt,
        mergify_config=EMPTY_CONFIG,
        comment="unrelated",
        user=None,
        rerun=True,
    )
    assert len(client.post.call_args_list) == 0

    await commands_runner.handle(
        ctxt=ctxt,
        mergify_config=EMPTY_CONFIG,
        comment=comment,
        user=user,
    )

    if result is None:
        assert len(client.post.call_args_list) == 0
    else:
        assert len(client.post.call_args_list) == 1
        assert result in client.post.call_args_list[0][1]["json"]["body"]
Ejemplo n.º 25
0
 async def get(cls: typing.Type[UserTokensT], redis: utils.RedisCache,
               owner_id: int) -> UserTokensT:
     return cls(
         redis,
         owner_id,
         [{
             "id":
             github_types.GitHubAccountIdType(_id),
             "login":
             github_types.GitHubLogin(login),
             "oauth_access_token":
             github_types.GitHubOAuthToken(oauth_access_token),
             "email":
             None,
             "name":
             None,
         } for _id, login, oauth_access_token in config.ACCOUNT_TOKENS],
     )
Ejemplo n.º 26
0
async def test_client_installation_HTTP_500(
        respx_mock: respx.MockRouter) -> None:
    respx_mock.get("/user/12345/installation").mock(side_effect=[
        httpx.Response(500, text="This is a 5XX error"),
        httpx.Response(500, text="This is a 5XX error"),
        httpx.Response(500, text="This is a 5XX error"),
        httpx.Response(500, text="This is a 5XX error"),
        httpx.Response(500, text="This is a 5XX error"),
    ])

    with pytest.raises(http.HTTPServerSideError) as exc_info:
        await github.get_installation_from_account_id(
            github_types.GitHubAccountIdType(12345))

    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}/user/12345/installation")
Ejemplo n.º 27
0
def fake_repository(
    redis_cache: utils.RedisCache,
    fake_subscription: subscription.Subscription,
) -> context.Repository:
    gh_owner = github_types.GitHubAccount(
        {
            "login": github_types.GitHubLogin("Mergifyio"),
            "id": github_types.GitHubAccountIdType(0),
            "type": "User",
            "avatar_url": "",
        }
    )

    gh_repo = github_types.GitHubRepository(
        {
            "full_name": "Mergifyio/mergify-engine",
            "name": github_types.GitHubRepositoryName("mergify-engine"),
            "private": False,
            "id": github_types.GitHubRepositoryIdType(0),
            "owner": gh_owner,
            "archived": False,
            "url": "",
            "html_url": "",
            "default_branch": github_types.GitHubRefType("main"),
        }
    )
    installation_json = github_types.GitHubInstallation(
        {
            "id": github_types.GitHubInstallationIdType(12345),
            "target_type": gh_owner["type"],
            "permissions": {},
            "account": gh_owner,
        }
    )

    fake_client = redis_queue = mock.Mock()
    # NOTE(Syffe): Since redis_queue is not used in fake_repository, we simply mock it,
    # otherwise a fixture is needed for it. This might change with future use of redis_queue.
    installation = context.Installation(
        installation_json, fake_subscription, fake_client, redis_cache, redis_queue
    )
    return context.Repository(installation, gh_repo)
Ejemplo n.º 28
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.º 29
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.º 30
0
async def test_init(redis_cache):
    application.Application(
        redis_cache,
        0,
        "app name",
        "api_access_key",
        "api_secret_key",
        {
            "id": github_types.GitHubAccountIdType(12345),
            "login": github_types.GitHubLogin("login"),
        },
    )

    application.Application(
        redis_cache,
        0,
        "app name",
        "api_access_key",
        "api_secret_key",
        None,
    )