Files
team-tryouts/tests/test_admin_panel.py
T
cedrick2711 d18979a3e9
CI - Security, Lint & Tests / validate (push) Failing after 56s
ajout de tests
2026-08-25 15:53:46 -04:00

150 lines
5.0 KiB
Python

"""Admin panel — access control, dashboard rendering, and template integrity.
ADMIN-004. The admin panel at /admin must only be reachable by admins,
must render all expected sections, and must serve static assets correctly.
"""
import pytest
from app.extensions import db
from app.models import User
NON_ADMIN_ROLES = ['player', 'coach', 'manager', 'scout']
ADMIN_MUTATION_ROUTES = [
'/admin/backup/create',
'/admin/toggle-tryouts',
'/admin/season/start',
'/admin/season/end',
'/admin/teams/wipe',
]
def _redirected(response):
return response.status_code in (301, 302)
# ---------------------------------------------------------------------------
# Access control
# ---------------------------------------------------------------------------
class TestAdminAccessControl:
@pytest.mark.parametrize('role', NON_ADMIN_ROLES)
def test_non_admin_is_redirected_from_dashboard(self, client, as_role, role):
as_role(role)
response = client.get('/admin', follow_redirects=False)
assert _redirected(response), f'{role} reached /admin'
def test_admin_reaches_dashboard(self, client, as_role):
as_role('admin')
response = client.get('/admin')
assert response.status_code == 200
@pytest.mark.parametrize('route', ADMIN_MUTATION_ROUTES)
@pytest.mark.parametrize('role', NON_ADMIN_ROLES)
def test_non_admin_cannot_post_to_admin_routes(self, client, as_role, role, route):
as_role(role)
response = client.post(route, data={}, follow_redirects=False)
assert _redirected(response), f'{role} reached {route}'
# ---------------------------------------------------------------------------
# Dashboard rendering
# ---------------------------------------------------------------------------
class TestAdminDashboardRendering:
def test_dashboard_shows_stats(self, client, as_role):
as_role('admin')
response = client.get('/admin')
html = response.data.decode()
assert 'Total Users' in html
assert 'Players' in html
assert 'Org Teams' in html
assert 'Active Tryouts' in html
def test_dashboard_shows_tryout_status(self, client, as_role):
as_role('admin')
response = client.get('/admin')
html = response.data.decode()
# Either OPEN or CLOSED badge must be present
assert 'OPEN' in html or 'CLOSED' in html
def test_dashboard_shows_season_info(self, client, as_role):
as_role('admin')
response = client.get('/admin')
html = response.data.decode()
assert 'Season Management' in html
assert 'Name:' in html
def test_dashboard_shows_audit_log_section(self, client, as_role):
as_role('admin')
response = client.get('/admin')
html = response.data.decode()
assert 'Audit Log' in html
def test_dashboard_shows_backup_section(self, client, as_role):
as_role('admin')
response = client.get('/admin')
html = response.data.decode()
assert 'Manual Backup' in html
assert 'Backup History' in html
# ---------------------------------------------------------------------------
# Template integrity
# ---------------------------------------------------------------------------
class TestAdminTemplateIntegrity:
def test_page_returns_200(self, client, as_role):
as_role('admin')
response = client.get('/admin')
assert response.status_code == 200
def test_page_has_html_doctype(self, client, as_role):
as_role('admin')
response = client.get('/admin')
html = response.data.decode()
assert '<!DOCTYPE html>' in html or '<!doctype html>' in html.lower()
def test_all_buttons_are_present(self, client, as_role):
as_role('admin')
response = client.get('/admin')
html = response.data.decode()
# Key buttons that must exist
assert 'Create Backup Now' in html
assert 'Wipe Team Rosters' in html
# Toggle button text depends on state
assert 'Tryouts' in html or 'tryouts' in html.lower()
def test_all_forms_have_csrf_tokens(self, client, as_role):
as_role('admin')
response = client.get('/admin')
html = response.data.decode()
# Count <form> tags and csrf_token occurrences
form_count = html.count('<form ')
csrf_count = html.count('csrf_token')
assert form_count > 0, 'No forms found on admin page'
assert csrf_count >= form_count, (
f'Found {form_count} forms but only {csrf_count} csrf_token(s)'
)
def test_static_css_loads(self, client):
response = client.get('/static/css/style.css')
assert response.status_code == 200
assert 'text/css' in response.content_type
def test_static_js_loads(self, client):
response = client.get('/static/js/main.js')
assert response.status_code == 200
assert 'javascript' in response.content_type or 'text/' in response.content_type