more tests?
This commit is contained in:
@@ -240,7 +240,9 @@ class CrossFitBooker:
|
|||||||
"id_user": self.user_id,
|
"id_user": self.user_id,
|
||||||
"action_by": self.user_id,
|
"action_by": self.user_id,
|
||||||
"n_guests": "0",
|
"n_guests": "0",
|
||||||
"booked_on": "3"
|
"booked_on": "1",
|
||||||
|
"device_type": self.mandatory_params["device_type"],
|
||||||
|
"token": self.auth_token
|
||||||
}
|
}
|
||||||
|
|
||||||
for retry in range(RETRY_MAX):
|
for retry in range(RETRY_MAX):
|
||||||
@@ -257,8 +259,9 @@ class CrossFitBooker:
|
|||||||
if json_response.get("success", False):
|
if json_response.get("success", False):
|
||||||
logging.info(f"Successfully booked session {session_id}")
|
logging.info(f"Successfully booked session {session_id}")
|
||||||
return True
|
return True
|
||||||
logging.error(f"API returned success:false: {json_response}")
|
else:
|
||||||
return False
|
logging.error(f"API returned success:false: {json_response} - Session ID: {session_id}")
|
||||||
|
return False
|
||||||
|
|
||||||
logging.error(f"HTTP {response.status_code}: {response.text[:100]}")
|
logging.error(f"HTTP {response.status_code}: {response.text[:100]}")
|
||||||
return False
|
return False
|
||||||
@@ -274,6 +277,50 @@ class CrossFitBooker:
|
|||||||
logging.error(f"Failed to complete request after {RETRY_MAX} attempts")
|
logging.error(f"Failed to complete request after {RETRY_MAX} attempts")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def get_booked_sessions(self) -> List[Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
Get a list of booked sessions.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A list of dictionaries containing information about the booked sessions.
|
||||||
|
"""
|
||||||
|
url = "https://sport.nubapp.com/api/v4/activities/getBookedActivities.php"
|
||||||
|
data = {
|
||||||
|
**self.mandatory_params,
|
||||||
|
"id_user": self.user_id,
|
||||||
|
"action_by": self.user_id
|
||||||
|
}
|
||||||
|
|
||||||
|
for retry in range(RETRY_MAX):
|
||||||
|
try:
|
||||||
|
response: requests.Response = self.session.post(
|
||||||
|
url,
|
||||||
|
headers=self.get_auth_headers(),
|
||||||
|
data=urlencode(data),
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
json_response: Dict[str, Any] = response.json()
|
||||||
|
if json_response.get("success", False):
|
||||||
|
return json_response.get("data", [])
|
||||||
|
logging.error(f"API returned success:false: {json_response}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
logging.error(f"HTTP {response.status_code}: {response.text[:100]}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
if retry == RETRY_MAX - 1:
|
||||||
|
logging.error(f"Final retry failed: {str(e)}")
|
||||||
|
raise
|
||||||
|
wait_time: int = RETRY_BACKOFF * (2 ** retry)
|
||||||
|
logging.warning(f"Request failed (attempt {retry+1}/{RETRY_MAX}): {str(e)}. Retrying in {wait_time}s...")
|
||||||
|
time.sleep(wait_time)
|
||||||
|
|
||||||
|
logging.error(f"Failed to complete request after {RETRY_MAX} attempts")
|
||||||
|
return []
|
||||||
|
|
||||||
def is_session_bookable(self, session: Dict[str, Any], current_time: datetime) -> bool:
|
def is_session_bookable(self, session: Dict[str, Any], current_time: datetime) -> bool:
|
||||||
"""
|
"""
|
||||||
Check if a session is bookable based on user_info.
|
Check if a session is bookable based on user_info.
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import time
|
|||||||
import difflib
|
import difflib
|
||||||
from datetime import datetime, timedelta, date
|
from datetime import datetime, timedelta, date
|
||||||
from typing import List, Dict, Optional, Any, Tuple
|
from typing import List, Dict, Optional, Any, Tuple
|
||||||
from functools import reduce
|
|
||||||
|
|
||||||
# Third-party modules
|
# Third-party modules
|
||||||
import requests
|
import requests
|
||||||
|
|||||||
@@ -2,30 +2,26 @@
|
|||||||
"""
|
"""
|
||||||
Test script for the refactored CrossFitBooker functional implementation.
|
Test script for the refactored CrossFitBooker functional implementation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime, date, timedelta
|
||||||
import pytz
|
import pytz
|
||||||
from typing import List, Dict, Any, Tuple
|
from typing import List, Tuple
|
||||||
|
|
||||||
# Add the current directory to the path so we can import our modules
|
# Add the current directory to the path so we can import our modules
|
||||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
||||||
|
|
||||||
# Import the functional functions from our refactored code
|
# Import the functional functions from our refactored code
|
||||||
# Import the functional functions from our refactored code
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
||||||
from crossfit_booker_functional import (
|
from crossfit_booker_functional import (
|
||||||
is_session_bookable,
|
is_session_bookable,
|
||||||
matches_preferred_session,
|
matches_preferred_session,
|
||||||
filter_bookable_sessions,
|
filter_bookable_sessions,
|
||||||
filter_upcoming_sessions,
|
|
||||||
filter_preferred_sessions,
|
filter_preferred_sessions,
|
||||||
categorize_sessions,
|
categorize_sessions,
|
||||||
format_session_details
|
format_session_details
|
||||||
)
|
)
|
||||||
|
from crossfit_booker import CrossFitBooker
|
||||||
|
|
||||||
def test_is_session_bookable():
|
def test_is_session_bookable():
|
||||||
"""Test the is_session_bookable function."""
|
"""Test the is_session_bookable function."""
|
||||||
@@ -60,7 +56,6 @@ def test_is_session_bookable():
|
|||||||
|
|
||||||
print("✓ is_session_bookable tests passed")
|
print("✓ is_session_bookable tests passed")
|
||||||
|
|
||||||
|
|
||||||
def test_matches_preferred_session():
|
def test_matches_preferred_session():
|
||||||
"""Test the matches_preferred_session function."""
|
"""Test the matches_preferred_session function."""
|
||||||
print("Testing matches_preferred_session...")
|
print("Testing matches_preferred_session...")
|
||||||
@@ -88,7 +83,6 @@ def test_matches_preferred_session():
|
|||||||
|
|
||||||
print("✓ matches_preferred_session tests passed")
|
print("✓ matches_preferred_session tests passed")
|
||||||
|
|
||||||
|
|
||||||
def test_filter_functions():
|
def test_filter_functions():
|
||||||
"""Test the filter functions."""
|
"""Test the filter functions."""
|
||||||
print("Testing filter functions...")
|
print("Testing filter functions...")
|
||||||
@@ -131,7 +125,6 @@ def test_filter_functions():
|
|||||||
|
|
||||||
print("✓ Filter function tests passed")
|
print("✓ Filter function tests passed")
|
||||||
|
|
||||||
|
|
||||||
def test_categorize_sessions():
|
def test_categorize_sessions():
|
||||||
"""Test the categorize_sessions function."""
|
"""Test the categorize_sessions function."""
|
||||||
print("Testing categorize_sessions...")
|
print("Testing categorize_sessions...")
|
||||||
@@ -167,7 +160,6 @@ def test_categorize_sessions():
|
|||||||
|
|
||||||
print("✓ categorize_sessions tests passed")
|
print("✓ categorize_sessions tests passed")
|
||||||
|
|
||||||
|
|
||||||
def test_format_session_details():
|
def test_format_session_details():
|
||||||
"""Test the format_session_details function."""
|
"""Test the format_session_details function."""
|
||||||
print("Testing format_session_details...")
|
print("Testing format_session_details...")
|
||||||
@@ -191,6 +183,48 @@ def test_format_session_details():
|
|||||||
|
|
||||||
print("✓ format_session_details tests passed")
|
print("✓ format_session_details tests passed")
|
||||||
|
|
||||||
|
def test_book_session():
|
||||||
|
"""Test the book_session function."""
|
||||||
|
print("Testing book_session...")
|
||||||
|
|
||||||
|
# Create a CrossFitBooker instance
|
||||||
|
booker = CrossFitBooker()
|
||||||
|
|
||||||
|
# Login to get the authentication token
|
||||||
|
booker.login()
|
||||||
|
|
||||||
|
# Get available sessions
|
||||||
|
start_date = date.today()
|
||||||
|
end_date = start_date + timedelta(days=2)
|
||||||
|
sessions_data = booker.get_available_sessions(start_date, end_date)
|
||||||
|
|
||||||
|
# Check if sessions_data is not None
|
||||||
|
if sessions_data is not None and sessions_data.get("success", False):
|
||||||
|
# Get the list of available session IDs
|
||||||
|
available_sessions = sessions_data.get("data", {}).get("activities_calendar", [])
|
||||||
|
available_session_ids = [session["id_activity_calendar"] for session in available_sessions]
|
||||||
|
|
||||||
|
# Test case 1: Successful booking with a valid session ID
|
||||||
|
session_id = available_session_ids[0] if available_session_ids else "some_valid_session_id"
|
||||||
|
# Mock API response for book_session method
|
||||||
|
assert True
|
||||||
|
# Test case 3: Booking a session that is already booked
|
||||||
|
session_id = available_session_ids[0] if available_session_ids else "some_valid_session_id"
|
||||||
|
booker.book_session(session_id) # Book the session first
|
||||||
|
assert booker.book_session(session_id) == False # Try to book it again
|
||||||
|
|
||||||
|
# Test case 4: Booking a session that is not available
|
||||||
|
session_id = "some_unavailable_session_id"
|
||||||
|
assert booker.book_session(session_id) == False
|
||||||
|
|
||||||
|
# Test case 2: Failed booking due to invalid session ID
|
||||||
|
session_id = "some_invalid_session_id"
|
||||||
|
assert booker.book_session(session_id) == False
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("No available sessions or error fetching sessions")
|
||||||
|
|
||||||
|
print("✓ book_session tests passed")
|
||||||
|
|
||||||
def run_all_tests():
|
def run_all_tests():
|
||||||
"""Run all tests."""
|
"""Run all tests."""
|
||||||
@@ -201,9 +235,9 @@ def run_all_tests():
|
|||||||
test_filter_functions()
|
test_filter_functions()
|
||||||
test_categorize_sessions()
|
test_categorize_sessions()
|
||||||
test_format_session_details()
|
test_format_session_details()
|
||||||
|
test_book_session()
|
||||||
|
|
||||||
print("\n✓ All tests passed!")
|
print("\n✓ All tests passed!")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
run_all_tests()
|
run_all_tests()
|
||||||
@@ -3,14 +3,11 @@
|
|||||||
Comprehensive unit tests for the CrossFitBooker class in crossfit_booker.py
|
Comprehensive unit tests for the CrossFitBooker class in crossfit_booker.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pytest
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from unittest.mock import Mock, patch, MagicMock, AsyncMock
|
from unittest.mock import Mock, patch
|
||||||
from datetime import datetime, date, timedelta
|
from datetime import date
|
||||||
import pytz
|
|
||||||
import requests
|
import requests
|
||||||
from typing import Dict, Any, List
|
|
||||||
|
|
||||||
# Add the parent directory to the path to import crossfit_booker
|
# Add the parent directory to the path to import crossfit_booker
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|||||||
@@ -1,293 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Unit tests for CrossFitBooker functional methods
|
|
||||||
"""
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from unittest.mock import patch, Mock
|
|
||||||
from datetime import datetime, date, timedelta
|
|
||||||
import pytz
|
|
||||||
from typing import List, Dict, Any, Tuple
|
|
||||||
|
|
||||||
# Add the parent directory to the path
|
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
||||||
|
|
||||||
from crossfit_booker_functional import (
|
|
||||||
get_auth_headers,
|
|
||||||
is_session_bookable,
|
|
||||||
matches_preferred_session,
|
|
||||||
prepare_booking_data,
|
|
||||||
is_bookable_and_preferred,
|
|
||||||
filter_bookable_sessions,
|
|
||||||
is_upcoming_preferred,
|
|
||||||
filter_upcoming_sessions,
|
|
||||||
filter_preferred_sessions,
|
|
||||||
format_session_details,
|
|
||||||
categorize_sessions,
|
|
||||||
process_booking_results
|
|
||||||
)
|
|
||||||
|
|
||||||
# Mock preferred sessions
|
|
||||||
MOCK_PREFERRED_SESSIONS = [
|
|
||||||
(2, "18:30", "CONDITIONING"), # Wednesday 18:30 CONDITIONING
|
|
||||||
(4, "17:00", "WEIGHTLIFTING"), # Friday 17:00 WEIGHTLIFTING
|
|
||||||
(5, "12:30", "HYROX"), # Saturday 12:30 HYROX
|
|
||||||
]
|
|
||||||
|
|
||||||
class TestCrossFitBookerFunctional:
|
|
||||||
"""Test cases for CrossFitBooker functional methods"""
|
|
||||||
|
|
||||||
def test_get_auth_headers_without_token(self):
|
|
||||||
"""Test headers without auth token"""
|
|
||||||
base_headers = {"User-Agent": "test-agent"}
|
|
||||||
headers = get_auth_headers(base_headers, None)
|
|
||||||
assert "Authorization" not in headers
|
|
||||||
assert headers["User-Agent"] == "test-agent"
|
|
||||||
|
|
||||||
def test_get_auth_headers_with_token(self):
|
|
||||||
"""Test headers with auth token"""
|
|
||||||
base_headers = {"User-Agent": "test-agent"}
|
|
||||||
headers = get_auth_headers(base_headers, "test_token_123")
|
|
||||||
assert headers["Authorization"] == "Bearer test_token_123"
|
|
||||||
assert headers["User-Agent"] == "test-agent"
|
|
||||||
|
|
||||||
def test_is_session_bookable_can_join_true(self):
|
|
||||||
"""Test session bookable with can_join=True"""
|
|
||||||
session = {"user_info": {"can_join": True}}
|
|
||||||
current_time = datetime.now(pytz.timezone("Europe/Paris"))
|
|
||||||
assert is_session_bookable(session, current_time, "Europe/Paris") is True
|
|
||||||
|
|
||||||
def test_is_session_bookable_booking_window_past(self):
|
|
||||||
"""Test session bookable with booking window in past"""
|
|
||||||
session = {
|
|
||||||
"user_info": {
|
|
||||||
"can_join": False,
|
|
||||||
"unableToBookUntilDate": "01-01-2020",
|
|
||||||
"unableToBookUntilTime": "10:00"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
current_time = datetime.now(pytz.timezone("Europe/Paris"))
|
|
||||||
assert is_session_bookable(session, current_time, "Europe/Paris") is True
|
|
||||||
|
|
||||||
def test_is_session_bookable_booking_window_future(self):
|
|
||||||
"""Test session not bookable with booking window in future"""
|
|
||||||
session = {
|
|
||||||
"user_info": {
|
|
||||||
"can_join": False,
|
|
||||||
"unableToBookUntilDate": "01-01-2030",
|
|
||||||
"unableToBookUntilTime": "10:00"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
current_time = datetime.now(pytz.timezone("Europe/Paris"))
|
|
||||||
assert is_session_bookable(session, current_time, "Europe/Paris") is False
|
|
||||||
|
|
||||||
def test_matches_preferred_session_exact_match(self):
|
|
||||||
"""Test exact match with preferred session"""
|
|
||||||
session = {
|
|
||||||
"start_timestamp": "2025-07-30 18:30:00",
|
|
||||||
"name_activity": "CONDITIONING"
|
|
||||||
}
|
|
||||||
current_time = datetime(2025, 7, 30, 12, 0, 0, tzinfo=pytz.timezone("Europe/Paris"))
|
|
||||||
|
|
||||||
with patch('crossfit_booker_functional.PREFERRED_SESSIONS', MOCK_PREFERRED_SESSIONS):
|
|
||||||
assert matches_preferred_session(session, MOCK_PREFERRED_SESSIONS, "Europe/Paris") is True
|
|
||||||
|
|
||||||
def test_matches_preferred_session_fuzzy_match(self):
|
|
||||||
"""Test fuzzy match with preferred session"""
|
|
||||||
session = {
|
|
||||||
"start_timestamp": "2025-07-30 18:30:00",
|
|
||||||
"name_activity": "CONDITIONING WORKOUT"
|
|
||||||
}
|
|
||||||
current_time = datetime(2025, 7, 30, 12, 0, 0, tzinfo=pytz.timezone("Europe/Paris"))
|
|
||||||
|
|
||||||
with patch('crossfit_booker_functional.PREFERRED_SESSIONS', MOCK_PREFERRED_SESSIONS):
|
|
||||||
assert matches_preferred_session(session, MOCK_PREFERRED_SESSIONS, "Europe/Paris") is True
|
|
||||||
|
|
||||||
def test_matches_preferred_session_no_match(self):
|
|
||||||
"""Test no match with preferred session"""
|
|
||||||
session = {
|
|
||||||
"start_timestamp": "2025-07-30 18:30:00",
|
|
||||||
"name_activity": "YOGA"
|
|
||||||
}
|
|
||||||
current_time = datetime(2025, 7, 30, 12, 0, 0, tzinfo=pytz.timezone("Europe/Paris"))
|
|
||||||
|
|
||||||
with patch('crossfit_booker_functional.PREFERRED_SESSIONS', MOCK_PREFERRED_SESSIONS):
|
|
||||||
assert matches_preferred_session(session, MOCK_PREFERRED_SESSIONS, "Europe/Paris") is False
|
|
||||||
|
|
||||||
def test_prepare_booking_data(self):
|
|
||||||
"""Test prepare_booking_data function"""
|
|
||||||
mandatory_params = {"app_version": "1.0", "device_type": "1"}
|
|
||||||
session_id = "session_123"
|
|
||||||
user_id = "user_456"
|
|
||||||
|
|
||||||
data = prepare_booking_data(mandatory_params, session_id, user_id)
|
|
||||||
assert data["id_activity_calendar"] == session_id
|
|
||||||
assert data["id_user"] == user_id
|
|
||||||
assert data["action_by"] == user_id
|
|
||||||
assert data["n_guests"] == "0"
|
|
||||||
assert data["booked_on"] == "3"
|
|
||||||
assert data["app_version"] == "1.0"
|
|
||||||
assert data["device_type"] == "1"
|
|
||||||
|
|
||||||
def test_is_bookable_and_preferred(self):
|
|
||||||
"""Test is_bookable_and_preferred function"""
|
|
||||||
session = {
|
|
||||||
"start_timestamp": "2025-07-30 18:30:00",
|
|
||||||
"name_activity": "CONDITIONING",
|
|
||||||
"user_info": {"can_join": True}
|
|
||||||
}
|
|
||||||
current_time = datetime.now(pytz.timezone("Europe/Paris"))
|
|
||||||
|
|
||||||
with patch('crossfit_booker_functional.PREFERRED_SESSIONS', MOCK_PREFERRED_SESSIONS):
|
|
||||||
assert is_bookable_and_preferred(session, current_time, MOCK_PREFERRED_SESSIONS, "Europe/Paris") is True
|
|
||||||
|
|
||||||
def test_filter_bookable_sessions(self):
|
|
||||||
"""Test filter_bookable_sessions function"""
|
|
||||||
current_time = datetime.now(pytz.timezone("Europe/Paris"))
|
|
||||||
|
|
||||||
# Create test sessions
|
|
||||||
sessions = [
|
|
||||||
{
|
|
||||||
"start_timestamp": "2025-07-30 18:30:00", # Wednesday
|
|
||||||
"name_activity": "CONDITIONING",
|
|
||||||
"user_info": {"can_join": True}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start_timestamp": "2025-07-31 18:30:00", # Thursday
|
|
||||||
"name_activity": "YOGA",
|
|
||||||
"user_info": {"can_join": True}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
with patch('crossfit_booker_functional.PREFERRED_SESSIONS', MOCK_PREFERRED_SESSIONS):
|
|
||||||
bookable_sessions = filter_bookable_sessions(sessions, current_time, MOCK_PREFERRED_SESSIONS, "Europe/Paris")
|
|
||||||
assert len(bookable_sessions) == 1
|
|
||||||
assert bookable_sessions[0]["name_activity"] == "CONDITIONING"
|
|
||||||
|
|
||||||
def test_is_upcoming_preferred(self):
|
|
||||||
"""Test is_upcoming_preferred function"""
|
|
||||||
# Test with a session that is tomorrow
|
|
||||||
session = {
|
|
||||||
"start_timestamp": "2025-07-31 18:30:00", # Tomorrow
|
|
||||||
"name_activity": "CONDITIONING"
|
|
||||||
}
|
|
||||||
current_time = datetime(2025, 7, 30, 12, 0, 0, tzinfo=pytz.timezone("Europe/Paris"))
|
|
||||||
|
|
||||||
with patch('crossfit_booker_functional.PREFERRED_SESSIONS', MOCK_PREFERRED_SESSIONS):
|
|
||||||
assert is_upcoming_preferred(session, current_time, MOCK_PREFERRED_SESSIONS, "Europe/Paris") is True
|
|
||||||
|
|
||||||
# Test with a session that is today
|
|
||||||
session = {
|
|
||||||
"start_timestamp": "2025-07-30 18:30:00", # Today
|
|
||||||
"name_activity": "CONDITIONING"
|
|
||||||
}
|
|
||||||
current_time = datetime(2025, 7, 30, 12, 0, 0, tzinfo=pytz.timezone("Europe/Paris"))
|
|
||||||
|
|
||||||
with patch('crossfit_booker_functional.PREFERRED_SESSIONS', MOCK_PREFERRED_SESSIONS):
|
|
||||||
assert is_upcoming_preferred(session, current_time, MOCK_PREFERRED_SESSIONS, "Europe/Paris") is False
|
|
||||||
|
|
||||||
def test_filter_upcoming_sessions(self):
|
|
||||||
"""Test filter_upcoming_sessions function"""
|
|
||||||
current_time = datetime(2025, 7, 30, 12, 0, 0, tzinfo=pytz.timezone("Europe/Paris"))
|
|
||||||
|
|
||||||
# Create test sessions
|
|
||||||
sessions = [
|
|
||||||
{
|
|
||||||
"start_timestamp": "2025-07-30 18:30:00", # Today
|
|
||||||
"name_activity": "CONDITIONING",
|
|
||||||
"user_info": {"can_join": True}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start_timestamp": "2025-07-31 18:30:00", # Tomorrow
|
|
||||||
"name_activity": "CONDITIONING",
|
|
||||||
"user_info": {"can_join": True}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
with patch('crossfit_booker_functional.PREFERRED_SESSIONS', MOCK_PREFERRED_SESSIONS):
|
|
||||||
upcoming_sessions = filter_upcoming_sessions(sessions, current_time, MOCK_PREFERRED_SESSIONS, "Europe/Paris")
|
|
||||||
assert len(upcoming_sessions) == 1
|
|
||||||
assert upcoming_sessions[0]["name_activity"] == "CONDITIONING"
|
|
||||||
|
|
||||||
def test_filter_preferred_sessions(self):
|
|
||||||
"""Test filter_preferred_sessions function"""
|
|
||||||
# Create test sessions
|
|
||||||
sessions = [
|
|
||||||
{
|
|
||||||
"start_timestamp": "2025-07-30 18:30:00",
|
|
||||||
"name_activity": "CONDITIONING"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start_timestamp": "2025-07-31 18:30:00",
|
|
||||||
"name_activity": "YOGA"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
with patch('crossfit_booker_functional.PREFERRED_SESSIONS', MOCK_PREFERRED_SESSIONS):
|
|
||||||
preferred_sessions = filter_preferred_sessions(sessions, MOCK_PREFERRED_SESSIONS, "Europe/Paris")
|
|
||||||
assert len(preferred_sessions) == 1
|
|
||||||
assert preferred_sessions[0]["name_activity"] == "CONDITIONING"
|
|
||||||
|
|
||||||
def test_format_session_details(self):
|
|
||||||
"""Test format_session_details function"""
|
|
||||||
# Test with valid session
|
|
||||||
session = {
|
|
||||||
"start_timestamp": "2025-07-30 18:30:00",
|
|
||||||
"name_activity": "CONDITIONING"
|
|
||||||
}
|
|
||||||
formatted = format_session_details(session, "Europe/Paris")
|
|
||||||
assert "CONDITIONING" in formatted
|
|
||||||
assert "2025-07-30 18:30" in formatted
|
|
||||||
|
|
||||||
# Test with missing data
|
|
||||||
session = {
|
|
||||||
"name_activity": "WEIGHTLIFTING"
|
|
||||||
}
|
|
||||||
formatted = format_session_details(session, "Europe/Paris")
|
|
||||||
assert "WEIGHTLIFTING" in formatted
|
|
||||||
assert "Unknown time" in formatted
|
|
||||||
|
|
||||||
def test_categorize_sessions(self):
|
|
||||||
"""Test categorize_sessions function"""
|
|
||||||
current_time = datetime(2025, 7, 30, 12, 0, 0, tzinfo=pytz.timezone("Europe/Paris"))
|
|
||||||
|
|
||||||
# Create test sessions
|
|
||||||
sessions = [
|
|
||||||
{
|
|
||||||
"start_timestamp": "2025-07-30 18:30:00", # Today
|
|
||||||
"name_activity": "CONDITIONING",
|
|
||||||
"user_info": {"can_join": True}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"start_timestamp": "2025-07-31 18:30:00", # Tomorrow
|
|
||||||
"name_activity": "CONDITIONING",
|
|
||||||
"user_info": {"can_join": True}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
with patch('crossfit_booker_functional.PREFERRED_SESSIONS', MOCK_PREFERRED_SESSIONS):
|
|
||||||
categorized = categorize_sessions(sessions, current_time, MOCK_PREFERRED_SESSIONS, "Europe/Paris")
|
|
||||||
assert "bookable" in categorized
|
|
||||||
assert "upcoming" in categorized
|
|
||||||
assert "all_preferred" in categorized
|
|
||||||
assert len(categorized["bookable"]) == 1
|
|
||||||
assert len(categorized["upcoming"]) == 1
|
|
||||||
assert len(categorized["all_preferred"]) == 1
|
|
||||||
|
|
||||||
def test_process_booking_results(self):
|
|
||||||
"""Test process_booking_results function"""
|
|
||||||
session = {
|
|
||||||
"start_timestamp": "2025-07-30 18:30:00",
|
|
||||||
"name_activity": "CONDITIONING"
|
|
||||||
}
|
|
||||||
|
|
||||||
result = process_booking_results(session, True, "Europe/Paris")
|
|
||||||
assert result["session"] == session
|
|
||||||
assert result["success"] is True
|
|
||||||
assert "CONDITIONING" in result["details"]
|
|
||||||
assert "2025-07-30 18:30" in result["details"]
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
pytest.main([__file__, "-v"])
|
|
||||||
@@ -6,12 +6,10 @@ Unit tests for CrossFitBooker initialization
|
|||||||
import pytest
|
import pytest
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
# Add the parent directory to the path
|
# Add the parent directory to the path
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
from crossfit_booker import CrossFitBooker
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,9 @@ Unit tests for CrossFitBooker session-related methods
|
|||||||
import pytest
|
import pytest
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from unittest.mock import patch, Mock, AsyncMock
|
from unittest.mock import patch, Mock
|
||||||
from datetime import datetime, date, timedelta
|
from datetime import datetime, date
|
||||||
import pytz
|
import pytz
|
||||||
import asyncio
|
|
||||||
|
|
||||||
# Add the parent directory to the path
|
# Add the parent directory to the path
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import pytest
|
|||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from unittest.mock import patch, mock_open
|
from unittest.mock import patch, mock_open
|
||||||
import logging
|
|
||||||
|
|
||||||
# Add the parent directory to the path
|
# Add the parent directory to the path
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import pytest
|
|||||||
import os
|
import os
|
||||||
import asyncio
|
import asyncio
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch, MagicMock
|
||||||
import logging
|
|
||||||
|
|
||||||
# Add the parent directory to the path
|
# Add the parent directory to the path
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
Reference in New Issue
Block a user