kamau1's picture
feat: ticket comments
495529d

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

  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

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%