diff --git a/server.py b/server.py index db9561fa1..dff4541a0 100644 --- a/server.py +++ b/server.py @@ -75,7 +75,7 @@ def show_summary(): if request.method == "POST": email = request.form.get("email") if not email: - flash("Email is required.") + flash("Empty field.") return redirect(url_for("index")) # Find the club by email from the form data @@ -91,14 +91,12 @@ def show_summary(): # Handle GET request email = session.get("email") if not email: - flash("Session expired. Please log in again.") - return redirect(url_for("index")) + raise Unauthorized("You must be connected.") # Find the club by email from the session data club = next((club for club in clubs if club["email"] == email), None) if not club: - flash("Email does not exist.") - return redirect(url_for("index")) + raise Unauthorized("You must have an account.") # Update the booking status for each competition now = datetime.now() @@ -122,10 +120,16 @@ def book(competition, club): otherwise the welcome page with an error message. :rtype: werkzeug.wrappers.Response """ + + if not session.get("email"): + raise Unauthorized("You must be connected.") + found_club = [c for c in clubs if c["name"] == club][0] found_competition = [c for c in competitions if c["name"] == competition][0] - if found_club and found_competition: + + if found_club and found_competition and found_competition["canBeBooked"] is True: return render_template("booking.html", club=found_club, competition=found_competition) + flash("Something went wrong - please try again.") return redirect(url_for("show_summary")) @@ -180,7 +184,20 @@ def purchase_places(): @app.route("/logout") def logout(): """Log out and redirect to the index page.""" + session.pop("email", None) return redirect(url_for("index")) -# TODO: Add route for points display +@app.route("/clubs", methods=["GET"]) +def display_club_points(): + """ + Render the club points table page if the user is authenticated. + + :raises Unauthorized: If the user is not logged in. + :return: The rendered template for the clubs page. + :rtype: flask.Response + """ + if not session.get("email"): + raise Unauthorized("You must be connected.") + + return render_template("clubs.html", clubs=clubs) diff --git a/templates/clubs.html b/templates/clubs.html new file mode 100644 index 000000000..b545532a1 --- /dev/null +++ b/templates/clubs.html @@ -0,0 +1,81 @@ + + + +
+ + +Club Name | +Points | +
---|---|
{{ c.name }} | +{{ c.points }} | +
Points available: {{ club['points'] }}
diff --git a/tests/integration_tests/test_integration.py b/tests/integration_tests/test_integration.py index a840f218c..55e6de01b 100644 --- a/tests/integration_tests/test_integration.py +++ b/tests/integration_tests/test_integration.py @@ -104,7 +104,7 @@ def test_login_no_email(client): response = client.post("/show_summary", data={}, follow_redirects=True) response_text = response.data.decode("utf-8") assert response.status_code == 200 - assert "Email is required" in response_text + assert "Empty field" in response_text def test_get_welcome_page_with_email_in_session(client, mocker): @@ -142,8 +142,7 @@ def test_get_welcome_page_without_email_in_session(client): :return: None """ response = client.get("/show_summary") - assert response.status_code == 302 - assert response.headers["Location"] == "/" + assert response.status_code == 401 def test_get_welcome_page_with_invalid_email_in_session(client): @@ -161,8 +160,7 @@ def test_get_welcome_page_with_invalid_email_in_session(client): sess["email"] = "invalid@example.com" response = client.get("/show_summary") - assert response.status_code == 302 - assert response.headers["Location"] == "/" + assert response.status_code == 401 def test_purchase_success(client, mocker): @@ -423,3 +421,56 @@ def test_initialize_club_bookings_count_if_not_present(client, mocker): client.post("/purchase_places", data={"competition": competitions[0]["name"], "club": clubs[0]["name"], "places": 1}, follow_redirects=True) assert competitions[0]["clubBookings"]["Club1"] == 1 + + +def test_display_club_points_authenticated(client, mocker): + """ + Test that the clubs page is rendered correctly when the user is authenticated. + + This test mocks the club data and simulates a logged-in user session. + It then sends a GET request to the `/clubs` route and checks: + + - The HTTP response status code is 200 (OK). + - The names of the clubs are present in the rendered HTML. + + :param client: The Flask test client used to simulate requests. + :type client: flask.testing.FlaskClient + :param mocker: The pytest mock object used for patching functions and variables. + :type mocker: pytest_mock.MockerFixture + """ + # Mock club data + clubs = [ + {"name": "Club1", "points": 20}, + {"name": "Club2", "points": 30}, + ] + mocker.patch("server.clubs", clubs) + + # Simulate a session with a logged-in user + with client.session_transaction() as session: + session["email"] = "club1@test.com" + + response = client.get("/clubs") + + assert response.status_code == 200 + assert b"Club1" in response.data + assert b"Club2" in response.data + + +def test_display_club_points_unauthenticated(client): + """ + Test that an unauthenticated user is redirected to the index page. + + This test sends a GET request to the `/clubs` route without a logged-in user session. + It checks: + + - The HTTP response status code is 200 after the redirect. + - A flash message is displayed informing the user they must be logged in. + - The redirect leads to the index page. + + :param client: The Flask test client used to simulate requests. + :type client: flask.testing.FlaskClient + """ + + response = client.get("/clubs", follow_redirects=True) + + assert response.status_code == 401