| """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" |
| assert user_id[3:].isdigit() |
|
|
| 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 |
|
|
| def test_generate_user_id_uniqueness(self): |
| """Test that multiple calls generate different IDs.""" |
| ids = [generate_user_id("Test") for _ in range(10)] |
| |
| assert len(set(ids)) > 5 |
|
|
| 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 |
| 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="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): |
| 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" |
|
|