Files
team-tryouts/tests/test_admin_tryout_toggle.py
cedrick2711 e53bc3b80d
CI - Security, Lint & Tests / validate (push) Failing after 25m59s
first cleanup iter
2026-09-09 08:26:47 -04:00

155 lines
5.5 KiB
Python

"""Admin tryout toggle — open/close gate and enforcement on tryout routes.
ADMIN-006. The tryouts_open setting gates every tryout mutation route for
non-admins. Admins always bypass the lock. These tests verify the toggle
itself and the gate on each affected route.
"""
import pytest
from app.models import AppSettings, Tryout
NON_ADMIN_ROLES = ['manager', 'coach']
def _redirected(response):
return response.status_code in (301, 302)
# ---------------------------------------------------------------------------
# Toggle logic
# ---------------------------------------------------------------------------
class TestTryoutToggle:
def test_toggle_from_open_to_closed(self, client, as_role):
as_role('admin')
# Default is open
client.post('/admin/toggle-tryouts', data={}, follow_redirects=False)
# Now should be closed
with client.application.app_context():
assert not AppSettings.get_bool('tryouts_open', default=True)
def test_toggle_from_closed_to_open(self, client, as_role):
as_role('admin')
# Close first
client.post('/admin/toggle-tryouts', data={}, follow_redirects=False)
# Open again
client.post('/admin/toggle-tryouts', data={}, follow_redirects=False)
with client.application.app_context():
assert AppSettings.get_bool('tryouts_open', default=True)
def test_toggle_creates_audit_log(self, client, as_role):
from app.models import AuditLog
as_role('admin')
client.post('/admin/toggle-tryouts', data={}, follow_redirects=False)
with client.application.app_context():
entry = AuditLog.query.filter_by(action='tryouts_toggled').first()
assert entry is not None
def test_default_is_open(self, app):
with app.app_context():
assert AppSettings.get_bool('tryouts_open', default=True)
# ---------------------------------------------------------------------------
# Gate enforcement on tryout routes
# ---------------------------------------------------------------------------
class TestTryoutGateEnforcement:
@pytest.mark.parametrize('role', NON_ADMIN_ROLES)
def test_non_admin_cannot_create_tryout_when_closed(self, client, as_role, role):
as_role('admin')
client.post('/admin/toggle-tryouts', data={}) # close
as_role(role)
response = client.post(
'/tryouts/create',
data={'title': 'Test', 'game': 'Valorant', 'date': '2026-12-01'},
follow_redirects=True,
)
html = response.data.decode()
assert 'closed' in html.lower() or 'open tryouts' in html.lower()
@pytest.mark.parametrize('role', NON_ADMIN_ROLES)
def test_non_admin_cannot_edit_tryout_when_closed(self, app, client, as_role, make_user, role):
# Create a tryout as admin first
as_role('admin')
client.post(
'/tryouts/create',
data={'title': 'Edit Test', 'game': 'Valorant', 'date': '2026-12-01'},
follow_redirects=False,
)
with app.app_context():
tryout_id = Tryout.query.filter_by(title='Edit Test').first().id
# Close tryouts
client.post('/admin/toggle-tryouts', data={})
# Try to edit as non-admin
as_role(role)
response = client.post(
f'/tryouts/{tryout_id}/edit',
data={'title': 'Hacked', 'game': 'Valorant', 'date': '2026-12-01'},
follow_redirects=True,
)
html = response.data.decode()
assert 'closed' in html.lower() or 'open tryouts' in html.lower()
@pytest.mark.parametrize('role', NON_ADMIN_ROLES)
def test_non_admin_cannot_delete_tryout_when_closed(
self, app, client, as_role, make_user, role
):
as_role('admin')
client.post(
'/tryouts/create',
data={'title': 'Delete Test', 'game': 'Valorant', 'date': '2026-12-01'},
follow_redirects=False,
)
with app.app_context():
tryout_id = Tryout.query.filter_by(title='Delete Test').first().id
client.post('/admin/toggle-tryouts', data={}) # close
as_role(role)
response = client.post(
f'/tryouts/{tryout_id}/delete',
data={},
follow_redirects=True,
)
html = response.data.decode()
assert 'closed' in html.lower() or 'open tryouts' in html.lower()
def test_admin_can_always_create_tryout(self, client, as_role):
as_role('admin')
# Close tryouts
client.post('/admin/toggle-tryouts', data={})
# Admin should still be able to create
response = client.post(
'/tryouts/create',
data={'title': 'Admin Test', 'game': 'Valorant', 'date': '2026-12-01'},
follow_redirects=False,
)
assert _redirected(response) # success redirect, not blocked
def test_admin_can_always_edit_tryout(self, app, client, as_role):
as_role('admin')
client.post(
'/tryouts/create',
data={'title': 'Admin Edit', 'game': 'Valorant', 'date': '2026-12-01'},
follow_redirects=False,
)
with app.app_context():
tryout_id = Tryout.query.filter_by(title='Admin Edit').first().id
client.post('/admin/toggle-tryouts', data={}) # close
response = client.post(
f'/tryouts/{tryout_id}/edit',
data={'title': 'Admin Edited', 'game': 'Valorant', 'date': '2026-12-01'},
follow_redirects=False,
)
assert _redirected(response) # success, not blocked