"""Tests for FileService."""
import base64
import pytest
class TestListFiles:
"""Tests for list_files method."""
def test_list_files_root(self, populated_temp_root, file_service):
"""Test listing files in root directory."""
result = file_service.list_files(".")
assert result.total_count >= 5
assert len(result.files) >= 5
file_names = {f.name for f in result.files}
assert "file1.txt" in file_names
assert "file2.txt" in file_names
assert "script.py" in file_names
def test_list_files_pattern(self, populated_temp_root, file_service):
"""Test listing files with pattern filter."""
result = file_service.list_files(".", pattern="*.txt")
assert result.total_count >= 2
for file in result.files:
assert file.name.endswith(".txt")
def test_list_files_subdirectory(self, populated_temp_root, file_service):
"""Test listing files in subdirectory."""
result = file_service.list_files("dir1")
assert result.total_count >= 2
file_names = {f.name for f in result.files}
assert "nested.txt" in file_names
def test_list_files_empty_directory(self, populated_temp_root, file_service):
"""Test listing files in empty directory."""
result = file_service.list_files("empty_dir")
assert result.total_count == 0
assert len(result.files) == 0
def test_list_files_not_found(self, file_service):
"""Test listing files in non-existent directory."""
with pytest.raises(FileNotFoundError):
file_service.list_files("nonexistent")
def test_list_files_binary_detection(self, populated_temp_root, file_service):
"""Test that binary files are correctly detected."""
result = file_service.list_files(".")
for file in result.files:
if file.name == "binary.bin":
assert file.is_binary is True
elif file.name.endswith(".txt"):
assert file.is_binary is False
class TestReadFile:
"""Tests for read_file method."""
def test_read_text_file(self, populated_temp_root, file_service):
"""Test reading a text file."""
result = file_service.read_file("file1.txt")
assert result.is_binary is False
assert result.encoding == "utf-8"
assert "Hello World" in result.content
assert result.total_size > 0
assert result.bytes_read > 0
def test_read_binary_file(self, populated_temp_root, file_service):
"""Test reading a binary file returns base64."""
result = file_service.read_file("binary.bin")
assert result.is_binary is True
assert result.encoding is None
# Verify it's valid base64
decoded = base64.b64decode(result.content)
assert decoded == b"\x00\x01\x02\x03\x04\x05\xff\xfe\xfd"
def test_read_file_with_offset(self, populated_temp_root, file_service):
"""Test reading file with offset."""
result = file_service.read_file("file1.txt", offset=6)
assert "World" in result.content
assert result.offset == 6
def test_read_file_with_limit(self, populated_temp_root, file_service):
"""Test reading file with limit."""
result = file_service.read_file("file1.txt", limit=10)
assert result.bytes_read == 10
assert len(result.content) <= 10
def test_read_file_with_offset_and_limit(self, populated_temp_root, file_service):
"""Test reading file with both offset and limit."""
result = file_service.read_file("file1.txt", offset=5, limit=5)
assert result.offset == 5
assert result.bytes_read == 5
def test_read_file_not_found(self, file_service):
"""Test reading non-existent file."""
with pytest.raises(FileNotFoundError):
file_service.read_file("nonexistent.txt")
class TestWriteFile:
"""Tests for write_file method."""
def test_write_text_file(self, temp_root, file_service):
"""Test writing a text file."""
content = "This is a test file\nWith multiple lines"
result = file_service.write_file("new.txt", content)
assert result.success is True
assert "written successfully" in result.message.lower()
# Verify file was created
file_path = temp_root / "new.txt"
assert file_path.exists()
assert file_path.read_text() == content
def test_write_binary_file(self, temp_root, file_service):
"""Test writing a binary file with base64."""
binary_data = b"\x00\x01\x02\x03\xff\xfe\xfd"
base64_content = base64.b64encode(binary_data).decode("ascii")
result = file_service.write_file("new.bin", base64_content, is_base64=True)
assert result.success is True
# Verify file was created with correct content
file_path = temp_root / "new.bin"
assert file_path.exists()
assert file_path.read_bytes() == binary_data
def test_write_file_creates_parent_dirs(self, temp_root, file_service):
"""Test writing file creates parent directories."""
result = file_service.write_file("parent/child/file.txt", "content")
assert result.success is True
assert (temp_root / "parent" / "child" / "file.txt").exists()
def test_write_file_overwrites(self, populated_temp_root, file_service):
"""Test writing to existing file overwrites it."""
original_content = (populated_temp_root / "file1.txt").read_text()
new_content = "Completely new content"
result = file_service.write_file("file1.txt", new_content)
assert result.success is True
assert (populated_temp_root / "file1.txt").read_text() == new_content
assert (populated_temp_root / "file1.txt").read_text() != original_content
class TestAppendFile:
"""Tests for append_file method."""
def test_append_to_file(self, populated_temp_root, file_service):
"""Test appending to existing file."""
original_content = (populated_temp_root / "file1.txt").read_text()
append_text = "\nAppended line"
result = file_service.append_file("file1.txt", append_text)
assert result.success is True
new_content = (populated_temp_root / "file1.txt").read_text()
assert new_content == original_content + append_text
def test_append_to_nonexistent_file(self, file_service):
"""Test appending to non-existent file fails."""
result = file_service.append_file("nonexistent.txt", "content")
assert result.success is False
assert "not found" in result.message.lower()
class TestDeleteFile:
"""Tests for delete_file method."""
def test_delete_file(self, populated_temp_root, file_service):
"""Test deleting a file."""
result = file_service.delete_file("file1.txt")
assert result.success is True
assert "deleted successfully" in result.message.lower()
assert not (populated_temp_root / "file1.txt").exists()
def test_delete_file_not_found(self, file_service):
"""Test deleting non-existent file."""
result = file_service.delete_file("nonexistent.txt")
assert result.success is False
assert "not found" in result.message.lower()
class TestMoveFile:
"""Tests for move_file method."""
def test_move_file_simple(self, populated_temp_root, file_service):
"""Test moving a file."""
original_content = (populated_temp_root / "file1.txt").read_text()
result = file_service.move_file("file1.txt", "renamed.txt")
assert result.success is True
assert not (populated_temp_root / "file1.txt").exists()
assert (populated_temp_root / "renamed.txt").exists()
assert (populated_temp_root / "renamed.txt").read_text() == original_content
def test_move_file_to_subdirectory(self, populated_temp_root, file_service):
"""Test moving file to subdirectory."""
result = file_service.move_file("file1.txt", "dir1/moved.txt")
assert result.success is True
assert not (populated_temp_root / "file1.txt").exists()
assert (populated_temp_root / "dir1" / "moved.txt").exists()
def test_move_file_source_not_found(self, file_service):
"""Test moving non-existent file."""
result = file_service.move_file("nonexistent.txt", "destination.txt")
assert result.success is False
assert "not found" in result.message.lower()
def test_move_file_destination_exists(self, populated_temp_root, file_service):
"""Test moving to existing destination fails."""
result = file_service.move_file("file1.txt", "file2.txt")
assert result.success is False
assert "already exists" in result.message.lower()
class TestGetFileMetadata:
"""Tests for get_file_metadata method."""
def test_get_file_metadata_text(self, populated_temp_root, file_service):
"""Test getting metadata for text file."""
result = file_service.get_file_metadata("file1.txt")
assert result.exists is True
assert result.is_binary is False
assert result.created > 0
assert result.modified > 0
assert result.accessed > 0
assert result.permissions is not None
def test_get_file_metadata_binary(self, populated_temp_root, file_service):
"""Test getting metadata for binary file."""
result = file_service.get_file_metadata("binary.bin")
assert result.exists is True
assert result.is_binary is True
def test_get_file_metadata_not_found(self, file_service):
"""Test metadata for non-existent file."""
result = file_service.get_file_metadata("nonexistent.txt")
assert result.exists is False
def test_get_file_metadata_mime_type(self, populated_temp_root, file_service):
"""Test MIME type detection."""
result = file_service.get_file_metadata("script.py")
assert result.exists is True
# Python files should have text/x-python or similar MIME type
assert result.mime_type is not None