diff --git a/src/pilgrim/models/entry.py b/src/pilgrim/models/entry.py index 7835067..7ae7abd 100644 --- a/src/pilgrim/models/entry.py +++ b/src/pilgrim/models/entry.py @@ -1,5 +1,6 @@ -from typing import Any +from typing import Any, List +from pilgrim.models.photo import Photo from pilgrim.models.photo_in_entry import photo_entry_association from sqlalchemy import Column, Integer, String, ForeignKey, DateTime from sqlalchemy.orm import relationship @@ -21,9 +22,12 @@ class Entry(Base): fk_travel_diary_id = Column(Integer, ForeignKey("travel_diaries.id"), nullable=False) travel_diary = relationship("TravelDiary", back_populates="entries") - def __init__(self, title: str, text: str, date: str, travel_diary_id: int, **kw: Any): + def __init__(self, title: str, text: str, date: Any, travel_diary_id: int, photos: List[Photo] = None, **kw: Any): super().__init__(**kw) self.title = title self.text = text self.date = date self.fk_travel_diary_id = travel_diary_id + if photos is not None: + self.photos = photos + diff --git a/tests/conftest.py b/tests/conftest.py index d2f50ba..b89d02d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,9 +4,12 @@ from unittest.mock import patch import pytest from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker +from datetime import datetime +from pilgrim.models.entry import Entry from pilgrim.database import Base from pilgrim.models.travel_diary import TravelDiary +from pilgrim.models.entry import Entry from pilgrim.models.photo import Photo from pilgrim.utils import DirectoryManager @@ -101,4 +104,36 @@ def backup_test_env_files_only(tmp_path): } session.close() +@pytest.fixture +def entry_with_photo_references(session_with_one_diary): + session, diary = session_with_one_diary + photo1 = Photo(filepath="p1.jpg", name="P1", photo_hash="aaaaaaaa", fk_travel_diary_id=diary.id) + photo2 = Photo(filepath="p2.jpg", name="P2", photo_hash="bbbbbbbb", fk_travel_diary_id=diary.id) + session.add_all([photo1, photo2]) + session.flush() + entry = Entry( + title="Entrada com Fotos", + text="Texto com a foto A [[photo::aaaaaaaa]] e também a foto B [[photo::bbbbbbbb]].", + date=datetime.now(), + travel_diary_id=diary.id, + photos=[photo1, photo2] + ) + session.add(entry) + session.commit() + session.refresh(entry) + + return session, entry + + +@pytest.fixture +def session_with_multiple_entries(session_with_one_diary): + session, diary = session_with_one_diary + session.query(Entry).delete() + entry1 = Entry(title="Entrada 1", text="Texto 1", date=datetime.now(), travel_diary_id=diary.id) + entry2 = Entry(title="Entrada 2", text="Texto 2", date=datetime.now(), travel_diary_id=diary.id) + + session.add_all([entry1, entry2]) + session.commit() + + return session, diary diff --git a/tests/service/test_entry_service.py b/tests/service/test_entry_service.py index cdad48f..5cab040 100644 --- a/tests/service/test_entry_service.py +++ b/tests/service/test_entry_service.py @@ -261,3 +261,46 @@ def test_delete_returns_none_if_entry_does_not_exist(db_session): non_existent_entry.id = 999 result = service.delete(non_existent_entry) assert result is None + +def test_delete_references_for_specific_photo(entry_with_photo_references): + session, entry = entry_with_photo_references + service = EntryService(session) + updated_entry = service.delete_references_for_specific_photo(entry, "aaaaaaaa") + assert "[[photo::aaaaaaaa]]" not in updated_entry.text + assert "[[photo::bbbbbbbb]]" in updated_entry.text + +def test_delete_specific_photo_reference_does_nothing_if_no_match(entry_with_photo_references): + session, entry = entry_with_photo_references + service = EntryService(session) + + original_text = entry.text + updated_entry = service.delete_references_for_specific_photo(entry, "cccccccc") + assert updated_entry.text == original_text + +def test_delete_all_photo_references_removes_all_refs(entry_with_photo_references): + session, entry = entry_with_photo_references + service = EntryService(session) + updated_entry = service.delete_all_photo_references(entry) + assert "[[photo::aaaaaaaa]]" not in updated_entry.text + assert "[[photo::bbbbbbbb]]" not in updated_entry.text + +def test_delete_all_photo_references_uses_truncated_hash(session_with_one_diary): + session, diary = session_with_one_diary + service = EntryService(session) + long_hash_photo = Photo( + filepath="long.jpg", name="Long", + photo_hash="1234567890abcdef", # Hash com 16 caracteres + fk_travel_diary_id=diary.id + ) + entry = Entry( + title="Teste de Hash Curto", + text="Referência com hash truncado [[photo::12345678]].", # Texto usa só os 8 primeiros + date=datetime.now(), + travel_diary_id=diary.id + ) + entry.photos.append(long_hash_photo) + session.add_all([long_hash_photo, entry]) + session.commit() + updated_entry = service.delete_all_photo_references(entry) + expected_text = "Referência com hash truncado ." + assert "[[photo::12345678]]" not in updated_entry.text diff --git a/tests/service/test_travel_diary_service.py b/tests/service/test_travel_diary_service.py index efab0f9..9a1e890 100644 --- a/tests/service/test_travel_diary_service.py +++ b/tests/service/test_travel_diary_service.py @@ -1,9 +1,12 @@ -from unittest.mock import patch, MagicMock from pathlib import Path +from unittest.mock import patch, MagicMock + import pytest -from pilgrim import TravelDiary +from pilgrim.models.photo import Photo +from pilgrim.models.travel_diary import TravelDiary +from pilgrim.models.entry import Entry from pilgrim.service.travel_diary_service import TravelDiaryService @patch.object(TravelDiaryService, '_ensure_diary_directory') @@ -140,4 +143,34 @@ def test_sanitize_directory_name_handles_uniqueness(db_session): db_session.commit() third_sanitized_name = service._sanitize_directory_name("Viagem para a Praia") - assert third_sanitized_name == "viagem_para_a_praia_2" \ No newline at end of file + assert third_sanitized_name == "viagem_para_a_praia_2" + +def test_delete_all_entries_successfully(session_with_multiple_entries): + session, diary = session_with_multiple_entries + service = TravelDiaryService(session) + diary_id = 1 + assert session.query(Entry).filter_by(fk_travel_diary_id=diary_id).count() == 2 + result = service.delete_all_entries(diary) + assert result is True + assert session.query(Entry).filter_by(fk_travel_diary_id=diary_id).count() == 0 + +@patch.object(TravelDiaryService, '_ensure_diary_directory') +@patch('pathlib.Path.unlink') +@patch('pathlib.Path.exists', return_value=True) +@patch('pilgrim.utils.DirectoryManager.get_diaries_root', return_value=Path("/fake/diaries_root")) +def test_delete_all_photos_orchestration( + mock_ensure_dir, mock_unlink, mock_exists, mock_get_root, entry_with_photo_references +): + session, entry = entry_with_photo_references + diary_id = entry.fk_travel_diary_id + service = TravelDiaryService(session) + assert session.query(Photo).filter_by(fk_travel_diary_id=diary_id).count() == 2 + assert "[[photo::" in entry.text + diary = session.get(TravelDiary, diary_id) + result = service.delete_all_photos(diary) + assert result is True + photos_after_delete = session.query(Photo).filter_by(fk_travel_diary_id=diary_id).all() + assert len(photos_after_delete) == 0 + session.refresh(entry) + assert "[[photo::" not in entry.text + assert mock_unlink.call_count == 2