Payloads are now built with Jinja templates
This commit is contained in:
parent
ccd019eb4c
commit
badced0a30
12 changed files with 222 additions and 175 deletions
88
poetry.lock
generated
88
poetry.lock
generated
|
@ -383,6 +383,92 @@ files = [
|
||||||
[package.extras]
|
[package.extras]
|
||||||
colors = ["colorama (>=0.4.6)"]
|
colors = ["colorama (>=0.4.6)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jinja2"
|
||||||
|
version = "3.1.3"
|
||||||
|
description = "A very fast and expressive template engine."
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"},
|
||||||
|
{file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
MarkupSafe = ">=2.0"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
i18n = ["Babel (>=2.7)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "markupsafe"
|
||||||
|
version = "2.1.5"
|
||||||
|
description = "Safely add untrusted strings to HTML/XML markup."
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
|
||||||
|
{file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
|
||||||
|
{file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "multidict"
|
name = "multidict"
|
||||||
version = "6.0.5"
|
version = "6.0.5"
|
||||||
|
@ -1151,4 +1237,4 @@ multidict = ">=4.0"
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.10"
|
python-versions = "^3.10"
|
||||||
content-hash = "c85317b4b8334d5d25f97ac426cfa6cd1f63c3c3d0726e313c97cf1de43c985a"
|
content-hash = "eb2292ededdcd551249bd05bdc2fd3d38dfeeba495cb3ea8dd7ba5dfd9250980"
|
||||||
|
|
|
@ -14,6 +14,7 @@ pendulum = "^3.0.0"
|
||||||
pydantic = "^2.6.1"
|
pydantic = "^2.6.1"
|
||||||
pydantic-extra-types = "^2.5.0"
|
pydantic-extra-types = "^2.5.0"
|
||||||
python-dotenv = "^1.0.1"
|
python-dotenv = "^1.0.1"
|
||||||
|
jinja2 = "^3.1.3"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
black = "^24.1.1"
|
black = "^24.1.1"
|
||||||
|
@ -30,7 +31,7 @@ line-length = 88
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
pythonpath = [
|
pythonpath = [
|
||||||
".", "resa_padel", "rr"
|
"resa_padel"
|
||||||
]
|
]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
|
|
|
@ -90,3 +90,7 @@ def init_log_config():
|
||||||
with open(logging_file, "r") as f:
|
with open(logging_file, "r") as f:
|
||||||
logging_config = yaml.safe_load(f.read())
|
logging_config = yaml.safe_load(f.read())
|
||||||
logging.config.dictConfig(logging_config)
|
logging.config.dictConfig(logging_config)
|
||||||
|
|
||||||
|
|
||||||
|
ROOT_PATH = Path(__file__).parent.resolve()
|
||||||
|
RESOURCES_DIR = Path(ROOT_PATH, "resources")
|
||||||
|
|
7
resa_padel/gestion_sports/gestion_sports_config.py
Normal file
7
resa_padel/gestion_sports/gestion_sports_config.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import config
|
||||||
|
|
||||||
|
RESOURCES_DIR = Path(config.RESOURCES_DIR, "gestion-sports")
|
||||||
|
BOOKING_TEMPLATE = Path(RESOURCES_DIR, "booking-payload.txt")
|
||||||
|
LOGIN_TEMPLATE = Path(RESOURCES_DIR, "login-payload.txt")
|
|
@ -6,7 +6,10 @@ from urllib.parse import urljoin
|
||||||
from aiohttp import ClientResponse, ClientSession
|
from aiohttp import ClientResponse, ClientSession
|
||||||
|
|
||||||
import config
|
import config
|
||||||
from gestion_sports.gestion_sports_payload_builder import GestionSportsPayloadBuilder
|
from gestion_sports.payload_builders import (
|
||||||
|
GestionSportsLoginPayloadBuilder,
|
||||||
|
GestionSportsBookingPayloadBuilder,
|
||||||
|
)
|
||||||
from models import BookingFilter, Club, User
|
from models import BookingFilter, Club, User
|
||||||
|
|
||||||
DATE_FORMAT = "%d/%m/%Y"
|
DATE_FORMAT = "%d/%m/%Y"
|
||||||
|
@ -26,7 +29,6 @@ class GestionSportsConnector:
|
||||||
LOGGER.info("Initializing connection to GestionSports API")
|
LOGGER.info("Initializing connection to GestionSports API")
|
||||||
self.url = url
|
self.url = url
|
||||||
self.session = session
|
self.session = session
|
||||||
self.payload_builder = GestionSportsPayloadBuilder()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def landing_url(self) -> str:
|
def landing_url(self) -> str:
|
||||||
|
@ -72,12 +74,8 @@ class GestionSportsConnector:
|
||||||
|
|
||||||
:return: the response from the login
|
:return: the response from the login
|
||||||
"""
|
"""
|
||||||
payload = (
|
payload_builder = GestionSportsLoginPayloadBuilder()
|
||||||
self.payload_builder.login(user.login)
|
payload = payload_builder.user(user).club(club).build()
|
||||||
.password(user.password)
|
|
||||||
.club_id(club.id)
|
|
||||||
.build_login_payload()
|
|
||||||
)
|
|
||||||
|
|
||||||
async with self.session.post(
|
async with self.session.post(
|
||||||
self.login_url, data=payload, headers=POST_HEADERS
|
self.login_url, data=payload, headers=POST_HEADERS
|
||||||
|
@ -105,10 +103,11 @@ class GestionSportsConnector:
|
||||||
return_exceptions=True,
|
return_exceptions=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
return await self.get_booked_court(bookings)
|
return self.get_booked_court(bookings)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def get_booked_court(bookings):
|
def get_booked_court(bookings):
|
||||||
|
LOGGER.info(bookings)
|
||||||
for court, is_booked in bookings:
|
for court, is_booked in bookings:
|
||||||
if is_booked:
|
if is_booked:
|
||||||
return court
|
return court
|
||||||
|
@ -117,23 +116,23 @@ class GestionSportsConnector:
|
||||||
async def book_one_court(
|
async def book_one_court(
|
||||||
self, booking_filter: BookingFilter, court_id: int
|
self, booking_filter: BookingFilter, court_id: int
|
||||||
) -> tuple[int, bool]:
|
) -> tuple[int, bool]:
|
||||||
|
payload_builder = GestionSportsBookingPayloadBuilder()
|
||||||
payload = (
|
payload = (
|
||||||
self.payload_builder.date(booking_filter.date.date().strftime(DATE_FORMAT))
|
payload_builder.booking_filter(booking_filter).court_id(court_id).build()
|
||||||
.time(booking_filter.date.time().strftime(TIME_FORMAT))
|
|
||||||
.sport_id(booking_filter.sport_id)
|
|
||||||
.court_id(court_id)
|
|
||||||
.build_booking_payload()
|
|
||||||
)
|
)
|
||||||
return court_id, await self.is_court_booked(payload)
|
LOGGER.info(payload)
|
||||||
|
|
||||||
async def is_court_booked(self, payload: str) -> bool:
|
|
||||||
async with self.session.post(
|
async with self.session.post(
|
||||||
self.booking_url, data=payload, headers=POST_HEADERS
|
self.booking_url, data=payload, headers=POST_HEADERS
|
||||||
) as response:
|
) as response:
|
||||||
return self.is_response_status_ok(await response.text())
|
resp_json = await response.text()
|
||||||
|
|
||||||
|
return court_id, self.is_response_status_ok(resp_json)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_response_status_ok(response: str) -> bool:
|
def is_response_status_ok(response: str) -> bool:
|
||||||
|
|
||||||
|
LOGGER.info(response)
|
||||||
formatted_result = response.removeprefix('"').removesuffix('"')
|
formatted_result = response.removeprefix('"').removesuffix('"')
|
||||||
result_json = json.loads(formatted_result)
|
result_json = json.loads(formatted_result)
|
||||||
return result_json["status"] == "ok"
|
return result_json["status"] == "ok"
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
from exceptions import ArgumentMissing
|
|
||||||
|
|
||||||
|
|
||||||
class GestionSportsPayloadBuilder:
|
|
||||||
def __init__(self):
|
|
||||||
self._login = None
|
|
||||||
self._password = None
|
|
||||||
self._club_id = None
|
|
||||||
self._date = None
|
|
||||||
self._time = None
|
|
||||||
self._sport_id = None
|
|
||||||
self._court_id = None
|
|
||||||
|
|
||||||
def login(self, login: str):
|
|
||||||
self._login = login
|
|
||||||
return self
|
|
||||||
|
|
||||||
def password(self, password: str):
|
|
||||||
self._password = password
|
|
||||||
return self
|
|
||||||
|
|
||||||
def club_id(self, club_id: str):
|
|
||||||
self._club_id = club_id
|
|
||||||
return self
|
|
||||||
|
|
||||||
def date(self, date: str):
|
|
||||||
self._date = date
|
|
||||||
return self
|
|
||||||
|
|
||||||
def time(self, time: str):
|
|
||||||
self._time = time
|
|
||||||
return self
|
|
||||||
|
|
||||||
def sport_id(self, sport_id: int):
|
|
||||||
self._sport_id = sport_id
|
|
||||||
return self
|
|
||||||
|
|
||||||
def court_id(self, court_id: int):
|
|
||||||
self._court_id = court_id
|
|
||||||
return self
|
|
||||||
|
|
||||||
def build_login_payload(self):
|
|
||||||
if self._login is None:
|
|
||||||
raise ArgumentMissing("Login not provided")
|
|
||||||
if self.password is None:
|
|
||||||
raise ArgumentMissing("Password not provided")
|
|
||||||
if self._club_id is None:
|
|
||||||
raise ArgumentMissing("Club ID not provided")
|
|
||||||
|
|
||||||
return (
|
|
||||||
f"ajax=connexionUser&id_club={self._club_id}&email={self._login}&form_ajax=1&pass={self._password}&compte"
|
|
||||||
f"=user&playeridonesignal=0&identifiant=identifiant&externCo=true"
|
|
||||||
).encode("utf-8")
|
|
||||||
|
|
||||||
def build_booking_payload(self):
|
|
||||||
if self._date is None:
|
|
||||||
raise ArgumentMissing("Date not provided")
|
|
||||||
if self._time is None:
|
|
||||||
raise ArgumentMissing("Time not provided")
|
|
||||||
if self._sport_id is None:
|
|
||||||
raise ArgumentMissing("Sport ID not provided")
|
|
||||||
if self._court_id is None:
|
|
||||||
raise ArgumentMissing("Court ID not provided")
|
|
||||||
|
|
||||||
return (
|
|
||||||
f"ajax=addResa&date={self._date}&hour={self._time}&duration=90&partners=null|null|null"
|
|
||||||
f"&paiement=facultatif&idSport={self._sport_id}&creaPartie=false&idCourt={self._court_id}"
|
|
||||||
f"&pay=false&token=undefined&totalPrice=44&saveCard=0&foodNumber=0"
|
|
||||||
).encode("utf-8")
|
|
59
resa_padel/gestion_sports/payload_builders.py
Normal file
59
resa_padel/gestion_sports/payload_builders.py
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
|
||||||
|
from exceptions import ArgumentMissing
|
||||||
|
from gestion_sports.gestion_sports_config import LOGIN_TEMPLATE, BOOKING_TEMPLATE
|
||||||
|
from models import User, Club, BookingFilter
|
||||||
|
|
||||||
|
|
||||||
|
class GestionSportsLoginPayloadBuilder:
|
||||||
|
def __init__(self):
|
||||||
|
self._user: User | None = None
|
||||||
|
self._club: Club | None = None
|
||||||
|
self._template = LOGIN_TEMPLATE
|
||||||
|
|
||||||
|
def user(self, user: User):
|
||||||
|
self._user = user
|
||||||
|
return self
|
||||||
|
|
||||||
|
def club(self, club: Club):
|
||||||
|
self._club = club
|
||||||
|
return self
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
if self._user is None:
|
||||||
|
raise ArgumentMissing("No user was provided")
|
||||||
|
if self._club is None:
|
||||||
|
raise ArgumentMissing("No club was provided")
|
||||||
|
|
||||||
|
environment = Environment(loader=FileSystemLoader(self._template.parent))
|
||||||
|
template = environment.get_template(self._template.name)
|
||||||
|
|
||||||
|
return template.render(club=self._club, user=self._user)
|
||||||
|
|
||||||
|
|
||||||
|
class GestionSportsBookingPayloadBuilder:
|
||||||
|
def __init__(self):
|
||||||
|
self._booking_filter: BookingFilter | None = None
|
||||||
|
self._court_id: int | None = None
|
||||||
|
self._template = BOOKING_TEMPLATE
|
||||||
|
|
||||||
|
def booking_filter(self, booking_filter: BookingFilter):
|
||||||
|
self._booking_filter = booking_filter
|
||||||
|
return self
|
||||||
|
|
||||||
|
def court_id(self, court_id: int):
|
||||||
|
self._court_id = court_id
|
||||||
|
return self
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
if self._booking_filter is None:
|
||||||
|
raise ArgumentMissing("No booking filter was provided")
|
||||||
|
if self.court_id is None:
|
||||||
|
raise ArgumentMissing("No court id was provided")
|
||||||
|
|
||||||
|
environment = Environment(loader=FileSystemLoader(self._template.parent))
|
||||||
|
template = environment.get_template(self._template.name)
|
||||||
|
|
||||||
|
return template.render(
|
||||||
|
court_id=self._court_id, booking_filter=self._booking_filter
|
||||||
|
)
|
1
resa_padel/resources/gestion-sports/booking-payload.txt
Normal file
1
resa_padel/resources/gestion-sports/booking-payload.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ajax=addResa&date={{ booking_filter.date.date().strftime("%d/%m/%Y") }}&hour={{ booking_filter.date.time().strftime("%H:%M") }}&duration=90&partners=null|null|null&paiement=facultatif&idSport={{ booking_filter.sport_id }}&creaPartie=false&idCourt={{ court_id }}&pay=false&token=undefined&totalPrice=44&saveCard=0&foodNumber=0
|
1
resa_padel/resources/gestion-sports/login-payload.txt
Normal file
1
resa_padel/resources/gestion-sports/login-payload.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ajax=connexionUser&id_club={{ club.id }}&email={{ user.login }}&form_ajax=1&pass={{ user.password }}&compte=user&playeridonesignal=0&identifiant=identifiant&externCo=true
|
|
@ -3,9 +3,7 @@ import json
|
||||||
import pendulum
|
import pendulum
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from resa_padel.gestion_sports.gestion_sports_payload_builder import (
|
from gestion_sports.payload_builders import GestionSportsBookingPayloadBuilder
|
||||||
GestionSportsPayloadBuilder,
|
|
||||||
)
|
|
||||||
from resa_padel.models import BookingFilter, Club, User
|
from resa_padel.models import BookingFilter, Club, User
|
||||||
|
|
||||||
user = User(login="padel.testing@jouf.fr", password="ridicule", club_id="123")
|
user = User(login="padel.testing@jouf.fr", password="ridicule", club_id="123")
|
||||||
|
@ -38,12 +36,10 @@ booking_success_response = json.dumps(
|
||||||
date_format = "%d/%m/%Y"
|
date_format = "%d/%m/%Y"
|
||||||
time_format = "%H:%M"
|
time_format = "%H:%M"
|
||||||
booking_payload = (
|
booking_payload = (
|
||||||
GestionSportsPayloadBuilder()
|
GestionSportsBookingPayloadBuilder()
|
||||||
.date(booking_date.date().strftime(date_format))
|
.booking_filter(booking_filter)
|
||||||
.time(booking_date.time().strftime(time_format))
|
|
||||||
.sport_id(sport_id)
|
|
||||||
.court_id(courts[0])
|
.court_id(courts[0])
|
||||||
.build_booking_payload()
|
.build()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ from resa_padel.gestion_sports.gestion_sports_connector import GestionSportsConn
|
||||||
from tests.fixtures import (
|
from tests.fixtures import (
|
||||||
a_booking_failure_response,
|
a_booking_failure_response,
|
||||||
a_booking_filter,
|
a_booking_filter,
|
||||||
a_booking_payload,
|
|
||||||
a_booking_success_response,
|
a_booking_success_response,
|
||||||
a_club,
|
a_club,
|
||||||
a_user,
|
a_user,
|
||||||
|
@ -140,46 +139,3 @@ def test_response_status_should_be_not_ok(a_booking_failure_response: str) -> No
|
||||||
"""
|
"""
|
||||||
is_booked = GestionSportsConnector.is_response_status_ok(a_booking_failure_response)
|
is_booked = GestionSportsConnector.is_response_status_ok(a_booking_failure_response)
|
||||||
assert not is_booked
|
assert not is_booked
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_court_should_not_be_booked(
|
|
||||||
aioresponses, a_booking_payload: str, a_booking_failure_response: str
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
Test that no court is booked when there is a failure response
|
|
||||||
from the booking request
|
|
||||||
|
|
||||||
:param aioresponses: the http requests mock
|
|
||||||
:param a_booking_payload: the payload that is sent for booking
|
|
||||||
:param a_booking_failure_response: the failure response mock
|
|
||||||
"""
|
|
||||||
async with ClientSession() as session:
|
|
||||||
tpc_connector = GestionSportsConnector(session, tpc_url)
|
|
||||||
aioresponses.post(
|
|
||||||
URL(tpc_connector.booking_url), status=200, body=a_booking_failure_response
|
|
||||||
)
|
|
||||||
is_booked = await tpc_connector.is_court_booked(a_booking_payload)
|
|
||||||
assert not is_booked
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_court_should_be_booked(
|
|
||||||
aioresponses, a_booking_payload: str, a_booking_success_response: str
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
Test that a court is booked when there is a success response
|
|
||||||
from the booking request
|
|
||||||
|
|
||||||
:param aioresponses: the http requests mock
|
|
||||||
:param a_booking_payload: the payload that is sent for booking
|
|
||||||
:param a_booking_success_response: the success response mock
|
|
||||||
"""
|
|
||||||
async with ClientSession() as session:
|
|
||||||
tpc_connector = GestionSportsConnector(session, tpc_url)
|
|
||||||
|
|
||||||
aioresponses.post(
|
|
||||||
URL(tpc_connector.booking_url), status=200, body=a_booking_success_response
|
|
||||||
)
|
|
||||||
is_booked = await tpc_connector.is_court_booked(a_booking_payload)
|
|
||||||
assert is_booked
|
|
||||||
|
|
|
@ -1,44 +1,50 @@
|
||||||
import pendulum
|
from resa_padel.gestion_sports.payload_builders import (
|
||||||
|
GestionSportsLoginPayloadBuilder,
|
||||||
from resa_padel.gestion_sports.gestion_sports_payload_builder import (
|
GestionSportsBookingPayloadBuilder,
|
||||||
GestionSportsPayloadBuilder,
|
|
||||||
)
|
)
|
||||||
|
from tests.fixtures import a_user, a_club, a_booking_filter
|
||||||
|
|
||||||
|
|
||||||
def test_login_payload_should_be_built():
|
def test_login_payload_should_be_built(a_user, a_club):
|
||||||
payload_builder = GestionSportsPayloadBuilder()
|
"""
|
||||||
login = "jacques"
|
Test that the login payload is filled with the right template
|
||||||
password = "chirac"
|
and filled accordingly
|
||||||
club_id = "27"
|
|
||||||
login_payload = (
|
:param a_user: the user information fixture
|
||||||
payload_builder.login(login)
|
:param a_club: the club information fixture
|
||||||
.password(password)
|
"""
|
||||||
.club_id(club_id)
|
payload_builder = GestionSportsLoginPayloadBuilder()
|
||||||
.build_login_payload()
|
login_payload = payload_builder.user(a_user).club(a_club).build()
|
||||||
|
|
||||||
|
expected_payload = (
|
||||||
|
f"ajax=connexionUser&id_club={a_club.id}&email={a_user.login}&form_ajax=1"
|
||||||
|
f"&pass={a_user.password}&compte=user&playeridonesignal=0"
|
||||||
|
f"&identifiant=identifiant&externCo=true"
|
||||||
)
|
)
|
||||||
|
|
||||||
assert login_payload == (
|
assert login_payload == expected_payload
|
||||||
f"ajax=connexionUser&id_club={club_id}&email={login}&form_ajax=1&pass={password}&compte"
|
|
||||||
f"=user&playeridonesignal=0&identifiant=identifiant&externCo=true"
|
|
||||||
).encode("utf-8")
|
|
||||||
|
|
||||||
|
|
||||||
def test_booking_payload_should_be_built():
|
def test_booking_payload_should_be_built(a_booking_filter):
|
||||||
booking_builder = GestionSportsPayloadBuilder()
|
"""
|
||||||
booking_date = pendulum.now("Europe/Paris")
|
Test that the booking payload is filled with the right template
|
||||||
sport_id = "27"
|
and filled accordingly
|
||||||
court_id = "55"
|
|
||||||
|
:param a_booking_filter: the booking information fixture
|
||||||
|
"""
|
||||||
|
booking_builder = GestionSportsBookingPayloadBuilder()
|
||||||
booking_payload = (
|
booking_payload = (
|
||||||
booking_builder.date(booking_date.date())
|
booking_builder.booking_filter(a_booking_filter).court_id(4).build()
|
||||||
.time(booking_date.time())
|
|
||||||
.sport_id(sport_id)
|
|
||||||
.court_id(court_id)
|
|
||||||
.build_booking_payload()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
assert booking_payload == (
|
expected_date = a_booking_filter.date.date().strftime("%d/%m/%Y")
|
||||||
f"ajax=addResa&date={booking_date.date()}&hour={booking_date.time()}&duration=90"
|
expected_time = a_booking_filter.date.time().strftime("%H:%M")
|
||||||
f"&partners=null|null|null&paiement=facultatif&idSport={sport_id}"
|
expected_payload = (
|
||||||
f"&creaPartie=false&idCourt={court_id}&pay=false&token=undefined&totalPrice=44&saveCard=0"
|
f"ajax=addResa&date={expected_date}"
|
||||||
f"&foodNumber=0"
|
f"&hour={expected_time}&duration=90&partners=null|null|null"
|
||||||
).encode("utf-8")
|
f"&paiement=facultatif&idSport={a_booking_filter.sport_id}"
|
||||||
|
f"&creaPartie=false&idCourt=4&pay=false&token=undefined&totalPrice=44"
|
||||||
|
f"&saveCard=0&foodNumber=0"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert booking_payload == expected_payload
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue