From 2faa118968029f38d0200ea13abd69e6ec97fe51 Mon Sep 17 00:00:00 2001 From: mariatta Date: Wed, 21 Oct 2026 17:43:15 -0700 Subject: [PATCH] Test that the add_blurb form renders No test requested GET /add_blurb, so a template error or a broken inline script in the form would pass CI. Add a test that signs in through the session, stubs the GitHub App lookups, and checks that the page renders with every field the POST handler reads, the Security option, and the hooks the CVE toggle script relies on. Also test the two redirects around it: an anonymous request to the form goes home, and a signed-in request to the home page goes to the form. The redirect tests showed that the handlers return HTTPFound instead of raising it, which aiohttp deprecates and which the suite's warnings-as-errors setting turns into a server error. Raise all six redirects instead, which is also what the error middleware expects. --- blurb_it/__main__.py | 20 +++++------- tests/test_main.py | 74 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 13 deletions(-) diff --git a/blurb_it/__main__.py b/blurb_it/__main__.py index da130f0..ae83ac9 100644 --- a/blurb_it/__main__.py +++ b/blurb_it/__main__.py @@ -33,14 +33,8 @@ async def handle_get(request: Request) -> Response: request_session = await get_session(request) context = util.get_app_context() if request_session.get("username") and request_session.get("token"): - context["username"] = request_session["username"] - location = request.app.router["add_blurb"].url_for() - response = web.HTTPFound(location=location) - else: - response = aiohttp_jinja2.render_template( - "index.html", request, context=context - ) - return response + raise web.HTTPFound(location=request.app.router["add_blurb"].url_for()) + return aiohttp_jinja2.render_template("index.html", request, context=context) @routes.get("/howto", name="howto") @@ -89,7 +83,7 @@ async def handle_add_blurb_get(request: Request) -> Response: try: await util.get_installation(gh, jwt, context["username"]) except error.InstallationNotFound: - return web.HTTPFound(location=request.app.router["install"].url_for()) + raise web.HTTPFound(location=request.app.router["install"].url_for()) elif token is not None: @@ -120,12 +114,12 @@ async def handle_add_blurb_get(request: Request) -> Response: try: await util.get_installation(gh, jwt, context["username"]) except error.InstallationNotFound: - return web.HTTPFound( + raise web.HTTPFound( location=request.app.router["install"].url_for() ) else: - return web.HTTPFound(location=request.app.router["home"].url_for()) + raise web.HTTPFound(location=request.app.router["home"].url_for()) response = aiohttp_jinja2.render_template( "add_blurb.html", request, context=context @@ -186,7 +180,7 @@ async def handle_add_blurb_post(request: Request) -> Response: gh, jwt, session_context["username"] ) except error.InstallationNotFound: - return web.HTTPFound(location=request.app.router["install"].url_for()) + raise web.HTTPFound(location=request.app.router["install"].url_for()) else: access_token = await get_installation_access_token( gh, @@ -237,7 +231,7 @@ async def handle_add_blurb_post(request: Request) -> Response: response = aiohttp_jinja2.render_template(template, request, context=context) return response else: - return web.HTTPFound(location=request.app.router["add_blurb"].url_for()) + raise web.HTTPFound(location=request.app.router["add_blurb"].url_for()) if __name__ == "__main__": # pragma: no cover diff --git a/tests/test_main.py b/tests/test_main.py index 791b6fa..582cd85 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -7,6 +7,8 @@ import jinja2 import pytest from aiohttp import web +from aiohttp.web_request import Request +from aiohttp_session import new_session from aiohttp_session import setup as setup_session from aiohttp_session.cookie_storage import EncryptedCookieStorage from cryptography import fernet @@ -31,6 +33,14 @@ def create_app() -> web.Application: return app +async def sign_in(request: Request) -> web.Response: + """Test route that signs the client in as a placeholder GitHub user.""" + session = await new_session(request) + session["username"] = "octocat" + session["token"] = "gho_token" + return web.Response(text="signed in") + + async def test_health_check(aiohttp_client) -> None: app = create_app() app.router.add_get("/health", __main__.health_check) @@ -106,3 +116,67 @@ async def test_handle_install(aiohttp_client) -> None: ) def test_get_access_token(token_str: str, expected: str | None) -> None: assert __main__.get_access_token(token_str) == expected + + +async def test_handle_get_redirects_signed_in_user(aiohttp_client) -> None: + # Arrange + app = create_app() + app.router.add_get("/sign-in", sign_in) + app.router.add_get("/", __main__.handle_get, name="home") + app.router.add_get("/add_blurb", __main__.handle_add_blurb_get, name="add_blurb") + client = await aiohttp_client(app) + await client.get("/sign-in") + + # Act + resp = await client.get("/", allow_redirects=False) + + # Assert + assert resp.status == 302 + assert resp.headers["Location"] == "/add_blurb" + + +async def test_handle_add_blurb_get_redirects_without_session(aiohttp_client) -> None: + # Arrange + app = create_app() + app.router.add_get("/", __main__.handle_get, name="home") + app.router.add_get("/add_blurb", __main__.handle_add_blurb_get, name="add_blurb") + client = await aiohttp_client(app) + + # Act + resp = await client.get("/add_blurb", allow_redirects=False) + + # Assert + assert resp.status == 302 + assert resp.headers["Location"] == "/" + + +async def test_handle_add_blurb_get_renders_form(aiohttp_client, monkeypatch) -> None: + # Arrange: a signed-in session, with the GitHub App lookups stubbed out. + monkeypatch.setattr(__main__, "get_jwt", lambda **kwargs: "jwt") + + async def get_installation(gh, jwt, username): + return {"id": 1} + + monkeypatch.setattr(__main__.util, "get_installation", get_installation) + + app = create_app() + app.router.add_get("/sign-in", sign_in) + app.router.add_get("/install", __main__.handle_install, name="install") + app.router.add_get("/add_blurb", __main__.handle_add_blurb_get, name="add_blurb") + client = await aiohttp_client(app) + await client.get("/sign-in") + + # Act + resp = await client.get("/add_blurb") + + # Assert: the template renders, and the form still posts every field the + # handler reads, with the hooks the inline script relies on. + assert resp.status == 200 + text = await resp.text() + assert "📜🤖 Blurb It!" in text + assert "octocat" in text + for field in ("csrf", "issue_number", "pr_number", "section", "cve", "news_entry"): + assert f'name="{field}"' in text + assert f"" in text + assert 'id="cve-group"' in text + assert 'getElementById("cve-group")' in text