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 "