Skip to content

Commit

Permalink
Use GitHub Issues (#265)
Browse files Browse the repository at this point in the history
* Use GitHub Issues instead of BPO

* Use GH issues instead of BPO

* Customize the web app url

* Fix the textbox helper text

* Clarify that it's the CPython GitHub issue number.

* Change the form labels to GH Issue # and GH PR #

Produce filename with `gh-issue-<n>`
Update tests.
  • Loading branch information
Mariatta committed Apr 10, 2022
1 parent 668a1e9 commit d482551
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[run]
dynamic_context = test_function
5 changes: 3 additions & 2 deletions blurb_it/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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 = {}
Expand Down
6 changes: 3 additions & 3 deletions blurb_it/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ coverage==6.3.2
pytest==7.1.1
pytest-aiohttp==1.0.4
pytest-mock==3.7.0
pytest-cov==3.0.0
2 changes: 1 addition & 1 deletion runtime.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
python-3.8.7
python-3.10.2
8 changes: 4 additions & 4 deletions templates/add_blurb.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ <h3>📜🤖 Blurb it again?</h3>
<input type="hidden" name="csrf" value="{{ csrf }}">
<div class="mb-3">
<div class="col form-inline">
<label for="bpo_number" class="form-inline">bpo-</label><input type="text" class="form-control form-inline" placeholder="12345" id="bpo_number" name="bpo_number" required>
<label for="issue_number" class="form-inline">GH Issue #</label><input type="text" class="form-control form-inline" placeholder="12345" id="issue_number" name="issue_number" required>
</div>
<div class="col form-inline">
<small id="bpo-help" class="form-text text-muted">The bugs.python.org issue number.</small>
<small id="issue_number-help" class="form-text text-muted">The CPython GitHub issue number.</small>
</div>
</div>
<div class="mb-3">
<div class="col form-inline">
<label for="pr_number" class="form-inline">GH-</label><input type="text" class="form-control form-inline" placeholder="12345" id="pr_number" name="pr_number" required>
<label for="pr_number" class="form-inline">GH Pull Request #</label><input type="text" class="form-control form-inline" placeholder="12345" id="pr_number" name="pr_number" required>
</div>
<div class="col form-inline">
<small id="gh-help" class="form-text text-muted">The CPython GitHub pull request number.</small>
Expand Down Expand Up @@ -54,7 +54,7 @@ <h3>📜🤖 Blurb it again?</h3>
<div class="mb-3">
<textarea class="form-control" id="news_entry" name="news_entry" rows="10" placeholder="Write your Misc/NEWS entry below.
It should be a simple ReST paragraph.
Don't start with '- Issue #<n>: ' or '- bpo-<n>: ' or that sort of stuff." required></textarea>
Don't start with '- Issue #<n>: ' or '- gh-issue-<n>: ' or that sort of stuff." required></textarea>
</div>
<button type="submit" class="btn btn-primary mb-2">📜🤖 blurb it!</button>
</form>
Expand Down
2 changes: 1 addition & 1 deletion templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<h5 class="my-0 mr-md-auto font-weight-normal"><a href="/">📜🤖 Blurb it!</a></h5>
<h5 class="my-0 mr-md-auto font-weight-normal"><a href="/howto">How do I use Blurb It?</a></h5>
{% if not username %}
<a class="btn btn-outline-primary btn-social btn-github" href="https://github.com/login/oauth/authorize?client_id={{ client_id }}&scope=repo&redirect_uri=https://blurb-it.herokuapp.com/add_blurb">
<a class="btn btn-outline-primary btn-social btn-github" href="https://github.com/login/oauth/authorize?client_id={{ client_id }}&scope=repo&redirect_uri=https://{{ app_url }}/add_blurb">
<span class="fa fa-github"></span>
Sign in with GitHub
</a>
Expand Down
2 changes: 1 addition & 1 deletion templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ <h1 class="display-4">📜🤖 Blurb it!</h1>
</div>

<p class="lead text-center">
<a class="btn btn-social btn-github" href="https://github.com/login/oauth/authorize?client_id={{ client_id }}&scope=repo&redirect_uri=https://blurb-it.herokuapp.com/add_blurb">
<a class="btn btn-social btn-github" href="https://github.com/login/oauth/authorize?client_id={{ client_id }}&scope=repo&redirect_uri=https://{{ app_url}}/add_blurb">
<span class="fa fa-github"></span>
Sign in with GitHub
</a>
Expand Down
76 changes: 72 additions & 4 deletions tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand All @@ -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"
Expand All @@ -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():
Expand All @@ -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)
Expand All @@ -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")

Expand All @@ -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"

0 comments on commit d482551

Please sign in to comment.