File size: 6,090 Bytes
35765b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
"""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"]