import os from unittest.mock import patch import pytest from ra_aid.tools.write_file import put_complete_file_contents @pytest.fixture def temp_test_dir(tmp_path): """Create a temporary test directory.""" test_dir = tmp_path / "test_write_dir" test_dir.mkdir(exist_ok=True) return test_dir def test_basic_write_functionality(temp_test_dir): """Test basic successful file writing.""" test_file = temp_test_dir / "test.txt" content = "Hello, World!\nTest content" result = put_complete_file_contents( {"filepath": str(test_file), "complete_file_contents": content} ) # Verify file contents assert test_file.read_text() == content # Verify return dict format assert isinstance(result, dict) assert result["success"] is True assert result["filepath"] == str(test_file) assert result["bytes_written"] == len(content.encode("utf-8")) assert "Successfully wrote" in result["message"] assert "bytes" in result["message"] def test_directory_creation(temp_test_dir): """Test writing to a file in a non-existent directory.""" nested_dir = temp_test_dir / "nested" / "subdirs" test_file = nested_dir / "test.txt" content = "Test content" result = put_complete_file_contents( {"filepath": str(test_file), "complete_file_contents": content} ) assert test_file.exists() assert test_file.read_text() == content assert result["success"] is True def test_different_encodings(temp_test_dir): """Test writing files with different encodings.""" test_file = temp_test_dir / "encoded.txt" content = "Hello 世界" # Mixed ASCII and Unicode # Test UTF-8 result_utf8 = put_complete_file_contents( { "filepath": str(test_file), "complete_file_contents": content, "encoding": "utf-8", } ) assert result_utf8["success"] is True assert test_file.read_text(encoding="utf-8") == content # Test UTF-16 result_utf16 = put_complete_file_contents( { "filepath": str(test_file), "complete_file_contents": content, "encoding": "utf-16", } ) assert result_utf16["success"] is True assert test_file.read_text(encoding="utf-16") == content @patch("builtins.open") def test_permission_error(mock_open_func, temp_test_dir): """Test handling of permission errors.""" mock_open_func.side_effect = PermissionError("Permission denied") test_file = temp_test_dir / "noperm.txt" result = put_complete_file_contents( {"filepath": str(test_file), "complete_file_contents": "test content"} ) assert result["success"] is False assert "Permission denied" in result["message"] assert result["error"] is not None @patch("builtins.open") def test_io_error(mock_open_func, temp_test_dir): """Test handling of IO errors.""" mock_open_func.side_effect = IOError("IO Error occurred") test_file = temp_test_dir / "ioerror.txt" result = put_complete_file_contents( {"filepath": str(test_file), "complete_file_contents": "test content"} ) assert result["success"] is False assert "IO Error" in result["message"] assert result["error"] is not None def test_empty_content(temp_test_dir): """Test writing empty content to a file.""" test_file = temp_test_dir / "empty.txt" result = put_complete_file_contents({"filepath": str(test_file)}) assert test_file.exists() assert test_file.read_text() == "" assert result["success"] is True assert result["bytes_written"] == 0 assert "initialized empty file" in result["message"].lower() def test_write_empty_file_default(temp_test_dir): """Test creating an empty file using default parameter.""" test_file = temp_test_dir / "empty_default.txt" result = put_complete_file_contents({"filepath": str(test_file)}) assert test_file.exists() assert test_file.read_text() == "" assert result["success"] is True assert result["bytes_written"] == 0 assert "initialized empty file" in result["message"].lower() def test_overwrite_existing_file(temp_test_dir): """Test overwriting an existing file.""" test_file = temp_test_dir / "overwrite.txt" # Write initial content test_file.write_text("Initial content") # Overwrite with new content new_content = "New content" result = put_complete_file_contents( {"filepath": str(test_file), "complete_file_contents": new_content} ) assert test_file.read_text() == new_content assert result["success"] is True assert result["bytes_written"] == len(new_content.encode("utf-8")) def test_large_file_write(temp_test_dir): """Test writing a large file and verify statistics.""" test_file = temp_test_dir / "large.txt" content = "Large content\n" * 1000 # Create substantial content result = put_complete_file_contents( {"filepath": str(test_file), "complete_file_contents": content} ) assert test_file.exists() assert test_file.read_text() == content assert result["success"] is True assert result["bytes_written"] == len(content.encode("utf-8")) assert os.path.getsize(test_file) == len(content.encode("utf-8")) def test_invalid_path_characters(temp_test_dir): """Test handling of invalid path characters.""" invalid_path = temp_test_dir / "invalid\0file.txt" result = put_complete_file_contents( {"filepath": str(invalid_path), "complete_file_contents": "test content"} ) assert result["success"] is False assert "Invalid file path" in result["message"] def test_write_to_readonly_directory(temp_test_dir): """Test writing to a readonly directory.""" readonly_dir = temp_test_dir / "readonly" readonly_dir.mkdir() test_file = readonly_dir / "test.txt" # Make directory readonly os.chmod(readonly_dir, 0o444) try: result = put_complete_file_contents( {"filepath": str(test_file), "complete_file_contents": "test content"} ) assert result["success"] is False assert "Permission" in result["message"] finally: # Restore permissions for cleanup os.chmod(readonly_dir, 0o755)