Skip to content

Commit c0699a1

Browse files
committed
(fix) test-endpoints purchase places
1 parent 0d14487 commit c0699a1

File tree

7 files changed

+188
-48
lines changed

7 files changed

+188
-48
lines changed

.flake8

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[flake8]
2+
max-line-length = 80
3+
exclude =
4+
bin/activate.py,
5+
lib,
6+
packages,
7+
migrations,
8+
build,
9+
dist,
10+
*.pyc,
11+
__pycache__,
12+
bin/activate_this.py

competitions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
{
99
"name": "Fall Classic",
1010
"date": "2020-10-22 13:30:00",
11-
"numberOfPlaces": "2"
11+
"numberOfPlaces": "14"
1212
}
1313
]
1414
}

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[tool.black]
2+
line-length = 80

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ Jinja2==2.11.2
55
MarkupSafe==1.1.1
66
Werkzeug==1.0.1
77
black
8-
pytest
8+
pytest
9+
flake8

server.py

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import json
22
from flask import Flask, render_template, request, redirect, flash, url_for
33

4+
app = Flask(__name__)
5+
app.secret_key = "something_special"
6+
app.config["COMPETITIONS_FILE"] = "competitions.json"
7+
48

59
def loadClubs():
610
with open("clubs.json") as c:
@@ -9,14 +13,11 @@ def loadClubs():
913

1014

1115
def loadCompetitions():
12-
with open("competitions.json") as comps:
16+
with open(app.config["COMPETITIONS_FILE"], "r") as comps:
1317
listOfCompetitions = json.load(comps)["competitions"]
1418
return listOfCompetitions
1519

1620

17-
app = Flask(__name__)
18-
app.secret_key = "something_special"
19-
2021
competitions = loadCompetitions()
2122
clubs = loadClubs()
2223

@@ -28,12 +29,8 @@ def index():
2829

2930
@app.route("/showSummary", methods=["POST"])
3031
def showSummary():
31-
club = [club for club in clubs if club["email"] == request.form["email"]][
32-
0
33-
]
34-
return render_template(
35-
"welcome.html", club=club, competitions=competitions
36-
)
32+
club = [club for club in clubs if club["email"] == request.form["email"]][0]
33+
return render_template("welcome.html", club=club, competitions=competitions)
3734

3835

3936
@app.route("/book/<competition>/<club>")
@@ -62,26 +59,37 @@ def purchasePlaces():
6259
club = [c for c in clubs if c["name"] == request.form["club"]][0]
6360

6461
# Check if request.form['places'] exist and positive *
65-
if not request.form['places'] or int(request.form['places']) < 1 :
62+
if not request.form["places"] or int(request.form["places"]) < 1:
6663
flash("Places required must be a positive integer")
67-
return redirect(url_for('book',competition=competition['name'],club=club['name']))
64+
return redirect(
65+
url_for("book", competition=competition["name"], club=club["name"])
66+
)
6867

6968
# Check if placesRequired does not exceed 12
7069
placesRequired = int(request.form["places"])
71-
if placesRequired > 12 :
70+
71+
if placesRequired > 12:
7272
flash(
7373
"Places required must be a positive integer that does not exceed 12"
7474
)
7575
return redirect(
76-
url_for(
77-
"book", competition=competition["name"], club=club["name"]
78-
)
76+
url_for("book", competition=competition["name"], club=club["name"])
77+
)
78+
79+
# Check if placesRequired does not exceed places available:
80+
places_available = int(competition["numberOfPlaces"])
81+
82+
if placesRequired > places_available:
83+
flash(
84+
f"Places required must be lower than places available: "
85+
f"{places_available}"
86+
)
87+
return redirect(
88+
url_for("book", competition=competition["name"], club=club["name"])
7989
)
8090

8191
# Update places in competition
82-
competition["numberOfPlaces"] = (
83-
int(competition["numberOfPlaces"]) - placesRequired
84-
)
92+
competition["numberOfPlaces"] = places_available - placesRequired
8593

8694
# Store the str() value of 'numberOfPlaces' in the dict of competition in
8795
# the list-dict competitions
@@ -94,13 +102,10 @@ def purchasePlaces():
94102
dict_competitions["competitions"] = competitions
95103

96104
# unload
97-
with open("competitions.json", "w") as file_competition:
105+
with open(app.config["COMPETITIONS_FILE"], "w") as file_competition:
98106
json.dump(dict_competitions, file_competition, indent=4)
99107
flash("Great-booking complete!")
100-
return render_template(
101-
"welcome.html", club=club, competitions=competitions
102-
)
103-
108+
return render_template("welcome.html", club=club, competitions=competitions)
104109

105110

106111
# TODO: Add route for points display
@@ -109,3 +114,7 @@ def purchasePlaces():
109114
@app.route("/logout")
110115
def logout():
111116
return redirect(url_for("index"))
117+
118+
119+
if __name__ == "__main__":
120+
app.run(debug=True)

templates/booking.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ <h2>{{competition['name']}}</h2>
1919
<form action="/purchasePlaces" method="post">
2020
<input type="hidden" name="club" value="{{club['name']}}">
2121
<input type="hidden" name="competition" value="{{competition['name']}}">
22-
<label for="places">How many places?</label><input type="number" name="places" id=""/>
22+
<label for="places">How many places?</label><input type="number" name="places" id="places"/>
2323
<button type="submit">Book</button>
2424
</form>
2525
</body>

tests/test_endpoints.py

Lines changed: 137 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,154 @@
11
import pytest
2-
from server import app
2+
import json
33
import html
4+
from server import app
5+
6+
7+
@pytest.fixture
8+
def temp_competitions_file(tmpdir, request):
9+
original_competitions_file = tmpdir.join("competitions.json")
10+
num_places = request.param if hasattr(request, "param") else "10"
11+
initial_competitions = {
12+
"competitions": [
13+
{
14+
"name": "Spring Festival",
15+
"date": "2020-03-27 10:00:00",
16+
"numberOfPlaces": "13",
17+
},
18+
{
19+
"name": "Fall Classic",
20+
"date": "2020-10-22 13:30:00",
21+
"numberOfPlaces": num_places,
22+
},
23+
]
24+
}
25+
with open(original_competitions_file, "w") as competitions_file:
26+
json.dump(initial_competitions, competitions_file, indent=4)
27+
app.config["COMPETITIONS_FILE"] = str(original_competitions_file)
28+
return initial_competitions
29+
430

31+
@pytest.fixture
32+
def client(temp_competitions_file):
33+
with app.test_client() as client:
34+
yield client
535

6-
@pytest.fixture()
7-
def client():
8-
return app.test_client()
936

10-
def test_purchasePlaces_input_less_12(client):
11-
response = client.post("/purchasePlaces", data = {"places":11,"competition":"Fall Classic","club":"Iron Temple"})
37+
@pytest.fixture(autouse=True)
38+
def reset_competitions(temp_competitions_file):
39+
from server import competitions
40+
41+
competitions.clear()
42+
competitions.extend(temp_competitions_file["competitions"])
43+
44+
45+
@pytest.mark.parametrize("temp_competitions_file", ["10"], indirect=True)
46+
def test_purchasePlaces_input_less_12_sucess(client, tmpdir):
47+
response = client.post(
48+
"/purchasePlaces",
49+
data={
50+
"places": 9,
51+
"competition": "Fall Classic",
52+
"club": "Iron Temple",
53+
},
54+
)
1255
assert response.status_code == 200
13-
assert b'Great-booking complete!' in response.data
56+
assert b"Great-booking complete!" in response.data
57+
58+
59+
@pytest.mark.parametrize("temp_competitions_file", ["10"], indirect=True)
60+
def test_purchasePlaces_input_less_12_but_more_than_places_available(
61+
client, tmpdir
62+
):
63+
response = client.post(
64+
"/purchasePlaces",
65+
data={
66+
"places": 11,
67+
"competition": "Fall Classic",
68+
"club": "Iron Temple",
69+
},
70+
)
71+
assert response.status_code == 302
72+
response_redirect = client.get("/book/Fall%20Classic/Iron%20Temple")
73+
decoding_response_data = response_redirect.data.decode("UTF-8")
74+
converted_str = html.unescape(decoding_response_data)
75+
assert (
76+
"Places required must be lower than places available: 10"
77+
in converted_str
78+
)
1479

1580

16-
def test_purchasePlaces_input_more_12(client):
17-
response = client.post("/purchasePlaces", data = {"places":13,"competition":"Fall Classic","club":"Iron Temple"})
81+
@pytest.mark.parametrize("temp_competitions_file", ["14"], indirect=True)
82+
def test_purchasePlaces_input_more_12(client, tmpdir):
83+
response = client.post(
84+
"/purchasePlaces",
85+
data={
86+
"places": 13,
87+
"competition": "Fall Classic",
88+
"club": "Iron Temple",
89+
},
90+
)
1891
assert response.status_code == 302
1992
response_redirect = client.get("/book/Fall%20Classic/Iron%20Temple")
20-
decoding_response_data = response_redirect.data.decode('UTF-8')
21-
converted_str = html.unescape(decoding_response_data)
22-
assert "Places required must be a positive integer that does not exceed 12" in converted_str
93+
decoding_response_data = response_redirect.data.decode("UTF-8")
94+
converted_str = html.unescape(decoding_response_data)
95+
assert (
96+
"Places required must be a positive integer that does not exceed 12"
97+
in converted_str
98+
)
2399

24-
def test_purchasePlaces_input_negatif(client):
25-
response = client.post("/purchasePlaces", data = {"places":-1,"competition":"Fall Classic","club":"Iron Temple"})
100+
101+
@pytest.mark.parametrize("temp_competitions_file", ["10"], indirect=True)
102+
def test_purchasePlaces_input_negatif(client, tmpdir):
103+
response = client.post(
104+
"/purchasePlaces",
105+
data={
106+
"places": -1,
107+
"competition": "Fall Classic",
108+
"club": "Iron Temple",
109+
},
110+
)
26111
assert response.status_code == 302
27112
response_redirect = client.get("/book/Fall%20Classic/Iron%20Temple")
28-
decoding_response_data = response_redirect.data.decode('UTF-8')
29-
converted_str = html.unescape(decoding_response_data)
113+
decoding_response_data = response_redirect.data.decode("UTF-8")
114+
converted_str = html.unescape(decoding_response_data)
30115
assert "Places required must be a positive integer" in converted_str
31116

32-
def test_purchasePlaces_input_none(client):
33-
response = client.post("/purchasePlaces", data = {"places":"","competition":"Fall Classic","club":"Iron Temple"})
117+
118+
@pytest.mark.parametrize("temp_competitions_file", ["10"], indirect=True)
119+
def test_purchasePlaces_input_none(client, tmpdir):
120+
response = client.post(
121+
"/purchasePlaces",
122+
data={
123+
"places": "",
124+
"competition": "Fall Classic",
125+
"club": "Iron Temple",
126+
},
127+
)
34128
assert response.status_code == 302
35129
response_redirect = client.get("/book/Fall%20Classic/Iron%20Temple")
36-
decoding_response_data = response_redirect.data.decode('UTF-8')
37-
converted_str = html.unescape(decoding_response_data)
38-
assert "Places required must be a positive integer" in converted_str
130+
decoding_response_data = response_redirect.data.decode("UTF-8")
131+
converted_str = html.unescape(decoding_response_data)
132+
assert "Places required must be a positive integer" in converted_str
133+
134+
135+
@pytest.mark.parametrize("temp_competitions_file", ["10"], indirect=True)
136+
def test_purchasePlaces_update_number_places(client, tmpdir):
137+
response = client.post(
138+
"/purchasePlaces",
139+
data={
140+
"places": 1,
141+
"competition": "Fall Classic",
142+
"club": "Iron Temple",
143+
},
144+
)
145+
assert response.status_code == 200
146+
assert b"Great-booking complete!" in response.data
147+
# Verify number of places have been updated
148+
with open(app.config["COMPETITIONS_FILE"]) as f:
149+
updated_competitions = json.load(f)["competitions"]
150+
updated_competition = next(
151+
c for c in updated_competitions if c["name"] == "Fall Classic"
152+
)
153+
print("in test updated competition", updated_competition)
154+
assert updated_competition["numberOfPlaces"] == "9"

0 commit comments

Comments
 (0)