diff options
| author | Mohamed Bassem <me@mbassem.com> | 2025-09-28 11:03:48 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-28 11:03:48 +0100 |
| commit | 62f7d900c52784ff05d933b52379e5455ea6bd00 (patch) | |
| tree | 2702d74c96576447974af84850f3ba6b66beeeb4 /packages/e2e_tests/tests/api | |
| parent | 9fe09bfa9021c8d85d2d9aef591936101cab19f6 (diff) | |
| download | karakeep-62f7d900c52784ff05d933b52379e5455ea6bd00.tar.zst | |
feat: Add tag search and pagination (#1987)
* feat: Add tag search and use in the homepage
* use paginated query in the all tags view
* wire the load more buttons
* add skeleton to all tags page
* fix attachedby aggregation
* fix loading states
* fix hasNextPage
* use action buttons for load more buttons
* migrate the tags auto complete to the search api
* Migrate the tags editor to the new search API
* Replace tag merging dialog with tag auto completion
* Merge both search and list APIs
* fix tags.list
* add some tests for the endpoint
* add relevance based sorting
* change cursor
* update the REST API
* fix review comments
* more fixes
* fix lockfile
* i18n
* fix visible tags
Diffstat (limited to 'packages/e2e_tests/tests/api')
| -rw-r--r-- | packages/e2e_tests/tests/api/tags.test.ts | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/packages/e2e_tests/tests/api/tags.test.ts b/packages/e2e_tests/tests/api/tags.test.ts index 6c387628..bfedb307 100644 --- a/packages/e2e_tests/tests/api/tags.test.ts +++ b/packages/e2e_tests/tests/api/tags.test.ts @@ -198,4 +198,105 @@ describe("Tags API", () => { expect(updatedTaggedBookmarks!.bookmarks.length).toBe(1); expect(updatedTaggedBookmarks!.bookmarks[0].id).toBe(secondBookmark!.id); }); + + it("should paginate through tags", async () => { + // Create multiple tags + const tagNames = ["Tag A", "Tag B", "Tag C", "Tag D", "Tag E"]; + const createdTags = []; + + for (const name of tagNames) { + const { data: tag } = await client.POST("/tags", { + body: { name }, + }); + createdTags.push(tag!); + } + + // Test pagination with limit of 2 + const { data: firstPage, response: firstResponse } = await client.GET( + "/tags", + { + params: { + query: { + limit: 2, + }, + }, + }, + ); + + expect(firstResponse.status).toBe(200); + expect(firstPage!.tags.length).toBe(2); + expect(firstPage!.nextCursor).toBeDefined(); + + // Get second page using cursor + const { data: secondPage, response: secondResponse } = await client.GET( + "/tags", + { + params: { + query: { + limit: 2, + cursor: firstPage!.nextCursor!, + }, + }, + }, + ); + + expect(secondResponse.status).toBe(200); + expect(secondPage!.tags.length).toBe(2); + expect(secondPage!.nextCursor).toBeDefined(); + + // Get third page + const { data: thirdPage, response: thirdResponse } = await client.GET( + "/tags", + { + params: { + query: { + limit: 2, + cursor: secondPage!.nextCursor!, + }, + }, + }, + ); + + expect(thirdResponse.status).toBe(200); + expect(thirdPage!.tags.length).toBe(1); // Only one tag remaining + expect(thirdPage!.nextCursor).toBeNull(); // No more pages + + // Verify all tags are accounted for across pages + const allPagedTags = [ + ...firstPage!.tags, + ...secondPage!.tags, + ...thirdPage!.tags, + ]; + expect(allPagedTags.length).toBe(5); + + // Verify all created tags are included + const allPagedTagIds = allPagedTags.map((tag) => tag.id); + const createdTagIds = createdTags.map((tag) => tag.id); + expect(allPagedTagIds.sort()).toEqual(createdTagIds.sort()); + }); + + it("Invalid cursor should return 400", async () => { + const { response } = await client.GET("/tags", { + params: { + query: { + limit: 2, + cursor: "{}", + }, + }, + }); + expect(response.status).toBe(400); + }); + + it("Listing without args returns all tags", async () => { + const tagNames = ["Tag A", "Tag B", "Tag C", "Tag D", "Tag E"]; + + for (const name of tagNames) { + await client.POST("/tags", { + body: { name }, + }); + } + + const { data } = await client.GET("/tags"); + expect(data?.tags).toHaveLength(tagNames.length); + }); }); |
