"""P14.1 — Comments API tests. Covers: - List comments for task - Create comment - Update comment - Delete comment - Comment permissions """ import pytest class TestComments: """Comment management endpoints.""" def test_list_comments(self, client, db, make_user, make_project, auth_header, seed_roles_and_permissions, make_member): """List comments for a task.""" admin_role, mgr_role, dev_role = seed_roles_and_permissions user = make_user() project = make_project() make_member(project.id, user.id, dev_role.id) from app.models.milestone import Milestone, MilestoneStatus from app.models.task import Task, TaskStatus, TaskPriority from app.models.models import Comment milestone = Milestone(title="M1", project_id=project.id, status=MilestoneStatus.OPEN) db.add(milestone) db.commit() task = Task( title="Test Task", project_id=project.id, milestone_id=milestone.id, reporter_id=user.id, status=TaskStatus.OPEN, priority=TaskPriority.MEDIUM ) db.add(task) db.commit() # Add comments comment1 = Comment(content="Comment 1", task_id=task.id, author_id=user.id) comment2 = Comment(content="Comment 2", task_id=task.id, author_id=user.id) db.add_all([comment1, comment2]) db.commit() resp = client.get(f"/projects/{project.id}/tasks/{task.id}/comments", headers=auth_header(user)) assert resp.status_code == 200 data = resp.json() assert len(data) == 2 def test_create_comment(self, client, db, make_user, make_project, auth_header, seed_roles_and_permissions, make_member): """Create comment on task.""" admin_role, mgr_role, dev_role = seed_roles_and_permissions user = make_user() project = make_project() make_member(project.id, user.id, dev_role.id) from app.models.milestone import Milestone, MilestoneStatus from app.models.task import Task, TaskStatus, TaskPriority milestone = Milestone(title="M1", project_id=project.id, status=MilestoneStatus.OPEN) db.add(milestone) db.commit() task = Task( title="Test Task", project_id=project.id, milestone_id=milestone.id, reporter_id=user.id, status=TaskStatus.OPEN, priority=TaskPriority.MEDIUM ) db.add(task) db.commit() resp = client.post( f"/projects/{project.id}/tasks/{task.id}/comments", json={"content": "This is a test comment"}, headers=auth_header(user) ) assert resp.status_code == 201 data = resp.json() assert data["content"] == "This is a test comment" assert data["author_id"] == user.id def test_update_comment(self, client, db, make_user, make_project, auth_header, seed_roles_and_permissions, make_member): """Update own comment.""" admin_role, mgr_role, dev_role = seed_roles_and_permissions user = make_user() project = make_project() make_member(project.id, user.id, dev_role.id) from app.models.milestone import Milestone, MilestoneStatus from app.models.task import Task, TaskStatus, TaskPriority from app.models.models import Comment milestone = Milestone(title="M1", project_id=project.id, status=MilestoneStatus.OPEN) db.add(milestone) db.commit() task = Task( title="Test Task", project_id=project.id, milestone_id=milestone.id, reporter_id=user.id, status=TaskStatus.OPEN, priority=TaskPriority.MEDIUM ) db.add(task) db.commit() comment = Comment(content="Original", task_id=task.id, author_id=user.id) db.add(comment) db.commit() resp = client.patch( f"/projects/{project.id}/tasks/{task.id}/comments/{comment.id}", json={"content": "Updated content"}, headers=auth_header(user) ) assert resp.status_code == 200 data = resp.json() assert data["content"] == "Updated content" def test_delete_comment(self, client, db, make_user, make_project, auth_header, seed_roles_and_permissions, make_member): """Delete comment.""" admin_role, mgr_role, dev_role = seed_roles_and_permissions user = make_user() project = make_project() make_member(project.id, user.id, dev_role.id) from app.models.milestone import Milestone, MilestoneStatus from app.models.task import Task, TaskStatus, TaskPriority from app.models.models import Comment milestone = Milestone(title="M1", project_id=project.id, status=MilestoneStatus.OPEN) db.add(milestone) db.commit() task = Task( title="Test Task", project_id=project.id, milestone_id=milestone.id, reporter_id=user.id, status=TaskStatus.OPEN, priority=TaskPriority.MEDIUM ) db.add(task) db.commit() comment = Comment(content="To delete", task_id=task.id, author_id=user.id) db.add(comment) db.commit() resp = client.delete( f"/projects/{project.id}/tasks/{task.id}/comments/{comment.id}", headers=auth_header(user) ) assert resp.status_code == 204 def test_cannot_edit_others_comment(self, client, db, make_user, make_project, auth_header, seed_roles_and_permissions, make_member): """Cannot edit another user's comment.""" admin_role, mgr_role, dev_role = seed_roles_and_permissions user1 = make_user(username="user1") user2 = make_user(username="user2") project = make_project() make_member(project.id, user1.id, dev_role.id) make_member(project.id, user2.id, dev_role.id) from app.models.milestone import Milestone, MilestoneStatus from app.models.task import Task, TaskStatus, TaskPriority from app.models.models import Comment milestone = Milestone(title="M1", project_id=project.id, status=MilestoneStatus.OPEN) db.add(milestone) db.commit() task = Task( title="Test Task", project_id=project.id, milestone_id=milestone.id, reporter_id=user1.id, status=TaskStatus.OPEN, priority=TaskPriority.MEDIUM ) db.add(task) db.commit() comment = Comment(content="User1's comment", task_id=task.id, author_id=user1.id) db.add(comment) db.commit() resp = client.patch( f"/projects/{project.id}/tasks/{task.id}/comments/{comment.id}", json={"content": "Hacked!"}, headers=auth_header(user2) ) assert resp.status_code == 403