PW = "correct-horse-battery-staple" def test_login_success_sets_cookie(client): r = client.post("/login", data={"username": "admin", "password": PW}) assert r.status_code == 303 set_cookie = r.headers.get("set-cookie", "") assert "bike_session=" in set_cookie assert "httponly" in set_cookie.lower() def test_login_failure_generic_error(client): r = client.post("/login", data={"username": "admin", "password": "wrong"}) assert r.status_code == 200 # Generic error - does not reveal whether the user exists. assert "Invalid username or password" in r.text def test_login_failure_unknown_user_same_message(client): r = client.post("/login", data={"username": "ghost", "password": "x"}) assert r.status_code == 200 assert "Invalid username or password" in r.text def test_dashboard_requires_auth(client): r = client.get("/", follow_redirects=False) assert r.status_code == 303 assert r.headers["location"].startswith("/login") def test_dashboard_when_authed(client): client.post("/login", data={"username": "admin", "password": PW}) r = client.get("/") assert r.status_code == 200 assert "Your bikes" in r.text def test_logout_clears_session(client): client.post("/login", data={"username": "admin", "password": PW}) r = client.get("/logout") assert r.status_code == 200 # Session cookie should be cleared (max-age 0). assert "bike_session=" in r.headers.get("set-cookie", "")