fix: guard against merging a tag into itself to prevent destructive deletion

This commit is contained in:
Bhagya Amarasinghe
2026-03-03 20:06:50 +05:30
parent 32d40e3fe9
commit 95f3950123
3 changed files with 22 additions and 0 deletions

View File

@@ -195,6 +195,20 @@ describe("tag lib", () => {
});
}
});
test("returns error when merging a tag into itself", async () => {
const result = await mergeTags(baseTag.id, baseTag.id);
expect(result.ok).toBe(false);
if (!result.ok) {
expect(result.error).toStrictEqual({
code: "merge_same_tag",
message: "Cannot merge a tag into itself",
});
}
expect(prisma.tag.findUnique).not.toHaveBeenCalled();
expect(prisma.$transaction).not.toHaveBeenCalled();
});
test("throws on prisma error", async () => {
vi.mocked(prisma.tag.findUnique).mockRejectedValueOnce(new Error("fail"));
const result = await mergeTags(baseTag.id, newTag.id);

View File

@@ -72,6 +72,13 @@ export const mergeTags = async (
): Promise<Result<TTag, { code: TagError; message: string; meta?: Record<string, string> }>> => {
validateInputs([originalTagId, ZId], [newTagId, ZId]);
if (originalTagId === newTagId) {
return err({
code: TagError.MERGE_SAME_TAG,
message: "Cannot merge a tag into itself",
});
}
try {
let originalTag: TTag | null;

View File

@@ -1,5 +1,6 @@
export enum TagError {
TAG_NOT_FOUND = "tag_not_found",
TAG_NAME_ALREADY_EXISTS = "tag_name_already_exists",
MERGE_SAME_TAG = "merge_same_tag",
UNEXPECTED_ERROR = "unexpected_error",
}