from app.models.arrival import Arrival from app.models.departure import Departure from app.models.local_flight import LocalFlight from app.models.movement import Movement, MovementType def enable_public_booking(monkeypatch, enabled=True): monkeypatch.setattr("app.api.endpoints.public_book.settings.allow_public_booking", enabled) def test_public_booking_rejects_requests_when_disabled(client, monkeypatch): enable_public_booking(monkeypatch, enabled=False) response = client.post( "/api/v1/public-book/local-flights", json={ "registration": "G-PUB1", "pob": 1, "flight_type": "LOCAL", }, ) assert response.status_code == 403 assert response.json()["detail"] == "Public booking is currently disabled" def test_public_booking_creates_local_flight_and_circuit(client, db, monkeypatch): enable_public_booking(monkeypatch) flight_response = client.post( "/api/v1/public-book/local-flights", json={ "registration": "g-pub1", "type": "C152", "callsign": "GPUB1", "pob": 1, "flight_type": "LOCAL", "duration": 30, "etd": "2026-06-20T10:00:00", "notes": "Public local", "pilot_email": " PILOT@EXAMPLE.COM ", }, ) assert flight_response.status_code == 200 flight = flight_response.json() assert flight["registration"] == "G-PUB1" assert flight["status"] == "BOOKED_OUT" assert flight["submitted_via"] == "PUBLIC" assert flight["pilot_email"] == "pilot@example.com" circuit_response = client.post( "/api/v1/public-book/circuits", json={ "local_flight_id": flight["id"], "circuit_timestamp": "2026-06-20T10:15:00", "pilot_email": "", }, ) assert circuit_response.status_code == 200 assert circuit_response.json()["local_flight_id"] == flight["id"] db_flight = db.query(LocalFlight).filter(LocalFlight.id == flight["id"]).one() assert db_flight.created_by == "PUBLIC_PILOT" movement = db.query(Movement).filter(Movement.entity_type == "LOCAL_FLIGHT").one() assert movement.movement_type == MovementType.TOUCH_AND_GO def test_public_booking_creates_departure_and_arrival(client, db, monkeypatch): enable_public_booking(monkeypatch) departure_response = client.post( "/api/v1/public-book/departures", json={ "registration": "g-pub2", "type": "PA28", "callsign": "GPUB2", "pob": 2, "out_to": "egkk", "etd": "2026-06-20T11:00:00", "notes": "Public departure", "pilot_email": "depart@example.com", }, ) arrival_response = client.post( "/api/v1/public-book/arrivals", json={ "registration": "g-pub3", "type": "DA40", "callsign": "GPUB3", "pob": 3, "in_from": "egll", "eta": "2026-06-20T12:00:00", "notes": "Public arrival", "pilot_email": "arrive@example.com", }, ) assert departure_response.status_code == 200 departure = departure_response.json() assert departure["registration"] == "G-PUB2" assert departure["status"] == "BOOKED_OUT" assert departure["submitted_via"] == "PUBLIC" assert departure["pilot_email"] == "depart@example.com" assert arrival_response.status_code == 200 arrival = arrival_response.json() assert arrival["registration"] == "G-PUB3" assert arrival["status"] == "BOOKED_IN" assert arrival["submitted_via"] == "PUBLIC" assert arrival["pilot_email"] == "arrive@example.com" db_departure = db.query(Departure).filter(Departure.id == departure["id"]).one() db_arrival = db.query(Arrival).filter(Arrival.id == arrival["id"]).one() assert db_departure.created_by == "PUBLIC_PILOT" assert db_arrival.created_by == "PUBLIC_PILOT" def test_public_booking_validates_payloads(client, monkeypatch): enable_public_booking(monkeypatch) local_response = client.post( "/api/v1/public-book/local-flights", json={"registration": "", "pob": 0, "flight_type": "LOCAL"}, ) departure_response = client.post( "/api/v1/public-book/departures", json={"registration": "G-BAD", "pob": 0, "out_to": ""}, ) arrival_response = client.post( "/api/v1/public-book/arrivals", json={"registration": "G-BAD", "pob": 0, "in_from": ""}, ) assert local_response.status_code == 422 assert departure_response.status_code == 422 assert arrival_response.status_code == 422