Skip to content

Commit 0ae485b

Browse files
committed
Add further tests for non-working set enumeration
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
1 parent 9c84f38 commit 0ae485b

1 file changed

Lines changed: 126 additions & 0 deletions

File tree

Tests/NextcloudFileProviderKitTests/EnumeratorTests.swift

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,4 +1165,130 @@ final class EnumeratorTests: XCTestCase {
11651165
XCTAssertEqual(observer.observedPages.first, NSFileProviderPage.initialPageSortedByName as NSFileProviderPage)
11661166
XCTAssertEqual(observer.observedPages.count, 5)
11671167
}
1168+
1169+
func testEmptyFolderPaginatedEnumeration() async throws {
1170+
// 1. Setup: remoteFolder exists in the DB but has no children.
1171+
// Ensure the folder itself is in the database, as the enumerator for a specific item
1172+
// will try to fetch its metadata.
1173+
remoteFolder.children = [] // Ensure it's empty for this test
1174+
Self.dbManager.addItemMetadata(remoteFolder.toItemMetadata(account: Self.account))
1175+
XCTAssertNotNil(Self.dbManager.itemMetadata(ocId: remoteFolder.identifier), "Folder metadata should be in DB for enumeration.")
1176+
1177+
let db = Self.dbManager.ncDatabase() // Strong ref for in-memory test db
1178+
debugPrint(db)
1179+
// Enable pagination in MockRemoteInterface to ensure the pagination path is taken
1180+
let remoteInterface = MockRemoteInterface(rootItem: rootItem, pagination: true)
1181+
1182+
// 2. Create enumerator for the empty folder with a specific pageSize.
1183+
let enumerator = Enumerator(
1184+
enumeratedItemIdentifier: NSFileProviderItemIdentifier(remoteFolder.identifier),
1185+
account: Self.account,
1186+
remoteInterface: remoteInterface,
1187+
dbManager: Self.dbManager,
1188+
pageSize: 5 // Page size can be anything, as the folder is empty
1189+
)
1190+
let observer = MockEnumerationObserver(enumerator: enumerator)
1191+
1192+
// 3. Enumerate items.
1193+
try await observer.enumerateItems()
1194+
1195+
// 4. Assertions.
1196+
// When enumerating a folder (even an empty one) with depth .targetAndDirectChildren,
1197+
// the folder item itself should not be returned.
1198+
XCTAssertEqual(observer.items.count, 0, "Should enumerate nothing.")
1199+
1200+
// For an empty folder, there's only one "page" of results (the folder itself).
1201+
XCTAssertEqual(observer.observedPages.count, 1, "Should be one page call for an empty folder.")
1202+
1203+
// Verify the folder's metadata in the database is up-to-date.
1204+
// This ensures the enumeration process also updates the target item's metadata if necessary
1205+
let dbFolderMetadata =
1206+
try XCTUnwrap(Self.dbManager.itemMetadata(ocId: remoteFolder.identifier))
1207+
XCTAssertEqual(
1208+
dbFolderMetadata.etag,
1209+
remoteFolder.versionIdentifier,
1210+
"Folder ETag should be updated in DB if changed by enumeration."
1211+
)
1212+
let storedFolderItem = Item(
1213+
metadata: dbFolderMetadata,
1214+
parentItemIdentifier: .init(rootItem.identifier),
1215+
account: Self.account,
1216+
remoteInterface: remoteInterface,
1217+
dbManager: Self.dbManager
1218+
)
1219+
let childItemCount = storedFolderItem.childItemCount as? Int
1220+
let expectedChildItemCount = remoteFolder.children.count
1221+
XCTAssertEqual(childItemCount, expectedChildItemCount)
1222+
}
1223+
1224+
func testFolderWithFewItemsPaginatedEnumeration() async throws {
1225+
// 1. Setup: remoteFolder with 3 children (fewer than pageSize 5).
1226+
// Add folder metadata to DB.
1227+
remoteFolder.children = []
1228+
for i in 0..<3 {
1229+
let childItem = MockRemoteItem(
1230+
identifier: "fewItems-child\(i)",
1231+
name: "child\(i).txt",
1232+
remotePath: remoteFolder.remotePath + "/child\(i).txt",
1233+
account: Self.account.ncKitAccount,
1234+
username: Self.account.username,
1235+
userId: Self.account.id,
1236+
serverUrl: Self.account.serverUrl
1237+
)
1238+
childItem.parent = remoteFolder
1239+
remoteFolder.children.append(childItem)
1240+
}
1241+
Self.dbManager.addItemMetadata(remoteFolder.toItemMetadata(account: Self.account))
1242+
XCTAssertNotNil(Self.dbManager.itemMetadata(ocId: remoteFolder.identifier))
1243+
1244+
let db = Self.dbManager.ncDatabase()
1245+
debugPrint(db)
1246+
let remoteInterface = MockRemoteInterface(rootItem: rootItem, pagination: true)
1247+
1248+
// 2. Create enumerator with pageSize > number of children.
1249+
let enumerator = Enumerator(
1250+
enumeratedItemIdentifier: NSFileProviderItemIdentifier(remoteFolder.identifier),
1251+
account: Self.account,
1252+
remoteInterface: remoteInterface,
1253+
dbManager: Self.dbManager,
1254+
pageSize: 5
1255+
)
1256+
let observer = MockEnumerationObserver(enumerator: enumerator)
1257+
1258+
// 3. Enumerate items.
1259+
try await observer.enumerateItems()
1260+
1261+
// 4. Assertions.
1262+
// Expected items: 0 (folder itself) + 3 children = 3 items.
1263+
XCTAssertEqual(observer.items.count, 3, "Should enumerate the 3 children.")
1264+
XCTAssertFalse(
1265+
observer.items.contains(where: { $0.itemIdentifier.rawValue == remoteFolder.identifier }),
1266+
"Folder itself should be enumerated."
1267+
)
1268+
for i in 0..<3 {
1269+
XCTAssertTrue(
1270+
observer.items.contains(where: { $0.itemIdentifier.rawValue == "fewItems-child\(i)" }),
1271+
"Child item fewItems-child\(i) should be enumerated."
1272+
)
1273+
}
1274+
1275+
// All items fit on one page.
1276+
XCTAssertEqual(
1277+
observer.observedPages.count,
1278+
1,
1279+
"Should be one page call as all items fit in the first page."
1280+
)
1281+
1282+
// Verify folder metadata in DB.
1283+
let dbFolderMetadata =
1284+
try XCTUnwrap(Self.dbManager.itemMetadata(ocId: remoteFolder.identifier))
1285+
XCTAssertEqual(dbFolderMetadata.etag, remoteFolder.versionIdentifier)
1286+
// Ensure all children are also in the DB after enumeration
1287+
for i in 0..<3 {
1288+
XCTAssertNotNil(
1289+
Self.dbManager.itemMetadata(ocId: "fewItems-child\(i)"),
1290+
"Child item fewItems-child\(i) metadata should be in DB."
1291+
)
1292+
}
1293+
}
11681294
}

0 commit comments

Comments
 (0)