"""Unit tests for edge cases. Note: File cleanup tests have been consolidated into test_processor.py. This file now focuses on file_utils edge cases and other standalone edge case tests. """ import os import tempfile class TestFileUtilsEdgeCases: """Tests for file_utils edge cases.""" def test_create_temp_file_creates_secure_file(self): """Test that create_temp_file creates a file with secure permissions.""" from src.utils.file_utils import create_temp_file temp_path = create_temp_file() try: # Verify file exists assert os.path.exists(temp_path) # Verify file has secure permissions (readable/writable by owner only) stat_info = os.stat(temp_path) mode = stat_info.st_mode & 0o777 # mkstemp creates files with 0600 permissions assert mode == 0o600 finally: if os.path.exists(temp_path): os.remove(temp_path) def test_create_temp_file_with_custom_dir(self): """Test create_temp_file with custom directory.""" from src.utils.file_utils import create_temp_file # Create a temporary directory with tempfile.TemporaryDirectory() as tmpdir: ref_file = os.path.join(tmpdir, 'reference.txt') # Create reference file with open(ref_file, 'w') as f: f.write('test') # Generate new path in same directory new_path = create_temp_file(ref_file) try: # Verify it's in the same directory (use realpath for macOS symlink resolution) assert os.path.realpath(os.path.dirname(new_path)) == os.path.realpath( tmpdir ) assert os.path.exists(new_path) finally: if os.path.exists(new_path): os.remove(new_path) def test_create_temp_file_multiple_calls_unique_names(self): """Test that multiple calls create unique temp files.""" from src.utils.file_utils import create_temp_file paths = [] try: # Create multiple temp files for _ in range(5): path = create_temp_file() paths.append(path) assert os.path.exists(path) # All paths should be unique assert len(set(paths)) == 5 finally: for path in paths: if os.path.exists(path): os.remove(path) def test_create_temp_file_survives_beyond_creation(self): """Test temp file persists after creation (not auto-deleted).""" from src.utils.file_utils import create_temp_file temp_path = create_temp_file() try: # Write to file with open(temp_path, 'w') as f: f.write('test data') # File should still exist and be readable with open(temp_path, 'r') as f: content = f.read() assert content == 'test data' finally: if os.path.exists(temp_path): os.remove(temp_path) def test_create_temp_file_writable(self): """Test temp file is writable.""" from src.utils.file_utils import create_temp_file temp_path = create_temp_file() try: # Should be able to write to file with open(temp_path, 'w') as f: f.write('x' * 1000) # Verify size assert os.path.getsize(temp_path) == 1000 finally: if os.path.exists(temp_path): os.remove(temp_path) class TestFileOperationEdgeCases: """Edge case tests for file operations.""" def test_large_file_handling(self): """Test handling of large file paths.""" from src.utils.file_utils import create_temp_file # Very long filename (within OS limits) with tempfile.TemporaryDirectory() as tmpdir: long_name = 'a' * 200 + '.txt' ref_file = os.path.join(tmpdir, long_name) with open(ref_file, 'w') as f: f.write('test') try: new_path = create_temp_file(ref_file) assert os.path.exists(new_path) os.remove(new_path) except OSError: # OS may have path length limits, this is acceptable pass def test_temp_file_with_special_chars_in_dirname(self): """Test temp file creation with special characters in directory name.""" from src.utils.file_utils import create_temp_file with tempfile.TemporaryDirectory() as tmpdir: # Create subdirectory with special chars special_dir = os.path.join(tmpdir, 'test-dir_123') os.makedirs(special_dir, exist_ok=True) ref_file = os.path.join(special_dir, 'ref.txt') with open(ref_file, 'w') as f: f.write('test') try: new_path = create_temp_file(ref_file) assert os.path.exists(new_path) assert os.path.dirname(new_path) == os.path.dirname(ref_file) os.remove(new_path) except Exception: pass def test_concurrent_temp_file_creation(self): """Test concurrent temp file creation doesn't cause conflicts.""" import threading from src.utils.file_utils import create_temp_file paths = [] lock = threading.Lock() errors = [] def create_file(): try: path = create_temp_file() with lock: paths.append(path) except Exception as e: with lock: errors.append(e) # Create files concurrently threads = [threading.Thread(target=create_file) for _ in range(10)] for thread in threads: thread.start() for thread in threads: thread.join() try: # Should have no errors assert len(errors) == 0 # All paths should be unique assert len(set(paths)) == 10 # All files should exist for path in paths: assert os.path.exists(path) finally: for path in paths: if os.path.exists(path): os.remove(path) def test_file_permissions_not_world_readable(self): """Test temp files are not world-readable for security.""" from src.utils.file_utils import create_temp_file temp_path = create_temp_file() try: stat_info = os.stat(temp_path) mode = stat_info.st_mode & 0o777 # Should not be readable by others (no 0o004 bit) assert not (mode & 0o004) # Should not be writable by others (no 0o002 bit) assert not (mode & 0o002) finally: if os.path.exists(temp_path): os.remove(temp_path) def test_temp_file_empty_initially(self): """Test temp file is empty when created.""" from src.utils.file_utils import create_temp_file temp_path = create_temp_file() try: assert os.path.getsize(temp_path) == 0 finally: if os.path.exists(temp_path): os.remove(temp_path) def test_temp_file_in_system_temp_dir_by_default(self): """Test temp file created in system temp directory by default.""" from src.utils.file_utils import create_temp_file temp_path = create_temp_file() try: # Should be in a temp directory # On macOS, /tmp and /var/folders are both valid temp directories # Check if it's in either /tmp or the system temp directory real_path = os.path.realpath(temp_path) system_tmp = os.path.realpath(tempfile.gettempdir()) # Accept either /private/tmp or system temp directory is_in_tmp = real_path.startswith('/private/tmp') or real_path.startswith( '/tmp' ) is_in_system_tmp = real_path.startswith(system_tmp) assert is_in_tmp or is_in_system_tmp, ( f'File not in temp directory. Path: {real_path}, ' f'System temp: {system_tmp}' ) finally: if os.path.exists(temp_path): os.remove(temp_path)