import { describe, expect, it } from "vitest"; import { TRPCError } from "@trpc/server"; import { assertCommentManageableByActor, buildCommentCreateData, buildCommentMentionNotifications, commentAuthorSelect, commentBelongsToEntity, commentThreadInclude, commentWithAuthorInclude, parseCommentMentions, } from "../router/comment-support.js"; describe("comment support", () => { it("parses unique mention ids from comment markdown", () => { expect(parseCommentMentions("Hi @[Alice](user_1) and @[Bob](user_2) and @[Alice](user_1)")).toEqual([ "user_1", "user_2", ]); }); it("exposes stable include definitions for comment reads and writes", () => { expect(commentAuthorSelect).toEqual({ id: true, name: true, email: true, image: true, }); expect(commentWithAuthorInclude).toEqual({ author: { select: commentAuthorSelect }, }); expect(commentThreadInclude).toEqual({ author: { select: commentAuthorSelect }, replies: { include: { author: { select: commentAuthorSelect }, }, orderBy: { createdAt: "asc" }, }, }); }); it("builds comment create payloads and mention notifications", () => { expect(buildCommentCreateData({ entityType: "estimate", entityId: "est_1", parentId: "comment_parent", authorId: "user_1", body: "Please review @[Bob](user_2)", mentions: ["user_2"], })).toEqual({ entityType: "estimate", entityId: "est_1", parentId: "comment_parent", authorId: "user_1", body: "Please review @[Bob](user_2)", mentions: ["user_2"], }); expect(buildCommentMentionNotifications({ mentionedUserIds: ["user_2"], authorName: "Alice Example", body: "x".repeat(121), entityId: "est_1", entityType: "estimate", senderId: "user_1", link: "/estimates/est_1", })).toEqual([ { userId: "user_2", type: "COMMENT_MENTION", title: "Alice Example mentioned you in a comment", body: `${"x".repeat(120)}...`, entityId: "est_1", entityType: "estimate", senderId: "user_1", link: "/estimates/est_1", channel: "in_app", }, ]); }); it("checks entity ownership and author-or-admin permissions", () => { expect(commentBelongsToEntity({ comment: { entityType: "resource", entityId: "res_1", }, entityType: "resource", entityId: "res_1", })).toBe(true); expect(() => assertCommentManageableByActor({ authorId: "user_2", actorUserId: "user_1", isAdmin: false, action: "delete", })).toThrowError(TRPCError); expect(() => assertCommentManageableByActor({ authorId: "user_2", actorUserId: "user_1", isAdmin: true, action: "resolve", })).not.toThrow(); }); });