style: formater le depot avec ruff format
QUA-002, premiere moitie. **Ce commit ne fait que reformater** : aucun changement de comportement, aucune ligne de logique touchee. 72 fichiers, 4 restaient deja conformes. Il est isole exprès, pour que `git log -p` sur les commits voisins reste lisible. `quote-style = "preserve"` etait deja pose dans pyproject.toml, ce qui evite le brassage guillemets simples / doubles : le diff porte sur les retours a la ligne, l indentation des appels longs et les virgules finales, pas sur le style de chaine. Verification : 263 tests passent avant et apres, ruff check propre. L activation en CI arrive dans le commit suivant, separement, pour que ce diff-ci ne contienne rien d autre. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
+103
-66
@@ -61,9 +61,7 @@ class TestVerticalAccess:
|
||||
def test_only_admin_reaches_user_management(self, client, as_role, role, route):
|
||||
as_role(role)
|
||||
response = client.get(route, follow_redirects=False)
|
||||
assert _redirected(response), (
|
||||
f'{role} reached {route}, which is meant to be admin-only'
|
||||
)
|
||||
assert _redirected(response), f'{role} reached {route}, which is meant to be admin-only'
|
||||
|
||||
def test_admin_reaches_user_management(self, client, as_role):
|
||||
as_role('admin')
|
||||
@@ -106,8 +104,10 @@ class TestHorizontalAccess:
|
||||
owner_id = make_user('player')
|
||||
with app.app_context():
|
||||
slot = PlayerDisponibility(
|
||||
player_id=owner_id, day_of_week=1,
|
||||
start_time=time(10, 0), end_time=time(10, 30),
|
||||
player_id=owner_id,
|
||||
day_of_week=1,
|
||||
start_time=time(10, 0),
|
||||
end_time=time(10, 30),
|
||||
)
|
||||
db.session.add(slot)
|
||||
db.session.commit()
|
||||
@@ -134,8 +134,11 @@ class TestNestedResourceOwnership:
|
||||
|
||||
with app.app_context():
|
||||
tryout = Tryout(
|
||||
title=title, game='Valorant', date=date(2030, 1, 1),
|
||||
created_by=owner_id, status='upcoming',
|
||||
title=title,
|
||||
game='Valorant',
|
||||
date=date(2030, 1, 1),
|
||||
created_by=owner_id,
|
||||
status='upcoming',
|
||||
)
|
||||
db.session.add(tryout)
|
||||
db.session.flush()
|
||||
@@ -144,9 +147,7 @@ class TestNestedResourceOwnership:
|
||||
db.session.commit()
|
||||
return tryout.id, team.id
|
||||
|
||||
def test_cannot_add_a_player_to_a_team_of_another_tryout(
|
||||
self, app, client, as_role, make_user
|
||||
):
|
||||
def test_cannot_add_a_player_to_a_team_of_another_tryout(self, app, client, as_role, make_user):
|
||||
from app.models import TeamMember, TryoutRegistration
|
||||
|
||||
other_admin = make_user('admin')
|
||||
@@ -157,8 +158,7 @@ class TestNestedResourceOwnership:
|
||||
|
||||
player_id = make_user('player')
|
||||
with app.app_context():
|
||||
db.session.add(TryoutRegistration(
|
||||
tryout_id=own_tryout_id, player_id=player_id))
|
||||
db.session.add(TryoutRegistration(tryout_id=own_tryout_id, player_id=player_id))
|
||||
db.session.commit()
|
||||
|
||||
response = client.post(
|
||||
@@ -167,15 +167,11 @@ class TestNestedResourceOwnership:
|
||||
follow_redirects=False,
|
||||
)
|
||||
|
||||
assert response.status_code == 404, (
|
||||
'a team belonging to another tryout was accepted'
|
||||
)
|
||||
assert response.status_code == 404, 'a team belonging to another tryout was accepted'
|
||||
with app.app_context():
|
||||
assert TeamMember.query.filter_by(team_id=foreign_team_id).count() == 0
|
||||
|
||||
def test_cannot_add_a_player_who_is_not_registered(
|
||||
self, app, client, as_role, make_user
|
||||
):
|
||||
def test_cannot_add_a_player_who_is_not_registered(self, app, client, as_role, make_user):
|
||||
from app.models import TeamMember
|
||||
|
||||
manager_id = as_role('manager')
|
||||
@@ -191,9 +187,7 @@ class TestNestedResourceOwnership:
|
||||
with app.app_context():
|
||||
assert TeamMember.query.filter_by(team_id=team_id).count() == 0
|
||||
|
||||
def test_a_registered_player_can_still_be_added(
|
||||
self, app, client, as_role, make_user
|
||||
):
|
||||
def test_a_registered_player_can_still_be_added(self, app, client, as_role, make_user):
|
||||
"""Guard against over-correcting: the normal path must keep working."""
|
||||
from app.models import TeamMember, TryoutRegistration
|
||||
|
||||
@@ -243,11 +237,15 @@ class TestInputValidation:
|
||||
user_id = as_role('player')
|
||||
payload = '<img src=x onerror=alert(1)>'
|
||||
|
||||
client.post('/users/profile/edit', data={
|
||||
'username': payload,
|
||||
'full_name': 'Legit Name',
|
||||
'email': '[email protected]',
|
||||
}, follow_redirects=True)
|
||||
client.post(
|
||||
'/users/profile/edit',
|
||||
data={
|
||||
'username': payload,
|
||||
'full_name': 'Legit Name',
|
||||
'email': '[email protected]',
|
||||
},
|
||||
follow_redirects=True,
|
||||
)
|
||||
|
||||
with app.app_context():
|
||||
assert db.session.get(User, user_id).username != payload
|
||||
@@ -257,12 +255,16 @@ class TestInputValidation:
|
||||
with app.app_context():
|
||||
before = db.session.get(User, user_id).password_hash
|
||||
|
||||
client.post('/users/profile/edit', data={
|
||||
'username': _username(app, user_id),
|
||||
'full_name': 'Legit Name',
|
||||
'email': '[email protected]',
|
||||
'password': 'a',
|
||||
}, follow_redirects=True)
|
||||
client.post(
|
||||
'/users/profile/edit',
|
||||
data={
|
||||
'username': _username(app, user_id),
|
||||
'full_name': 'Legit Name',
|
||||
'email': '[email protected]',
|
||||
'password': 'a',
|
||||
},
|
||||
follow_redirects=True,
|
||||
)
|
||||
|
||||
with app.app_context():
|
||||
assert db.session.get(User, user_id).password_hash == before, (
|
||||
@@ -272,13 +274,17 @@ class TestInputValidation:
|
||||
def test_create_user_enforces_the_password_policy(self, app, client, as_role):
|
||||
as_role('admin')
|
||||
|
||||
client.post('/users/create', data={
|
||||
'username': 'weakling',
|
||||
'email': '[email protected]',
|
||||
'password': 'a',
|
||||
'full_name': 'Weak Account',
|
||||
'role': 'admin',
|
||||
}, follow_redirects=True)
|
||||
client.post(
|
||||
'/users/create',
|
||||
data={
|
||||
'username': 'weakling',
|
||||
'email': 'weak@example.test',
|
||||
'password': 'a',
|
||||
'full_name': 'Weak Account',
|
||||
'role': 'admin',
|
||||
},
|
||||
follow_redirects=True,
|
||||
)
|
||||
|
||||
with app.app_context():
|
||||
created = User.query.filter_by(username='weakling').first()
|
||||
@@ -292,11 +298,15 @@ class TestInputValidation:
|
||||
with app.app_context():
|
||||
taken = db.session.get(User, other_id).email
|
||||
|
||||
response = client.post(f'/users/{target_id}/edit', data={
|
||||
'full_name': 'Target',
|
||||
'email': taken,
|
||||
'role': 'player',
|
||||
}, follow_redirects=False)
|
||||
response = client.post(
|
||||
f'/users/{target_id}/edit',
|
||||
data={
|
||||
'full_name': 'Target',
|
||||
'email': taken,
|
||||
'role': 'player',
|
||||
},
|
||||
follow_redirects=False,
|
||||
)
|
||||
|
||||
assert response.status_code < 500, 'duplicate email produced a server error'
|
||||
|
||||
@@ -305,18 +315,21 @@ class TestAdminSafety:
|
||||
def test_the_last_admin_cannot_demote_itself(self, app, client, as_role):
|
||||
admin_id = as_role('admin')
|
||||
|
||||
client.post(f'/users/{admin_id}/edit', data={
|
||||
'full_name': 'Admin',
|
||||
'email': '[email protected]',
|
||||
'role': 'player',
|
||||
}, follow_redirects=True)
|
||||
client.post(
|
||||
f'/users/{admin_id}/edit',
|
||||
data={
|
||||
'full_name': 'Admin',
|
||||
'email': '[email protected]',
|
||||
'role': 'player',
|
||||
},
|
||||
follow_redirects=True,
|
||||
)
|
||||
|
||||
with app.app_context():
|
||||
assert db.session.get(User, admin_id).role == 'admin', (
|
||||
'the only administrator demoted itself; no interface can undo this'
|
||||
)
|
||||
|
||||
|
||||
def test_an_admin_cannot_change_its_own_role_even_with_others_present(
|
||||
self, app, client, as_role, make_user
|
||||
):
|
||||
@@ -324,9 +337,15 @@ class TestAdminSafety:
|
||||
make_user('admin')
|
||||
admin_id = as_role('admin')
|
||||
|
||||
client.post(f'/users/{admin_id}/edit', data={
|
||||
'full_name': 'Admin', 'email': '[email protected]', 'role': 'player',
|
||||
}, follow_redirects=True)
|
||||
client.post(
|
||||
f'/users/{admin_id}/edit',
|
||||
data={
|
||||
'full_name': 'Admin',
|
||||
'email': '[email protected]',
|
||||
'role': 'player',
|
||||
},
|
||||
follow_redirects=True,
|
||||
)
|
||||
|
||||
with app.app_context():
|
||||
assert db.session.get(User, admin_id).role == 'admin'
|
||||
@@ -336,10 +355,16 @@ class TestAdminSafety:
|
||||
other_id = make_user('admin')
|
||||
as_role('admin')
|
||||
|
||||
client.post(f'/users/{other_id}/edit', data={
|
||||
'full_name': 'Other', 'email': '[email protected]t',
|
||||
'role': 'coach', 'is_active_account': 'on',
|
||||
}, follow_redirects=True)
|
||||
client.post(
|
||||
f'/users/{other_id}/edit',
|
||||
data={
|
||||
'full_name': 'Other',
|
||||
'email': '[email protected]',
|
||||
'role': 'coach',
|
||||
'is_active_account': 'on',
|
||||
},
|
||||
follow_redirects=True,
|
||||
)
|
||||
|
||||
with app.app_context():
|
||||
assert db.session.get(User, other_id).role == 'coach'
|
||||
@@ -350,11 +375,16 @@ class TestCsrf:
|
||||
"""CSRFProtect is global. This pins that down so a future
|
||||
@csrf.exempt cannot slip in unnoticed."""
|
||||
client = app_with_csrf.test_client()
|
||||
response = client.post('/auth/login', data={
|
||||
'username': 'someone', 'password': 'Password123',
|
||||
})
|
||||
response = client.post(
|
||||
'/auth/login',
|
||||
data={
|
||||
'username': 'someone',
|
||||
'password': 'Password123',
|
||||
},
|
||||
)
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
class TestCorsPolicy:
|
||||
"""SEC-WEB-003 — with no origins configured, flask-cors defaulted to '*'
|
||||
and, credentials being allowed, echoed back the caller's Origin."""
|
||||
@@ -367,12 +397,19 @@ class TestCorsPolicy:
|
||||
def test_configured_origins_are_still_honoured(self, app_with_csrf):
|
||||
from app.app import create_app
|
||||
|
||||
application = create_app({
|
||||
'SECRET_KEY': 'test', 'SQLALCHEMY_DATABASE_URI': 'sqlite:///:memory:',
|
||||
'TESTING': True, 'FORCE_HTTPS': False, 'ENABLE_DISCORD_BOT': False,
|
||||
'AUTO_CREATE_TABLES': False, 'CORS_ALLOWED_ORIGINS': 'https://trusted.test',
|
||||
})
|
||||
application = create_app(
|
||||
{
|
||||
'SECRET_KEY': 'test',
|
||||
'SQLALCHEMY_DATABASE_URI': 'sqlite:///:memory:',
|
||||
'TESTING': True,
|
||||
'FORCE_HTTPS': False,
|
||||
'ENABLE_DISCORD_BOT': False,
|
||||
'AUTO_CREATE_TABLES': False,
|
||||
'CORS_ALLOWED_ORIGINS': 'https://trusted.test',
|
||||
}
|
||||
)
|
||||
response = application.test_client().get(
|
||||
'/auth/login', headers={'Origin': 'https://trusted.test'})
|
||||
'/auth/login', headers={'Origin': 'https://trusted.test'}
|
||||
)
|
||||
|
||||
assert response.headers.get('Access-Control-Allow-Origin') == 'https://trusted.test'
|
||||
|
||||
Reference in New Issue
Block a user