phase 13
All checks were successful
CI/CD Pipeline / VM Test - security (push) Successful in 7s
CI/CD Pipeline / Backend Linting (push) Successful in 4s
CI/CD Pipeline / VM Test - backend-integration (push) Successful in 11s
CI/CD Pipeline / VM Test - full-stack (push) Successful in 8s
CI/CD Pipeline / VM Test - performance (push) Successful in 8s
CI/CD Pipeline / Nix Flake Check (push) Successful in 38s
CI/CD Pipeline / CI Summary (push) Successful in 0s
CI/CD Pipeline / Frontend Linting (push) Successful in 17s

This commit is contained in:
Danilo Reyes
2025-11-02 14:48:03 -06:00
parent e5abcced74
commit 948fe591dc
28 changed files with 2123 additions and 54 deletions

View File

@@ -0,0 +1,289 @@
"""Integration tests for group endpoints."""
from uuid import uuid4
import pytest
from httpx import AsyncClient
from sqlalchemy.orm import Session
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
pytestmark = pytest.mark.asyncio
async def test_create_group(client: AsyncClient, test_user: User, db: Session):
"""Test creating a group with images."""
# Create 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)
# Create images
images = []
for i in range(3):
image = Image(
id=uuid4(),
user_id=test_user.id,
filename=f"test{i}.jpg",
storage_path=f"{test_user.id}/test{i}.jpg",
file_size=1024,
mime_type="image/jpeg",
width=800,
height=600,
metadata={"format": "jpeg", "checksum": f"abc{i}"},
)
db.add(image)
images.append(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},
z_order=i,
)
db.add(board_image)
db.commit()
# Create group
response = await client.post(
f"/api/boards/{board.id}/groups",
json={
"name": "Test Group",
"color": "#FF5733",
"annotation": "Group annotation",
"image_ids": [str(img.id) for img in images[:2]],
},
)
assert response.status_code == 201
data = response.json()
assert data["name"] == "Test Group"
assert data["color"] == "#FF5733"
assert data["annotation"] == "Group annotation"
assert data["member_count"] == 2
async def test_list_groups(client: AsyncClient, test_user: User, db: Session):
"""Test listing groups on a board."""
from app.database.models.group import Group
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)
# Create groups
for i in range(3):
group = Group(
id=uuid4(),
board_id=board.id,
name=f"Group {i}",
color=f"#FF573{i}",
annotation=f"Annotation {i}",
)
db.add(group)
db.commit()
# List groups
response = await client.get(f"/api/boards/{board.id}/groups")
assert response.status_code == 200
data = response.json()
assert len(data) == 3
assert data[0]["name"] == "Group 2" # Most recent first
async def test_get_group(client: AsyncClient, test_user: User, db: Session):
"""Test getting a specific group."""
from app.database.models.group import Group
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)
group = Group(
id=uuid4(),
board_id=board.id,
name="Test Group",
color="#FF5733",
annotation="Test annotation",
)
db.add(group)
db.commit()
# Get group
response = await client.get(f"/api/boards/{board.id}/groups/{group.id}")
assert response.status_code == 200
data = response.json()
assert data["name"] == "Test Group"
assert data["color"] == "#FF5733"
async def test_update_group(client: AsyncClient, test_user: User, db: Session):
"""Test updating group metadata."""
from app.database.models.group import Group
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)
group = Group(
id=uuid4(),
board_id=board.id,
name="Original Name",
color="#FF5733",
annotation="Original annotation",
)
db.add(group)
db.commit()
# Update group
response = await client.patch(
f"/api/boards/{board.id}/groups/{group.id}",
json={
"name": "Updated Name",
"color": "#00FF00",
"annotation": "Updated annotation",
},
)
assert response.status_code == 200
data = response.json()
assert data["name"] == "Updated Name"
assert data["color"] == "#00FF00"
assert data["annotation"] == "Updated annotation"
async def test_delete_group(client: AsyncClient, test_user: User, db: Session):
"""Test deleting a group."""
from app.database.models.group import Group
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)
# Create image
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": "abc"},
)
db.add(image)
# Create group
group = Group(
id=uuid4(),
board_id=board.id,
name="Test Group",
color="#FF5733",
)
db.add(group)
# Add image to board and group
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},
z_order=0,
group_id=group.id,
)
db.add(board_image)
db.commit()
# Delete group
response = await client.delete(f"/api/boards/{board.id}/groups/{group.id}")
assert response.status_code == 204
# Verify image is ungrouped
db.refresh(board_image)
assert board_image.group_id is None
async def test_group_unauthorized_board(client: AsyncClient, test_user: User, db: Session):
"""Test that users can't create groups on boards they don't own."""
# 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)
db.commit()
# Try to create group
response = await client.post(
f"/api/boards/{board.id}/groups",
json={
"name": "Test Group",
"color": "#FF5733",
"image_ids": [str(uuid4())],
},
)
assert response.status_code == 404 # Board not found (for security)
async def test_invalid_color_format(client: AsyncClient, test_user: User, db: Session):
"""Test that invalid color formats are rejected."""
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)
db.commit()
# Try with invalid color
response = await client.post(
f"/api/boards/{board.id}/groups",
json={
"name": "Test Group",
"color": "red", # Invalid: not hex
"image_ids": [str(uuid4())],
},
)
assert response.status_code == 422