Compare commits
3 Commits
d1e5fc1003
...
f5e0bba298
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5e0bba298 | ||
|
|
9a35a57c7f | ||
|
|
cd5f0a54ac |
@@ -4,7 +4,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: crossfit-booker
|
# container_name: crossfit-booker
|
||||||
environment:
|
environment:
|
||||||
- TZ=Europe/Paris
|
- TZ=Europe/Paris
|
||||||
- CROSSFIT_USERNAME=${CROSSFIT_USERNAME}
|
- CROSSFIT_USERNAME=${CROSSFIT_USERNAME}
|
||||||
@@ -19,4 +19,4 @@ services:
|
|||||||
- TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}
|
- TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}
|
||||||
volumes:
|
volumes:
|
||||||
- ./log:/app/log
|
- ./log:/app/log
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -77,7 +77,13 @@ class AuthHandler:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
login_data: Dict[str, Any] = response.json()
|
login_data: Dict[str, Any] = response.json()
|
||||||
self.user_id = str(login_data["data"]["user"]["id_user"])
|
# Try to find id_user in the nested structure
|
||||||
|
try:
|
||||||
|
# First try the new structure: data.user.applications[0].users[0].id_user
|
||||||
|
self.user_id = str(login_data["data"]["user"]["applications"][0]["users"][0]["id_user"])
|
||||||
|
except (KeyError, IndexError, TypeError):
|
||||||
|
# Fallback to old structure if it exists
|
||||||
|
self.user_id = str(login_data["data"]["user"]["id_user"])
|
||||||
except (KeyError, ValueError) as e:
|
except (KeyError, ValueError) as e:
|
||||||
logging.error(f"Error during login: {str(e)} - Response: {response.text}")
|
logging.error(f"Error during login: {str(e)} - Response: {response.text}")
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ class SessionNotifier:
|
|||||||
# Check environment variable for impossible booking notifications
|
# Check environment variable for impossible booking notifications
|
||||||
self.notify_impossible = os.environ.get("NOTIFY_IMPOSSIBLE_BOOKING", "true").lower() in ("true", "1", "yes")
|
self.notify_impossible = os.environ.get("NOTIFY_IMPOSSIBLE_BOOKING", "true").lower() in ("true", "1", "yes")
|
||||||
|
|
||||||
|
# Get crossfit username from environment
|
||||||
|
self.crossfit_username = os.environ.get("CROSSFIT_USERNAME", "User")
|
||||||
|
|
||||||
def send_email_notification(self, message):
|
def send_email_notification(self, message):
|
||||||
"""
|
"""
|
||||||
Send an email notification with the given message.
|
Send an email notification with the given message.
|
||||||
@@ -114,8 +117,8 @@ class SessionNotifier:
|
|||||||
session_details (str): Details about the booked session
|
session_details (str): Details about the booked session
|
||||||
"""
|
"""
|
||||||
# Create messages for both email and Telegram
|
# Create messages for both email and Telegram
|
||||||
email_message = f"Session booked: {session_details}"
|
email_message = f"Session booked for {self.crossfit_username}: {session_details}"
|
||||||
telegram_message = f"Session booked: {session_details}"
|
telegram_message = f"Session booked for {self.crossfit_username}: {session_details}"
|
||||||
|
|
||||||
# Send notifications through enabled channels
|
# Send notifications through enabled channels
|
||||||
if self.enable_email:
|
if self.enable_email:
|
||||||
@@ -133,8 +136,8 @@ class SessionNotifier:
|
|||||||
days_until (int): Number of days until the session
|
days_until (int): Number of days until the session
|
||||||
"""
|
"""
|
||||||
# Create messages for both email and Telegram
|
# Create messages for both email and Telegram
|
||||||
email_message = f"Session available soon: {session_details} (in {days_until} days)"
|
email_message = f"Session available soon for {self.crossfit_username}: {session_details} (in {days_until} days)"
|
||||||
telegram_message = f"Session available soon: {session_details} (in {days_until} days)"
|
telegram_message = f"Session available soon for {self.crossfit_username}: {session_details} (in {days_until} days)"
|
||||||
|
|
||||||
# Send notifications through enabled channels
|
# Send notifications through enabled channels
|
||||||
if self.enable_email:
|
if self.enable_email:
|
||||||
@@ -164,8 +167,8 @@ class SessionNotifier:
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Create messages for both email and Telegram
|
# Create messages for both email and Telegram
|
||||||
email_message = f"Failed to book session: {session_details}"
|
email_message = f"Failed to book session for {self.crossfit_username}: {session_details}"
|
||||||
telegram_message = f"Failed to book session: {session_details}"
|
telegram_message = f"Failed to book session for {self.crossfit_username}: {session_details}"
|
||||||
|
|
||||||
# Send notifications through enabled channels
|
# Send notifications through enabled channels
|
||||||
if self.enable_email:
|
if self.enable_email:
|
||||||
|
|||||||
@@ -37,18 +37,17 @@ class TestSessionConfig:
|
|||||||
"""Test behavior when the config file is not found"""
|
"""Test behavior when the config file is not found"""
|
||||||
# Mock the open function to raise FileNotFoundError
|
# Mock the open function to raise FileNotFoundError
|
||||||
with patch('builtins.open', side_effect=FileNotFoundError):
|
with patch('builtins.open', side_effect=FileNotFoundError):
|
||||||
with patch('logging.warning') as mock_warning:
|
with patch('logging.error') as mock_error:
|
||||||
sessions = SessionConfig.load_preferred_sessions()
|
with pytest.raises(SystemExit) as excinfo:
|
||||||
|
SessionConfig.load_preferred_sessions()
|
||||||
|
|
||||||
# Verify warning was logged
|
# Verify error was logged
|
||||||
mock_warning.assert_called_once()
|
assert mock_error.call_count == 2
|
||||||
assert "not found" in mock_warning.call_args[0][0]
|
assert "not found" in mock_error.call_args_list[0][0][0]
|
||||||
|
assert "example" in mock_error.call_args_list[1][0][0]
|
||||||
|
|
||||||
# Verify default sessions are returned
|
# Verify SystemExit was raised with exit code 1
|
||||||
assert len(sessions) == 3
|
assert excinfo.value.code == 1
|
||||||
assert sessions[0] == (2, "18:30", "CONDITIONING")
|
|
||||||
assert sessions[1] == (4, "17:00", "WEIGHTLIFTING")
|
|
||||||
assert sessions[2] == (5, "12:30", "HYROX")
|
|
||||||
|
|
||||||
def test_load_preferred_sessions_invalid_json(self):
|
def test_load_preferred_sessions_invalid_json(self):
|
||||||
"""Test behavior when the config file contains invalid JSON"""
|
"""Test behavior when the config file contains invalid JSON"""
|
||||||
@@ -57,18 +56,16 @@ class TestSessionConfig:
|
|||||||
|
|
||||||
# Mock the open function to return invalid JSON
|
# Mock the open function to return invalid JSON
|
||||||
with patch('builtins.open', mock_open(read_data=invalid_json)):
|
with patch('builtins.open', mock_open(read_data=invalid_json)):
|
||||||
with patch('logging.warning') as mock_warning:
|
with patch('logging.error') as mock_error:
|
||||||
sessions = SessionConfig.load_preferred_sessions()
|
with pytest.raises(SystemExit) as excinfo:
|
||||||
|
SessionConfig.load_preferred_sessions()
|
||||||
|
|
||||||
# Verify warning was logged
|
# Verify error was logged
|
||||||
mock_warning.assert_called_once()
|
mock_error.assert_called_once()
|
||||||
assert "decode" in mock_warning.call_args[0][0]
|
assert "decode" in mock_error.call_args[0][0]
|
||||||
|
|
||||||
# Verify default sessions are returned
|
# Verify SystemExit was raised with exit code 1
|
||||||
assert len(sessions) == 3
|
assert excinfo.value.code == 1
|
||||||
assert sessions[0] == (2, "18:30", "CONDITIONING")
|
|
||||||
assert sessions[1] == (4, "17:00", "WEIGHTLIFTING")
|
|
||||||
assert sessions[2] == (5, "12:30", "HYROX")
|
|
||||||
|
|
||||||
def test_load_preferred_sessions_empty_file(self):
|
def test_load_preferred_sessions_empty_file(self):
|
||||||
"""Test behavior when the config file is empty"""
|
"""Test behavior when the config file is empty"""
|
||||||
@@ -79,11 +76,8 @@ class TestSessionConfig:
|
|||||||
with patch('builtins.open', mock_open(read_data=empty_json)):
|
with patch('builtins.open', mock_open(read_data=empty_json)):
|
||||||
sessions = SessionConfig.load_preferred_sessions()
|
sessions = SessionConfig.load_preferred_sessions()
|
||||||
|
|
||||||
# Verify default sessions are returned
|
# Verify empty list is returned
|
||||||
assert len(sessions) == 3
|
assert sessions == []
|
||||||
assert sessions[0] == (2, "18:30", "CONDITIONING")
|
|
||||||
assert sessions[1] == (4, "17:00", "WEIGHTLIFTING")
|
|
||||||
assert sessions[2] == (5, "12:30", "HYROX")
|
|
||||||
|
|
||||||
def test_load_preferred_sessions_missing_fields(self):
|
def test_load_preferred_sessions_missing_fields(self):
|
||||||
"""Test behavior when some fields are missing in the JSON data"""
|
"""Test behavior when some fields are missing in the JSON data"""
|
||||||
@@ -111,18 +105,16 @@ class TestSessionConfig:
|
|||||||
|
|
||||||
# Mock the open function to return partial JSON
|
# Mock the open function to return partial JSON
|
||||||
with patch('builtins.open', mock_open(read_data=partial_json)):
|
with patch('builtins.open', mock_open(read_data=partial_json)):
|
||||||
with patch('logging.warning') as mock_warning:
|
with patch('logging.error') as mock_error:
|
||||||
sessions = SessionConfig.load_preferred_sessions()
|
with pytest.raises(SystemExit) as excinfo:
|
||||||
|
SessionConfig.load_preferred_sessions()
|
||||||
|
|
||||||
# Verify warning was logged
|
# Verify error was logged
|
||||||
mock_warning.assert_called_once()
|
mock_error.assert_called_once()
|
||||||
assert "decode" in mock_warning.call_args[0][0]
|
assert "decode" in mock_error.call_args[0][0]
|
||||||
|
|
||||||
# Verify default sessions are returned
|
# Verify SystemExit was raised with exit code 1
|
||||||
assert len(sessions) == 3
|
assert excinfo.value.code == 1
|
||||||
assert sessions[0] == (2, "18:30", "CONDITIONING")
|
|
||||||
assert sessions[1] == (4, "17:00", "WEIGHTLIFTING")
|
|
||||||
assert sessions[2] == (5, "12:30", "HYROX")
|
|
||||||
|
|
||||||
def test_load_preferred_sessions_incorrect_field_types(self):
|
def test_load_preferred_sessions_incorrect_field_types(self):
|
||||||
"""Test behavior when the config file contains JSON with incorrect field types"""
|
"""Test behavior when the config file contains JSON with incorrect field types"""
|
||||||
|
|||||||
Reference in New Issue
Block a user