Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ lib
.Python
tests/
.envrc
__pycache__
__pycache__
htmlcov/
.coverage

502 changes: 502 additions & 0 deletions .venv/Scripts/Activate.ps1

Large diffs are not rendered by default.

70 changes: 70 additions & 0 deletions .venv/Scripts/activate
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# This file must be used with "source bin/activate" *from bash*
# You cannot run it directly

deactivate () {
# reset old environment variables
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
PATH="${_OLD_VIRTUAL_PATH:-}"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi

# Call hash to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
hash -r 2> /dev/null

if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
PS1="${_OLD_VIRTUAL_PS1:-}"
export PS1
unset _OLD_VIRTUAL_PS1
fi

unset VIRTUAL_ENV
unset VIRTUAL_ENV_PROMPT
if [ ! "${1:-}" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}

# unset irrelevant variables
deactivate nondestructive

# on Windows, a path can contain colons and backslashes and has to be converted:
if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then
# transform D:\path\to\venv to /d/path/to/venv on MSYS
# and to /cygdrive/d/path/to/venv on Cygwin
export VIRTUAL_ENV=$(cygpath "C:\Users\Lénovo P70\Desktop\projet 11\Python_Testing\.venv")
else
# use the path as-is
export VIRTUAL_ENV="C:\Users\Lénovo P70\Desktop\projet 11\Python_Testing\.venv"
fi

_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/Scripts:$PATH"
export PATH

# unset PYTHONHOME if set
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
# could use `if (set -u; : $PYTHONHOME) ;` in bash
if [ -n "${PYTHONHOME:-}" ] ; then
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
unset PYTHONHOME
fi

if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
_OLD_VIRTUAL_PS1="${PS1:-}"
PS1="(.venv) ${PS1:-}"
export PS1
VIRTUAL_ENV_PROMPT="(.venv) "
export VIRTUAL_ENV_PROMPT
fi

# Call hash to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
hash -r 2> /dev/null
34 changes: 34 additions & 0 deletions .venv/Scripts/activate.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@echo off

rem This file is UTF-8 encoded, so we need to update the current code page while executing it
for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do (
set _OLD_CODEPAGE=%%a
)
if defined _OLD_CODEPAGE (
"%SystemRoot%\System32\chcp.com" 65001 > nul
)

set VIRTUAL_ENV=C:\Users\Lénovo P70\Desktop\projet 11\Python_Testing\.venv

if not defined PROMPT set PROMPT=$P$G

if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT%
if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%

set _OLD_VIRTUAL_PROMPT=%PROMPT%
set PROMPT=(.venv) %PROMPT%

if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%
set PYTHONHOME=

if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%
if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH%

set PATH=%VIRTUAL_ENV%\Scripts;%PATH%
set VIRTUAL_ENV_PROMPT=(.venv)

:END
if defined _OLD_CODEPAGE (
"%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul
set _OLD_CODEPAGE=
)
Binary file added .venv/Scripts/coverage-3.12.exe
Binary file not shown.
Binary file added .venv/Scripts/coverage.exe
Binary file not shown.
Binary file added .venv/Scripts/coverage3.exe
Binary file not shown.
22 changes: 22 additions & 0 deletions .venv/Scripts/deactivate.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@echo off

if defined _OLD_VIRTUAL_PROMPT (
set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
)
set _OLD_VIRTUAL_PROMPT=

if defined _OLD_VIRTUAL_PYTHONHOME (
set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%"
set _OLD_VIRTUAL_PYTHONHOME=
)

if defined _OLD_VIRTUAL_PATH (
set "PATH=%_OLD_VIRTUAL_PATH%"
)

set _OLD_VIRTUAL_PATH=

set VIRTUAL_ENV=
set VIRTUAL_ENV_PROMPT=

:END
Binary file added .venv/Scripts/flask.exe
Binary file not shown.
Binary file added .venv/Scripts/pip.exe
Binary file not shown.
Binary file added .venv/Scripts/pip3.12.exe
Binary file not shown.
Binary file added .venv/Scripts/pip3.exe
Binary file not shown.
Binary file added .venv/Scripts/py.test.exe
Binary file not shown.
Binary file added .venv/Scripts/pygmentize.exe
Binary file not shown.
Binary file added .venv/Scripts/pytest.exe
Binary file not shown.
Binary file added .venv/Scripts/python.exe
Binary file not shown.
Binary file added .venv/Scripts/pythonw.exe
Binary file not shown.
5 changes: 5 additions & 0 deletions .venv/pyvenv.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
home = C:\Users\Lénovo P70\AppData\Local\Programs\Python\Python312
include-system-site-packages = false
version = 3.12.6
executable = C:\Users\Lénovo P70\AppData\Local\Programs\Python\Python312\python.exe
command = C:\Users\Lénovo P70\AppData\Local\Programs\Python\Python312\python.exe -m venv C:\Users\Lénovo P70\Desktop\projet 11\Python_Testing\.venv
51 changes: 42 additions & 9 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,15 @@ 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)
# Correction BUG 1 "email"
email = request.form.get('email')
club = next((club for club in clubs if club['email'] == email), None)

if club:
return render_template('welcome.html', club=club, competitions=competitions)
else:
flash("Sorry, that email wasn't found.")
return redirect(url_for('index'))


@app.route('/book/<competition>/<club>')
Expand All @@ -43,15 +50,41 @@ def book(competition,club):

@app.route('/purchasePlaces',methods=['POST'])
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'])
competition['numberOfPlaces'] = int(competition['numberOfPlaces'])-placesRequired
flash('Great-booking complete!')
return render_template('welcome.html', club=club, competitions=competitions)


# TODO: Add route for points display
try:
# Récupération données
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_places = int(competition['numberOfPlaces'])
club_points = int(club['points'])

# Correction BUG 4: Limite de 12 places par club
if placesRequired > 12:
flash("Error: You cannot book more than 12 places per competition.")
return render_template('welcome.html', club=club, competitions=competitions), 400

# Correction BUG 5 : Vérification des points du club
if placesRequired > club_points:
flash("Your club doesn't have enough points.")
return render_template('welcome.html', club=club, competitions=competitions), 400

# Correction BUG 3: Mise à jour des points du club
competition['numberOfPlaces'] = competition_places - placesRequired
club['points'] = club_points - placesRequired

flash('Great-booking complete!')
return render_template('welcome.html', club=club, competitions=competitions)
except Exception as e:
flash(str(e))
return redirect(url_for('index')), 400

# Correction BUG 2: Tableau d'affichage des points
@app.route('/pointsDisplay')
def pointsDisplay():
return render_template('points_display.html', clubs=clubs)


@app.route('/logout')
Expand Down
16 changes: 13 additions & 3 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,19 @@
<body>
<h1>Welcome to the GUDLFT Registration Portal!</h1>
Please enter your secretary email to continue:
<form action="showSummary" method="post">
<label for="email">Email:</label>
<input type="email" name="email" id=""/>

{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li style="color:red;">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<form action="{{ url_for('showSummary') }}" method="post">
<label>Email:</label>
<input type="email" name="email" id="email" required />
<button type="submit">Enter</button>
</form>
</body>
Expand Down
27 changes: 27 additions & 0 deletions templates/points_display.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Clubs Points | GUDLFT</title>
</head>
<body>
<h1>Clubs Points</h1>
<a href="{{url_for('index')}}">Back to login</a>
<table>
<thead>
<tr>
<th>Club</th>
<th>Points</th>
</tr>
</thead>
<tbody>
{% for club in clubs %}
<tr>
<td>{{ club['name'] }}</td>
<td>{{ club['points'] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
49 changes: 49 additions & 0 deletions tests/integration/test_insufficient_points_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import pytest
from server import app, clubs, competitions

@pytest.fixture
def client():
app.config['TESTING'] = True
with app.test_client() as client:
yield client

def test_points_update_insufficient_points(client):
"""Test intégration complet - points non déduits quand réservation impossible"""
# 1. Setup - données de test
TEST_CLUB = "Iron Temple" # Doit avoir 4 points dans clubs.json
TEST_COMPETITION = "Spring Festival"
PLACES_REQUIRED = 5 # > points disponibles

# 2. Pré-test - vérification données
club = next(c for c in clubs if c['name'] == TEST_CLUB)
initial_points = int(club['points'])
assert initial_points < PLACES_REQUIRED, "Configuration incorrecte pour le test"

# 3. Execution - 2 requêtes simulées
# a. Login (si nécessaire)
client.post('/showSummary', data={'email': '[email protected]'})

# b. Tentative réservation
response = client.post('/purchasePlaces',
data={
'competition': TEST_COMPETITION,
'club': TEST_CLUB,
'places': str(PLACES_REQUIRED)
},
follow_redirects=True)

# 4. Vérifications
# a. Message d'erreur
assert b"Your club doesn't have enough points" in response.data or \
b"doesn&#39;t have enough points" in response.data

# b. Code statut (200 car follow_redirects=True)
assert response.status_code == 400

# c. Points inchangés
updated_club = next(c for c in clubs if c['name'] == TEST_CLUB)
assert int(updated_club['points']) == initial_points, \
f"Points modifiés incorrectement (avant: {initial_points}, après: {updated_club['points']})"
25 changes: 25 additions & 0 deletions tests/unit/test_email_login.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import pytest
from server import app

@pytest.fixture
def client():
app.config['TESTING'] = True
with app.test_client() as client:
yield client

def test_login_with_valid_email(client):
response = client.post('/showSummary',
data={'email': '[email protected]'},
follow_redirects=True)
assert response.status_code == 200
assert b'Welcome' in response.data

def test_login_with_invalid_email(client):
response = client.post('/showSummary',
data={'email': '[email protected]'},
follow_redirects=True)
assert response.status_code == 200
assert b"Sorry, that email wasn&#39;t found." in response.data
28 changes: 28 additions & 0 deletions tests/unit/test_insufficient_points.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import pytest
from server import app, clubs, competitions


@pytest.fixture
def client():
app.config['TESTING'] = True
with app.test_client() as client:
yield client


def test_insufficient_points(client):
"""Test simplifié pour points insuffisants"""
club_name = "Iron Temple" # 4 points
initial_points = int(next(c['points'] for c in clubs if c['name'] == club_name))

response = client.post('/purchasePlaces', data={
'competition': 'Spring Festival',
'club': club_name,
'places': '5' # Plus que les 4 points disponibles
}, follow_redirects=True)

# Vérifications essentielles seulement
assert b"points" in response.data or b"Error" in response.data
assert int(next(c['points'] for c in clubs if c['name'] == club_name)) == initial_points
Loading