def get_pull(self, id: int): pr = [p for p in self.prs if p.number == id] if len(pr) == 0: raise UnknownObjectException(status=404, data="PR does not exist") if len(pr) > 1: raise ValueError("Multiple PRs exist") return pr[0]
def get(self, url, **request_kwargs): """ If response.status_code is not 200 then exit program Otherwise return original response """ while True: response = super().get(url, **request_kwargs) if response.status_code != 200: if response.status_code == 404: raise UnknownObjectException(response.status_code, response.url) elif response.headers.get("X-Ratelimit-Remaining") == "0": print( response.json().get("message"), "<--- https://developer.github.com/v3/#rate-limiting", ) datetime_of_reset = datetime.fromtimestamp( int(response.headers["X-Ratelimit-Reset"])) delay_until(datetime_of_reset) else: raise GithubException( response.status_code, f"Could not fetch {response.url}! Caused by: {response.text}", ) else: break return response
def download_file(self, repo_name, path, branch=None, local_path=None): """Download a file from a repo by path and branch. Defaults to the repo's default branch if branch is not supplied. Uses the download_url directly rather than the API because the API only supports contents up to 1MB from a repo directly, and the process for downloading larger files through the API is much more involved. Because download_url does not go through the API, it does not support username / password authentication, and requires a token to authenticate. Args: repo_name: str Full repo name (account/name) path: str Path from the repo base directory branch: Optional[str] Branch to download file from. Defaults to repo default branch local_path: Optional[str] Local file path to download file to. Will create a temp file if not supplied. Returns: str File path of downloaded file """ if not local_path: local_path = files.create_temp_file_for_path(path) repo = self.client.get_repo(repo_name) if branch is None: branch = repo.default_branch logger.info( f'Downloading {path} from {repo_name}, branch {branch} to {local_path}' ) headers = None if self.access_token: headers = { 'Authorization': f'token {self.access_token}', } res = requests.get( f'https://raw.githubusercontent.com/{repo_name}/{branch}/{path}', headers=headers) if res.status_code == 404: raise UnknownObjectException(status=404, data=res.content) elif res.status_code != 200: raise ParsonsGitHubError( f'Error downloading {path} from repo {repo_name}: {res.content}' ) with open(local_path, 'wb') as f: f.write(res.content) logger.info(f'Downloaded {path} to {local_path}') return local_path
def get_commit_combined_statuses(self, commit): """ Calls GitHub's '<commit>/statuses' endpoint for a given commit. See https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref Arguments: commit: One of: - string (interprets as git SHA and fetches commit) - GitCommit (uses the accompanying git SHA and fetches commit) - Commit (directly gets the combined status) Returns: github.CommitCombinedStatus.CommitCombinedStatus Raises: RequestFailed: If the response fails validation. """ self.log_rate_limit() if isinstance(commit, six.string_types): commit = self.github_repo.get_commit(commit) elif isinstance(commit, GitCommit): commit = self.github_repo.get_commit(commit.sha) elif not isinstance(commit, Commit): raise UnknownObjectException( 500, 'commit is neither a valid sha nor github.Commit.Commit object.' ) return commit.get_combined_status()
def get_commit_check_suites(self, commit): """ Calls GitHub's `<commit>/check-suites` endpoint for a given commit. See https://developer.github.com/v3/checks/suites/#list-check-suites-for-a-specific-ref Arguments: commit: One of: - string (interprets as git SHA and fetches commit) - GitCommit (uses the accompanying git SHA and fetches commit) - Commit (directly gets the combined status) Returns: Json representing the check suites """ self.log_rate_limit() if isinstance(commit, six.string_types): commit = self.github_repo.get_commit(commit) elif isinstance(commit, GitCommit): commit = self.github_repo.get_commit(commit.sha) elif not isinstance(commit, Commit): raise UnknownObjectException( 500, "commit is neither a valid sha nor github.Commit.Commit object." ) _, data = commit._requester.requestJsonAndCheck( # pylint: disable=protected-access "GET", commit.url + "/check-suites", headers={"Accept": "application/vnd.github.antiope-preview+json"}) return data
def test_get_unknown_organization(self, mock_github): mock_github.side_effect = UnknownObjectException(404, "") g = Github("abc123") with self.assertRaises(SystemExit) as se: dsegithub.organization.get_organization(g, "test") self.assertEqual(se.exception.code, "Organization test not found!")
def test_get_repository_does_not_exist(self, mock_github): mock_github().get_repo.side_effect = UnknownObjectException(status=404, data="") g = Github("abc123") org = dsegithub.organization.get_organization(g, "test") self.assertIsNone(dsegithub.repository.get_repository( org, "test-repo"))
def test_create_readme(self, mock_github): mock_github().create_repo( ).get_readme.side_effect = UnknownObjectException(status=404, data="") g = Github("abc123") org = dsegithub.organization.get_organization(g, "test") repository = dsegithub.repository.create_repository(org, "test-repo") self.assertTrue(dsegithub.repository.create_readme(repository))
async def test_yolo_merge_invalid_pull(yolo, context, gh, repo, skip_if_private_channel): gh.get_repo.return_value = repo repo.get_pull.side_effect = UnknownObjectException(status=404, data=None, headers=None) with pytest.raises(UnknownObjectException): await yolo.yolo(context, 404) repo.get_pull.assert_called_once_with(404)
def test_comment_on_pr_with_pull_request_not_found(mocker): get_repo_mock = mocker.patch.object(Github, "get_repo", autospec=True) repo_mock = MagicMock(wrap=Repository.Repository) repo_mock.owner = 'org' repo_mock.repo = 'trybe' get_repo_mock.return_value = repo_mock get_pull_mock = mocker.patch.object(repo_mock, "get_pull", autospec=True) get_pull_mock.side_effect = UnknownObjectException(mocker.Mock(status=404), 'not found') with pytest.raises(UnknownObjectException): main.comment_on_pr('')
def test_create_folder_failed(self, mock_github): mock_github().create_repo( ).get_contents.side_effect = UnknownObjectException(status=404, data="") mock_github().create_repo().create_file.side_effect = GithubException( status=422, data="") g = Github("abc123") org = dsegithub.organization.get_organization(g, "test") repository = dsegithub.repository.create_repository(org, "test-repo") self.assertFalse( dsegithub.repository.create_folder(repository, "test-folder"))
def get_commit_combined_statuses(self, commit): """ Calls GitHub's '<commit>/statuses' endpoint for a given commit. See https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref Returns: github.CommitCombinedStatus.CommitCombinedStatus Raises: RequestFailed: If the response fails validation. """ if isinstance(commit, six.string_types): commit = self.github_repo.get_commit(commit) elif isinstance(commit, GitCommit): commit = self.github_repo.get_commit(commit.sha) elif not isinstance(commit, Commit): raise UnknownObjectException( 500, 'commit is neither a valid sha nor github.Commit.Commit object.' ) return commit.get_combined_status()
def test_get_reviews_get_repo_fails(self, mock_has_new_comments, mock_githubreview, mock_last_comment, mock_check_request_state): """ Tests get_reviews function where getting the repo fails """ # Set up mock return values and side effects mock_uname = MagicMock() mock_uname.get_repo.side_effect = UnknownObjectException(status=101, data=101) # Call function with self.assertRaises(Exception): GithubService().get_reviews( uname=mock_uname, repo_name="dummy_repo") # Validate function calls and response mock_uname.get_repo.assert_called_with('dummy_repo') mock_has_new_comments.assert_not_called() mock_githubreview.assert_not_called() mock_last_comment.assert_not_called() mock_check_request_state.assert_not_called()
def test_request_reviews_failed_user(self, mock_github_patch): """ Tests request_reviews except the getting the Github user should throw an exception """ # Set up mock return values and side effects mock_github_instance = MagicMock(name="mock_github_instance") mock_github_instance.get_user.side_effect = \ UnknownObjectException(data="", status=101) mock_github_patch.return_value = mock_github_instance # Call function with self.assertRaises(Exception) as context: GithubService().request_reviews( user_name="dummy_user", token='dummy_token') # Validate function calls and response self.assertIn('Invalid username/organizaton: dummy_user', context.exception.__str__()) mock_github_instance.get_user.assert_called_with('dummy_user') mock_github_patch.assert_called_with('dummy_token')
def mock_get_repo(repo_name): raise UnknownObjectException("args", "kwargs")
def test_get_unknown_user(self, mock_github): mock_github.side_effect = UnknownObjectException(404, "") g = Github("abc123") self.assertIsNone(dsegithub.user.get_user(g, "test"))
def test_comment_on_pr_with_repository_not_found(mocker): get_repo_mock = mocker.patch.object(Github, "get_repo", autospec=True) get_repo_mock.side_effect = UnknownObjectException(mocker.Mock(status=404), 'not found') with pytest.raises(UnknownObjectException): main.comment_on_pr('')
def mock_get_user(user_name): raise UnknownObjectException("param1", "param2")
def test_wrap_github_404(self, m): with patch("github.Github.get_repo") as get_repo_mock: get_repo_mock.side_effect = UnknownObjectException("", "") with self.assertRaises(ParsonsGitHubError): self.github.get_repo("octocat/Hello-World")
def mock_get_repo(repo_name): raise UnknownObjectException('args', 'kwargs')
def mock_get_user(user_name): raise UnknownObjectException('param1', 'param2')