- Add CROSSFIT_USERNAME from .env to all Telegram notifications - Make session_config exit safely when config file is missing or invalid - Remove default hardcoded sessions, return empty list instead - Update unit tests to reflect new error handling behavior 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
170 lines
7.3 KiB
Python
170 lines
7.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Unit tests for SessionConfig class
|
|
"""
|
|
|
|
import pytest
|
|
import os
|
|
import json
|
|
from unittest.mock import patch, mock_open
|
|
|
|
# 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_config import SessionConfig
|
|
|
|
class TestSessionConfig:
|
|
|
|
def test_load_preferred_sessions_valid_file(self):
|
|
"""Test loading preferred sessions from a valid JSON file"""
|
|
# Create a mock JSON file content
|
|
mock_content = json.dumps([
|
|
{"day_of_week": 1, "start_time": "08:00", "session_name_contains": "Morning"},
|
|
{"day_of_week": 3, "start_time": "18:00", "session_name_contains": "Evening"}
|
|
])
|
|
|
|
# Mock the open function to return our mock file content
|
|
with patch('builtins.open', mock_open(read_data=mock_content)):
|
|
sessions = SessionConfig.load_preferred_sessions()
|
|
|
|
# Verify the returned sessions match our mock content
|
|
assert len(sessions) == 2
|
|
assert sessions[0] == (1, "08:00", "Morning")
|
|
assert sessions[1] == (3, "18:00", "Evening")
|
|
|
|
def test_load_preferred_sessions_file_not_found(self):
|
|
"""Test behavior when the config file is not found"""
|
|
# Mock the open function to raise FileNotFoundError
|
|
with patch('builtins.open', side_effect=FileNotFoundError):
|
|
with patch('logging.error') as mock_error:
|
|
with pytest.raises(SystemExit) as excinfo:
|
|
SessionConfig.load_preferred_sessions()
|
|
|
|
# Verify error was logged
|
|
assert mock_error.call_count == 2
|
|
assert "not found" in mock_error.call_args_list[0][0][0]
|
|
assert "example" in mock_error.call_args_list[1][0][0]
|
|
|
|
# Verify SystemExit was raised with exit code 1
|
|
assert excinfo.value.code == 1
|
|
|
|
def test_load_preferred_sessions_invalid_json(self):
|
|
"""Test behavior when the config file contains invalid JSON"""
|
|
# Create invalid JSON content
|
|
invalid_json = "{invalid json content}"
|
|
|
|
# Mock the open function to return invalid JSON
|
|
with patch('builtins.open', mock_open(read_data=invalid_json)):
|
|
with patch('logging.error') as mock_error:
|
|
with pytest.raises(SystemExit) as excinfo:
|
|
SessionConfig.load_preferred_sessions()
|
|
|
|
# Verify error was logged
|
|
mock_error.assert_called_once()
|
|
assert "decode" in mock_error.call_args[0][0]
|
|
|
|
# Verify SystemExit was raised with exit code 1
|
|
assert excinfo.value.code == 1
|
|
|
|
def test_load_preferred_sessions_empty_file(self):
|
|
"""Test behavior when the config file is empty"""
|
|
# Create empty JSON content
|
|
empty_json = json.dumps([])
|
|
|
|
# Mock the open function to return empty JSON
|
|
with patch('builtins.open', mock_open(read_data=empty_json)):
|
|
sessions = SessionConfig.load_preferred_sessions()
|
|
|
|
# Verify empty list is returned
|
|
assert sessions == []
|
|
|
|
def test_load_preferred_sessions_missing_fields(self):
|
|
"""Test behavior when some fields are missing in the JSON data"""
|
|
# Create JSON with missing fields
|
|
mock_content = json.dumps([
|
|
{"day_of_week": 1}, # Missing start_time and session_name_contains
|
|
{"start_time": "18:00"}, # Missing day_of_week and session_name_contains
|
|
{"session_name_contains": "Test"} # Missing day_of_week and start_time
|
|
])
|
|
|
|
# Mock the open function to return our mock file content
|
|
with patch('builtins.open', mock_open(read_data=mock_content)):
|
|
sessions = SessionConfig.load_preferred_sessions()
|
|
|
|
# Verify the returned sessions have default values for missing fields
|
|
assert len(sessions) == 3
|
|
assert sessions[0] == (1, "00:00", "")
|
|
assert sessions[1] == (0, "18:00", "")
|
|
assert sessions[2] == (0, "00:00", "Test")
|
|
|
|
def test_load_preferred_sessions_partial_json(self):
|
|
"""Test behavior when the config file contains partial JSON content"""
|
|
# Create partial JSON content
|
|
partial_json = '{"day_of_week": 1, "start_time": "08:00" ' # Missing closing brace
|
|
|
|
# Mock the open function to return partial JSON
|
|
with patch('builtins.open', mock_open(read_data=partial_json)):
|
|
with patch('logging.error') as mock_error:
|
|
with pytest.raises(SystemExit) as excinfo:
|
|
SessionConfig.load_preferred_sessions()
|
|
|
|
# Verify error was logged
|
|
mock_error.assert_called_once()
|
|
assert "decode" in mock_error.call_args[0][0]
|
|
|
|
# Verify SystemExit was raised with exit code 1
|
|
assert excinfo.value.code == 1
|
|
|
|
def test_load_preferred_sessions_incorrect_field_types(self):
|
|
"""Test behavior when the config file contains JSON with incorrect field types"""
|
|
# Create JSON with incorrect field types
|
|
mock_content = json.dumps([
|
|
{"day_of_week": "Monday", "start_time": "08:00", "session_name_contains": "Morning"},
|
|
{"day_of_week": 1, "start_time": 800, "session_name_contains": "Morning"},
|
|
])
|
|
|
|
# Mock the open function to return our mock file content
|
|
with patch('builtins.open', mock_open(read_data=mock_content)):
|
|
sessions = SessionConfig.load_preferred_sessions()
|
|
|
|
# Verify the returned sessions use the values as provided
|
|
assert len(sessions) == 2
|
|
assert sessions[0] == ("Monday", "08:00", "Morning")
|
|
assert sessions[1] == (1, 800, "Morning")
|
|
|
|
def test_load_preferred_sessions_extra_fields(self):
|
|
"""Test behavior when the config file contains JSON with extra fields"""
|
|
# Create JSON with extra fields
|
|
mock_content = json.dumps([
|
|
{"day_of_week": 1, "start_time": "08:00", "session_name_contains": "Morning", "extra_field": "extra_value"},
|
|
])
|
|
|
|
# Mock the open function to return our mock file content
|
|
with patch('builtins.open', mock_open(read_data=mock_content)):
|
|
sessions = SessionConfig.load_preferred_sessions()
|
|
|
|
# Verify the returned sessions ignore extra fields
|
|
assert len(sessions) == 1
|
|
assert sessions[0] == (1, "08:00", "Morning")
|
|
|
|
def test_load_preferred_sessions_duplicate_entries(self):
|
|
"""Test behavior when the config file contains duplicate session entries"""
|
|
# Create JSON with duplicate entries
|
|
mock_content = json.dumps([
|
|
{"day_of_week": 1, "start_time": "08:00", "session_name_contains": "Morning"},
|
|
{"day_of_week": 1, "start_time": "08:00", "session_name_contains": "Morning"},
|
|
])
|
|
|
|
# Mock the open function to return our mock file content
|
|
with patch('builtins.open', mock_open(read_data=mock_content)):
|
|
sessions = SessionConfig.load_preferred_sessions()
|
|
|
|
# Verify the returned sessions contain duplicates
|
|
assert len(sessions) == 2
|
|
assert sessions[0] == (1, "08:00", "Morning")
|
|
assert sessions[1] == (1, "08:00", "Morning")
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__, "-v"])
|