feat(api): implement notebook management CRUD endpoints

Implement Sprint 1: Notebook Management CRUD

- Add NotebookService with full CRUD operations
- Add POST /api/v1/notebooks (create notebook)
- Add GET /api/v1/notebooks (list with pagination)
- Add GET /api/v1/notebooks/{id} (get by ID)
- Add PATCH /api/v1/notebooks/{id} (partial update)
- Add DELETE /api/v1/notebooks/{id} (delete)
- Add Pydantic models for requests/responses
- Add custom exceptions (ValidationError, NotFoundError, NotebookLMError)
- Add comprehensive unit tests (31 tests, 97% coverage)
- Add API integration tests (26 tests)
- Fix router prefix duplication
- Fix JSON serialization in error responses

BREAKING CHANGE: None
This commit is contained in:
Luca Sacchi Ricciardi
2026-04-06 01:13:13 +02:00
commit 4b7a419a98
65 changed files with 10507 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
"""Tests for logging module."""
from unittest.mock import MagicMock, patch
import pytest
import structlog
from notebooklm_agent.core.config import Settings
from notebooklm_agent.core.logging import setup_logging
@pytest.mark.unit
class TestSetupLogging:
"""Test suite for setup_logging function."""
@patch("notebooklm_agent.core.logging.structlog.configure")
@patch("notebooklm_agent.core.logging.logging.basicConfig")
def test_configures_structlog(self, mock_basic_config, mock_structlog_configure):
"""Should configure structlog with correct processors."""
# Arrange
settings = Settings(log_level="INFO", log_format="json")
# Act
setup_logging(settings)
# Assert
mock_structlog_configure.assert_called_once()
call_args = mock_structlog_configure.call_args
assert "processors" in call_args.kwargs
@patch("notebooklm_agent.core.logging.structlog.configure")
@patch("notebooklm_agent.core.logging.logging.basicConfig")
def test_uses_json_renderer_for_json_format(self, mock_basic_config, mock_structlog_configure):
"""Should use JSONRenderer for json log format."""
# Arrange
settings = Settings(log_level="INFO", log_format="json")
# Act
setup_logging(settings)
# Assert
processors = mock_structlog_configure.call_args.kwargs["processors"]
assert any("JSONRenderer" in str(p) for p in processors)
@patch("notebooklm_agent.core.logging.structlog.configure")
@patch("notebooklm_agent.core.logging.logging.basicConfig")
def test_uses_console_renderer_for_console_format(self, mock_basic_config, mock_structlog_configure):
"""Should use ConsoleRenderer for console log format."""
# Arrange
settings = Settings(log_level="INFO", log_format="console")
# Act
setup_logging(settings)
# Assert
processors = mock_structlog_configure.call_args.kwargs["processors"]
assert any("ConsoleRenderer" in str(p) for p in processors)
@patch("notebooklm_agent.core.logging.structlog.configure")
@patch("notebooklm_agent.core.logging.logging.basicConfig")
def test_sets_uvicorn_log_level(self, mock_basic_config, mock_structlog_configure):
"""Should set uvicorn loggers to WARNING."""
# Arrange
settings = Settings(log_level="INFO", log_format="json")
# Act
setup_logging(settings)
# Assert
# basicConfig should be called
mock_basic_config.assert_called_once()