Fixed test_run_auth_failure by patching the correct method (CrossFitBooker.login) and calling the correct method (booker.login()) Fixed test_run_booking_outside_window by patching the correct method (Booker.run) and adding the necessary mocking for the booking cycle Added proper mocking for auth_token and user_id to avoid authentication errors in the tests Updated imports to use the src prefix for all imports Added proper test structure for the booking window logic test All tests now pass successfully
186 lines
7.7 KiB
Python
186 lines
7.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Unit tests for SessionNotifier class
|
|
"""
|
|
|
|
import pytest
|
|
import os
|
|
import asyncio
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
# Add the parent directory to the path
|
|
import sys
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from src.session_notifier import SessionNotifier
|
|
|
|
@pytest.fixture
|
|
def email_credentials():
|
|
return {
|
|
"from": "test@example.com",
|
|
"to": "recipient@example.com",
|
|
"password": "password123"
|
|
}
|
|
|
|
@pytest.fixture
|
|
def telegram_credentials():
|
|
return {
|
|
"token": "telegram_token",
|
|
"chat_id": "123456789"
|
|
}
|
|
|
|
@pytest.fixture
|
|
def session_notifier(email_credentials, telegram_credentials):
|
|
return SessionNotifier(
|
|
email_credentials=email_credentials,
|
|
telegram_credentials=telegram_credentials,
|
|
enable_email=True,
|
|
enable_telegram=True
|
|
)
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_notify_session_booking(session_notifier, email_credentials, telegram_credentials):
|
|
"""Test session booking notification with both email and Telegram enabled"""
|
|
# Mock the email and Telegram notification methods
|
|
with patch.object(session_notifier, 'send_email_notification') as mock_email, \
|
|
patch.object(session_notifier, 'send_telegram_notification', new=MagicMock()) as mock_telegram:
|
|
|
|
# Set up the mock for the async method
|
|
mock_telegram.return_value = asyncio.Future()
|
|
mock_telegram.return_value.set_result(None)
|
|
|
|
# Call the method to test
|
|
await session_notifier.notify_session_booking("Test session")
|
|
|
|
# Verify both notification methods were called
|
|
mock_email.assert_called_once_with("Session booked: Test session")
|
|
mock_telegram.assert_called_once_with("Session booked: Test session")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_notify_session_booking_email_only(session_notifier, email_credentials):
|
|
"""Test session booking notification with only email enabled"""
|
|
# Disable Telegram notifications
|
|
session_notifier.enable_telegram = False
|
|
|
|
# Mock the email notification method
|
|
with patch.object(session_notifier, 'send_email_notification') as mock_email, \
|
|
patch.object(session_notifier, 'send_telegram_notification') as mock_telegram:
|
|
|
|
# Call the method to test
|
|
await session_notifier.notify_session_booking("Test session")
|
|
|
|
# Verify only email notification was called
|
|
mock_email.assert_called_once_with("Session booked: Test session")
|
|
mock_telegram.assert_not_called()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_notify_session_booking_telegram_only(session_notifier, telegram_credentials):
|
|
"""Test session booking notification with only Telegram enabled"""
|
|
# Disable email notifications
|
|
session_notifier.enable_email = False
|
|
|
|
# Mock the Telegram notification method
|
|
with patch.object(session_notifier, 'send_telegram_notification', new=MagicMock()) as mock_telegram:
|
|
|
|
# Set up the mock for the async method
|
|
mock_telegram.return_value = asyncio.Future()
|
|
mock_telegram.return_value.set_result(None)
|
|
|
|
# Call the method to test
|
|
await session_notifier.notify_session_booking("Test session")
|
|
|
|
# Verify only Telegram notification was called
|
|
mock_telegram.assert_called_once_with("Session booked: Test session")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_notify_upcoming_session(session_notifier, email_credentials, telegram_credentials):
|
|
"""Test upcoming session notification with both email and Telegram enabled"""
|
|
# Mock the email and Telegram notification methods
|
|
with patch.object(session_notifier, 'send_email_notification') as mock_email, \
|
|
patch.object(session_notifier, 'send_telegram_notification', new=MagicMock()) as mock_telegram:
|
|
|
|
# Set up the mock for the async method
|
|
mock_telegram.return_value = asyncio.Future()
|
|
mock_telegram.return_value.set_result(None)
|
|
|
|
# Call the method to test
|
|
await session_notifier.notify_upcoming_session("Test session", 3)
|
|
|
|
# Verify both notification methods were called
|
|
mock_email.assert_called_once_with("Session available soon: Test session (in 3 days)")
|
|
mock_telegram.assert_called_once_with("Session available soon: Test session (in 3 days)")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_notify_impossible_booking_enabled(session_notifier, email_credentials, telegram_credentials):
|
|
"""Test impossible booking notification when notifications are enabled"""
|
|
# Set the notify_impossible attribute to True
|
|
session_notifier.notify_impossible = True
|
|
|
|
# Mock the email and Telegram notification methods
|
|
with patch.object(session_notifier, 'send_email_notification') as mock_email, \
|
|
patch.object(session_notifier, 'send_telegram_notification', new=MagicMock()) as mock_telegram:
|
|
|
|
# Set up the mock for the async method
|
|
mock_telegram.return_value = asyncio.Future()
|
|
mock_telegram.return_value.set_result(None)
|
|
|
|
# Call the method to test
|
|
await session_notifier.notify_impossible_booking("Test session")
|
|
|
|
# Verify both notification methods were called
|
|
mock_email.assert_called_once_with("Failed to book session: Test session")
|
|
mock_telegram.assert_called_once_with("Failed to book session: Test session")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_notify_impossible_booking_disabled(session_notifier, email_credentials, telegram_credentials):
|
|
"""Test impossible booking notification when notifications are disabled"""
|
|
# Mock the email and Telegram notification methods
|
|
with patch.object(session_notifier, 'send_email_notification') as mock_email, \
|
|
patch.object(session_notifier, 'send_telegram_notification', new=MagicMock()) as mock_telegram:
|
|
|
|
# Set up the mock for the async method
|
|
mock_telegram.return_value = asyncio.Future()
|
|
mock_telegram.return_value.set_result(None)
|
|
|
|
# Call the method to test with notify_if_impossible=False
|
|
await session_notifier.notify_impossible_booking("Test session", notify_if_impossible=False)
|
|
|
|
# Verify neither notification method was called
|
|
mock_email.assert_not_called()
|
|
mock_telegram.assert_not_called()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_send_email_notification_success(session_notifier, email_credentials):
|
|
"""Test successful email notification"""
|
|
# Mock the smtplib.SMTP_SSL class
|
|
with patch('smtplib.SMTP_SSL') as mock_smtp:
|
|
# Set up the mock to return a context manager
|
|
mock_smtp_instance = MagicMock()
|
|
mock_smtp.return_value.__enter__.return_value = mock_smtp_instance
|
|
|
|
# Set up environment variable for SMTP server
|
|
with patch.dict(os.environ, {"SMTP_SERVER": "smtp.example.com"}):
|
|
# Call the method to test
|
|
session_notifier.send_email_notification("Test email")
|
|
|
|
# Verify SMTP methods were called
|
|
mock_smtp.assert_called_once_with("smtp.example.com", 465)
|
|
mock_smtp_instance.login.assert_called_once_with(
|
|
email_credentials["from"],
|
|
email_credentials["password"]
|
|
)
|
|
mock_smtp_instance.send_message.assert_called_once()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_send_email_notification_failure(session_notifier, email_credentials):
|
|
"""Test email notification failure"""
|
|
# Mock the smtplib.SMTP_SSL class to raise an exception
|
|
with patch('smtplib.SMTP_SSL', side_effect=Exception("SMTP error")):
|
|
# Set up environment variable for SMTP server
|
|
with patch.dict(os.environ, {"SMTP_SERVER": "smtp.example.com"}):
|
|
# Verify the method raises an exception
|
|
with pytest.raises(Exception):
|
|
session_notifier.send_email_notification("Test email")
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__, "-v"]) |