"""Integration tests for image deletion endpoints.""" import pytest from httpx import AsyncClient from sqlalchemy.ext.asyncio import AsyncSession from uuid import uuid4 from app.database.models.user import User from app.database.models.board import Board from app.database.models.image import Image from app.database.models.board_image import BoardImage @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()