Files
chitai/backend/tests/unit/test_services/test_library_service.py
2025-12-04 00:33:37 -05:00

154 lines
5.0 KiB
Python

"""Tests for LibraryService"""
import pytest
from pathlib import Path
from sqlalchemy.ext.asyncio import AsyncSession
from chitai.schemas.library import LibraryCreate
from chitai.services import LibraryService
from chitai.database import models as m
from chitai.services.utils import DirectoryDoesNotExist
@pytest.mark.asyncio
class TestLibraryServiceCRUD:
"""Test CRUD operation for libraries."""
async def test_create_library(
self, library_service: LibraryService, tmp_path: Path
) -> None:
"""Test creating a library with a valid root path."""
library_path = f"{tmp_path}/books"
library_data = LibraryCreate(
name="Test Library",
root_path=library_path,
path_template="{author}/{title}",
read_only=False,
)
library = await library_service.create(library_data)
assert library.name == "Test Library"
assert library.root_path == library_path
assert library.path_template == "{author}/{title}"
assert library.description == None
assert library.read_only == False
# Check if directory was created
assert Path(library.root_path).is_dir()
async def test_create_library_root_path_permission_error(
self, library_service: LibraryService, tmp_path: Path
) -> None:
"""Test creating a library with a root path that is not permitted."""
# Change permissions on the temp path
tmp_path.chmod(0o544)
library_path = f"{tmp_path}/books"
library_data = LibraryCreate(
name="Test Library",
root_path=library_path,
path_template="{author}/{title}",
read_only=False,
)
with pytest.raises(PermissionError) as exc_info:
library = await library_service.create(library_data)
# Check if directory was created
assert not Path(library_path).exists()
# Change permissions back
tmp_path.chmod(0o755)
async def test_create_library_read_only_path_exists(
self, library_service: LibraryService, tmp_path: Path
) -> None:
"""Test creating a read-only library with a root path that exists."""
# Create the path beforehand
library_path = f"{tmp_path}/books"
Path(library_path).mkdir()
library_data = LibraryCreate(
name="Test Library",
root_path=library_path,
path_template="{author}/{title}",
read_only=True,
)
library = await library_service.create(library_data)
assert library.name == "Test Library"
assert library.root_path == library_path
assert library.path_template == "{author}/{title}"
assert library.description == None
assert library.read_only == True
async def test_create_library_read_only_nonexistent_path(
self, library_service: LibraryService, tmp_path: Path
) -> None:
"""Test creating a read-only library with a nonexistent root path."""
library_path = f"{tmp_path}/books"
library_data = LibraryCreate(
name="Test Library",
root_path=library_path,
path_template="{author}/{title}",
read_only=True,
)
with pytest.raises(DirectoryDoesNotExist) as exc_info:
await library_service.create(library_data)
assert "Root directory" in str(exc_info.value)
assert "must exist for a read-only library" in str(exc_info.value)
# Check if directory was created
assert not Path(library_path).exists()
async def test_get_library(
self, session: AsyncSession, library_service: LibraryService
) -> None:
"""Test retrieving a library."""
# Add a library to the database
library_data = m.Library(
name="Testing Library",
slug="testing-library",
root_path="./books",
path_template="{author}/{title}",
description=None,
read_only=False,
)
session.add(library_data)
await session.commit()
await session.refresh(library_data)
library = await library_service.get(library_data.id)
assert library is not None
assert library.id == library_data.id
assert library.name == "Testing Library"
assert library.root_path == "./books"
assert library.path_template == "{author}/{title}"
assert library.description is None
assert library.read_only == False
# async def test_delete_library_keep_files(
# self, session: AsyncSession, library_service: LibraryService
# ) -> None:
# """Test deletion of a library's metadata and associated entities."""
# raise NotImplementedError()
# async def test_delete_library_delete_files(
# self, session: AsyncSession, library_service: LibraryService
# ) -> None:
# """Test deletion of a library's metadata, associated enties, and files/directories."""
# raise NotImplementedError()