Spaces:
Sleeping
Ticket Comments - Testing Guide
Manual Testing Checklist
1. Create Comment β
curl -X POST "http://localhost:7860/api/v1/tickets/{ticket_id}/comments" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"comment_text": "Customer prefers morning visits",
"is_internal": true,
"comment_type": "note"
}'
Expected: 201 Created with comment details
2. Create Reply (Threading) β
curl -X POST "http://localhost:7860/api/v1/tickets/{ticket_id}/comments" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"comment_text": "I will handle this",
"parent_comment_id": "{parent_comment_id}",
"is_internal": true,
"comment_type": "note"
}'
Expected: 201 Created with parent_comment_id set
3. List Comments β
curl -X GET "http://localhost:7860/api/v1/tickets/{ticket_id}/comments?page=1&page_size=20" \
-H "Authorization: Bearer {token}"
Expected: 200 OK with paginated list
4. Get Comment Replies β
curl -X GET "http://localhost:7860/api/v1/comments/{comment_id}/replies" \
-H "Authorization: Bearer {token}"
Expected: 200 OK with array of replies
5. Update Comment β
curl -X PUT "http://localhost:7860/api/v1/comments/{comment_id}" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"comment_text": "Updated: Customer prefers afternoon"
}'
Expected: 200 OK with is_edited=true
6. Delete Comment β
curl -X DELETE "http://localhost:7860/api/v1/comments/{comment_id}" \
-H "Authorization: Bearer {token}"
Expected: 200 OK with success message
Error Cases to Test
1. Create Comment on Non-Existent Ticket
curl -X POST "http://localhost:7860/api/v1/tickets/00000000-0000-0000-0000-000000000000/comments" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"comment_text": "Test", "is_internal": true, "comment_type": "note"}'
Expected: 404 Not Found - "Ticket not found"
2. Update Someone Else's Comment
# Create comment as User A
# Try to update as User B
curl -X PUT "http://localhost:7860/api/v1/comments/{comment_id}" \
-H "Authorization: Bearer {user_b_token}" \
-H "Content-Type: application/json" \
-d '{"comment_text": "Hacked!"}'
Expected: 403 Forbidden - "You can only edit your own comments"
3. Reply to Non-Existent Comment
curl -X POST "http://localhost:7860/api/v1/tickets/{ticket_id}/comments" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"comment_text": "Reply",
"parent_comment_id": "00000000-0000-0000-0000-000000000000",
"is_internal": true,
"comment_type": "note"
}'
Expected: 404 Not Found - "Parent comment not found"
4. Mention Non-Existent User
curl -X POST "http://localhost:7860/api/v1/tickets/{ticket_id}/comments" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"comment_text": "Test",
"mentioned_user_ids": ["00000000-0000-0000-0000-000000000000"],
"is_internal": true,
"comment_type": "note"
}'
Expected: 400 Bad Request - "One or more mentioned users not found"
5. Empty Comment Text
curl -X POST "http://localhost:7860/api/v1/tickets/{ticket_id}/comments" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"comment_text": "",
"is_internal": true,
"comment_type": "note"
}'
Expected: 422 Validation Error - "comment_text must be at least 1 character"
Integration Testing
Scenario 1: Threaded Conversation
- User A creates comment: "Need help with this ticket"
- User B replies: "I can help"
- User A replies to B: "Thanks!"
- Verify reply_count increments
- Load replies and verify order (oldest first)
Scenario 2: Edit Tracking
- User creates comment
- User edits comment
- Verify is_edited=true, edited_at set, edited_by_user_id set
- Edit again
- Verify edited_at updated
Scenario 3: Soft Delete
- User creates comment
- User deletes comment
- Verify deleted_at set
- Try to list comments - deleted comment should not appear
- Try to get deleted comment by ID - should return 404
Scenario 4: Pagination
- Create 100 comments
- List with page_size=20
- Verify pages=5
- Load each page
- Verify no duplicates, no missing comments
Performance Testing
Load Test: Create 1000 Comments
import asyncio
import aiohttp
async def create_comment(session, ticket_id, token):
async with session.post(
f"http://localhost:7860/api/v1/tickets/{ticket_id}/comments",
headers={"Authorization": f"Bearer {token}"},
json={
"comment_text": "Load test comment",
"is_internal": True,
"comment_type": "note"
}
) as response:
return await response.json()
async def main():
async with aiohttp.ClientSession() as session:
tasks = [create_comment(session, ticket_id, token) for _ in range(1000)]
results = await asyncio.gather(*tasks)
print(f"Created {len(results)} comments")
asyncio.run(main())
Expected: All 1000 comments created successfully in < 30 seconds
Database Verification
Check Comment Count
SELECT COUNT(*) FROM ticket_comments WHERE deleted_at IS NULL;
Check Threading
SELECT
id,
comment_text,
parent_comment_id,
(SELECT COUNT(*) FROM ticket_comments c2 WHERE c2.parent_comment_id = c1.id) as reply_count
FROM ticket_comments c1
WHERE ticket_id = '{ticket_id}' AND deleted_at IS NULL
ORDER BY created_at DESC;
Check Edit History
SELECT
id,
comment_text,
is_edited,
edited_at,
edited_by_user_id
FROM ticket_comments
WHERE is_edited = TRUE AND deleted_at IS NULL;
Common Issues & Solutions
Issue: 500 Internal Server Error
Cause: Missing relationship loading
Solution: Ensure all relationships use joinedload() in service layer
Issue: Comments not appearing
Cause: Soft delete not filtered
Solution: Always filter deleted_at IS NULL
Issue: Reply count incorrect
Cause: Not counting replies properly
Solution: Use subquery to count replies in _to_response()
Issue: Mentions not working
Cause: User IDs not validated Solution: Query users table to verify all mentioned_user_ids exist
Monitoring
Key Metrics to Track
- Comment creation rate (comments/hour)
- Average reply depth (threading level)
- Edit frequency (edits/comments ratio)
- Delete frequency (deletes/comments ratio)
- Response time for list endpoint
Alerts to Set Up
- Comment creation failures > 1%
- List endpoint response time > 2 seconds
- Database connection errors
- Validation errors > 5%