Files
PyGithub/tests/Requester.py
T
Enrico Minack ea45237d3b Sync GithubIntegration __init__ arguments with github.Github (#2556)
Github and GithubIntegration now both support the same (full) set of Requester arguments.
Creating a Github instance for a Github App Installation coming from GithubIntegration uses the same
Requester arguments (except for auth).
2023-06-21 09:04:19 +02:00

300 lines
12 KiB
Python

############################ Copyrights and license ############################
# #
# Copyright 2022 Enrico Minack <github@enrico.minack.dev> #
# #
# This file is part of PyGithub. #
# http://pygithub.readthedocs.io/ #
# #
# PyGithub is free software: you can redistribute it and/or modify it under #
# the terms of the GNU Lesser General Public License as published by the Free #
# Software Foundation, either version 3 of the License, or (at your option) #
# any later version. #
# #
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
# details. #
# #
# You should have received a copy of the GNU Lesser General Public License #
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
from unittest import mock
import github
from . import Framework
class Requester(Framework.TestCase):
logger = None
def setUp(self):
super().setUp()
self.logger = mock.MagicMock()
github.Requester.Requester.injectLogger(self.logger)
def tearDown(self):
github.Requester.Requester.resetLogger()
super().tearDown()
def testRecreation(self):
class TestAuth(github.Auth.AppAuth):
pass
# create a Requester with non-default arguments
auth = TestAuth(123, "key")
requester = github.Requester.Requester(
auth=auth,
base_url="https://base.url",
timeout=1,
user_agent="user agent",
per_page=123,
verify=False,
retry=3,
pool_size=5,
)
kwargs = requester.kwargs
# assert kwargs consists of ALL constructor arguments
self.assertEqual(
kwargs.keys(), github.Requester.Requester.__init__.__annotations__.keys()
)
self.assertEqual(
kwargs,
dict(
auth=auth,
base_url="https://base.url",
timeout=1,
user_agent="user agent",
per_page=123,
verify=False,
retry=3,
pool_size=5,
),
)
# create a copy Requester, assert identity via kwargs
copy = github.Requester.Requester(**kwargs)
self.assertEqual(copy.kwargs, kwargs)
# create Github instance, assert identity requester
gh = github.Github(**kwargs)
self.assertEqual(gh._Github__requester.kwargs, kwargs)
# create GithubIntegration instance, assert identity requester
gi = github.GithubIntegration(**kwargs)
self.assertEqual(gi._GithubIntegration__requester.kwargs, kwargs)
def testWithAuth(self):
class TestAuth(github.Auth.AppAuth):
pass
# create a Requester with non-default arguments
auth = TestAuth(123, "key")
requester = github.Requester.Requester(
auth=auth,
base_url="https://base.url",
timeout=1,
user_agent="user agent",
per_page=123,
verify=False,
retry=3,
pool_size=5,
)
# create a copy with different auth
auth2 = TestAuth(456, "key2")
copy = requester.withAuth(auth2)
# assert kwargs of copy
self.assertEqual(
copy.kwargs,
dict(
auth=auth2,
base_url="https://base.url",
timeout=1,
user_agent="user agent",
per_page=123,
verify=False,
retry=3,
pool_size=5,
),
)
def testLoggingRedirection(self):
self.assertEqual(self.g.get_repo("EnricoMi/test").name, "test-renamed")
self.logger.info.assert_called_once_with(
"Following Github server redirection from /repos/EnricoMi/test to /repositories/638123443"
)
def testBaseUrlSchemeRedirection(self):
gh = github.Github(base_url="http://api.github.com")
with self.assertRaises(RuntimeError) as exc:
gh.get_repo("PyGithub/PyGithub")
self.assertEqual(
exc.exception.args,
(
"Github server redirected from http protocol to https, please correct your "
"Github server URL via base_url: Github(base_url=...)",
),
)
def testBaseUrlHostRedirection(self):
gh = github.Github(base_url="https://www.github.com")
with self.assertRaises(RuntimeError) as exc:
gh.get_repo("PyGithub/PyGithub")
self.assertEqual(
exc.exception.args,
(
"Github server redirected from host www.github.com to github.com, "
"please correct your Github server URL via base_url: Github(base_url=...)",
),
)
def testBaseUrlPortRedirection(self):
# replay data forged
gh = github.Github(base_url="https://api.github.com")
with self.assertRaises(RuntimeError) as exc:
gh.get_repo("PyGithub/PyGithub")
self.assertEqual(
exc.exception.args,
(
"Requested https://api.github.com/repos/PyGithub/PyGithub but server "
"redirected to https://api.github.com:443/repos/PyGithub/PyGithub, "
"you may need to correct your Github server URL "
"via base_url: Github(base_url=...)",
),
)
def testBaseUrlPrefixRedirection(self):
# replay data forged
gh = github.Github(base_url="https://api.github.com/api/v3")
self.assertEqual(gh.get_repo("PyGithub/PyGithub").name, "PyGithub")
self.logger.info.assert_called_once_with(
"Following Github server redirection from /api/v3/repos/PyGithub/PyGithub to /repos/PyGithub/PyGithub"
)
def assertException(self, exception, exception_type, status, data, headers, string):
self.assertIsInstance(exception, exception_type)
self.assertEqual(exception.status, status)
if data is None:
self.assertIsNone(exception.data)
else:
self.assertEqual(exception.data, data)
self.assertEqual(exception.headers, headers)
self.assertEqual(str(exception), string)
def testShouldCreateBadCredentialsException(self):
exc = self.g._Github__requester.__createException(
401, {"header": "value"}, {"message": "Bad credentials"}
)
self.assertException(
exc,
github.BadCredentialsException,
401,
{"message": "Bad credentials"},
{"header": "value"},
'401 {"message": "Bad credentials"}',
)
def testShouldCreateTwoFactorException(self):
exc = self.g._Github__requester.__createException(
401,
{"x-github-otp": "required; app"},
{
"message": "Must specify two-factor authentication OTP code.",
"documentation_url": "https://developer.github.com/v3/auth#working-with-two-factor-authentication",
},
)
self.assertException(
exc,
github.TwoFactorException,
401,
{
"message": "Must specify two-factor authentication OTP code.",
"documentation_url": "https://developer.github.com/v3/auth#working-with-two-factor-authentication",
},
{"x-github-otp": "required; app"},
'401 {"message": "Must specify two-factor authentication OTP code.", "documentation_url": "https://developer.github.com/v3/auth#working-with-two-factor-authentication"}',
)
def testShouldCreateBadUserAgentException(self):
exc = self.g._Github__requester.__createException(
403,
{"header": "value"},
{"message": "Missing or invalid User Agent string"},
)
self.assertException(
exc,
github.BadUserAgentException,
403,
{"message": "Missing or invalid User Agent string"},
{"header": "value"},
'403 {"message": "Missing or invalid User Agent string"}',
)
def testShouldCreateRateLimitExceededException(self):
for message in [
"API Rate Limit Exceeded for 92.104.200.119",
"You have triggered an abuse detection mechanism. Please wait a few minutes before you try again.",
"You have exceeded a secondary rate limit. Please wait a few minutes before you try again.",
]:
with self.subTest(message=message):
exc = self.g._Github__requester.__createException(
403, {"header": "value"}, {"message": message}
)
self.assertException(
exc,
github.RateLimitExceededException,
403,
{"message": message},
{"header": "value"},
f'403 {{"message": "{message}"}}',
)
def testShouldCreateUnknownObjectException(self):
exc = self.g._Github__requester.__createException(
404, {"header": "value"}, {"message": "Not Found"}
)
self.assertException(
exc,
github.UnknownObjectException,
404,
{"message": "Not Found"},
{"header": "value"},
'404 {"message": "Not Found"}',
)
def testShouldCreateGithubException(self):
for status in range(400, 600):
with self.subTest(status=status):
exc = self.g._Github__requester.__createException(
status, {"header": "value"}, {"message": "Something unknown"}
)
self.assertException(
exc,
github.GithubException,
status,
{"message": "Something unknown"},
{"header": "value"},
f'{status} {{"message": "Something unknown"}}',
)
def testShouldCreateExceptionWithoutMessage(self):
for status in range(400, 600):
with self.subTest(status=status):
exc = self.g._Github__requester.__createException(status, {}, {})
self.assertException(
exc, github.GithubException, status, {}, {}, f"{status} {{}}"
)
def testShouldCreateExceptionWithoutOutput(self):
for status in range(400, 600):
with self.subTest(status=status):
exc = self.g._Github__requester.__createException(status, {}, None)
self.assertException(
exc, github.GithubException, status, None, {}, f"{status} null"
)