From 79041869e640f620ea4ed7b44d2b0bb3282f49af Mon Sep 17 00:00:00 2001 From: systemblue Date: Wed, 10 Jun 2026 14:26:11 -0400 Subject: [PATCH] test: cover the keyed pagination de-duplication path PaginationStateTests never exercised dedupeKey: a key repeated across pages is filtered out on the later page, hasMore follows !newItems.isEmpty when a key is set (including a full page of already-seen keys ending pagination), and a reload resets the seen keys. --- Forji/ForjiTests/PaginationStateTests.swift | 47 +++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/Forji/ForjiTests/PaginationStateTests.swift b/Forji/ForjiTests/PaginationStateTests.swift index 32cd25f..c8cabd6 100644 --- a/Forji/ForjiTests/PaginationStateTests.swift +++ b/Forji/ForjiTests/PaginationStateTests.swift @@ -439,3 +439,50 @@ struct PaginationStateLoadMoreTests { #expect(!pagination.isLoading) } } + +// MARK: - Keyed de-duplication + +struct PaginationStateDedupeTests { + + @Test @MainActor func loadMoreFiltersKeysSeenOnEarlierPages() async { + let pagination = PaginationState(pageSize: 2) + pagination.dedupeKey = { $0 } + await pagination.reload { _, _ in ["a", "b"] }.value + + // "b" resurfaces on page 2 — only "c" is new + await pagination.loadMore { _, _ in ["b", "c"] } + #expect(pagination.items == ["a", "b", "c"]) + #expect(pagination.hasMore) // the page contributed a new item + } + + @Test @MainActor func hasMoreFollowsNewItemsNotPageSize() async { + let pagination = PaginationState(pageSize: 5) + pagination.dedupeKey = { $0 } + await pagination.reload { _, _ in ["a", "b"] }.value + #expect(pagination.hasMore) // 2 < pageSize 5, but the page contributed new items + } + + @Test @MainActor func hasMoreFalseWhenFullPageIsAllDuplicates() async { + let pagination = PaginationState(pageSize: 2) + pagination.dedupeKey = { $0 } + await pagination.reload { _, _ in ["a", "b"] }.value + #expect(pagination.hasMore) + + // 2 >= pageSize 2, but every key was already seen -> pagination ends + await pagination.loadMore { _, _ in ["a", "b"] } + #expect(pagination.items == ["a", "b"]) + #expect(!pagination.hasMore) + } + + @Test @MainActor func reloadResetsSeenKeys() async { + let pagination = PaginationState(pageSize: 2) + pagination.dedupeKey = { $0 } + await pagination.reload { _, _ in ["a", "b"] }.value + await pagination.loadMore { _, _ in ["b", "c"] } + #expect(pagination.items == ["a", "b", "c"]) + + // A fresh reload must accept keys seen in the previous cycle + await pagination.reload { _, _ in ["a", "b"] }.value + #expect(pagination.items == ["a", "b"]) + } +}