251 lines
7.8 KiB
Python
251 lines
7.8 KiB
Python
import os
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
import aiohttp
|
|
import pendulum
|
|
import pytest
|
|
from connectors import GestionSportsConnector
|
|
from models import BookingFilter, Club
|
|
from pendulum import DateTime
|
|
from yarl import URL
|
|
|
|
|
|
def retrieve_booking_datetime(
|
|
a_booking_filter: BookingFilter, a_club: Club
|
|
) -> DateTime:
|
|
"""
|
|
Utility to retrieve the booking datetime from the booking filter and the club
|
|
|
|
:param a_booking_filter: the booking filter that contains the date to book
|
|
:param a_club: the club which has the number of days before the date and the booking time
|
|
"""
|
|
booking_opening = a_club.booking_platform.booking_opening
|
|
opening_time = pendulum.parse(booking_opening.opening_time)
|
|
booking_hour = opening_time.hour
|
|
booking_minute = opening_time.minute
|
|
|
|
date_to_book = a_booking_filter.date
|
|
return date_to_book.subtract(days=booking_opening.days_before).at(
|
|
booking_hour, booking_minute
|
|
)
|
|
|
|
|
|
@patch.dict(
|
|
os.environ,
|
|
{"CLUB_ID": "tpc"},
|
|
clear=True,
|
|
)
|
|
def test_urls(connector):
|
|
assert (
|
|
connector.landing_url
|
|
== "https://toulousepadelclub.gestion-sports.com/connexion.php"
|
|
)
|
|
assert (
|
|
connector.login_url
|
|
== "https://toulousepadelclub.gestion-sports.com/connexion.php"
|
|
)
|
|
assert (
|
|
connector.booking_url
|
|
== "https://toulousepadelclub.gestion-sports.com/membre/reservation.html"
|
|
)
|
|
assert (
|
|
connector.user_bookings_url
|
|
== "https://toulousepadelclub.gestion-sports.com/membre/mesresas.html"
|
|
)
|
|
assert (
|
|
connector.booking_cancellation_url
|
|
== "https://toulousepadelclub.gestion-sports.com/membre/mesresas.html"
|
|
)
|
|
|
|
|
|
@patch.dict(
|
|
os.environ,
|
|
{"RESOURCES_FOLDER": "/some/path"},
|
|
clear=True,
|
|
)
|
|
def test_urls_payload_templates(connector):
|
|
resources_folder = Path("/some", "path", "gestion-sports")
|
|
assert connector.login_template == resources_folder / "login-payload.txt"
|
|
assert connector.booking_template == resources_folder / "booking-payload.txt"
|
|
assert (
|
|
connector.user_bookings_template
|
|
== resources_folder / "user-bookings-payload.txt"
|
|
)
|
|
assert (
|
|
connector.booking_cancel_template
|
|
== resources_folder / "booking-cancellation-payload.txt"
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_landing_page(connector):
|
|
async with aiohttp.ClientSession() as session:
|
|
response = await connector.land(session)
|
|
|
|
assert response.status == 200
|
|
assert response.request_info.method == "GET"
|
|
assert response.content_type == "text/html"
|
|
assert response.request_info.url == URL(connector.landing_url)
|
|
assert response.charset == "UTF-8"
|
|
assert response.cookies.get("PHPSESSID") is not None
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_login(connector, user):
|
|
async with aiohttp.ClientSession() as session:
|
|
await connector.land(session)
|
|
|
|
response = await connector.login(session, user)
|
|
|
|
assert response.status == 200
|
|
assert response.request_info.method == "POST"
|
|
assert response.content_type == "text/html"
|
|
assert response.request_info.url == URL(connector.landing_url)
|
|
assert response.charset == "UTF-8"
|
|
assert response.cookies.get("COOK_COMPTE") is not None
|
|
assert response.cookies.get("COOK_ID_CLUB").value == "88"
|
|
assert response.cookies.get("COOK_ID_USER").value == "232382"
|
|
|
|
|
|
def test_get_booked_court(
|
|
connector, booking_success_response, booking_failure_response
|
|
):
|
|
bookings = [
|
|
(601, booking_failure_response),
|
|
(602, booking_failure_response),
|
|
(603, booking_failure_response),
|
|
(614, booking_failure_response),
|
|
(605, booking_failure_response),
|
|
(606, booking_success_response),
|
|
(607, booking_failure_response),
|
|
(608, booking_failure_response),
|
|
]
|
|
|
|
court = connector.get_booked_court(bookings, "padel")
|
|
assert court.number == 9
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_book_one_court(connector, user, booking_filter):
|
|
async with aiohttp.ClientSession() as session:
|
|
await connector.land(session)
|
|
await connector.login(session, user)
|
|
|
|
court_id, response = await connector.send_booking_request(
|
|
session, pendulum.parse("2024-03-21T13:30:00+01:00"), 610, 217
|
|
)
|
|
|
|
assert court_id == 610
|
|
assert response.get("status") == "ok"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_book(connector, user, booking_filter):
|
|
booked_court = await connector.book(user, booking_filter)
|
|
|
|
assert booked_court is not None
|
|
|
|
|
|
def test_build_booking_datetime(connector, booking_filter):
|
|
opening_datetime = connector.build_booking_datetime(booking_filter)
|
|
assert opening_datetime.year == 2024
|
|
assert opening_datetime.month == 3
|
|
assert opening_datetime.day == 14
|
|
assert opening_datetime.hour == 0
|
|
assert opening_datetime.minute == 0
|
|
|
|
|
|
@patch("pendulum.now")
|
|
def test_wait_until_booking_time(mock_now, connector, booking_filter, club):
|
|
booking_datetime = retrieve_booking_datetime(booking_filter, club)
|
|
|
|
seconds = [
|
|
booking_datetime.subtract(seconds=3),
|
|
booking_datetime.subtract(seconds=2),
|
|
booking_datetime.subtract(seconds=1),
|
|
booking_datetime,
|
|
booking_datetime.add(microseconds=1),
|
|
booking_datetime.add(microseconds=2),
|
|
]
|
|
mock_now.side_effect = seconds
|
|
|
|
connector.wait_until_booking_time(booking_filter)
|
|
|
|
assert pendulum.now() == booking_datetime.add(microseconds=1)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_hash(connector, user):
|
|
async with aiohttp.ClientSession() as session:
|
|
await connector.land(session)
|
|
await connector.login(session, user)
|
|
|
|
hash_value = await connector.send_hash_request(session)
|
|
assert hash_value is not None
|
|
|
|
|
|
def test_get_hash_input():
|
|
resources_folder = Path(__file__).parent / "data"
|
|
html_file = resources_folder / "user_bookings_html_response.html"
|
|
html = html_file.read_text(encoding="utf-8")
|
|
|
|
hash_value = GestionSportsConnector.get_hash_input(html)
|
|
|
|
assert hash_value == "63470fa38e300fd503de1ee21a71b3bdb6fb206b"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_bookings(connector, user):
|
|
async with aiohttp.ClientSession() as session:
|
|
await connector.land(session)
|
|
await connector.login(session, user)
|
|
|
|
hash_value = await connector.send_hash_request(session)
|
|
payload = f"ajax=loadResa&hash={hash_value}"
|
|
|
|
bookings = await connector.send_user_bookings_request(session, payload)
|
|
print(bookings)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_ongoing_bookings(connector, user):
|
|
async with aiohttp.ClientSession() as session:
|
|
await connector.land(session)
|
|
await connector.login(session, user)
|
|
|
|
bookings = await connector.get_ongoing_bookings(session)
|
|
print(bookings)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_has_user_ongoing_bookings(connector, user):
|
|
assert await connector.has_user_ongoing_booking(user)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_cancel_booking_id(connector, user):
|
|
async with aiohttp.ClientSession() as session:
|
|
await connector.land(session)
|
|
await connector.login(session, user)
|
|
ongoing_bookings = await connector.get_ongoing_bookings(session)
|
|
booking_id = ongoing_bookings[0].id
|
|
|
|
response = await connector.cancel_booking_id(user, booking_id)
|
|
|
|
assert len(await connector.get_ongoing_bookings(session)) == 0
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
def test_find_court(connector):
|
|
court = connector.find_court(603, "Padel")
|
|
|
|
assert court.number == 6
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_cancel_booking(connector, user, booking_filter):
|
|
async with aiohttp.ClientSession() as session:
|
|
await connector.land(session)
|
|
await connector.login(session, user)
|
|
await connector.cancel_booking(session, booking_filter)
|