"""Creating and editing a tryout, through the form (ARCH-005). Same shape as the match routes: ten fields read off `request.form`, two of them checked and the rest believed. - `game` drives the position list and the gamertag fields a registering player is shown. It was accepted as any string, so a typo produced a tryout nobody could be evaluated for; - `max_players` was `int(x) if x else None` — a 500 on 'twelve', and a cheerful -3 otherwise; - `coach_ids` were loaded with `User.id.in_(...)` and no role filter, so a hand-made submission could name a player as coach of a tryout, which is a permission grant. """ from datetime import date import pytest from app.extensions import db from app.models import OrgTeam, Tryout @pytest.fixture def form_context(app, as_role, make_user): admin_id = as_role('admin') coach_id = make_user('coach') player_id = make_user('player') with app.app_context(): org_team = OrgTeam(name='Varsity', created_by=admin_id) db.session.add(org_team) db.session.commit() return {'org_team_id': org_team.id, 'coach_id': coach_id, 'player_id': player_id} VALID = { 'title': 'Spring tryout', 'game': 'Valorant', 'date': '2030-04-01', 'end_date': '2030-04-03', 'location': 'Arena', 'max_players': '12', } def _create(client, **overrides): return client.post('/tryouts/create', data=dict(VALID, **overrides), follow_redirects=True) def _only_tryout(app): with app.app_context(): return Tryout.query.one_or_none() class TestCreating: def test_a_valid_tryout_is_stored_with_typed_values(self, app, client, form_context): _create(client) tryout = _only_tryout(app) assert tryout is not None assert tryout.date == date(2030, 4, 1) assert tryout.end_date == date(2030, 4, 3) assert tryout.max_players == 12 def test_no_end_date_is_allowed(self, app, client, form_context): _create(client, end_date='') assert _only_tryout(app).end_date is None def test_no_player_limit_is_allowed(self, app, client, form_context): _create(client, max_players='') assert _only_tryout(app).max_players is None def test_a_coach_can_be_attached(self, app, client, form_context): _create(client, coach_ids=str(form_context['coach_id'])) with app.app_context(): tryout = Tryout.query.one() assert [c.id for c in tryout.coaches] == [form_context['coach_id']] class TestRefusals: def test_an_unknown_game_is_refused(self, app, client, form_context): _create(client, game='Pong') assert _only_tryout(app) is None def test_an_empty_title_is_refused(self, app, client, form_context): _create(client, title='') assert _only_tryout(app) is None def test_a_non_numeric_player_limit_is_refused_not_crashed(self, app, client, form_context): response = _create(client, max_players='twelve') assert response.status_code == 200 assert _only_tryout(app) is None def test_a_negative_player_limit_is_refused(self, app, client, form_context): _create(client, max_players='-3') assert _only_tryout(app) is None def test_an_end_before_the_start_is_refused(self, app, client, form_context): _create(client, date='2030-04-05', end_date='2030-04-01') assert _only_tryout(app) is None def test_a_player_cannot_be_slipped_in_as_a_coach(self, app, client, form_context): """Not a form the interface offers — the select lists coaches. It is a hand-made submission, and it used to work: being a coach of a tryout carries the right to manage it and evaluate its players.""" _create(client, coach_ids=str(form_context['player_id'])) with app.app_context(): tryout = Tryout.query.one() assert list(tryout.coaches) == []