• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SE25GroupProject / my-cookbook / 13548499350

26 Feb 2025 04:19PM UTC coverage: 80.058% (+13.0%) from 67.099%
13548499350

push

github

web-flow
Merge pull request #48 from SE25GroupProject/Pylint

Starting Lint

1381 of 1725 relevant lines covered (80.06%)

0.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.36
api/tests/test_comments_api.py
1
from fastapi.testclient import TestClient
1✔
2
import pytest
1✔
3
from os import remove
1✔
4
from api.db_middleware import DBConnectionMiddleware
1✔
5
from api.db.convert_json_to_sql import insert_data
1✔
6
import tempfile
1✔
7

8
from api.main import app
1✔
9

10
client = TestClient(app)
1✔
11

12
MAIN_DB = "cookbook.db"
1✔
13
TEST_DB = "tests/test_cookbook.db"
1✔
14
POSTS_BASE = "/posts"
1✔
15

16

17
# @pytest.fixture(scope="function", autouse=True)
18
# def setup_db():
19
#     """Copies the db to a testing db before each test"""
20
#     if path.exists(TEST_DB):
21
#         remove(TEST_DB)
22
#     insert_data(TEST_DB, "tests/recipeTest.json")
23
#     yield
24

25
#     # Cleanup after all tests
26
#     remove(temp_db_path)
27

28
@pytest.fixture(scope="module", autouse=True)
1✔
29
def clientSetup():
1✔
30
    """Copies the db to a testing db before each test"""
31
    temp_db = tempfile.NamedTemporaryFile(delete=False, suffix=".db")
1✔
32
    temp_db_path = temp_db.name
1✔
33
    temp_db.close()
1✔
34
    insert_data(temp_db_path, "tests/recipeTest.json")
1✔
35

36
    app.user_middleware = []
1✔
37
    app.add_middleware(DBConnectionMiddleware, db_path=temp_db_path)
1✔
38
    with TestClient(app) as client:
1✔
39
        yield client
1✔
40

41
    remove(temp_db_path)
1✔
42

43

44
@pytest.fixture(scope="module")
1✔
45
def test_user_id():
1✔
46
    """Fixture to create a test user and return its ID."""
47
    signup_data = {"username": "testuser_comments", "password": "testpass"}
1✔
48
    signup_url = "/user/signup"
1✔
49
    print(f"Attempting signup at: {signup_url}")
1✔
50
    signup_response = client.post(signup_url, json=signup_data)
1✔
51
    print(
1✔
52
        "Signup response: "
53
        f"{signup_response.status_code} - {signup_response.text}")
54
    if signup_response.status_code == 400:  # User already exists
1✔
55
        login_response = client.post("/user/login", json=signup_data)
×
56
        assert login_response.status_code == 200, "Login failed: "
×
57
        f"{login_response.text}"
×
58
        return login_response.json()["id"]
×
59
    assert signup_response.status_code == 200, "Signup failed: "
1✔
60
    f"{signup_response.text}"
1✔
61
    return signup_response.json()["id"]
1✔
62

63

64
@pytest.fixture(scope="module")
1✔
65
def test_post_id(test_user_id):
1✔
66
    """Fixture to create a test post and return its ID."""
67
    data = {
1✔
68
        "userId": test_user_id,
69
        "message": "Test post for comments",
70
        "image": None,
71
        "recipe_id": None}
72
    response = client.post("/posts/", json=data)
1✔
73
    assert response.status_code == 201, f"Create post failed: {response.text}"
1✔
74
    posts = client.get("/posts/").json()
1✔
75
    post = next(
1✔
76
        (p for p in posts if p["message"] == "Test post for comments"),
77
        None)
78
    assert post is not None, "Test post not found"
1✔
79
    return post["postId"]
1✔
80

81

82
def test_add_comment(test_post_id, test_user_id):
1✔
83
    """Test adding a comment to a post."""
84
    comment_data = {
1✔
85
        "userId": test_user_id,
86
        "postId": test_post_id,
87
        "message": "This is a test comment"
88
    }
89
    response = client.post(
1✔
90
        f"/posts/comments/{test_post_id}",
91
        json=comment_data)
92
    print(f"Add comment response status: {response.status_code}")
1✔
93
    print(f"Add comment response body: {response.text}")
1✔
94
    assert response.status_code == 201, "Failed with "
1✔
95
    f"{response.status_code}: {response.text}"
1✔
96
    response_json = response.json()
1✔
97
    assert response_json["message"] == "Comment added successfully"
1✔
98
    assert "commentId" in response_json
1✔
99
    comment_id = response_json["commentId"]
1✔
100
    assert isinstance(comment_id, int)
1✔
101

102

103
def test_get_post_with_comments(test_post_id, test_user_id):
1✔
104
    """Test retrieving a post with its comments."""
105
    comment_data = {
1✔
106
        "userId": test_user_id,
107
        "postId": test_post_id,
108
        "message": "Another test comment"
109
    }
110
    response = client.post(
1✔
111
        f"/posts/comments/{test_post_id}",
112
        json=comment_data)
113
    assert response.status_code == 201
1✔
114

115
    # Fetch the post
116
    response = client.get(f"/posts/{test_post_id}")
1✔
117
    assert response.status_code == 200
1✔
118
    post = response.json()
1✔
119
    assert post["postId"] == test_post_id
1✔
120
    assert isinstance(post["comments"], list)
1✔
121
    assert len(post["comments"]) > 0, "No comments found in post"
1✔
122
    comment = post["comments"][-1]  # Check the latest comment
1✔
123
    assert comment["userId"] == test_user_id
1✔
124
    assert comment["postId"] == test_post_id
1✔
125
    assert comment["message"] == "Another test comment"
1✔
126
    assert "commentId" in comment
1✔
127
    assert "date" in comment
1✔
128

129

130
def test_add_comment_invalid_user(test_post_id):
1✔
131
    """Test adding a comment with a non-existent user."""
132
    comment_data = {
1✔
133
        "userId": 9999,  # Non-existent user ID
134
        "postId": test_post_id,
135
        "message": "This should fail"
136
    }
137
    response = client.post(
1✔
138
        f"/posts/comments/{test_post_id}",
139
        json=comment_data)
140
    print(f"Add comment invalid user response status: {response.status_code}")
1✔
141
    print(f"Add comment invalid user response body: {response.text}")
1✔
142
    assert response.status_code == 400, "Expected 400, "
1✔
143
    f"got {response.status_code}: {response.text}"
1✔
144
    assert "detail" in response.json()
1✔
145
    assert "user" in response.json()["detail"].lower()
1✔
146

147

148
def test_delete_comment(test_post_id, test_user_id):
1✔
149
    """Test deleting a comment."""
150
    # Add a comment to delete
151
    comment_data = {
1✔
152
        "userId": test_user_id,
153
        "postId": test_post_id,
154
        "message": "Comment to delete"
155
    }
156
    add_response = client.post(
1✔
157
        f"/posts/comments/{test_post_id}",
158
        json=comment_data)
159
    assert add_response.status_code == 201
1✔
160
    comment_id = add_response.json()["commentId"]
1✔
161

162
    # Delete the comment
163
    delete_data = {"user_id": test_user_id, "post_id": test_post_id}
1✔
164
    response = client.delete(
1✔
165
        f"/posts/comments/{comment_id}",
166
        json=delete_data)
167
    print(f"Delete comment response status: {response.status_code}")
1✔
168
    print(f"Delete comment response body: {response.text}")
1✔
169
    assert response.status_code == 200, "Failed with "
1✔
170
    f"{response.status_code}: {response.text}"
1✔
171
    assert response.json()["message"] == "Comment deleted successfully"
1✔
172

173
    # Verify comment is gone
174
    post_response = client.get(f"/posts/{test_post_id}")
1✔
175
    post = post_response.json()
1✔
176
    assert not any(
1✔
177
        c["commentId"] == comment_id for c in post["comments"]), "Comment "
178
    "was not deleted"
1✔
179

180

181
def test_delete_comment_nonexistent(test_post_id, test_user_id):
1✔
182
    """Test deleting a non-existent comment."""
183
    delete_data = {"user_id": test_user_id}
1✔
184
    response = client.delete(
1✔
185
        f"/posts/comments/{test_post_id}/9999",
186
        json=delete_data)
187
    print(f"Delete nonexistent response status: {response.status_code}")
1✔
188
    print(f"Delete nonexistent response body: {response.text}")
1✔
189
    assert response.status_code == 404, "Expected 404, "
1✔
190
    f"got {response.status_code}: {response.text}"
1✔
191
    assert "detail" in response.json()
1✔
192
    assert "not found" in response.json()["detail"].lower()
1✔
193

194

195
def test_add_multiple_comments(test_post_id, test_user_id):
1✔
196
    """Test adding multiple comments to a post."""
197
    comments = [{"userId": test_user_id,
1✔
198
                 "postId": test_post_id,
199
                 "message": "First comment"},
200
                {"userId": test_user_id,
201
                 "postId": test_post_id,
202
                 "message": "Second comment"}]
203
    comment_ids = []
1✔
204
    for comment_data in comments:
1✔
205
        response = client.post(
1✔
206
            f"/posts/comments/{test_post_id}",
207
            json=comment_data)
208
        print(f"Add multiple comments response status: {response.status_code}")
1✔
209
        print(f"Add multiple comments response body: {response.text}")
1✔
210
        assert response.status_code == 201, "Failed with "
1✔
211
        f"{response.status_code}: {response.text}"
1✔
212
        response_json = response.json()
1✔
213
        assert response_json["message"] == "Comment added successfully"
1✔
214
        comment_ids.append(response_json["commentId"])
1✔
215

216
    # Verify all comments are present
217
    response = client.get(f"/posts/{test_post_id}")
1✔
218
    assert response.status_code == 200
1✔
219
    post = response.json()
1✔
220
    assert len(post["comments"]) >= 2, "Expected at least 2 comments"
1✔
221
    messages = [c["message"] for c in post["comments"]]
1✔
222
    assert "First comment" in messages
1✔
223
    assert "Second comment" in messages
1✔
224

225

226
def test_delete_comment_by_non_owner(test_post_id, test_user_id):
1✔
227
    """Test deleting a comment by a user who doesn't own it."""
228
    # Create a second user
229
    signup_data = {"username": "otheruser_comments", "password": "otherpass"}
1✔
230
    signup_response = client.post("/user/signup", json=signup_data)
1✔
231
    if signup_response.status_code == 400:
1✔
232
        login_response = client.post("/user/login", json=signup_data)
×
233
        assert login_response.status_code == 200
×
234
        other_user_id = login_response.json()["id"]
×
235
    else:
236
        assert signup_response.status_code == 200
1✔
237
        other_user_id = signup_response.json()["id"]
1✔
238

239
    # Add a comment with test_user_id
240
    comment_data = {
1✔
241
        "userId": test_user_id,
242
        "postId": test_post_id,
243
        "message": "Comment by owner"
244
    }
245
    add_response = client.post(
1✔
246
        f"/posts/comments/{test_post_id}",
247
        json=comment_data)
248
    assert add_response.status_code == 201
1✔
249
    comment_id = add_response.json()["commentId"]
1✔
250

251
    # Attempt to delete with other_user_id
252
    delete_data = {"post_id": test_post_id, "user_id": other_user_id}
1✔
253
    response = client.request(
1✔
254
        "DELETE",
255
        f"/posts/comments/{comment_id}",
256
        json=delete_data)
257
    print(f"Delete by non-owner response status: {response.status_code}")
1✔
258
    print(f"Delete by non-owner response body: {response.text}")
1✔
259
    assert response.status_code == 403, "Expected 403, "
1✔
260
    f"got {response.status_code}: {response.text}"
1✔
261
    assert "detail" in response.json()
1✔
262
    assert "own comments" in response.json()["detail"].lower()
1✔
263

264
    # Verify comment still exists
265
    post_response = client.get(f"/posts/{test_post_id}")
1✔
266
    post = post_response.json()
1✔
267
    assert any(c["commentId"] == comment_id for c in post["comments"]
1✔
268
               ), "Comment was unexpectedly deleted"
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc