From 50f7d665079335936bf44146e8c8e0d454cb0df7 Mon Sep 17 00:00:00 2001 From: Mariatta Wijaya Date: Tue, 15 Mar 2022 08:40:07 -0700 Subject: [PATCH 1/6] Use GitHub Issues instead of BPO --- .coveragerc | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..e69de29 From ec9c6b4d8473cca2b2846e611fabcefb7bb3a798 Mon Sep 17 00:00:00 2001 From: Mariatta Wijaya Date: Tue, 15 Mar 2022 08:42:17 -0700 Subject: [PATCH 2/6] Use GH issues instead of BPO --- blurb_it/__main__.py | 4 +-- blurb_it/util.py | 6 ++-- dev-requirements.txt | 1 + runtime.txt | 2 +- templates/add_blurb.html | 4 +-- tests/test_util.py | 76 +++++++++++++++++++++++++++++++++++++--- 6 files changed, 81 insertions(+), 12 deletions(-) diff --git a/blurb_it/__main__.py b/blurb_it/__main__.py index c4961a8..e4ecd1d 100644 --- a/blurb_it/__main__.py +++ b/blurb_it/__main__.py @@ -146,10 +146,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..82ffd44 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_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..59fb35b 100644 --- a/templates/add_blurb.html +++ b/templates/add_blurb.html @@ -18,10 +18,10 @@

📜🤖 Blurb it again?

- +
- The bugs.python.org issue number. + The GitHub issue number.
diff --git a/tests/test_util.py b/tests/test_util.py index 9fa3e2b..f268a31 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-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" From 1bb29e7b60cf48f1077cd1179c8b50a016e134f6 Mon Sep 17 00:00:00 2001 From: Mariatta Wijaya Date: Tue, 15 Mar 2022 08:51:21 -0700 Subject: [PATCH 3/6] Customize the web app url --- blurb_it/__main__.py | 1 + templates/base.html | 2 +- templates/index.html | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/blurb_it/__main__.py b/blurb_it/__main__.py index e4ecd1d..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() diff --git a/templates/base.html b/templates/base.html index 6ebdddd..b5229bc 100644 --- a/templates/base.html +++ b/templates/base.html @@ -20,7 +20,7 @@
📜🤖 Blurb it!
How do I use Blurb It?
{% if not username %} - + Sign in with GitHub diff --git a/templates/index.html b/templates/index.html index d9aa171..41c0008 100644 --- a/templates/index.html +++ b/templates/index.html @@ -8,7 +8,7 @@

📜🤖 Blurb it!

- + Sign in with GitHub From 3812fc9096d922f49eb36b6c8caf292a18bdaba1 Mon Sep 17 00:00:00 2001 From: Mariatta Wijaya Date: Tue, 15 Mar 2022 09:00:50 -0700 Subject: [PATCH 4/6] Fix the textbox helper text --- templates/add_blurb.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/add_blurb.html b/templates/add_blurb.html index 59fb35b..c12f394 100644 --- a/templates/add_blurb.html +++ b/templates/add_blurb.html @@ -54,7 +54,7 @@

📜🤖 Blurb it again?

+Don't start with '- Issue #: ' or '- gh-: ' or that sort of stuff." required>
From b72b57c1272b41acb7f532db5f1e9e1e36fe7c6f Mon Sep 17 00:00:00 2001 From: Mariatta Wijaya Date: Tue, 15 Mar 2022 14:02:28 -0700 Subject: [PATCH 5/6] Clarify that it's the CPython GitHub issue number. --- templates/add_blurb.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/add_blurb.html b/templates/add_blurb.html index c12f394..715a02b 100644 --- a/templates/add_blurb.html +++ b/templates/add_blurb.html @@ -21,7 +21,7 @@

📜🤖 Blurb it again?

- The GitHub issue number. + The CPython GitHub issue number.
From 32eaed7fe26d42db16349a8666658f95e4a61287 Mon Sep 17 00:00:00 2001 From: Mariatta Wijaya Date: Wed, 23 Mar 2022 21:23:42 -0700 Subject: [PATCH 6/6] Change the form labels to GH Issue # and GH PR # Produce filename with `gh-issue-` Update tests. --- .coveragerc | 2 ++ blurb_it/util.py | 2 +- templates/add_blurb.html | 6 +++--- tests/test_util.py | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.coveragerc b/.coveragerc index e69de29..d07bcb5 100644 --- a/.coveragerc +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +dynamic_context = test_function \ No newline at end of file diff --git a/blurb_it/util.py b/blurb_it/util.py index 82ffd44..4cc536a 100644 --- a/blurb_it/util.py +++ b/blurb_it/util.py @@ -11,7 +11,7 @@ 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}.gh-{issue_number}.{nonce}.rst" + path = f"Misc/NEWS.d/next/{section}/{date}.gh-issue-{issue_number}.{nonce}.rst" return path diff --git a/templates/add_blurb.html b/templates/add_blurb.html index 715a02b..87f1ae3 100644 --- a/templates/add_blurb.html +++ b/templates/add_blurb.html @@ -18,7 +18,7 @@

📜🤖 Blurb it again?

- +
The CPython GitHub issue number. @@ -26,7 +26,7 @@

📜🤖 Blurb it again?

- +
The CPython GitHub pull request number. @@ -54,7 +54,7 @@

📜🤖 Blurb it again?

+Don't start with '- Issue #: ' or '- gh-issue-: ' or that sort of stuff." required>
diff --git a/tests/test_util.py b/tests/test_util.py index f268a31..8de474e 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -54,7 +54,7 @@ async def test_get_misc_news_filename(): ) assert path.startswith("Misc/NEWS.d/next/Library/") - assert path.endswith(".gh-123.Ps4kgC.rst") + assert path.endswith(".gh-issue-123.Ps4kgC.rst") async def test_has_session():