Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 13 additions & 21 deletions backend/src/controllers/comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,24 +63,24 @@ export const getComment = async (req: AuthenticatedRequest, res: Response) => {
};

/**
* GET /api/comments/post/:postId or /api/comments/rating/:ratingId
* Returns a flat list of comments for the post or rating
* GET /api/comments/post/:postId
* Returns a flat list of comments for the post
*/
export const getCommentsTree = async (req: AuthenticatedRequest, res: Response) => {
const timestamp = new Date().toISOString();
const { postId, ratingId } = req.params;
const { postId } = req.params;
const userId = req.user?.id;

if (!postId && !ratingId) {
if (!postId) {
return res.status(400).json({
message: "Missing postId or ratingId",
message: "Missing postId",
timestamp,
});
}

try {
const comments = await prisma.comment.findMany({
where: postId ? { postId } : { ratingId },
where: { postId },
orderBy: { createdAt: 'asc' },
include: {
UserProfile: { select: { userId: true, username: true, profilePicture: true } },
Expand All @@ -92,7 +92,6 @@ export const getCommentsTree = async (req: AuthenticatedRequest, res: Response)
const commentsWithLikes = comments.map((comment) => ({
id: comment.id,
userId: comment.userId,
ratingId: comment.ratingId,
postId: comment.postId,
parentId: comment.parentId,
content: comment.content,
Expand Down Expand Up @@ -129,7 +128,7 @@ export const createComment = async (req: AuthenticatedRequest, res: Response) =>
});
}

const { content, ratingId, postId, parentId } = req.body;
const { content, postId, parentId } = req.body;

if (!content || typeof content !== "string" || content.trim() === "") {
return res.status(400).json({
Expand All @@ -143,7 +142,6 @@ export const createComment = async (req: AuthenticatedRequest, res: Response) =>
const newComment = await prisma.comment.create({
data: {
userId: req.user.id,
ratingId: ratingId ?? null,
postId: postId ?? null,
parentId: parentId ?? null,
content: content,
Expand Down Expand Up @@ -446,26 +444,21 @@ export async function getMovieComments(req: Request, res: Response) {
return res.status(400).json({ message: "movieId is required" });
}

// 1) Find all ratings for this movie
const ratingsForMovie = await prisma.rating.findMany({
// 1) Find all posts for this movie
const postsForMovie = await prisma.post.findMany({
where: { movieId },
select: { id: true },
});

const ratingIds = ratingsForMovie.map((r) => r.id);
if (ratingIds.length === 0) {
const postIds = postsForMovie.map((p) => p.id);
if (postIds.length === 0) {
return res.status(200).json({ comments: [] });
}

// 2) Find comments that reference those ratings
// 2) Find comments that reference those posts
const commentsFromDb = await prisma.comment.findMany({
where: {
ratingId: { in: ratingIds },
// If you later want to also include post-based comments:
// OR: [
// { ratingId: { in: ratingIds } },
// { post: { movieId } } // if you have relation from comment -> post -> movie
// ]
postId: { in: postIds },
},
orderBy: { createdAt: "desc" },
});
Expand All @@ -474,7 +467,6 @@ export async function getMovieComments(req: Request, res: Response) {
const comments = commentsFromDb.map((c) => ({
id: c.id,
userId: c.userId,
ratingId: c.ratingId,
postId: c.postId,
text: c.content, // frontend uses comment.text
date: c.createdAt.toISOString(), // frontend uses comment.date
Expand Down
1 change: 0 additions & 1 deletion backend/src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ router.post("/api/comment/:id/like", toggleCommentLike);
router.get("/api/comment/:id/likes", getCommentLikes);
router.get("/api/:movieId/comments", getMovieComments);
router.get("/api/comments/post/:postId", getCommentsTree);
router.get("/api/comments/rating/:ratingId", getCommentsTree);

// Ratings routes
router.post('/api/ratings', createRating);
Expand Down
118 changes: 3 additions & 115 deletions backend/src/tests/api/comment.api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,6 @@ jest.mock("../../middleware/auth", () => ({
describe("Comment API Tests", () => {
let app: express.Express;
let testCommentId: string;
let testRatingId: string;
let testPostId: string;

const TEST_USER_ID = "123e4567-e89b-12d3-a456-426614174000";
Expand Down Expand Up @@ -358,7 +357,6 @@ describe("Comment API Tests", () => {
}
});
await prisma.post.deleteMany({ where: { userId: TEST_USER_ID } });
await prisma.rating.deleteMany({ where: { userId: TEST_USER_ID } });

// Create test user profile
await prisma.userProfile.upsert({
Expand All @@ -385,21 +383,11 @@ describe("Comment API Tests", () => {

// Create a fresh comment for each test
beforeEach(async () => {
// Create a new rating for each test
const rating = await prisma.rating.create({
data: {
userId: TEST_USER_ID,
movieId: "test-movie-555",
stars: 5,
date: new Date(),
},
});
testRatingId = rating.id;

// Create a new post for each test
const post = await prisma.post.create({
data: {
userId: TEST_USER_ID,
movieId: "test-movie-555",
type: "SHORT",
content: "This is a test post!",
createdAt: new Date(),
Expand All @@ -411,7 +399,6 @@ describe("Comment API Tests", () => {
const comment = await prisma.comment.create({
data: {
userId: TEST_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "This is a test comment!",
createdAt: new Date(),
Expand All @@ -422,26 +409,22 @@ describe("Comment API Tests", () => {

// Clean up after each test
afterEach(async () => {
// Delete comments first (they reference ratings and posts)
// Delete comments first (they reference posts)
if (testCommentId) {
await prisma.comment.deleteMany({
where: {
OR: [
{ id: testCommentId },
{ ratingId: testRatingId },
{ postId: testPostId }
]
}
}).catch(() => {});
}

// Then delete posts and ratings
// Then delete posts
if (testPostId) {
await prisma.post.delete({ where: { id: testPostId } }).catch(() => {});
}
if (testRatingId) {
await prisma.rating.delete({ where: { id: testRatingId } }).catch(() => {});
}
});

// Clean up at the end
Expand All @@ -455,7 +438,6 @@ describe("Comment API Tests", () => {
}
});
await prisma.post.deleteMany({ where: { userId: TEST_USER_ID } });
await prisma.rating.deleteMany({ where: { userId: TEST_USER_ID } });
await prisma.$disconnect();
});

Expand All @@ -475,7 +457,6 @@ describe("Comment API Tests", () => {
id: testCommentId,
userId: TEST_USER_ID,
content: "This is a test comment!",
ratingId: testRatingId,
postId: testPostId,
});
});
Expand Down Expand Up @@ -521,7 +502,6 @@ describe("Comment API Tests", () => {
const otherUserComment = await prisma.comment.create({
data: {
userId: OTHER_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "Another user's comment",
createdAt: new Date(),
Expand Down Expand Up @@ -612,7 +592,6 @@ describe("Comment API Tests", () => {
const otherUserComment = await prisma.comment.create({
data: {
userId: OTHER_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "Another user's comment",
createdAt: new Date(),
Expand Down Expand Up @@ -644,7 +623,6 @@ describe("Comment API Tests", () => {
const childComment1 = await prisma.comment.create({
data: {
userId: TEST_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "First child comment",
parentId: testCommentId,
Expand All @@ -655,7 +633,6 @@ describe("Comment API Tests", () => {
const childComment2 = await prisma.comment.create({
data: {
userId: OTHER_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "Second child comment",
parentId: testCommentId,
Expand Down Expand Up @@ -691,7 +668,6 @@ describe("Comment API Tests", () => {
const payload = {
content: "This is a reply to the parent comment",
parentId: testCommentId,
ratingId: testRatingId,
postId: testPostId,
};

Expand Down Expand Up @@ -724,7 +700,6 @@ describe("Comment API Tests", () => {
const reply1 = await prisma.comment.create({
data: {
userId: TEST_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "First reply",
parentId: testCommentId,
Expand All @@ -735,7 +710,6 @@ describe("Comment API Tests", () => {
const reply2 = await prisma.comment.create({
data: {
userId: OTHER_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "Second reply",
parentId: testCommentId,
Expand Down Expand Up @@ -790,7 +764,6 @@ describe("Comment API Tests", () => {
const reply = await prisma.comment.create({
data: {
userId: TEST_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "A reply",
parentId: testCommentId,
Expand All @@ -816,7 +789,6 @@ describe("Comment API Tests", () => {
const childComment = await prisma.comment.create({
data: {
userId: OTHER_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "Child comment",
parentId: testCommentId,
Expand All @@ -828,7 +800,6 @@ describe("Comment API Tests", () => {
const grandchildComment = await prisma.comment.create({
data: {
userId: TEST_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "Grandchild comment",
parentId: childComment.id,
Expand Down Expand Up @@ -863,7 +834,6 @@ describe("Comment API Tests", () => {
const childComment = await prisma.comment.create({
data: {
userId: TEST_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "Child comment",
parentId: testCommentId,
Expand Down Expand Up @@ -893,7 +863,6 @@ describe("Comment API Tests", () => {
const childComment = await prisma.comment.create({
data: {
userId: TEST_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "Child comment",
parentId: testCommentId,
Expand Down Expand Up @@ -937,7 +906,6 @@ describe("Comment API Tests", () => {
const separateParent = await prisma.comment.create({
data: {
userId: TEST_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "Separate parent comment",
createdAt: new Date(),
Expand All @@ -948,7 +916,6 @@ describe("Comment API Tests", () => {
const child1 = await prisma.comment.create({
data: {
userId: TEST_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "Child 1",
parentId: separateParent.id,
Expand All @@ -959,7 +926,6 @@ describe("Comment API Tests", () => {
const child2 = await prisma.comment.create({
data: {
userId: OTHER_USER_ID,
ratingId: testRatingId,
postId: testPostId,
content: "Child 2",
parentId: separateParent.id,
Expand Down Expand Up @@ -1107,82 +1073,4 @@ describe("Comment API Tests", () => {
await prisma.comment.delete({ where: { id: replyComment.id } });
});
});

describe("GET /api/comments/rating/:ratingId (getCommentsTree)", () => {
it("should retrieve all comments for a rating with user profile info", async () => {
const res = await request(app)
.get(`/api/comments/rating/${testRatingId}`)
.set(authHeader())
.expect(HTTP_STATUS.OK)
.expect("Content-Type", /json/);

expect(res.body).toHaveProperty("message", "Comments retrieved");
expect(res.body).toHaveProperty("comments");
expect(Array.isArray(res.body.comments)).toBe(true);

// The test comment is associated with both the post and rating
const testComment = res.body.comments.find((c: any) => c.id === testCommentId);
expect(testComment).toBeDefined();
expect(testComment.ratingId).toBe(testRatingId);
});

it("should return empty array for rating with no comments", async () => {
// Create a new rating with no comments
const emptyRating = await prisma.rating.create({
data: {
userId: TEST_USER_ID,
movieId: "empty-rating-movie",
stars: 4,
date: new Date(),
},
});

const res = await request(app)
.get(`/api/comments/rating/${emptyRating.id}`)
.set(authHeader())
.expect(HTTP_STATUS.OK);

expect(res.body.comments).toEqual([]);

// Clean up
await prisma.rating.delete({ where: { id: emptyRating.id } });
});

it("should only return comments for the specific rating", async () => {
// Create another rating with its own comment
const otherRating = await prisma.rating.create({
data: {
userId: TEST_USER_ID,
movieId: "other-movie",
stars: 3,
date: new Date(),
},
});

const otherComment = await prisma.comment.create({
data: {
userId: TEST_USER_ID,
ratingId: otherRating.id,
content: "Comment on other rating",
createdAt: new Date(),
},
});

// Fetch comments for original rating
const res = await request(app)
.get(`/api/comments/rating/${testRatingId}`)
.set(authHeader())
.expect(HTTP_STATUS.OK);

// Should not include the other rating's comment
const otherCommentInResponse = res.body.comments.find(
(c: any) => c.id === otherComment.id
);
expect(otherCommentInResponse).toBeUndefined();

// Clean up
await prisma.comment.delete({ where: { id: otherComment.id } });
await prisma.rating.delete({ where: { id: otherRating.id } });
});
});
});
Loading