aboutsummaryrefslogtreecommitdiffstats
path: root/packages/trpc/routers
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2025-09-21 16:27:21 +0000
committerMohamed Bassem <me@mbassem.com>2025-09-21 16:27:55 +0000
commit9fe09bfa9021c8d85d2d9aef591936101cab19f6 (patch)
treeac853b78e306afe5f37859b673d9583b6a94ee40 /packages/trpc/routers
parentbbc5e6c2cdb07e66ea76df86ee8e01f37f290db1 (diff)
downloadkarakeep-9fe09bfa9021c8d85d2d9aef591936101cab19f6.tar.zst
fix: optimize memory usage of tag listing
Diffstat (limited to 'packages/trpc/routers')
-rw-r--r--packages/trpc/routers/tags.test.ts74
1 files changed, 74 insertions, 0 deletions
diff --git a/packages/trpc/routers/tags.test.ts b/packages/trpc/routers/tags.test.ts
index a4d690ee..4004cc2c 100644
--- a/packages/trpc/routers/tags.test.ts
+++ b/packages/trpc/routers/tags.test.ts
@@ -20,6 +20,42 @@ describe("Tags Routes", () => {
expect(res.numBookmarks).toBeGreaterThanOrEqual(0);
});
+ test<CustomTestContext>("get tag returns bookmark stats", async ({
+ apiCallers,
+ }) => {
+ const tagsApi = apiCallers[0].tags;
+ const bookmarksApi = apiCallers[0].bookmarks;
+
+ const firstBookmark = await bookmarksApi.createBookmark({
+ url: "https://example.com/first",
+ type: BookmarkTypes.LINK,
+ });
+ const secondBookmark = await bookmarksApi.createBookmark({
+ url: "https://example.com/second",
+ type: BookmarkTypes.LINK,
+ });
+
+ const firstAttachment = await bookmarksApi.updateTags({
+ bookmarkId: firstBookmark.id,
+ attach: [{ tagName: "stats-tag" }],
+ detach: [],
+ });
+
+ const tagId = firstAttachment.attached[0];
+
+ await bookmarksApi.updateTags({
+ bookmarkId: secondBookmark.id,
+ attach: [{ tagId }],
+ detach: [],
+ });
+
+ const stats = await tagsApi.get({ tagId });
+
+ expect(stats.numBookmarks).toBe(2);
+ expect(stats.numBookmarksByAttachedType.human).toBe(2);
+ expect(stats.numBookmarksByAttachedType.ai).toBe(0);
+ });
+
test<CustomTestContext>("get tag - not found", async ({ apiCallers }) => {
const api = apiCallers[0].tags;
await expect(() => api.get({ tagId: "nonExistentId" })).rejects.toThrow(
@@ -135,6 +171,44 @@ describe("Tags Routes", () => {
expect(res.tags.some((tag) => tag.name === "tag2")).toBeTruthy();
});
+ test<CustomTestContext>("list tags includes bookmark stats", async ({
+ apiCallers,
+ }) => {
+ const tagsApi = apiCallers[0].tags;
+ const bookmarksApi = apiCallers[0].bookmarks;
+
+ const firstBookmark = await bookmarksApi.createBookmark({
+ url: "https://example.com/list-first",
+ type: BookmarkTypes.LINK,
+ });
+ const secondBookmark = await bookmarksApi.createBookmark({
+ url: "https://example.com/list-second",
+ type: BookmarkTypes.LINK,
+ });
+
+ const firstAttachment = await bookmarksApi.updateTags({
+ bookmarkId: firstBookmark.id,
+ attach: [{ tagName: "list-stats-tag" }],
+ detach: [],
+ });
+
+ const tagId = firstAttachment.attached[0];
+
+ await bookmarksApi.updateTags({
+ bookmarkId: secondBookmark.id,
+ attach: [{ tagId }],
+ detach: [],
+ });
+
+ const list = await tagsApi.list();
+ const tagStats = list.tags.find((tag) => tag.id === tagId);
+
+ expect(tagStats).toBeDefined();
+ expect(tagStats!.numBookmarks).toBe(2);
+ expect(tagStats!.numBookmarksByAttachedType.human).toBe(2);
+ expect(tagStats!.numBookmarksByAttachedType.ai).toBe(0);
+ });
+
test<CustomTestContext>("list tags - privacy", async ({ apiCallers }) => {
const apiUser1 = apiCallers[0].tags;
await apiUser1.create({ name: "user1Tag" });