kamau1's picture
feat: ticket comments
495529d
# Ticket Comments - Testing Guide
## Manual Testing Checklist
### 1. Create Comment ✅
```bash
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) ✅
```bash
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 ✅
```bash
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 ✅
```bash
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 ✅
```bash
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 ✅
```bash
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
```bash
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
```bash
# 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
```bash
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
```bash
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
```bash
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
1. User A creates comment: "Need help with this ticket"
2. User B replies: "I can help"
3. User A replies to B: "Thanks!"
4. Verify reply_count increments
5. Load replies and verify order (oldest first)
### Scenario 2: Edit Tracking
1. User creates comment
2. User edits comment
3. Verify is_edited=true, edited_at set, edited_by_user_id set
4. Edit again
5. Verify edited_at updated
### Scenario 3: Soft Delete
1. User creates comment
2. User deletes comment
3. Verify deleted_at set
4. Try to list comments - deleted comment should not appear
5. Try to get deleted comment by ID - should return 404
### Scenario 4: Pagination
1. Create 100 comments
2. List with page_size=20
3. Verify pages=5
4. Load each page
5. Verify no duplicates, no missing comments
---
## Performance Testing
### Load Test: Create 1000 Comments
```python
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
```sql
SELECT COUNT(*) FROM ticket_comments WHERE deleted_at IS NULL;
```
### Check Threading
```sql
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
```sql
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%