110 lines
2.9 KiB
TypeScript
110 lines
2.9 KiB
TypeScript
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();
|
|
});
|
|
});
|