"""Integration tests for image deletion endpoints.""" from uuid import uuid4 import pytest from httpx import AsyncClient from sqlalchemy.ext.asyncio import AsyncSession from app.database.models.board import Board from app.database.models.board_image import BoardImage from app.database.models.image import Image from app.database.models.user import User @pytest.mark.asyncio async def test_remove_image_from_board(client: AsyncClient, test_user: User, db: AsyncSession): """Test removing image from board (not deleting).""" # Create board and image board = Board( id=uuid4(), user_id=test_user.id, title="Test Board", viewport_state={"x": 0, "y": 0, "zoom": 1.0, "rotation": 0}, ) db.add(board) image = Image( id=uuid4(), user_id=test_user.id, filename="test.jpg", storage_path=f"{test_user.id}/test.jpg", file_size=1024, mime_type="image/jpeg", width=800, height=600, metadata={"format": "jpeg", "checksum": "abc123"}, reference_count=1, ) db.add(image) board_image = BoardImage( id=uuid4(), board_id=board.id, image_id=image.id, position={"x": 100, "y": 100}, transformations={ "scale": 1.0, "rotation": 0, "opacity": 1.0, "flipped_h": False, "flipped_v": False, "greyscale": False, }, z_order=0, ) db.add(board_image) await db.commit() # Remove from board response = await client.delete(f"/api/images/boards/{board.id}/images/{image.id}") assert response.status_code == 204 @pytest.mark.asyncio async def test_remove_image_not_on_board(client: AsyncClient, test_user: User, db: AsyncSession): """Test removing image that's not on the board.""" board = Board( id=uuid4(), user_id=test_user.id, title="Test Board", viewport_state={"x": 0, "y": 0, "zoom": 1.0, "rotation": 0}, ) db.add(board) image = Image( id=uuid4(), user_id=test_user.id, filename="test.jpg", storage_path=f"{test_user.id}/test.jpg", file_size=1024, mime_type="image/jpeg", width=800, height=600, metadata={"format": "jpeg", "checksum": "abc123"}, ) db.add(image) await db.commit() # Try to remove (image not on board) response = await client.delete(f"/api/images/boards/{board.id}/images/{image.id}") assert response.status_code == 404 @pytest.mark.asyncio async def test_remove_image_unauthorized(client: AsyncClient, test_user: User, db: AsyncSession): """Test removing image from board not owned by user.""" # Create another user other_user = User(id=uuid4(), email="other@example.com", password_hash="hashed") db.add(other_user) # Create board owned by other user board = Board( id=uuid4(), user_id=other_user.id, title="Other Board", viewport_state={"x": 0, "y": 0, "zoom": 1.0, "rotation": 0}, ) db.add(board) image = Image( id=uuid4(), user_id=other_user.id, filename="test.jpg", storage_path=f"{other_user.id}/test.jpg", file_size=1024, mime_type="image/jpeg", width=800, height=600, metadata={"format": "jpeg", "checksum": "abc123"}, ) db.add(image) board_image = BoardImage( id=uuid4(), board_id=board.id, image_id=image.id, position={"x": 100, "y": 100}, transformations={ "scale": 1.0, "rotation": 0, "opacity": 1.0, "flipped_h": False, "flipped_v": False, "greyscale": False, }, z_order=0, ) db.add(board_image) await db.commit() # Try to remove as current user response = await client.delete(f"/api/images/boards/{board.id}/images/{image.id}") assert response.status_code == 403 @pytest.mark.asyncio async def test_permanent_delete_image(client: AsyncClient, test_user: User, db: AsyncSession): """Test permanently deleting image from library.""" image = Image( id=uuid4(), user_id=test_user.id, filename="test.jpg", storage_path=f"{test_user.id}/test.jpg", file_size=1024, mime_type="image/jpeg", width=800, height=600, metadata={"format": "jpeg", "checksum": "abc123"}, reference_count=0, # Not used on any boards ) db.add(image) await db.commit() # Delete permanently response = await client.delete(f"/api/images/{image.id}") assert response.status_code == 204 @pytest.mark.asyncio async def test_cannot_delete_image_in_use(client: AsyncClient, test_user: User, db: AsyncSession): """Test that images in use cannot be permanently deleted.""" board = Board( id=uuid4(), user_id=test_user.id, title="Test Board", viewport_state={"x": 0, "y": 0, "zoom": 1.0, "rotation": 0}, ) db.add(board) image = Image( id=uuid4(), user_id=test_user.id, filename="test.jpg", storage_path=f"{test_user.id}/test.jpg", file_size=1024, mime_type="image/jpeg", width=800, height=600, metadata={"format": "jpeg", "checksum": "abc123"}, reference_count=1, # Used on a board ) db.add(image) board_image = BoardImage( id=uuid4(), board_id=board.id, image_id=image.id, position={"x": 100, "y": 100}, transformations={ "scale": 1.0, "rotation": 0, "opacity": 1.0, "flipped_h": False, "flipped_v": False, "greyscale": False, }, z_order=0, ) db.add(board_image) await db.commit() # Try to delete response = await client.delete(f"/api/images/{image.id}") assert response.status_code == 400 assert "still used" in response.json()["detail"].lower()