Skip to content

Commit 0622638

Browse files
committed
Add test to check handling of empty remote page return
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
1 parent f2a616d commit 0622638

1 file changed

Lines changed: 86 additions & 0 deletions

File tree

Tests/NextcloudFileProviderKitTests/EnumeratorTests.swift

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,92 @@ final class EnumeratorTests: XCTestCase {
547547
XCTAssertNil(Self.dbManager.itemMetadata(ocId: rootItem.identifier))
548548
}
549549

550+
func testWorkingSetEnumerationStopsOnExhaustedTotal() async throws {
551+
// This test verifies that enumeration correctly terminates when a faulty server
552+
// provides a `nextPage` token but all items (according to `pageTotal`) have been received.
553+
554+
// 1. Setup: A folder with 9 items which, when including itself in the propfind, is an exact
555+
// multiple of the page size.
556+
rootItem.children = []
557+
let folder = MockRemoteItem(
558+
identifier: "folder10",
559+
name: "folder10",
560+
remotePath: Self.account.davFilesUrl + "/folder10",
561+
directory: true,
562+
account: Self.account.ncKitAccount,
563+
username: Self.account.username,
564+
userId: Self.account.id,
565+
serverUrl: Self.account.serverUrl
566+
)
567+
folder.parent = rootItem
568+
rootItem.children.append(folder)
569+
570+
for i in 0..<9 {
571+
let childItem = MockRemoteItem(
572+
identifier: "item\(i)",
573+
name: "item\(i).txt",
574+
remotePath: folder.remotePath + "/item\(i).txt",
575+
account: Self.account.ncKitAccount,
576+
username: Self.account.username,
577+
userId: Self.account.id,
578+
serverUrl: Self.account.serverUrl
579+
)
580+
childItem.parent = folder
581+
folder.children.append(childItem)
582+
}
583+
584+
let db = Self.dbManager.ncDatabase()
585+
debugPrint(db)
586+
587+
let remoteInterface = MockRemoteInterface(rootItem: rootItem, pagination: true)
588+
let pageSize = 5
589+
590+
// This test requires a modification to `MockRemoteInterface` to simulate a faulty server
591+
remoteInterface.forceNextPageOnLastContentPage = true
592+
593+
// 2. Manually drive the pagination loop.
594+
var allEnumeratedItems: [NSFileProviderItem] = []
595+
var currentPage: NSFileProviderPage? =
596+
NSFileProviderPage.initialPageSortedByName as NSFileProviderPage
597+
var loopCount = 0
598+
599+
while let pageToEnumerate = currentPage {
600+
loopCount += 1
601+
currentPage = nil // Reset for the next iteration
602+
603+
// Create a NEW enumerator and observer for this single page request
604+
let enumerator = Enumerator(
605+
enumeratedItemIdentifier: .workingSet,
606+
account: Self.account,
607+
remoteInterface: remoteInterface,
608+
dbManager: Self.dbManager,
609+
pageSize: pageSize
610+
)
611+
let observer = MockEnumerationObserver(enumerator: enumerator)
612+
try await observer.enumerateItemsPage(page: pageToEnumerate)
613+
XCTAssertNil(observer.error)
614+
allEnumeratedItems += observer.items
615+
currentPage = observer.page
616+
}
617+
618+
// 3. Assert the results.
619+
// The loop should have run 3 times:
620+
// 1. For root
621+
// 2. For `folder10` page 1 (items 0-4).
622+
// 3. For `folder10` page 2 (items 5-9). The enumerator logic should see that all items
623+
// have been delivered and should not return the phantom page token, terminating the loop.
624+
XCTAssertNil(currentPage, "Loop should have terminated with a nil next page.")
625+
XCTAssertEqual(loopCount, 3, "The enumeration loop should have terminated correctly.")
626+
627+
// Total items expected: 1 folder + 9 children = 10.
628+
let expectedTotalItems = 1 + 9
629+
XCTAssertEqual(
630+
allEnumeratedItems.count,
631+
expectedTotalItems,
632+
"The correct number of total items should be enumerated."
633+
)
634+
}
635+
550636
func testReadServerUrlFollowUpPagination() async throws {
551637
// 1. Arrange: Setup a folder with enough children to require multiple pages.
552638
remoteFolder.children = []

0 commit comments

Comments
 (0)