"""Tests for DS-09: Replace raw string fields with enums.""" from sqlalchemy import inspect from app.core.database import SessionLocal, engine from app.core.enums import ProjectStatus, UserRole from app.core.models import Project, User class TestUserRoleEnum: """User.role should accept only valid UserRole values.""" def test_user_role_accepts_valid_enum(self) -> None: """Creating a User with a valid enum role should work.""" user = User( google_id="enum-test-1", email="enum1@test.com", role=UserRole.ADMIN, ) assert user.role is UserRole.ADMIN assert user.role.value == "admin" def test_user_role_defaults_in_db(self) -> None: """Default User.role should be UserRole.USER when persisted.""" user = User( google_id="enum-test-2", email="enum2@test.com", ) db = SessionLocal() try: db.add(user) db.flush() # Apply defaults assert user.role == UserRole.USER finally: db.rollback() db.close() def test_user_role_column_type(self) -> None: """The DB column should be an Enum type (or String for SQLite compat).""" insp = inspect(engine) columns = {c["name"]: c for c in insp.get_columns("users")} role_col = columns["role"] assert role_col["type"] is not None def test_user_role_python_type_safety(self) -> None: """Type-annotated field ensures only UserRole values are expected.""" user = User( google_id="enum-test-4", email="enum4@test.com", role=UserRole.USER, ) assert isinstance(user.role, UserRole) # Setting to a non-enum via attribute is allowed at runtime (Python dynamic), # but the column type in the DB schema is now an enum type # (PostgreSQL will enforce; SQLite stores as text) class TestProjectStatusEnum: """Project.status should accept only valid ProjectStatus values.""" def test_project_status_accepts_valid_enum(self) -> None: """Creating a Project with a valid enum status should work.""" project = Project( user_id=1, title="Test Project", artifacts={}, status=ProjectStatus.ARCHIVED, ) assert project.status is ProjectStatus.ARCHIVED assert project.status.value == "archived" def test_project_status_defaults_in_db(self) -> None: """Default Project.status should be ProjectStatus.DRAFT when persisted.""" project = Project( user_id=1, title="Test Project", artifacts={}, ) db = SessionLocal() try: db.add(project) db.flush() assert project.status == ProjectStatus.DRAFT finally: db.rollback() db.close() def test_project_status_python_type_safety(self) -> None: """Type-annotated field ensures only ProjectStatus values are expected.""" project = Project( user_id=1, title="Test", artifacts={}, status=ProjectStatus.ACTIVE, ) assert isinstance(project.status, ProjectStatus)