"""Unit tests for project tools.""" import pytest from app.tools.projects import ( create_project, list_projects, join_project, check_project_id_available ) from app.database import SessionLocal from app.models import Project, ProjectMembership class TestCheckProjectIdAvailable: """Test project ID availability checking.""" def test_available_id(self, create_user): """Test checking an available project ID.""" result = check_project_id_available("nonexistent-project") assert result["available"] == True assert result["project_id"] == "nonexistent-project" def test_unavailable_id(self, create_user): """Test checking an ID that's already taken.""" user = create_user("Test", "User") # Create a project first create_project("takenid", "Description", user.id) # Check if the ID is available result = check_project_id_available("takenid") assert result["available"] == False assert result["project_id"] == "takenid" class TestCreateProject: """Test project creation with name as ID.""" def test_create_project_uses_name_as_id(self, create_user): """Test that project name is used as project ID.""" user = create_user("Creator", "Test") result = create_project("fastgate", "A fast gateway", user.id) assert result["id"] == "fastgate" assert result["name"] == "fastgate" assert result["description"] == "A fast gateway" assert result["created_by"] == user.id def test_create_project_adds_owner_membership(self, create_user): """Test that creator is added as owner.""" user = create_user("Owner", "Test") result = create_project("ownerproj", "Test", user.id) db = SessionLocal() try: membership = db.query(ProjectMembership).filter( ProjectMembership.project_id == result["id"], ProjectMembership.user_id == user.id ).first() assert membership is not None assert membership.role == "owner" finally: db.close() def test_create_project_duplicate_id_fails(self, create_user): """Test that creating project with existing ID fails.""" user = create_user("Test", "User") # Create first project create_project("duplicate", "First project", user.id) # Try to create another with same name/ID result = create_project("duplicate", "Second project", user.id) assert "error" in result assert "already exists" in result["error"] def test_create_project_nonexistent_user(self): """Test creating project with non-existent user fails.""" result = create_project("orphan", "No owner", "nonexistent-user-id") assert "error" in result assert "not found" in result["error"] class TestListProjects: """Test listing user's projects.""" def test_list_projects_empty(self, create_user): """Test listing projects for user with no projects.""" user = create_user("New", "User") result = list_projects(user.id) assert "projects" in result assert len(result["projects"]) == 0 def test_list_projects_with_owned_project(self, create_user): """Test listing projects includes owned projects.""" user = create_user("Owner", "Test") create_project("ownedproj", "My project", user.id) result = list_projects(user.id) assert len(result["projects"]) == 1 assert result["projects"][0]["name"] == "ownedproj" assert result["projects"][0]["role"] == "owner" def test_list_projects_with_member_project(self, create_user): """Test listing projects includes joined projects.""" owner = create_user("Owner", "Test") member = create_user("Member", "Test") create_project("sharedproj", "Shared project", owner.id) join_project("sharedproj", member.id) result = list_projects(member.id) assert len(result["projects"]) == 1 assert result["projects"][0]["name"] == "sharedproj" assert result["projects"][0]["role"] == "member" class TestJoinProject: """Test joining existing projects.""" def test_join_project_success(self, create_user): """Test successfully joining a project.""" owner = create_user("Owner", "Test") member = create_user("Member", "Test") create_project("jointest", "Test project", owner.id) result = join_project("jointest", member.id) assert "message" in result assert result["project_id"] == "jointest" assert result["role"] == "member" def test_join_project_already_member(self, create_user): """Test joining a project you're already a member of.""" owner = create_user("Owner", "Test") member = create_user("Member", "Test") create_project("alreadyin", "Test project", owner.id) join_project("alreadyin", member.id) # Try joining again result = join_project("alreadyin", member.id) assert "Already a member" in result.get("message", "") def test_join_nonexistent_project(self, create_user): """Test joining a project that doesn't exist.""" user = create_user("User", "Test") result = join_project("doesnotexist", user.id) assert "error" in result assert "not found" in result["error"] def test_join_project_nonexistent_user(self, create_user): """Test joining with non-existent user.""" owner = create_user("Owner", "Test") create_project("validproj", "Test", owner.id) result = join_project("validproj", "nonexistent-user") assert "error" in result assert "not found" in result["error"]