diff options
Diffstat (limited to 'packages/e2e_tests/tests/api')
| -rw-r--r-- | packages/e2e_tests/tests/api/assets.test.ts | 134 | ||||
| -rw-r--r-- | packages/e2e_tests/tests/api/bookmarks.test.ts | 288 | ||||
| -rw-r--r-- | packages/e2e_tests/tests/api/highlights.test.ts | 242 | ||||
| -rw-r--r-- | packages/e2e_tests/tests/api/lists.test.ts | 185 | ||||
| -rw-r--r-- | packages/e2e_tests/tests/api/tags.test.ts | 215 |
5 files changed, 1064 insertions, 0 deletions
diff --git a/packages/e2e_tests/tests/api/assets.test.ts b/packages/e2e_tests/tests/api/assets.test.ts new file mode 100644 index 00000000..0fab3d3f --- /dev/null +++ b/packages/e2e_tests/tests/api/assets.test.ts @@ -0,0 +1,134 @@ +import { createHoarderClient } from "@hoarderapp/sdk"; +import { assert, beforeEach, describe, expect, inject, it } from "vitest"; + +import { createTestUser, uploadTestAsset } from "../../utils/api"; + +describe("Assets API", () => { + const port = inject("hoarderPort"); + + if (!port) { + throw new Error("Missing required environment variables"); + } + + let client: ReturnType<typeof createHoarderClient>; + let apiKey: string; + + beforeEach(async () => { + apiKey = await createTestUser(); + client = createHoarderClient({ + baseUrl: `http://localhost:${port}/api/v1/`, + headers: { + "Content-Type": "application/json", + authorization: `Bearer ${apiKey}`, + }, + }); + }); + + it("should upload and retrieve an asset", async () => { + // Create a test file + const file = new File(["test content"], "test.pdf", { + type: "application/pdf", + }); + + // Upload the asset + const uploadResponse = await uploadTestAsset(apiKey, port, file); + expect(uploadResponse.assetId).toBeDefined(); + expect(uploadResponse.contentType).toBe("application/pdf"); + expect(uploadResponse.fileName).toBe("test.pdf"); + + // Retrieve the asset + const resp = await fetch( + `http://localhost:${port}/api/assets/${uploadResponse.assetId}`, + { + headers: { + authorization: `Bearer ${apiKey}`, + }, + }, + ); + + expect(resp.status).toBe(200); + }); + + it("should attach an asset to a bookmark", async () => { + // Create a test file + const file = new File(["test content"], "test.pdf", { + type: "application/pdf", + }); + + // Upload the asset + const uploadResponse = await uploadTestAsset(apiKey, port, file); + + // Create a bookmark + const { data: createdBookmark } = await client.POST("/bookmarks", { + body: { + type: "asset", + title: "Test Asset Bookmark", + assetType: "pdf", + assetId: uploadResponse.assetId, + }, + }); + + expect(createdBookmark).toBeDefined(); + expect(createdBookmark?.id).toBeDefined(); + + // Get the bookmark and verify asset + const { data: retrievedBookmark } = await client.GET( + "/bookmarks/{bookmarkId}", + { + params: { + path: { + bookmarkId: createdBookmark!.id, + }, + }, + }, + ); + + expect(retrievedBookmark).toBeDefined(); + assert(retrievedBookmark!.content.type === "asset"); + expect(retrievedBookmark!.content.assetId).toBe(uploadResponse.assetId); + }); + + it("should delete asset when deleting bookmark", async () => { + // Create a test file + const file = new File(["test content"], "test.pdf", { + type: "application/pdf", + }); + + // Upload the asset + const uploadResponse = await uploadTestAsset(apiKey, port, file); + + // Create a bookmark + const { data: createdBookmark } = await client.POST("/bookmarks", { + body: { + type: "asset", + title: "Test Asset Bookmark", + assetType: "pdf", + assetId: uploadResponse.assetId, + }, + }); + + // Delete the bookmark + const { response: deleteResponse } = await client.DELETE( + "/bookmarks/{bookmarkId}", + { + params: { + path: { + bookmarkId: createdBookmark!.id, + }, + }, + }, + ); + expect(deleteResponse.status).toBe(204); + + // Verify asset is deleted + const assetResponse = await fetch( + `http://localhost:${port}/api/assets/${uploadResponse.assetId}`, + { + headers: { + authorization: `Bearer ${apiKey}`, + }, + }, + ); + expect(assetResponse.status).toBe(404); + }); +}); diff --git a/packages/e2e_tests/tests/api/bookmarks.test.ts b/packages/e2e_tests/tests/api/bookmarks.test.ts new file mode 100644 index 00000000..727ca758 --- /dev/null +++ b/packages/e2e_tests/tests/api/bookmarks.test.ts @@ -0,0 +1,288 @@ +import { createHoarderClient } from "@hoarderapp/sdk"; +import { assert, beforeEach, describe, expect, inject, it } from "vitest"; + +import { createTestUser } from "../../utils/api"; + +describe("Bookmarks API", () => { + const port = inject("hoarderPort"); + + if (!port) { + throw new Error("Missing required environment variables"); + } + + let client: ReturnType<typeof createHoarderClient>; + let apiKey: string; + + beforeEach(async () => { + apiKey = await createTestUser(); + client = createHoarderClient({ + baseUrl: `http://localhost:${port}/api/v1/`, + headers: { + "Content-Type": "application/json", + authorization: `Bearer ${apiKey}`, + }, + }); + }); + + it("should create and retrieve a bookmark", async () => { + // Create a new bookmark + const { + data: createdBookmark, + response: createResponse, + error, + } = await client.POST("/bookmarks", { + body: { + type: "text", + title: "Test Bookmark", + text: "This is a test bookmark", + }, + }); + + if (error) { + console.error("Error creating bookmark:", error); + } + + expect(createResponse.status).toBe(201); + expect(createdBookmark).toBeDefined(); + expect(createdBookmark?.id).toBeDefined(); + + // Get the created bookmark + const { data: retrievedBookmark, response: getResponse } = await client.GET( + "/bookmarks/{bookmarkId}", + { + params: { + path: { + bookmarkId: createdBookmark.id, + }, + }, + }, + ); + + expect(getResponse.status).toBe(200); + expect(retrievedBookmark!.id).toBe(createdBookmark.id); + expect(retrievedBookmark!.title).toBe("Test Bookmark"); + assert(retrievedBookmark!.content.type === "text"); + expect(retrievedBookmark!.content.text).toBe("This is a test bookmark"); + }); + + it("should update a bookmark", async () => { + // Create a new bookmark + const { data: createdBookmark, error: createError } = await client.POST( + "/bookmarks", + { + body: { + type: "text", + title: "Test Bookmark", + text: "This is a test bookmark", + }, + }, + ); + + if (createError) { + console.error("Error creating bookmark:", createError); + throw createError; + } + if (!createdBookmark) { + throw new Error("Bookmark creation failed"); + } + + // Update the bookmark + const { data: updatedBookmark, response: updateResponse } = + await client.PATCH("/bookmarks/{bookmarkId}", { + params: { + path: { + bookmarkId: createdBookmark.id, + }, + }, + body: { + title: "Updated Title", + }, + }); + + expect(updateResponse.status).toBe(200); + expect(updatedBookmark!.title).toBe("Updated Title"); + }); + + it("should delete a bookmark", async () => { + // Create a new bookmark + const { data: createdBookmark, error: createError } = await client.POST( + "/bookmarks", + { + body: { + type: "text", + title: "Test Bookmark", + text: "This is a test bookmark", + }, + }, + ); + + if (createError) { + console.error("Error creating bookmark:", createError); + throw createError; + } + if (!createdBookmark) { + throw new Error("Bookmark creation failed"); + } + + // Delete the bookmark + const { response: deleteResponse } = await client.DELETE( + "/bookmarks/{bookmarkId}", + { + params: { + path: { + bookmarkId: createdBookmark.id, + }, + }, + }, + ); + + expect(deleteResponse.status).toBe(204); + + // Verify it's deleted + const { response: getResponse } = await client.GET( + "/bookmarks/{bookmarkId}", + { + params: { + path: { + bookmarkId: createdBookmark.id, + }, + }, + }, + ); + + expect(getResponse.status).toBe(404); + }); + + it("should paginate through bookmarks", async () => { + // Create multiple bookmarks + const bookmarkPromises = Array.from({ length: 5 }, (_, i) => + client.POST("/bookmarks", { + body: { + type: "text", + title: `Test Bookmark ${i}`, + text: `This is test bookmark ${i}`, + }, + }), + ); + + const createdBookmarks = await Promise.all(bookmarkPromises); + const bookmarkIds = createdBookmarks.map((b) => b.data!.id); + + // Get first page + const { data: firstPage, response: firstResponse } = await client.GET( + "/bookmarks", + { + params: { + query: { + limit: 2, + }, + }, + }, + ); + + expect(firstResponse.status).toBe(200); + expect(firstPage!.bookmarks.length).toBe(2); + expect(firstPage!.nextCursor).toBeDefined(); + + // Get second page + const { data: secondPage, response: secondResponse } = await client.GET( + "/bookmarks", + { + params: { + query: { + limit: 2, + cursor: firstPage!.nextCursor!, + }, + }, + }, + ); + + expect(secondResponse.status).toBe(200); + expect(secondPage!.bookmarks.length).toBe(2); + expect(secondPage!.nextCursor).toBeDefined(); + + // Get final page + const { data: finalPage, response: finalResponse } = await client.GET( + "/bookmarks", + { + params: { + query: { + limit: 2, + cursor: secondPage!.nextCursor!, + }, + }, + }, + ); + + expect(finalResponse.status).toBe(200); + expect(finalPage!.bookmarks.length).toBe(1); + expect(finalPage!.nextCursor).toBeNull(); + + // Verify all bookmarks were returned + const allBookmarks = [ + ...firstPage!.bookmarks, + ...secondPage!.bookmarks, + ...finalPage!.bookmarks, + ]; + expect(allBookmarks.map((b) => b.id)).toEqual( + expect.arrayContaining(bookmarkIds), + ); + }); + + it("should manage tags on a bookmark", async () => { + // Create a new bookmark + const { data: createdBookmark, error: createError } = await client.POST( + "/bookmarks", + { + body: { + type: "text", + title: "Test Bookmark", + text: "This is a test bookmark", + }, + }, + ); + + if (createError) { + console.error("Error creating bookmark:", createError); + throw createError; + } + if (!createdBookmark) { + throw new Error("Bookmark creation failed"); + } + + // Add tags + const { data: addTagsResponse, response: addTagsRes } = await client.POST( + "/bookmarks/{bookmarkId}/tags", + { + params: { + path: { + bookmarkId: createdBookmark.id, + }, + }, + body: { + tags: [{ tagName: "test-tag" }], + }, + }, + ); + + expect(addTagsRes.status).toBe(200); + expect(addTagsResponse!.attached.length).toBe(1); + + // Remove tags + const { response: removeTagsRes } = await client.DELETE( + "/bookmarks/{bookmarkId}/tags", + { + params: { + path: { + bookmarkId: createdBookmark.id, + }, + }, + body: { + tags: [{ tagId: addTagsResponse!.attached[0] }], + }, + }, + ); + + expect(removeTagsRes.status).toBe(200); + }); +}); diff --git a/packages/e2e_tests/tests/api/highlights.test.ts b/packages/e2e_tests/tests/api/highlights.test.ts new file mode 100644 index 00000000..94a4d28b --- /dev/null +++ b/packages/e2e_tests/tests/api/highlights.test.ts @@ -0,0 +1,242 @@ +import { createHoarderClient } from "@hoarderapp/sdk"; +import { beforeEach, describe, expect, inject, it } from "vitest"; + +import { createTestUser } from "../../utils/api"; + +describe("Highlights API", () => { + const port = inject("hoarderPort"); + + if (!port) { + throw new Error("Missing required environment variables"); + } + + let client: ReturnType<typeof createHoarderClient>; + let apiKey: string; + + beforeEach(async () => { + apiKey = await createTestUser(); + client = createHoarderClient({ + baseUrl: `http://localhost:${port}/api/v1/`, + headers: { + "Content-Type": "application/json", + authorization: `Bearer ${apiKey}`, + }, + }); + }); + + it("should create, get, update and delete a highlight", async () => { + // Create a bookmark first + const { data: createdBookmark } = await client.POST("/bookmarks", { + body: { + type: "text", + title: "Test Bookmark", + text: "This is a test bookmark", + }, + }); + + // Create a new highlight + const { data: createdHighlight, response: createResponse } = + await client.POST("/highlights", { + body: { + bookmarkId: createdBookmark!.id, + startOffset: 0, + endOffset: 5, + text: "This ", + note: "Test note", + color: "yellow", + }, + }); + + expect(createResponse.status).toBe(201); + expect(createdHighlight).toBeDefined(); + expect(createdHighlight?.id).toBeDefined(); + expect(createdHighlight?.text).toBe("This "); + expect(createdHighlight?.note).toBe("Test note"); + + // Get the created highlight + const { data: retrievedHighlight, response: getResponse } = + await client.GET("/highlights/{highlightId}", { + params: { + path: { + highlightId: createdHighlight!.id, + }, + }, + }); + + expect(getResponse.status).toBe(200); + expect(retrievedHighlight!.id).toBe(createdHighlight!.id); + expect(retrievedHighlight!.text).toBe("This "); + expect(retrievedHighlight!.note).toBe("Test note"); + + // Update the highlight + const { data: updatedHighlight, response: updateResponse } = + await client.PATCH("/highlights/{highlightId}", { + params: { + path: { + highlightId: createdHighlight!.id, + }, + }, + body: { + color: "blue", + }, + }); + + expect(updateResponse.status).toBe(200); + expect(updatedHighlight!.color).toBe("blue"); + + // Delete the highlight + const { response: deleteResponse } = await client.DELETE( + "/highlights/{highlightId}", + { + params: { + path: { + highlightId: createdHighlight!.id, + }, + }, + }, + ); + + expect(deleteResponse.status).toBe(200); + + // Verify it's deleted + const { response: getDeletedResponse } = await client.GET( + "/highlights/{highlightId}", + { + params: { + path: { + highlightId: createdHighlight!.id, + }, + }, + }, + ); + + expect(getDeletedResponse.status).toBe(404); + }); + + it("should paginate through highlights", async () => { + // Create a bookmark first + const { data: createdBookmark } = await client.POST("/bookmarks", { + body: { + type: "text", + title: "Test Bookmark", + text: "This is a test bookmark", + }, + }); + + // Create multiple highlights + const highlightPromises = Array.from({ length: 5 }, (_, i) => + client.POST("/highlights", { + body: { + bookmarkId: createdBookmark!.id, + startOffset: i * 5, + endOffset: (i + 1) * 5, + text: `Highlight ${i}`, + note: `Note ${i}`, + }, + }), + ); + + await Promise.all(highlightPromises); + + // Get first page + const { data: firstPage, response: firstResponse } = await client.GET( + "/highlights", + { + params: { + query: { + limit: 2, + }, + }, + }, + ); + + expect(firstResponse.status).toBe(200); + expect(firstPage!.highlights.length).toBe(2); + expect(firstPage!.nextCursor).toBeDefined(); + + // Get second page + const { data: secondPage, response: secondResponse } = await client.GET( + "/highlights", + { + params: { + query: { + limit: 2, + cursor: firstPage!.nextCursor!, + }, + }, + }, + ); + + expect(secondResponse.status).toBe(200); + expect(secondPage!.highlights.length).toBe(2); + expect(secondPage!.nextCursor).toBeDefined(); + + // Get final page + const { data: finalPage, response: finalResponse } = await client.GET( + "/highlights", + { + params: { + query: { + limit: 2, + cursor: secondPage!.nextCursor!, + }, + }, + }, + ); + + expect(finalResponse.status).toBe(200); + expect(finalPage!.highlights.length).toBe(1); + expect(finalPage!.nextCursor).toBeNull(); + }); + + it("should get highlights for a bookmark", async () => { + // Create a bookmark first + const { data: createdBookmark } = await client.POST("/bookmarks", { + body: { + type: "text", + title: "Test Bookmark", + text: "This is a test bookmark", + }, + }); + + // Create highlights + await client.POST("/highlights", { + body: { + bookmarkId: createdBookmark!.id, + startOffset: 0, + endOffset: 5, + text: "This ", + note: "First highlight", + color: "yellow", + }, + }); + + await client.POST("/highlights", { + body: { + bookmarkId: createdBookmark!.id, + startOffset: 5, + endOffset: 10, + text: "is a ", + note: "Second highlight", + color: "blue", + }, + }); + + // Get highlights for bookmark + const { data: highlights, response: getResponse } = await client.GET( + "/bookmarks/{bookmarkId}/highlights", + { + params: { + path: { + bookmarkId: createdBookmark!.id, + }, + }, + }, + ); + + expect(getResponse.status).toBe(200); + expect(highlights!.highlights.length).toBe(2); + expect(highlights!.highlights.map((h) => h.text)).toContain("This "); + expect(highlights!.highlights.map((h) => h.text)).toContain("is a "); + }); +}); diff --git a/packages/e2e_tests/tests/api/lists.test.ts b/packages/e2e_tests/tests/api/lists.test.ts new file mode 100644 index 00000000..2a954b6f --- /dev/null +++ b/packages/e2e_tests/tests/api/lists.test.ts @@ -0,0 +1,185 @@ +import { createHoarderClient } from "@hoarderapp/sdk"; +import { beforeEach, describe, expect, inject, it } from "vitest"; + +import { createTestUser } from "../../utils/api"; + +describe("Lists API", () => { + const port = inject("hoarderPort"); + + if (!port) { + throw new Error("Missing required environment variables"); + } + + let client: ReturnType<typeof createHoarderClient>; + let apiKey: string; + + beforeEach(async () => { + apiKey = await createTestUser(); + client = createHoarderClient({ + baseUrl: `http://localhost:${port}/api/v1/`, + headers: { + "Content-Type": "application/json", + authorization: `Bearer ${apiKey}`, + }, + }); + }); + + it("should create, get, update and delete a list", async () => { + // Create a new list + const { data: createdList, response: createResponse } = await client.POST( + "/lists", + { + body: { + name: "Test List", + icon: "🚀", + }, + }, + ); + + expect(createResponse.status).toBe(201); + expect(createdList).toBeDefined(); + expect(createdList?.id).toBeDefined(); + expect(createdList?.name).toBe("Test List"); + + // Get the created list + const { data: retrievedList, response: getResponse } = await client.GET( + "/lists/{listId}", + { + params: { + path: { + listId: createdList!.id, + }, + }, + }, + ); + + expect(getResponse.status).toBe(200); + expect(retrievedList!.id).toBe(createdList!.id); + expect(retrievedList!.name).toBe("Test List"); + + // Update the list + const { data: updatedList, response: updateResponse } = await client.PATCH( + "/lists/{listId}", + { + params: { + path: { + listId: createdList!.id, + }, + }, + body: { + name: "Updated List", + }, + }, + ); + + expect(updateResponse.status).toBe(200); + expect(updatedList!.name).toBe("Updated List"); + + // Delete the list + const { response: deleteResponse } = await client.DELETE( + "/lists/{listId}", + { + params: { + path: { + listId: createdList!.id, + }, + }, + }, + ); + + expect(deleteResponse.status).toBe(204); + + // Verify it's deleted + const { response: getDeletedResponse } = await client.GET( + "/lists/{listId}", + { + params: { + path: { + listId: createdList!.id, + }, + }, + }, + ); + + expect(getDeletedResponse.status).toBe(404); + }); + + it("should manage bookmarks in a list", async () => { + // Create a list + const { data: createdList } = await client.POST("/lists", { + body: { + name: "Test List", + icon: "🚀", + }, + }); + + // Create a bookmark + const { data: createdBookmark } = await client.POST("/bookmarks", { + body: { + type: "text", + title: "Test Bookmark", + text: "This is a test bookmark", + }, + }); + + // Add bookmark to list + const { response: addResponse } = await client.PUT( + "/lists/{listId}/bookmarks/{bookmarkId}", + { + params: { + path: { + listId: createdList!.id, + bookmarkId: createdBookmark!.id, + }, + }, + }, + ); + + expect(addResponse.status).toBe(204); + + // Get bookmarks in list + const { data: listBookmarks, response: getResponse } = await client.GET( + "/lists/{listId}/bookmarks", + { + params: { + path: { + listId: createdList!.id, + }, + }, + }, + ); + + expect(getResponse.status).toBe(200); + expect(listBookmarks!.bookmarks.length).toBe(1); + expect(listBookmarks!.bookmarks[0].id).toBe(createdBookmark!.id); + + // Remove bookmark from list + const { response: removeResponse } = await client.DELETE( + "/lists/{listId}/bookmarks/{bookmarkId}", + { + params: { + path: { + listId: createdList!.id, + bookmarkId: createdBookmark!.id, + }, + }, + }, + ); + + expect(removeResponse.status).toBe(204); + + // Verify bookmark is removed + const { data: updatedListBookmarks } = await client.GET( + "/lists/{listId}/bookmarks", + { + params: { + path: { + listId: createdList!.id, + }, + }, + }, + ); + + expect(updatedListBookmarks!.bookmarks.length).toBe(0); + }); +}); diff --git a/packages/e2e_tests/tests/api/tags.test.ts b/packages/e2e_tests/tests/api/tags.test.ts new file mode 100644 index 00000000..dfd3f14b --- /dev/null +++ b/packages/e2e_tests/tests/api/tags.test.ts @@ -0,0 +1,215 @@ +import { createHoarderClient } from "@hoarderapp/sdk"; +import { beforeEach, describe, expect, inject, it } from "vitest"; + +import { createTestUser } from "../../utils/api"; + +describe("Tags API", () => { + const port = inject("hoarderPort"); + + if (!port) { + throw new Error("Missing required environment variables"); + } + + let client: ReturnType<typeof createHoarderClient>; + let apiKey: string; + + beforeEach(async () => { + apiKey = await createTestUser(); + client = createHoarderClient({ + baseUrl: `http://localhost:${port}/api/v1/`, + headers: { + "Content-Type": "application/json", + authorization: `Bearer ${apiKey}`, + }, + }); + }); + + it("should get, update and delete a tag", async () => { + // Create a bookmark first + const { data: createdBookmark } = await client.POST("/bookmarks", { + body: { + type: "text", + title: "Test Bookmark", + text: "This is a test bookmark", + }, + }); + + // Create a tag by attaching it to the bookmark + const { data: addTagResponse } = await client.POST( + "/bookmarks/{bookmarkId}/tags", + { + params: { + path: { + bookmarkId: createdBookmark!.id, + }, + }, + body: { + tags: [{ tagName: "Test Tag" }], + }, + }, + ); + + const tagId = addTagResponse!.attached[0]; + + // Get the tag + const { data: retrievedTag, response: getResponse } = await client.GET( + "/tags/{tagId}", + { + params: { + path: { + tagId, + }, + }, + }, + ); + + expect(getResponse.status).toBe(200); + expect(retrievedTag!.id).toBe(tagId); + expect(retrievedTag!.name).toBe("Test Tag"); + + // Update the tag + const { data: updatedTag, response: updateResponse } = await client.PATCH( + "/tags/{tagId}", + { + params: { + path: { + tagId, + }, + }, + body: { + name: "Updated Tag", + }, + }, + ); + + expect(updateResponse.status).toBe(200); + expect(updatedTag!.name).toBe("Updated Tag"); + + // Delete the tag + const { response: deleteResponse } = await client.DELETE("/tags/{tagId}", { + params: { + path: { + tagId, + }, + }, + }); + + expect(deleteResponse.status).toBe(204); + + // Verify it's deleted + const { response: getDeletedResponse } = await client.GET("/tags/{tagId}", { + params: { + path: { + tagId, + }, + }, + }); + + expect(getDeletedResponse.status).toBe(404); + }); + + it("should manage bookmarks with a tag", async () => { + // Create a bookmark first + const { data: firstBookmark } = await client.POST("/bookmarks", { + body: { + type: "text", + title: "Test Bookmark", + text: "This is a test bookmark", + }, + }); + + // Create a tag by attaching it to the bookmark + const { data: addTagResponse } = await client.POST( + "/bookmarks/{bookmarkId}/tags", + { + params: { + path: { + bookmarkId: firstBookmark!.id, + }, + }, + body: { + tags: [{ tagName: "Test Tag" }], + }, + }, + ); + + const tagId = addTagResponse!.attached[0]; + + // Add tag to another bookmark + const { data: secondBookmark } = await client.POST("/bookmarks", { + body: { + type: "text", + title: "Second Bookmark", + text: "This is another test bookmark", + }, + }); + + const { data: addSecondTagResponse, response: addResponse } = + await client.POST("/bookmarks/{bookmarkId}/tags", { + params: { + path: { + bookmarkId: secondBookmark!.id, + }, + }, + body: { + tags: [{ tagId }], + }, + }); + + expect(addResponse.status).toBe(200); + expect(addSecondTagResponse!.attached.length).toBe(1); + + // Get bookmarks with tag + const { data: taggedBookmarks, response: getResponse } = await client.GET( + "/tags/{tagId}/bookmarks", + { + params: { + path: { + tagId, + }, + }, + }, + ); + + expect(getResponse.status).toBe(200); + expect(taggedBookmarks!.bookmarks.length).toBe(2); + expect(taggedBookmarks!.bookmarks.map((b) => b.id)).toContain( + firstBookmark!.id, + ); + expect(taggedBookmarks!.bookmarks.map((b) => b.id)).toContain( + secondBookmark!.id, + ); + + // Remove tag from first bookmark + const { response: removeResponse } = await client.DELETE( + "/bookmarks/{bookmarkId}/tags", + { + params: { + path: { + bookmarkId: firstBookmark!.id, + }, + }, + body: { + tags: [{ tagId }], + }, + }, + ); + + expect(removeResponse.status).toBe(200); + + // Verify tag is still on second bookmark + const { data: updatedTaggedBookmarks } = await client.GET( + "/tags/{tagId}/bookmarks", + { + params: { + path: { + tagId, + }, + }, + }, + ); + + expect(updatedTaggedBookmarks!.bookmarks.length).toBe(1); + expect(updatedTaggedBookmarks!.bookmarks[0].id).toBe(secondBookmark!.id); + }); +}); |
