diff --git a/tests/service/test_photo_service.py b/tests/service/test_photo_service.py index faceacd..62009f7 100644 --- a/tests/service/test_photo_service.py +++ b/tests/service/test_photo_service.py @@ -1,5 +1,7 @@ import pytest from pathlib import Path + +from pilgrim import TravelDiary from pilgrim.service.photo_service import PhotoService import hashlib from unittest.mock import patch @@ -109,6 +111,114 @@ def test_check_photo_by_hash_returns_none_when_not_found(session_with_photos): result2 = service.check_photo_by_hash(existing_hash, invalid_diary_id) assert result2 is None +def test_update_photo_metadata_successfully(session_with_photos): + session, photos = session_with_photos + service = PhotoService(session) + photo_to_update = photos[0] + photo_with_new_data = Photo( + filepath=photo_to_update.filepath, + name="Novo Nome da Foto", + caption="Nova legenda para a foto.", + photo_hash=photo_to_update.photo_hash, # O hash não muda + addition_date=photo_to_update.addition_date, + fk_travel_diary_id=photo_to_update.fk_travel_diary_id + ) + updated_photo = service.update(photo_to_update, photo_with_new_data) + assert updated_photo is not None + assert updated_photo.name == "Novo Nome da Foto" + assert updated_photo.caption == "Nova legenda para a foto." + assert updated_photo.photo_hash == photo_to_update.photo_hash + photo_in_db = session.query(Photo).get(photo_to_update.id) + assert photo_in_db.name == "Novo Nome da Foto" + + +@patch.object(PhotoService, 'hash_file') +@patch('pathlib.Path.unlink') +@patch('pathlib.Path.exists') +@patch.object(PhotoService, '_copy_photo_to_diary') +@patch.object(DirectoryManager, 'get_diaries_root', return_value="/fake/diaries_root") +def test_update_photo_with_new_file_successfully( + mock_get_root, mock_copy, mock_exists, mock_unlink, mock_hash, session_with_photos +): + session, photos = session_with_photos + service = PhotoService(session) + photo_to_update = photos[0] + new_source_path = Path("/path/para/nova_imagem.jpg") + new_copied_path = Path(f"/fake/diaries_root/{photo_to_update.travel_diary.directory_name}/images/nova_imagem.jpg") + + mock_copy.return_value = new_copied_path + mock_exists.return_value = True + mock_hash.return_value = "novo_hash_calculado" + photo_with_new_file = Photo( + filepath=new_source_path, + name=photo_to_update.name, + photo_hash="hash_antigo", + fk_travel_diary_id=photo_to_update.fk_travel_diary_id + ) + updated_photo = service.update(photo_to_update, photo_with_new_file) + mock_copy.assert_called_once_with(new_source_path, photo_to_update.travel_diary) + mock_unlink.assert_called_once() + mock_hash.assert_called_once_with(new_copied_path) + assert updated_photo.filepath == str(new_copied_path) + assert updated_photo.photo_hash == "novo_hash_calculado" + +def test_update_photo_returns_none_if_photo_does_not_exist(db_session): + service = PhotoService(db_session) + non_existent_photo_src = Photo( + filepath="/fake/path.jpg", name="dummy", + photo_hash="dummy", fk_travel_diary_id=1 + ) + non_existent_photo_src.id = 999 + photo_with_new_data = Photo( + filepath="/fake/new.jpg", name="new dummy", + photo_hash="new_dummy", fk_travel_diary_id=1 + ) + result = service.update(non_existent_photo_src, photo_with_new_data) + assert result is None + + +@patch.object(PhotoService, 'hash_file') +@patch('pathlib.Path.unlink') +@patch('pathlib.Path.exists') +@patch.object(PhotoService, '_copy_photo_to_diary') +@patch.object(DirectoryManager, 'get_diaries_root', return_value="/fake/diaries_root") +def test_update_photo_with_new_file_successfully( + mock_get_root, mock_copy, mock_exists, mock_unlink, mock_hash, session_with_photos +): + session, photos = session_with_photos + service = PhotoService(session) + photo_to_update = photos[0] + new_source_path = Path("/path/para/nova_imagem.jpg") + new_copied_path = Path(f"/fake/diaries_root/{photo_to_update.travel_diary.directory_name}/images/nova_imagem.jpg") + mock_copy.return_value = new_copied_path + mock_exists.return_value = True + mock_hash.return_value = "novo_hash_calculado" + photo_with_new_file = Photo( + filepath=new_source_path, name=photo_to_update.name, + photo_hash="hash_antigo", fk_travel_diary_id=photo_to_update.fk_travel_diary_id + ) + updated_photo = service.update(photo_to_update, photo_with_new_file) + mock_copy.assert_called_once_with(new_source_path, photo_to_update.travel_diary) + mock_unlink.assert_called_once() + mock_hash.assert_called_once_with(new_copied_path) + + assert updated_photo.filepath == str(new_copied_path) + assert updated_photo.photo_hash == "novo_hash_calculado" + +@patch.object(DirectoryManager, 'get_diary_images_directory') +def test_copy_photo_to_diary_handles_name_collision_with_patch(mock_get_images_dir, db_session, tmp_path: Path): + images_dir = tmp_path / "images" + images_dir.mkdir() + mock_get_images_dir.return_value = images_dir + source_file = tmp_path / "foto.jpg" + source_file.touch() + (images_dir / "foto.jpg").touch() + service = PhotoService(db_session) + fake_diary = TravelDiary(name="test",directory_name="fake_diary") + copied_path = service._copy_photo_to_diary(source_file, fake_diary) + assert copied_path.name == "foto_1.jpg" + assert copied_path.exists() + @patch('pathlib.Path.unlink') @patch('pathlib.Path.exists') @patch.object(DirectoryManager, 'get_diaries_root', return_value="/fake/diaries_root")