import json from tests.helpers import auth_headers, client, create_pending_order from app.core.config import get_settings from app.services.payments.gateway import MockPaymentGateway, get_payment_gateway def _pay_and_get_ticket(): token, checkout = create_pending_order() gateway = get_payment_gateway() assert isinstance(gateway, MockPaymentGateway) payment = checkout["payment"] payment_id = f"mock_pay_{checkout['id']}" signature = gateway.build_mock_checkout_signature(payment["provider_order_id"], payment_id) client.post( f"/api/orders/{checkout['id']}/payment/verify", headers=auth_headers(token), json={ "provider_order_id": payment["provider_order_id"], "provider_payment_id": payment_id, "signature": signature, }, ) tickets = client.get("/api/tickets/my", headers=auth_headers(token)).json() ticket_id = tickets[0]["id"] return token, ticket_id def test_ticket_detail_includes_qr() -> None: token, ticket_id = _pay_and_get_ticket() response = client.get(f"/api/tickets/{ticket_id}", headers=auth_headers(token)) assert response.status_code == 200 body = response.json() assert body["qr_image_base64"] assert body["event_title"] assert body["venue_name"] assert body["ticket_type_name"] assert body["code"].startswith("DC-") payload = json.loads(body["qr_payload"]) assert payload["token"] == body["qr_token"] def test_verify_marks_ticket_used_and_prevents_reuse() -> None: token, ticket_id = _pay_and_get_ticket() detail = client.get(f"/api/tickets/{ticket_id}", headers=auth_headers(token)).json() qr_token = detail["qr_token"] settings = get_settings() headers = {} if settings.ticket_verify_api_key: headers["X-Check-In-Key"] = settings.ticket_verify_api_key first = client.post("/api/tickets/verify", json={"qr_token": qr_token}, headers=headers) assert first.status_code == 200 assert first.json()["valid"] is True assert first.json()["status"] == "used" second = client.post("/api/tickets/verify", json={"qr_token": qr_token}, headers=headers) assert second.status_code == 200 assert second.json()["valid"] is False assert "already used" in second.json()["message"].lower()