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()
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}'" )
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
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()
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()
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()
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()
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()
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()