From 47df6543357d80159969dfc7bc973de9a8e2a72b Mon Sep 17 00:00:00 2001 From: Steve Date: Sat, 13 Jul 2024 21:21:49 +0200 Subject: [PATCH 1/9] first commit : purchase fix --- .gitignore | 5 +++-- server.py | 41 +++++++++++++++++++++++++---------------- tests/__init__.py | 0 tests/test_server.py | 5 +++++ 4 files changed, 33 insertions(+), 18 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/test_server.py diff --git a/.gitignore b/.gitignore index 2cba99d87..f944d3e49 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ bin include lib .Python -tests/ .envrc -__pycache__ \ No newline at end of file +__pycache__ +/env +.idea/ \ No newline at end of file diff --git a/server.py b/server.py index 4084baeac..148dea2a6 100644 --- a/server.py +++ b/server.py @@ -1,17 +1,17 @@ import json -from flask import Flask,render_template,request,redirect,flash,url_for +from flask import Flask, render_template, request, redirect, flash, url_for def loadClubs(): with open('clubs.json') as c: - listOfClubs = json.load(c)['clubs'] - return listOfClubs + listOfClubs = json.load(c)['clubs'] + return listOfClubs def loadCompetitions(): with open('competitions.json') as comps: - listOfCompetitions = json.load(comps)['competitions'] - return listOfCompetitions + listOfCompetitions = json.load(comps)['competitions'] + return listOfCompetitions app = Flask(__name__) @@ -20,35 +20,44 @@ def loadCompetitions(): competitions = loadCompetitions() clubs = loadClubs() + @app.route('/') def index(): return render_template('index.html') -@app.route('/showSummary',methods=['POST']) + +@app.route('/showSummary', methods=['POST']) def showSummary(): - club = [club for club in clubs if club['email'] == request.form['email']][0] - return render_template('welcome.html',club=club,competitions=competitions) + club = [club for club in clubs if club['email'] == request.form['email']][ + 0] + return render_template('welcome.html', club=club, + competitions=competitions) @app.route('/book//') -def book(competition,club): +def book(competition, club): foundClub = [c for c in clubs if c['name'] == club][0] foundCompetition = [c for c in competitions if c['name'] == competition][0] if foundClub and foundCompetition: - return render_template('booking.html',club=foundClub,competition=foundCompetition) + return render_template('booking.html', club=foundClub, + competition=foundCompetition) else: flash("Something went wrong-please try again") - return render_template('welcome.html', club=club, competitions=competitions) + return render_template('welcome.html', club=club, + competitions=competitions) -@app.route('/purchasePlaces',methods=['POST']) +@app.route('/purchasePlaces', methods=['POST']) def purchasePlaces(): - competition = [c for c in competitions if c['name'] == request.form['competition']][0] + competition = \ + [c for c in competitions if c['name'] == request.form['competition']][0] club = [c for c in clubs if c['name'] == request.form['club']][0] placesRequired = int(request.form['places']) - competition['numberOfPlaces'] = int(competition['numberOfPlaces'])-placesRequired + competition['numberOfPlaces'] = int( + competition['numberOfPlaces']) - placesRequired flash('Great-booking complete!') - return render_template('welcome.html', club=club, competitions=competitions) + return render_template('welcome.html', club=club, + competitions=competitions) # TODO: Add route for points display @@ -56,4 +65,4 @@ def purchasePlaces(): @app.route('/logout') def logout(): - return redirect(url_for('index')) \ No newline at end of file + return redirect(url_for('index')) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_server.py b/tests/test_server.py new file mode 100644 index 000000000..8d3c5afd8 --- /dev/null +++ b/tests/test_server.py @@ -0,0 +1,5 @@ + + +class PurchasePlaces: + def test_purchase_places(self): + assert False From 6a03829d0cf58a48228d96ad120c20b7f858d680 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 15 Jul 2024 13:50:33 +0200 Subject: [PATCH 2/9] Fixed max purchase limit --- pytest.ini | 3 +++ requirements.txt | 2 ++ server.py | 8 ++++++++ tests/conftest.py | 10 ++++++++++ tests/test_server.py | 40 +++++++++++++++++++++++++++++++++++++--- 5 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 pytest.ini create mode 100644 tests/conftest.py diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 000000000..c24fe5bb9 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +filterwarnings = + ignore::DeprecationWarning diff --git a/requirements.txt b/requirements.txt index 139affa05..94218a6e5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,5 @@ itsdangerous==1.1.0 Jinja2==2.11.2 MarkupSafe==1.1.1 Werkzeug==1.0.1 + +pytest~=8.2.2 \ No newline at end of file diff --git a/server.py b/server.py index 148dea2a6..e50c58eca 100644 --- a/server.py +++ b/server.py @@ -52,10 +52,18 @@ def purchasePlaces(): competition = \ [c for c in competitions if c['name'] == request.form['competition']][0] club = [c for c in clubs if c['name'] == request.form['club']][0] + placesRequired = int(request.form['places']) + + if placesRequired > 12: + flash('Max purchase 12.') + return render_template('welcome.html', club=club, + competitions=competitions) + competition['numberOfPlaces'] = int( competition['numberOfPlaces']) - placesRequired flash('Great-booking complete!') + return render_template('welcome.html', club=club, competitions=competitions) diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..ca8562ecd --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,10 @@ +import pytest + +from server import app, loadClubs, loadCompetitions + + +@pytest.fixture +def client(): + app.config['TESTING'] = True + with app.test_client() as client: + yield client diff --git a/tests/test_server.py b/tests/test_server.py index 8d3c5afd8..4200b2789 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -1,5 +1,39 @@ +from server import loadCompetitions, loadClubs -class PurchasePlaces: - def test_purchase_places(self): - assert False +def test_purchase_places(client): + + clubs = loadClubs() + competitions = loadCompetitions() + + test_club = clubs[0] + test_competition = competitions[0] + places_to_purchase = 8 + + response = client.post('/purchasePlaces', data={ + 'club': test_club['name'], + 'competition': test_competition['name'], + 'places': places_to_purchase + }) + + assert response.status_code == 200 + assert b'Great-booking complete!' in response.data + + +def test_max_purchase_places(client): + + clubs = loadClubs() + competitions = loadCompetitions() + + test_club = clubs[0] + test_competition = competitions[0] + places_to_purchase = 28 + + response = client.post('/purchasePlaces', data={ + 'club': test_club['name'], + 'competition': test_competition['name'], + 'places': places_to_purchase + }) + + assert response.status_code == 200 + assert b'Max purchase 12.' in response.data From 3da7f195b61585618f75d215ca755741cf660d76 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 15 Jul 2024 14:48:05 +0200 Subject: [PATCH 3/9] Fixed purchase when insufficiant club points --- server.py | 5 +++++ tests/test_server.py | 30 ++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/server.py b/server.py index e50c58eca..226bfa999 100644 --- a/server.py +++ b/server.py @@ -60,6 +60,11 @@ def purchasePlaces(): return render_template('welcome.html', club=club, competitions=competitions) + if placesRequired > int(club['points']): + flash('Insufficiant points.') + return render_template('welcome.html', club=club, + competitions=competitions) + competition['numberOfPlaces'] = int( competition['numberOfPlaces']) - placesRequired flash('Great-booking complete!') diff --git a/tests/test_server.py b/tests/test_server.py index 4200b2789..c16576a54 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -3,11 +3,8 @@ def test_purchase_places(client): - clubs = loadClubs() - competitions = loadCompetitions() - - test_club = clubs[0] - test_competition = competitions[0] + test_club = loadClubs()[0] + test_competition = loadCompetitions()[0] places_to_purchase = 8 response = client.post('/purchasePlaces', data={ @@ -22,11 +19,8 @@ def test_purchase_places(client): def test_max_purchase_places(client): - clubs = loadClubs() - competitions = loadCompetitions() - - test_club = clubs[0] - test_competition = competitions[0] + test_club = loadClubs()[0] + test_competition = loadCompetitions()[0] places_to_purchase = 28 response = client.post('/purchasePlaces', data={ @@ -37,3 +31,19 @@ def test_max_purchase_places(client): assert response.status_code == 200 assert b'Max purchase 12.' in response.data + + +def test_has_sufficient_points(client): + + test_club = loadClubs()[1] + test_competition = loadCompetitions()[0] + places_to_purchase = 9 + + response = client.post('/purchasePlaces', data={ + 'club': test_club['name'], + 'competition': test_competition['name'], + 'places': places_to_purchase + }) + + assert response.status_code == 200 + assert b'Insufficiant points.' in response.data From 17287a6cec9197eedf189519bb7822752f2309de Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 15 Jul 2024 19:07:18 +0200 Subject: [PATCH 4/9] Fixed update available club point after purchase --- server.py | 10 ++++++++++ tests/conftest.py | 16 +++++++++++++++- tests/test_server.py | 25 ++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/server.py b/server.py index 226bfa999..25b909a61 100644 --- a/server.py +++ b/server.py @@ -8,6 +8,12 @@ def loadClubs(): return listOfClubs +def saveClub(clubs): + + with open('clubs.json', 'w') as c: + json.dump({'clubs': clubs}, c) + + def loadCompetitions(): with open('competitions.json') as comps: listOfCompetitions = json.load(comps)['competitions'] @@ -65,8 +71,12 @@ def purchasePlaces(): return render_template('welcome.html', club=club, competitions=competitions) + club['points'] = str(int(club['points']) - placesRequired) + saveClub(clubs) + competition['numberOfPlaces'] = int( competition['numberOfPlaces']) - placesRequired + flash('Great-booking complete!') return render_template('welcome.html', club=club, diff --git a/tests/conftest.py b/tests/conftest.py index ca8562ecd..802b1df5c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,8 @@ +import copy import pytest +import json -from server import app, loadClubs, loadCompetitions +from server import app @pytest.fixture @@ -8,3 +10,15 @@ def client(): app.config['TESTING'] = True with app.test_client() as client: yield client + + +@pytest.fixture +def test_clubs(): + with open('clubs.json') as c: + return json.load(c)['clubs'] + + +@pytest.fixture +def test_competitions(): + with open('competitions.json') as comps: + return json.load(comps)['competitions'] diff --git a/tests/test_server.py b/tests/test_server.py index c16576a54..07e3860c7 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -1,8 +1,8 @@ +import server from server import loadCompetitions, loadClubs def test_purchase_places(client): - test_club = loadClubs()[0] test_competition = loadCompetitions()[0] places_to_purchase = 8 @@ -18,7 +18,6 @@ def test_purchase_places(client): def test_max_purchase_places(client): - test_club = loadClubs()[0] test_competition = loadCompetitions()[0] places_to_purchase = 28 @@ -34,7 +33,6 @@ def test_max_purchase_places(client): def test_has_sufficient_points(client): - test_club = loadClubs()[1] test_competition = loadCompetitions()[0] places_to_purchase = 9 @@ -47,3 +45,24 @@ def test_has_sufficient_points(client): assert response.status_code == 200 assert b'Insufficiant points.' in response.data + + +def test_purchase_places(client, test_clubs, test_competitions, mocker): + + mocker.patch('server.loadClubs', return_value=test_clubs) + mocker.patch('server.loadCompetitions', return_value=test_competitions) + mock_save_club = mocker.patch('server.saveClub') + + mocker.patch.object(server, 'clubs', test_clubs) + mocker.patch.object(server, 'competitions', test_competitions) + + places_to_purchase = 9 + + response = client.post('/purchasePlaces', data={ + 'club': test_clubs[0]['name'], + 'competition': test_competitions[0]['name'], + 'places': str(places_to_purchase) + }) + + assert int(test_clubs[0]['points']) == 4 + assert b'Great-booking complete!' in response.data From 5b708aa32cb6bd0adf65c6e1d5a5bec674bd5cad Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 15 Jul 2024 20:36:58 +0200 Subject: [PATCH 5/9] Fixed wrong email login --- server.py | 12 ++++++++---- templates/index.html | 10 ++++++++++ tests/test_server.py | 17 +++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/server.py b/server.py index 25b909a61..e220e4eb1 100644 --- a/server.py +++ b/server.py @@ -34,10 +34,14 @@ def index(): @app.route('/showSummary', methods=['POST']) def showSummary(): - club = [club for club in clubs if club['email'] == request.form['email']][ - 0] - return render_template('welcome.html', club=club, - competitions=competitions) + try: + club = [club for club in clubs if club['email'] == request.form['email']][ + 0] + return render_template('welcome.html', club=club, + competitions=competitions) + except IndexError: + flash('Wrong email-please try again') + return render_template('index.html') @app.route('/book//') diff --git a/templates/index.html b/templates/index.html index 926526b7d..ab38b4445 100644 --- a/templates/index.html +++ b/templates/index.html @@ -5,12 +5,22 @@ GUDLFT Registration +

Welcome to the GUDLFT Registration Portal!

+ Please enter your secretary email to continue:
+ + {% with messages = get_flashed_messages()%} + {% if messages %} + {% for message in messages %} + {{message}} + {% endfor %} + {% endif %} + {% endwith %} \ No newline at end of file diff --git a/tests/test_server.py b/tests/test_server.py index 07e3860c7..52ff018c0 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -66,3 +66,20 @@ def test_purchase_places(client, test_clubs, test_competitions, mocker): assert int(test_clubs[0]['points']) == 4 assert b'Great-booking complete!' in response.data + + +def test_login(client): + + response = client.post('/showSummary', data={ + 'email': 'john@simplylift.co' + }) + assert response.status_code == 200 + + +def test_wrong_login(client): + + response = client.post('/showSummary', data={ + 'email': 'wrong-email@test.com' + }) + assert response.status_code == 200 + assert b'Wrong email-please try again' in response.data From 4f7fa8a2b7e6554d2eb909c979bcc2b70d0c2200 Mon Sep 17 00:00:00 2001 From: Steve Date: Tue, 16 Jul 2024 10:47:18 +0200 Subject: [PATCH 6/9] Update test_server.py --- tests/test_server.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/test_server.py b/tests/test_server.py index 07e3860c7..c54583258 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -2,14 +2,18 @@ from server import loadCompetitions, loadClubs -def test_purchase_places(client): - test_club = loadClubs()[0] - test_competition = loadCompetitions()[0] +def test_purchase_places(client, test_clubs, test_competitions, mocker): + mocker.patch('server.loadClubs', return_value=test_clubs) + mocker.patch('server.loadCompetitions', return_value=test_competitions) + mock_save_club = mocker.patch('server.saveClub') + + mocker.patch.object(server, 'clubs', test_clubs) + mocker.patch.object(server, 'competitions', test_competitions) places_to_purchase = 8 response = client.post('/purchasePlaces', data={ - 'club': test_club['name'], - 'competition': test_competition['name'], + 'club': test_clubs[0]['name'], + 'competition': test_competitions[0]['name'], 'places': places_to_purchase }) @@ -47,7 +51,7 @@ def test_has_sufficient_points(client): assert b'Insufficiant points.' in response.data -def test_purchase_places(client, test_clubs, test_competitions, mocker): +def test_update_points_after_purchase(client, test_clubs, test_competitions, mocker): mocker.patch('server.loadClubs', return_value=test_clubs) mocker.patch('server.loadCompetitions', return_value=test_competitions) From 2d98a608cc53ba05f8e211cbd449843ec5b10f03 Mon Sep 17 00:00:00 2001 From: Steve Date: Tue, 16 Jul 2024 10:53:30 +0200 Subject: [PATCH 7/9] Display when competition is full --- server.py | 12 ++++++--- templates/index.html | 10 ++++++++ templates/welcome.html | 24 +++++++++--------- tests/conftest.py | 12 +++++++-- tests/test_server.py | 55 ++++++++++++++++++++++++++++++++++++------ 5 files changed, 89 insertions(+), 24 deletions(-) diff --git a/server.py b/server.py index 25b909a61..e220e4eb1 100644 --- a/server.py +++ b/server.py @@ -34,10 +34,14 @@ def index(): @app.route('/showSummary', methods=['POST']) def showSummary(): - club = [club for club in clubs if club['email'] == request.form['email']][ - 0] - return render_template('welcome.html', club=club, - competitions=competitions) + try: + club = [club for club in clubs if club['email'] == request.form['email']][ + 0] + return render_template('welcome.html', club=club, + competitions=competitions) + except IndexError: + flash('Wrong email-please try again') + return render_template('index.html') @app.route('/book//') diff --git a/templates/index.html b/templates/index.html index 926526b7d..c22b864ef 100644 --- a/templates/index.html +++ b/templates/index.html @@ -12,5 +12,15 @@

Welcome to the GUDLFT Registration Portal!

+ + + {% with messages = get_flashed_messages()%} + {% if messages %} + {% for message in messages %} + {{message}} + {% endfor %} + {% endif %} + {% endwith %} + \ No newline at end of file diff --git a/templates/welcome.html b/templates/welcome.html index ff6b261a2..4405feda4 100644 --- a/templates/welcome.html +++ b/templates/welcome.html @@ -7,7 +7,7 @@

Welcome, {{club['email']}}

Logout - {% with messages = get_flashed_messages()%} + {% with messages = get_flashed_messages() %} {% if messages %}
    {% for message in messages %} @@ -15,22 +15,24 @@

    Welcome, {{club['email']}}

    Logout {% endfor %}
{% endif%} - Points available: {{club['points']}} + Points available: {{ club['points'] }}

Competitions:

    - {% for comp in competitions%} + {% for comp in competitions %}
  • - {{comp['name']}}
    - Date: {{comp['date']}}
    - Number of Places: {{comp['numberOfPlaces']}} - {%if comp['numberOfPlaces']|int >0%} - Book Places - {%endif%} +

    {{ comp['name'] }}

    +

    Date: {{ comp['date'] }}

    +

    Number of Places: {{ comp['numberOfPlaces'] }}

    + {% if comp['numberOfPlaces']|int >0 %} + Book Places + {% else %} + - Competition complete + {% endif %}
  • -
    +
    {% endfor %}
- {%endwith%} + {% endwith %} \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index 802b1df5c..5a3c904e9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,8 +1,7 @@ -import copy import pytest import json -from server import app +from server import app, competitions @pytest.fixture @@ -22,3 +21,12 @@ def test_clubs(): def test_competitions(): with open('competitions.json') as comps: return json.load(comps)['competitions'] + + +@pytest.fixture +def test_competition_full(): + competitions[:] = [ + {'name': 'Spring Festival', + 'date': '2020-03-27 10:00:00', + 'numberOfPlaces': '0'} + ] diff --git a/tests/test_server.py b/tests/test_server.py index 07e3860c7..c66074ba0 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -2,14 +2,18 @@ from server import loadCompetitions, loadClubs -def test_purchase_places(client): - test_club = loadClubs()[0] - test_competition = loadCompetitions()[0] +def test_purchase_places(client, test_clubs, test_competitions, mocker): + mocker.patch('server.loadClubs', return_value=test_clubs) + mocker.patch('server.loadCompetitions', return_value=test_competitions) + mock_save_club = mocker.patch('server.saveClub') + + mocker.patch.object(server, 'clubs', test_clubs) + mocker.patch.object(server, 'competitions', test_competitions) places_to_purchase = 8 response = client.post('/purchasePlaces', data={ - 'club': test_club['name'], - 'competition': test_competition['name'], + 'club': test_clubs[0]['name'], + 'competition': test_competitions[0]['name'], 'places': places_to_purchase }) @@ -47,8 +51,7 @@ def test_has_sufficient_points(client): assert b'Insufficiant points.' in response.data -def test_purchase_places(client, test_clubs, test_competitions, mocker): - +def test_update_points_after_purchase(client, test_clubs, test_competitions, mocker): mocker.patch('server.loadClubs', return_value=test_clubs) mocker.patch('server.loadCompetitions', return_value=test_competitions) mock_save_club = mocker.patch('server.saveClub') @@ -66,3 +69,41 @@ def test_purchase_places(client, test_clubs, test_competitions, mocker): assert int(test_clubs[0]['points']) == 4 assert b'Great-booking complete!' in response.data + + +def test_login(client): + + response = client.post('/showSummary', data={ + 'email': 'john@simplylift.co' + }) + assert response.status_code == 200 + + +def test_wrong_login(client): + + response = client.post('/showSummary', data={ + 'email': 'wrong-email@test.com' + }) + assert response.status_code == 200 + assert b'Wrong email-please try again' in response.data + + +def test_display_book_available(client): + test_club = loadClubs()[0] + test_competitions = loadCompetitions() + + response = client.post('/showSummary', data={'email': test_club['email']}) + + assert response.status_code == 200 + assert b'Number of Places: 25' in response.data + + +def test_display_book_non_available(client, test_competition_full): + + test_club = loadClubs()[0] + + response = client.post('/showSummary', data={'email': test_club['email']}) + + assert response.status_code == 200 + assert b'Spring Festival' in response.data + assert b'- Competition complete' in response.data From 83a43e9f4b78ed641149567c24983f83d06c053b Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 17 Jul 2024 10:07:00 +0200 Subject: [PATCH 8/9] Added public display of points --- clubs.json | 25 +++++++++++--------- server.py | 15 +++++++++--- templates/clubs-points.html | 26 +++++++++++++++++++++ templates/index.html | 2 ++ tests/conftest.py | 16 ++++++++++--- tests/test_clubs.json | 19 +++++++++++++++ tests/test_competitions.json | 14 +++++++++++ tests/test_server.py | 45 +++++++++++++----------------------- 8 files changed, 116 insertions(+), 46 deletions(-) create mode 100644 templates/clubs-points.html create mode 100644 tests/test_clubs.json create mode 100644 tests/test_competitions.json diff --git a/clubs.json b/clubs.json index 1d7ad1ffe..d2432dc98 100644 --- a/clubs.json +++ b/clubs.json @@ -1,16 +1,19 @@ -{"clubs":[ +{ + "clubs": [ { - "name":"Simply Lift", - "email":"john@simplylift.co", - "points":"13" + "name": "Simply Lift", + "email": "john@simplylift.co", + "points": "13" }, { - "name":"Iron Temple", - "email": "admin@irontemple.com", - "points":"4" + "name": "Iron Temple", + "email": "admin@irontemple.com", + "points": "4" }, - { "name":"She Lifts", - "email": "kate@shelifts.co.uk", - "points":"12" + { + "name": "She Lifts", + "email": "kate@shelifts.co.uk", + "points": "12" } -]} \ No newline at end of file + ] +} \ No newline at end of file diff --git a/server.py b/server.py index e220e4eb1..3ec357c97 100644 --- a/server.py +++ b/server.py @@ -9,7 +9,6 @@ def loadClubs(): def saveClub(clubs): - with open('clubs.json', 'w') as c: json.dump({'clubs': clubs}, c) @@ -32,10 +31,19 @@ def index(): return render_template('index.html') +@app.route('/clubs-points') +def clubs_points(): + return render_template( + 'clubs-points.html', + clubs=clubs + ) + + @app.route('/showSummary', methods=['POST']) def showSummary(): try: - club = [club for club in clubs if club['email'] == request.form['email']][ + club = \ + [club for club in clubs if club['email'] == request.form['email']][ 0] return render_template('welcome.html', club=club, competitions=competitions) @@ -60,7 +68,8 @@ def book(competition, club): @app.route('/purchasePlaces', methods=['POST']) def purchasePlaces(): competition = \ - [c for c in competitions if c['name'] == request.form['competition']][0] + [c for c in competitions if c['name'] == request.form['competition']][ + 0] club = [c for c in clubs if c['name'] == request.form['club']][0] placesRequired = int(request.form['places']) diff --git a/templates/clubs-points.html b/templates/clubs-points.html new file mode 100644 index 000000000..0b9dd4ed8 --- /dev/null +++ b/templates/clubs-points.html @@ -0,0 +1,26 @@ + + + + + Clubs points || GUDLFT + + +

Clubs points

+ + {% if clubs %} + + + + + {% for club in clubs %} + + {% endfor %} + +
NamePoints
{{ club['name'] }}{{ club['points'] }}
+ + {% endif %} + + Back + + + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index c22b864ef..3bcdcc745 100644 --- a/templates/index.html +++ b/templates/index.html @@ -22,5 +22,7 @@

Welcome to the GUDLFT Registration Portal!

{% endif %} {% endwith %} + View clubs points + \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index 5a3c904e9..dce3d9e15 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,7 @@ import pytest import json +import server from server import app, competitions @@ -13,20 +14,29 @@ def client(): @pytest.fixture def test_clubs(): - with open('clubs.json') as c: + with open('tests/test_clubs.json') as c: return json.load(c)['clubs'] @pytest.fixture def test_competitions(): - with open('competitions.json') as comps: + with open('tests/test_competitions.json') as comps: return json.load(comps)['competitions'] @pytest.fixture def test_competition_full(): competitions[:] = [ - {'name': 'Spring Festival', + {'name': 'Test Comptetition #3', 'date': '2020-03-27 10:00:00', 'numberOfPlaces': '0'} ] + + +@pytest.fixture +def setup_mocks(mocker, test_clubs, test_competitions): + mocker.patch('server.loadClubs', return_value=test_clubs) + mocker.patch('server.loadCompetitions', return_value=test_competitions) + mocker.patch('server.saveClub') + mocker.patch.object(server, 'clubs', test_clubs) + mocker.patch.object(server, 'competitions', test_competitions) diff --git a/tests/test_clubs.json b/tests/test_clubs.json new file mode 100644 index 000000000..c5a2f3679 --- /dev/null +++ b/tests/test_clubs.json @@ -0,0 +1,19 @@ +{ + "clubs": [ + { + "name": "Test club #1", + "email": "john@test.com", + "points": "13" + }, + { + "name": "Test club #2", + "email": "admin@test.com", + "points": "4" + }, + { + "name": "Test club #3", + "email": "kate@test.com", + "points": "12" + } + ] +} \ No newline at end of file diff --git a/tests/test_competitions.json b/tests/test_competitions.json new file mode 100644 index 000000000..e0022d2a5 --- /dev/null +++ b/tests/test_competitions.json @@ -0,0 +1,14 @@ +{ + "competitions": [ + { + "name": "Test Competition #1", + "date": "2020-03-27 10:00:00", + "numberOfPlaces": "25" + }, + { + "name": "Test Competition #2", + "date": "2020-10-22 13:30:00", + "numberOfPlaces": "13" + } + ] +} \ No newline at end of file diff --git a/tests/test_server.py b/tests/test_server.py index c66074ba0..80d582092 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -1,14 +1,7 @@ -import server -from server import loadCompetitions, loadClubs +from server import loadClubs -def test_purchase_places(client, test_clubs, test_competitions, mocker): - mocker.patch('server.loadClubs', return_value=test_clubs) - mocker.patch('server.loadCompetitions', return_value=test_competitions) - mock_save_club = mocker.patch('server.saveClub') - - mocker.patch.object(server, 'clubs', test_clubs) - mocker.patch.object(server, 'competitions', test_competitions) +def test_purchase_places(client, test_clubs, test_competitions, setup_mocks): places_to_purchase = 8 response = client.post('/purchasePlaces', data={ @@ -21,14 +14,12 @@ def test_purchase_places(client, test_clubs, test_competitions, mocker): assert b'Great-booking complete!' in response.data -def test_max_purchase_places(client): - test_club = loadClubs()[0] - test_competition = loadCompetitions()[0] +def test_max_purchase_places(client, test_clubs, test_competitions, setup_mocks): places_to_purchase = 28 response = client.post('/purchasePlaces', data={ - 'club': test_club['name'], - 'competition': test_competition['name'], + 'club': test_clubs[0]['name'], + 'competition': test_competitions[0]['name'], 'places': places_to_purchase }) @@ -36,14 +27,12 @@ def test_max_purchase_places(client): assert b'Max purchase 12.' in response.data -def test_has_sufficient_points(client): - test_club = loadClubs()[1] - test_competition = loadCompetitions()[0] +def test_has_sufficient_points(client, test_clubs, test_competitions, setup_mocks): places_to_purchase = 9 response = client.post('/purchasePlaces', data={ - 'club': test_club['name'], - 'competition': test_competition['name'], + 'club': test_clubs[1]['name'], + 'competition': test_competitions[0]['name'], 'places': places_to_purchase }) @@ -51,14 +40,7 @@ def test_has_sufficient_points(client): assert b'Insufficiant points.' in response.data -def test_update_points_after_purchase(client, test_clubs, test_competitions, mocker): - mocker.patch('server.loadClubs', return_value=test_clubs) - mocker.patch('server.loadCompetitions', return_value=test_competitions) - mock_save_club = mocker.patch('server.saveClub') - - mocker.patch.object(server, 'clubs', test_clubs) - mocker.patch.object(server, 'competitions', test_competitions) - +def test_update_points_after_purchase(client, test_clubs, test_competitions, setup_mocks): places_to_purchase = 9 response = client.post('/purchasePlaces', data={ @@ -89,8 +71,8 @@ def test_wrong_login(client): def test_display_book_available(client): + test_club = loadClubs()[0] - test_competitions = loadCompetitions() response = client.post('/showSummary', data={'email': test_club['email']}) @@ -105,5 +87,10 @@ def test_display_book_non_available(client, test_competition_full): response = client.post('/showSummary', data={'email': test_club['email']}) assert response.status_code == 200 - assert b'Spring Festival' in response.data assert b'- Competition complete' in response.data + + +def test_display_points_table(client): + + response = client.get('/clubs-points') + assert response.status_code == 200 From 28200be693ba62826bb505f57fe007dfb6853fef Mon Sep 17 00:00:00 2001 From: Steve Date: Sat, 20 Jul 2024 01:46:51 +0200 Subject: [PATCH 9/9] Fixed purchase on completed competition --- .gitignore | 3 ++- server.py | 22 ++++++++++++++++++---- templates/welcome.html | 8 +++++++- tests/test_competitions.json | 2 +- tests/test_server.py | 33 +++++++++++++++++++++++++-------- 5 files changed, 53 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index f944d3e49..8f1fd70b8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ lib .envrc __pycache__ /env -.idea/ \ No newline at end of file +.idea/ +/flake8-report \ No newline at end of file diff --git a/server.py b/server.py index 3ec357c97..828d10898 100644 --- a/server.py +++ b/server.py @@ -1,4 +1,6 @@ import json +from datetime import datetime + from flask import Flask, render_template, request, redirect, flash, url_for @@ -26,6 +28,14 @@ def loadCompetitions(): clubs = loadClubs() +@app.template_filter('is_date_passed') +def is_date_passed(date_str): + date_format = "%Y-%m-%d %H:%M:%S" + date_to_check = datetime.strptime(date_str, date_format) + current_date = datetime.now() + return date_to_check < current_date + + @app.route('/') def index(): return render_template('index.html') @@ -43,10 +53,14 @@ def clubs_points(): def showSummary(): try: club = \ - [club for club in clubs if club['email'] == request.form['email']][ - 0] - return render_template('welcome.html', club=club, - competitions=competitions) + [club for club in clubs if club['email'] == request.form['email']][ + 0] + return render_template( + 'welcome.html', + club=club, + competitions=competitions, + datetime=datetime + ) except IndexError: flash('Wrong email-please try again') return render_template('index.html') diff --git a/templates/welcome.html b/templates/welcome.html index 4405feda4..3af2475a1 100644 --- a/templates/welcome.html +++ b/templates/welcome.html @@ -21,7 +21,13 @@

Competitions:

{% for comp in competitions %}
  • {{ comp['name'] }}

    -

    Date: {{ comp['date'] }}

    + + {% if comp['date']|is_date_passed %} +

    Competition over

    + {% else %} +

    Date: {{ comp['date'] }}

    + {% endif %} +

    Number of Places: {{ comp['numberOfPlaces'] }}

    {% if comp['numberOfPlaces']|int >0 %} Book Places diff --git a/tests/test_competitions.json b/tests/test_competitions.json index e0022d2a5..f30a5202d 100644 --- a/tests/test_competitions.json +++ b/tests/test_competitions.json @@ -2,7 +2,7 @@ "competitions": [ { "name": "Test Competition #1", - "date": "2020-03-27 10:00:00", + "date": "2029-03-27 10:00:00", "numberOfPlaces": "25" }, { diff --git a/tests/test_server.py b/tests/test_server.py index 80d582092..aa9a023c9 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -14,7 +14,10 @@ def test_purchase_places(client, test_clubs, test_competitions, setup_mocks): assert b'Great-booking complete!' in response.data -def test_max_purchase_places(client, test_clubs, test_competitions, setup_mocks): +def test_max_purchase_places(client, + test_clubs, + test_competitions, + setup_mocks): places_to_purchase = 28 response = client.post('/purchasePlaces', data={ @@ -27,7 +30,10 @@ def test_max_purchase_places(client, test_clubs, test_competitions, setup_mocks) assert b'Max purchase 12.' in response.data -def test_has_sufficient_points(client, test_clubs, test_competitions, setup_mocks): +def test_has_sufficient_points(client, + test_clubs, + test_competitions, + setup_mocks): places_to_purchase = 9 response = client.post('/purchasePlaces', data={ @@ -40,7 +46,10 @@ def test_has_sufficient_points(client, test_clubs, test_competitions, setup_mock assert b'Insufficiant points.' in response.data -def test_update_points_after_purchase(client, test_clubs, test_competitions, setup_mocks): +def test_update_points_after_purchase(client, + test_clubs, + test_competitions, + setup_mocks): places_to_purchase = 9 response = client.post('/purchasePlaces', data={ @@ -54,7 +63,6 @@ def test_update_points_after_purchase(client, test_clubs, test_competitions, set def test_login(client): - response = client.post('/showSummary', data={ 'email': 'john@simplylift.co' }) @@ -62,7 +70,6 @@ def test_login(client): def test_wrong_login(client): - response = client.post('/showSummary', data={ 'email': 'wrong-email@test.com' }) @@ -71,7 +78,6 @@ def test_wrong_login(client): def test_display_book_available(client): - test_club = loadClubs()[0] response = client.post('/showSummary', data={'email': test_club['email']}) @@ -81,7 +87,6 @@ def test_display_book_available(client): def test_display_book_non_available(client, test_competition_full): - test_club = loadClubs()[0] response = client.post('/showSummary', data={'email': test_club['email']}) @@ -91,6 +96,18 @@ def test_display_book_non_available(client, test_competition_full): def test_display_points_table(client): - response = client.get('/clubs-points') assert response.status_code == 200 + + +def test_purchase_completed_competition(client, + test_clubs, + test_competitions, + setup_mocks): + + response = client.post('/showSummary', data={ + 'email': test_clubs[0]['email'] + }) + + assert response.status_code == 200 + assert b'Competition over' in response.data