From 05c4777260be7e051a0b32d361b614354eee20b4 Mon Sep 17 00:00:00 2001 From: Jyrki Gadinger Date: Mon, 6 Oct 2025 11:21:56 +0200 Subject: [PATCH] fix(NKFile+Extensions): prevent `__NC_ROOT__` from appearing With nextcloud/NextcloudKit#169 the sync root folder name has changed. This required consumers of the API to update the handling of the root folder case accordingly. BUG: nextcloud/desktop#8832 Signed-off-by: Jyrki Gadinger --- .../Enumeration/Enumerator+SyncEngine.swift | 2 +- .../Extensions/NKFile+Extensions.swift | 7 +++---- Tests/Interface/MockRemoteItem.swift | 4 ++-- Tests/InterfaceTests/MockRemoteInterfaceTests.swift | 4 ++-- .../NKFileExtensionTests.swift | 8 ++++---- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Sources/NextcloudFileProviderKit/Enumeration/Enumerator+SyncEngine.swift b/Sources/NextcloudFileProviderKit/Enumeration/Enumerator+SyncEngine.swift index 1abf500e..8a0eda39 100644 --- a/Sources/NextcloudFileProviderKit/Enumeration/Enumerator+SyncEngine.swift +++ b/Sources/NextcloudFileProviderKit/Enumeration/Enumerator+SyncEngine.swift @@ -183,7 +183,7 @@ extension Enumerator { guard receivedFile.directory || serverUrl == dbManager.account.davFilesUrl || receivedFile.fullUrlMatches(dbManager.account.davFilesUrl + "/.") || - (receivedFile.fileName == "." && receivedFile.serverUrl == "..") + (receivedFile.fileName == NextcloudKit.shared.nkCommonInstance.rootFileName && receivedFile.serverUrl == dbManager.account.davFilesUrl) else { logger.debug("Read item is a file, converting.", [.url: serverUrl]) var metadata = receivedFile.toItemMetadata() diff --git a/Sources/NextcloudFileProviderKit/Extensions/NKFile+Extensions.swift b/Sources/NextcloudFileProviderKit/Extensions/NKFile+Extensions.swift index 9ab45821..569120df 100644 --- a/Sources/NextcloudFileProviderKit/Extensions/NKFile+Extensions.swift +++ b/Sources/NextcloudFileProviderKit/Extensions/NKFile+Extensions.swift @@ -26,14 +26,13 @@ extension NKFile { // Don't ask me why, NextcloudKit renames and moves the root folder details // Also don't ask me why, but, NextcloudKit marks the NKFile for this as not a directory - let rootRequiresFixup = serverUrl == ".." && fileName == "." + let rootServerUrl = urlBase + Account.webDavFilesUrlSuffix + userId + let rootRequiresFixup = serverUrl == rootServerUrl && fileName == NextcloudKit.shared.nkCommonInstance.rootFileName let ocId = rootRequiresFixup ? NSFileProviderItemIdentifier.rootContainer.rawValue : self.ocId let directory = rootRequiresFixup ? true : self.directory - let serverUrl = rootRequiresFixup - ? urlBase + Account.webDavFilesUrlSuffix + userId - : self.serverUrl + let serverUrl = rootRequiresFixup ? rootServerUrl : self.serverUrl let fileName = rootRequiresFixup ? "" : self.fileName return SendableItemMetadata( diff --git a/Tests/Interface/MockRemoteItem.swift b/Tests/Interface/MockRemoteItem.swift index 3b9cb0f8..70f68d55 100644 --- a/Tests/Interface/MockRemoteItem.swift +++ b/Tests/Interface/MockRemoteItem.swift @@ -140,7 +140,7 @@ public class MockRemoteItem: Equatable { let isRoot = identifier == NSFileProviderItemIdentifier.rootContainer.rawValue var file = NKFile() file.fileName = isRoot - ? "." + ? "__NC_ROOT__" : trashbinOriginalLocation?.split(separator: "/").last?.toString() ?? name file.size = size file.date = creationDate @@ -149,7 +149,7 @@ public class MockRemoteItem: Equatable { file.ocId = identifier file.fileId = identifier.replacingOccurrences(of: trashedItemIdSuffix, with: "") file.serverUrl = isRoot - ? ".." + ? serverUrl + "/remote.php/dav/files/" + userId : parent?.remotePath ?? remotePath file.account = account file.user = username diff --git a/Tests/InterfaceTests/MockRemoteInterfaceTests.swift b/Tests/InterfaceTests/MockRemoteInterfaceTests.swift index d438f508..f054d726 100644 --- a/Tests/InterfaceTests/MockRemoteInterfaceTests.swift +++ b/Tests/InterfaceTests/MockRemoteInterfaceTests.swift @@ -503,9 +503,9 @@ final class MockRemoteInterfaceTests: XCTestCase { let targetRootFile = result.files.first let expectedRoot = remoteInterface.rootItem XCTAssertEqual(targetRootFile?.ocId, expectedRoot?.identifier) - XCTAssertEqual(targetRootFile?.fileName, ".") // NextcloudKit gives the root dir this name + XCTAssertEqual(targetRootFile?.fileName, "__NC_ROOT__") // NextcloudKit gives the root dir this name XCTAssertNotEqual(targetRootFile?.fileName, expectedRoot?.name) - XCTAssertEqual(targetRootFile?.serverUrl, "..") // NextcloudKit gives the root dir this surl + XCTAssertEqual(targetRootFile?.serverUrl, "https://mock.nc.com/remote.php/dav/files/testUserId") // NextcloudKit gives the root dir this url XCTAssertEqual(targetRootFile?.date, expectedRoot?.creationDate) XCTAssertEqual(targetRootFile?.etag, expectedRoot?.versionIdentifier) diff --git a/Tests/NextcloudFileProviderKitTests/NKFileExtensionTests.swift b/Tests/NextcloudFileProviderKitTests/NKFileExtensionTests.swift index ddc395d0..ff676e51 100644 --- a/Tests/NextcloudFileProviderKitTests/NKFileExtensionTests.swift +++ b/Tests/NextcloudFileProviderKitTests/NKFileExtensionTests.swift @@ -46,8 +46,8 @@ final class NKFileExtensionsTests: NextcloudFileProviderKitTestCase { // which has a special serverUrl and fileName. let rootNKFile = createNKFile( ocId: "rootId", - serverUrl: "..", // Special root value - fileName: ".", // Special root value + serverUrl: "https://mock.nc.com/remote.php/dav/files/testUserId", // Special root value + fileName: "__NC_ROOT__", // Special root value directory: false // NextcloudKit sometimes marks the root as not a directory ) @@ -99,8 +99,8 @@ final class NKFileExtensionsTests: NextcloudFileProviderKitTestCase { // 1. Arrange: Create an array of NKFiles where the first item is the special root. let rootNKFile = createNKFile( ocId: "rootId", // This will be overridden by the logic - serverUrl: "..", - fileName: ".", + serverUrl: "https://mock.nc.com/remote.php/dav/files/testUserId", + fileName: "__NC_ROOT__", directory: false // Mimic NextcloudKit behavior ) let childNKFile = createNKFile(