#!/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.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"])