ProjectMemory / backend /tests /test_user_models.py
Amal Nimmy Lal
feat : Project Memory
35765b5
"""Unit tests for models module."""
import pytest
from datetime import datetime
from app.database import SessionLocal, init_db
from app.models import (
User, Project, Task, LogEntry, ProjectMembership,
generate_uuid, generate_user_id,
TaskStatus, ActorType, ActionType
)
class TestGenerateUserId:
"""Test user ID generation function."""
def test_generate_user_id_format(self):
"""Test generated ID has correct format: 3 letters + 4 digits."""
user_id = generate_user_id("Alice")
assert len(user_id) == 7
assert user_id[:3] == "ali" # First 3 letters lowercase
assert user_id[3:].isdigit() # Last 4 are digits
def test_generate_user_id_lowercase(self):
"""Test first name is lowercased."""
user_id = generate_user_id("JOHN")
assert user_id[:3] == "joh"
def test_generate_user_id_short_name(self):
"""Test with name shorter than 3 characters."""
user_id = generate_user_id("Jo")
assert user_id[:2] == "jo"
assert len(user_id) == 6 # 2 letters + 4 digits
def test_generate_user_id_uniqueness(self):
"""Test that multiple calls generate different IDs."""
ids = [generate_user_id("Test") for _ in range(10)]
# With 4 random digits, collisions are unlikely
assert len(set(ids)) > 5 # At least some should be unique
def test_generate_user_id_example(self):
"""Test example from requirements: Amal -> ama + 4 digits."""
user_id = generate_user_id("Amal")
assert user_id.startswith("ama")
assert len(user_id) == 7
class TestGenerateUuid:
"""Test UUID generation function."""
def test_generate_uuid_format(self):
"""Test UUID is valid format."""
uuid = generate_uuid()
assert len(uuid) == 36 # Standard UUID length with hyphens
assert uuid.count("-") == 4
def test_generate_uuid_uniqueness(self):
"""Test UUIDs are unique."""
uuids = [generate_uuid() for _ in range(100)]
assert len(set(uuids)) == 100
class TestUserModel:
"""Test User model."""
def test_user_creation(self, db_session):
"""Test creating a user with new fields."""
user_id = generate_user_id("Test")
user = User(
id=user_id,
first_name="Test",
last_name="User"
)
db_session.add(user)
db_session.commit()
assert user.id == user_id
assert user.first_name == "Test"
assert user.last_name == "User"
assert user.created_at is not None
def test_user_name_property(self, db_session):
"""Test the name property returns full name."""
user_id = generate_user_id("John")
user = User(id=user_id, first_name="John", last_name="Doe")
db_session.add(user)
db_session.commit()
assert user.name == "John Doe"
def test_user_optional_avatar(self, db_session):
"""Test avatar_url is optional."""
user_id = generate_user_id("Jane")
user = User(id=user_id, first_name="Jane", last_name="Smith")
db_session.add(user)
db_session.commit()
assert user.avatar_url is None
def test_user_with_avatar(self, db_session):
"""Test user with avatar URL."""
user_id = generate_user_id("Bob")
user = User(
id=user_id,
first_name="Bob",
last_name="Builder",
avatar_url="https://example.com/avatar.jpg"
)
db_session.add(user)
db_session.commit()
assert user.avatar_url == "https://example.com/avatar.jpg"
class TestProjectModel:
"""Test Project model."""
def test_project_with_name_as_id(self, db_session, create_user):
"""Test creating project with name as ID."""
user = create_user("Owner", "Test")
project = Project(
id="myproject", # Name used as ID
name="myproject",
description="Test project",
created_by=user.id
)
db_session.add(project)
db_session.commit()
assert project.id == "myproject"
assert project.name == "myproject"
def test_project_id_uniqueness(self, db_session, create_user):
"""Test that duplicate project IDs fail."""
user = create_user("Owner", "Test")
project1 = Project(id="unique", name="unique", description="First", created_by=user.id)
db_session.add(project1)
db_session.commit()
project2 = Project(id="unique", name="unique", description="Second", created_by=user.id)
db_session.add(project2)
with pytest.raises(Exception): # IntegrityError
db_session.commit()
class TestTaskModel:
"""Test Task model."""
def test_task_status_enum(self):
"""Test TaskStatus enum values."""
assert TaskStatus.todo.value == "todo"
assert TaskStatus.in_progress.value == "in_progress"
assert TaskStatus.done.value == "done"
def test_task_default_status(self, db_session, create_user):
"""Test task defaults to 'todo' status."""
user = create_user("Dev", "Test")
project = Project(id="taskproj", name="taskproj", description="Test", created_by=user.id)
db_session.add(project)
db_session.commit()
task = Task(
project_id=project.id,
title="Test Task",
description="Test description"
)
db_session.add(task)
db_session.commit()
assert task.status == TaskStatus.todo
class TestEnums:
"""Test enum definitions."""
def test_actor_type_enum(self):
"""Test ActorType enum."""
assert ActorType.human.value == "human"
assert ActorType.agent.value == "agent"
def test_action_type_enum(self):
"""Test ActionType enum."""
assert ActionType.task_completed.value == "task_completed"
assert ActionType.doc_generated.value == "doc_generated"
assert ActionType.query_answered.value == "query_answered"