diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..d07bcb5 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +dynamic_context = test_function \ No newline at end of file diff --git a/blurb_it/__main__.py b/blurb_it/__main__.py index c4961a8..825d5b9 100644 --- a/blurb_it/__main__.py +++ b/blurb_it/__main__.py @@ -30,6 +30,7 @@ async def handle_get(request): request_session = await get_session(request) context = {} context["client_id"] = os.environ.get("GH_CLIENT_ID") + context["app_url"] = os.environ.get("APP_URL") if request_session.get("username") and request_session.get("token"): context["username"] = request_session["username"] location = request.app.router["add_blurb"].url_for() @@ -146,10 +147,10 @@ async def handle_add_blurb_post(request): ): raise web.HTTPForbidden(reason="Invalid CSRF token. Please retry.") - bpo_number = data.get("bpo_number", "").strip() + issue_number = data.get("issue_number", "").strip() section = data.get("section", "").strip() news_entry = data.get("news_entry", "").strip() + "\n" - path = await util.get_misc_news_filename(bpo_number, section, news_entry) + path = await util.get_misc_news_filename(issue_number, section, news_entry) pr_number = data.get("pr_number", "").strip() context = {} diff --git a/blurb_it/util.py b/blurb_it/util.py index 767064b..4cc536a 100644 --- a/blurb_it/util.py +++ b/blurb_it/util.py @@ -8,10 +8,10 @@ from blurb_it import error -async def get_misc_news_filename(bpo, section, body): +async def get_misc_news_filename(issue_number, section, body): date = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) nonce = await nonceify(body) - path = f"Misc/NEWS.d/next/{section}/{date}.bpo-{bpo}.{nonce}.rst" + path = f"Misc/NEWS.d/next/{section}/{date}.gh-issue-{issue_number}.{nonce}.rst" return path @@ -57,7 +57,7 @@ async def get_installation(gh, jwt, username): "/app/installations", jwt=jwt, accept="application/vnd.github.machine-man-preview+json", - ): + ): # pragma: no cover if installation["account"]["login"] == username: return installation diff --git a/dev-requirements.txt b/dev-requirements.txt index bd63576..fb69edc 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -3,3 +3,4 @@ coverage==6.3.2 pytest==7.0.1 pytest-aiohttp==1.0.4 pytest-mock==3.7.0 +pytest-cov==3.0.0 \ No newline at end of file diff --git a/runtime.txt b/runtime.txt index 3e4835c..250d1e3 100644 --- a/runtime.txt +++ b/runtime.txt @@ -1 +1 @@ -python-3.8.7 +python-3.10.2 diff --git a/templates/add_blurb.html b/templates/add_blurb.html index 0443dfb..87f1ae3 100644 --- a/templates/add_blurb.html +++ b/templates/add_blurb.html @@ -18,15 +18,15 @@
- + Sign in with GitHub diff --git a/tests/test_util.py b/tests/test_util.py index 9fa3e2b..8de474e 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -2,9 +2,25 @@ import pytest -from blurb_it import util +from blurb_it import util, error from aiohttp.test_utils import make_mocked_request -from aiohttp_session import (Session, SESSION_KEY) +from aiohttp_session import Session, SESSION_KEY + + +class FakeGH: + def __init__(self, *, getiter=None, getitem=None, post=None): + self._getitem_return = getitem + self._getiter_return = getiter + self._post_return = post + self.getitem_url = None + self.getiter_url = None + self.post_url = [] + self.post_data = [] + + async def getiter(self, url, jwt=None, accept=None): + self.getiter_url = url + for item in self._getiter_return: + yield item async def test_nonceify(): @@ -25,7 +41,7 @@ async def test_nonceify(): async def test_get_misc_news_filename(): path = await util.get_misc_news_filename( - bpo=123, + issue_number=123, section="Library", body="Lorem ipsum dolor amet flannel squid normcore tbh raclette enim" "pabst tumblr wolf farm-to-table bitters. Bitters keffiyeh next" @@ -38,7 +54,7 @@ async def test_get_misc_news_filename(): ) assert path.startswith("Misc/NEWS.d/next/Library/") - assert path.endswith(".bpo-123.Ps4kgC.rst") + assert path.endswith(".gh-issue-123.Ps4kgC.rst") async def test_has_session(): @@ -55,6 +71,13 @@ async def test_session_context(): assert session_context == {"username": "blurb", "token": "124"} +async def test_no_session_context(): + request = mock_request_no_session() + + session_context = await util.get_session_context(request) + assert session_context == {} + + def mock_request_session(): request = make_mocked_request("GET", "/") session = Session("identity", data=None, new=False) @@ -65,6 +88,13 @@ def mock_request_session(): return request +def mock_request_no_session(): + request = make_mocked_request("GET", "/") + session = Session("identity", data=None, new=False) + request[SESSION_KEY] = session + return request + + def test_get_csrf_token__not_existing(mocker): mocker.patch("blurb_it.util.create_csrf_token", return_value="foobar") @@ -85,3 +115,41 @@ def test_create_csrf_token(): @pytest.mark.parametrize("token, match", [("a", True), ("b", False)]) def test_compare_csrf_tokens__match(token, match): assert util.compare_csrf_tokens("a", token) is match + + +async def test_get_installation(): + app_installations = [ + { + "id": 1, + "account": { + "login": "octocat", + "id": 1, + }, + } + ] + gh = FakeGH(getiter=app_installations) + result = await util.get_installation(gh, "fake_jwt", "octocat") + assert result == app_installations[0] + + +async def test_get_installation_not_found(): + app_installations = [ + { + "id": 1, + "account": { + "login": "octocat", + "id": 1, + }, + }, + { + "id": 1, + "account": { + "login": "octosaurus", + "id": 1, + }, + }, + ] + gh = FakeGH(getiter=app_installations) + with pytest.raises(error.InstallationNotFound) as exc: + await util.get_installation(gh, "fake_jwt", "octonauts") + assert exc.value.args[0] == "Can't find installation by that user: octonauts"