Files
crossfit/test/test_session_config.py

179 lines
7.8 KiB
Python

#!/usr/bin/env python3
"""
Unit tests for SessionConfig class
"""
import pytest
import os
import json
from unittest.mock import patch, mock_open
import logging
# Add the parent directory to the path
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from 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.warning') as mock_warning:
sessions = SessionConfig.load_preferred_sessions()
# Verify warning was logged
mock_warning.assert_called_once()
assert "not found" in mock_warning.call_args[0][0]
# Verify default sessions are returned
assert len(sessions) == 3
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):
"""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.warning') as mock_warning:
sessions = SessionConfig.load_preferred_sessions()
# Verify warning was logged
mock_warning.assert_called_once()
assert "decode" in mock_warning.call_args[0][0]
# Verify default sessions are returned
assert len(sessions) == 3
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):
"""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 default sessions are returned
assert len(sessions) == 3
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):
"""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.warning') as mock_warning:
sessions = SessionConfig.load_preferred_sessions()
# Verify warning was logged
mock_warning.assert_called_once()
assert "decode" in mock_warning.call_args[0][0]
# Verify default sessions are returned
assert len(sessions) == 3
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):
"""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"])