diff --git a/Cryptomator.xcodeproj/project.pbxproj b/Cryptomator.xcodeproj/project.pbxproj index 7dfbf7e15..2b06024a7 100644 --- a/Cryptomator.xcodeproj/project.pbxproj +++ b/Cryptomator.xcodeproj/project.pbxproj @@ -290,8 +290,6 @@ 4ABCF3522726D24800A7FBB7 /* MoveVaultViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ABCF3512726D24800A7FBB7 /* MoveVaultViewModelTests.swift */; }; 4AC005F127C3D80B006FFE87 /* PremiumManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AC005F027C3D80B006FFE87 /* PremiumManager.swift */; }; 4AC005F327C3D932006FFE87 /* PremiumManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AC005F227C3D932006FFE87 /* PremiumManagerMock.swift */; }; - 4AC1157627F5BD890023F51B /* Promise+AllIgnoringResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AC1157527F5BD890023F51B /* Promise+AllIgnoringResult.swift */; }; - 4AC1157827F5BEFD0023F51B /* Promise+AllIgnoringResultsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AC1157727F5BEFD0023F51B /* Promise+AllIgnoringResultsTests.swift */; }; 4AC86270273598CC00E15BA5 /* UIViewController+ProgressHUDError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AC8626F273598CC00E15BA5 /* UIViewController+ProgressHUDError.swift */; }; 4AD0F61C24AF203F0026B765 /* FileProvider+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AD0F61B24AF203F0026B765 /* FileProvider+Actions.swift */; }; 4AD3D7D6282EBDE7008188CD /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4AD3D7D5282EBDE7008188CD /* Intents.framework */; }; @@ -830,8 +828,6 @@ 4ABCF3512726D24800A7FBB7 /* MoveVaultViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveVaultViewModelTests.swift; sourceTree = ""; }; 4AC005F027C3D80B006FFE87 /* PremiumManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PremiumManager.swift; sourceTree = ""; }; 4AC005F227C3D932006FFE87 /* PremiumManagerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PremiumManagerMock.swift; sourceTree = ""; }; - 4AC1157527F5BD890023F51B /* Promise+AllIgnoringResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Promise+AllIgnoringResult.swift"; sourceTree = ""; }; - 4AC1157727F5BEFD0023F51B /* Promise+AllIgnoringResultsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Promise+AllIgnoringResultsTests.swift"; sourceTree = ""; }; 4AC8626F273598CC00E15BA5 /* UIViewController+ProgressHUDError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+ProgressHUDError.swift"; sourceTree = ""; }; 4AD0F61B24AF203F0026B765 /* FileProvider+Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileProvider+Actions.swift"; sourceTree = ""; }; 4AD3D7D4282EBDE7008188CD /* CryptomatorIntents.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = CryptomatorIntents.appex; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1218,7 +1214,6 @@ 4AFBFA19282946BF00E30818 /* InMemoryProgressManagerTests.swift */, 4AB1D4EF27D20420009060AB /* LocalURLProviderTests.swift */, 4A0AA12C2ABA277800CF24FD /* PermissionProviderImplTests.swift */, - 4AC1157727F5BEFD0023F51B /* Promise+AllIgnoringResultsTests.swift */, 4ADC66C427A7F6D6002E6CC7 /* UnlockMonitorTests.swift */, 4A4F47F224B875070033328B /* URL+NameCollisionExtensionTests.swift */, 4AE5196427F48D6600BA6E4A /* WorkflowDependencyFactoryTests.swift */, @@ -1932,7 +1927,6 @@ 4AEE6EE02822A33400E1B35E /* NSFileProviderItemIdentifier+Database.swift */, 4A0AA12A2AB8DB1800CF24FD /* PermissionProvider.swift */, 4AEE6EE92825716400E1B35E /* ProgressManager.swift */, - 4AC1157527F5BD890023F51B /* Promise+AllIgnoringResult.swift */, 4ADD233F26737CD400374E4E /* RootFileProviderItem.swift */, 4A7514A02937F777002E802E /* SessionTaskRegistrator.swift */, 4ADC66C027A7F426002E6CC7 /* UnlockMonitor.swift */, @@ -2578,7 +2572,6 @@ 4AB1C33C265E9DBC00DC7A49 /* CloudTaskExecutorTestCase.swift in Sources */, 4AE5196727F495BF00BA6E4A /* WorkflowDependencyTasksCollectionMock.swift in Sources */, 4A0AA12F2ABA2A1600CF24FD /* PermissionProviderMock.swift in Sources */, - 4AC1157827F5BEFD0023F51B /* Promise+AllIgnoringResultsTests.swift in Sources */, 4AE5196527F48D6600BA6E4A /* WorkflowDependencyFactoryTests.swift in Sources */, 4A49FABE271ECDE80069A0CC /* ItemEnumerationTaskManagerTests.swift in Sources */, 4A248229266E2DD6002D9F59 /* FileProviderAdapterCreateDirectoryTests.swift in Sources */, @@ -2963,7 +2956,6 @@ 4ADD234026737CD400374E4E /* RootFileProviderItem.swift in Sources */, 747F2F232587BC250072FB30 /* ItemMetadataDBManager.swift in Sources */, 4A511D47265FEFBE000A0E01 /* DownloadTask.swift in Sources */, - 4AC1157627F5BD890023F51B /* Promise+AllIgnoringResult.swift in Sources */, 4A09E54E27071F4F0056D32A /* ErrorMapper.swift in Sources */, 4AEECD35279EB0FD00C6E2B5 /* FileProviderEnumerator.swift in Sources */, 4AE0D8DC2653DF1300DF5D22 /* DownloadTaskExecutor.swift in Sources */, diff --git a/Cryptomator/Snapshots/SnapshotCoordinator.swift b/Cryptomator/Snapshots/SnapshotCoordinator.swift index 30a75aa07..e9e29171a 100644 --- a/Cryptomator/Snapshots/SnapshotCoordinator.swift +++ b/Cryptomator/Snapshots/SnapshotCoordinator.swift @@ -100,10 +100,6 @@ private class SnapshotVaultLockingMock: VaultLocking { reply(true) } - func getUnlockedVaultDomainIdentifiers(reply: @escaping ([NSFileProviderDomainIdentifier]) -> Void) { - fatalError() - } - var serviceName: NSFileProviderServiceName = .init("org.cryptomator.ios.vault-locking") func makeListenerEndpoint() throws -> NSXPCListenerEndpoint { diff --git a/Cryptomator/VaultList/VaultCellViewModel.swift b/Cryptomator/VaultList/VaultCellViewModel.swift index a97e41c98..1a0ccf816 100644 --- a/Cryptomator/VaultList/VaultCellViewModel.swift +++ b/Cryptomator/VaultList/VaultCellViewModel.swift @@ -16,7 +16,6 @@ protocol VaultCellViewModelProtocol: TableViewCellViewModel, ViewModel { var vault: VaultInfo { get } var lockButtonIsHidden: AnyPublisher { get } func lockVault() -> Promise - func setVaultUnlockStatus(unlocked: Bool) } class VaultCellViewModel: TableViewCellViewModel, VaultCellViewModelProtocol { @@ -46,7 +45,7 @@ class VaultCellViewModel: TableViewCellViewModel, VaultCellViewModelProtocol { return getXPCPromise.then { xpc in xpc.proxy.lockVault(domainIdentifier: domainIdentifier) }.then { - self.setVaultUnlockStatus(unlocked: false) + self.vault.vaultIsUnlocked.value = false }.catch { error in self.errorPublisher.send(error) }.always { @@ -54,10 +53,6 @@ class VaultCellViewModel: TableViewCellViewModel, VaultCellViewModelProtocol { } } - func setVaultUnlockStatus(unlocked: Bool) { - vault.vaultIsUnlocked.value = unlocked - } - override func hash(into hasher: inout Hasher) { hasher.combine(vault.vaultUID) } diff --git a/Cryptomator/VaultList/VaultListViewModel.swift b/Cryptomator/VaultList/VaultListViewModel.swift index facc4ed0a..0adb8722b 100644 --- a/Cryptomator/VaultList/VaultListViewModel.swift +++ b/Cryptomator/VaultList/VaultListViewModel.swift @@ -104,24 +104,23 @@ class VaultListViewModel: ViewModel, VaultListViewModelProtocol { } func refreshVaultLockStates() -> Promise { - let getXPCPromise: Promise> = fileProviderConnector.getXPC(serviceName: .vaultLocking, domain: nil) + let promises = vaultCellViewModels.map { vaultCellViewModel in + return checkVaultUnlockStatus(for: vaultCellViewModel.vault) + } + return all(ignoringResult: promises) + } + + private func checkVaultUnlockStatus(for vault: VaultInfo) -> Promise { + let domainIdentifier = NSFileProviderDomainIdentifier(vault.vaultUID) + let getXPCPromise: Promise> = fileProviderConnector.getXPC(serviceName: .vaultLocking, domainIdentifier: domainIdentifier) return getXPCPromise.then { xpc in - return wrap { handler in - xpc.proxy.getUnlockedVaultDomainIdentifiers(reply: handler) - } - }.then { unlockedVaultDomainIdentifiers -> Void in - for domainIdentifier in unlockedVaultDomainIdentifiers { - let vaultInfo = self.vaultCellViewModels.first { $0.vault.vaultUID == domainIdentifier.rawValue } - vaultInfo?.setVaultUnlockStatus(unlocked: true) - } - self.vaultCellViewModels.filter { vaultCellViewModel in - unlockedVaultDomainIdentifiers.allSatisfy { domainIdentifier in - vaultCellViewModel.vault.vaultUID != domainIdentifier.rawValue - } - }.forEach { vaultCellViewModel in - vaultCellViewModel.setVaultUnlockStatus(unlocked: false) - } + return xpc.proxy.getIsUnlockedVault(domainIdentifier: domainIdentifier) + }.then { isUnlocked -> Void in + DDLogDebug("Vault \(vault.vaultUID) unlock status: \(isUnlocked ? "Unlocked" : "Locked")") + vault.vaultIsUnlocked.value = isUnlocked + }.catch { error in + DDLogError("Failed to check unlock status for vault \(vault.vaultUID): \(error)") }.always { self.fileProviderConnector.invalidateXPC(getXPCPromise) } diff --git a/CryptomatorCommon/Sources/CryptomatorCommonCore/FileProviderXPC/VaultLocking.swift b/CryptomatorCommon/Sources/CryptomatorCommonCore/FileProviderXPC/VaultLocking.swift index efa769e1c..f5fe652bc 100644 --- a/CryptomatorCommon/Sources/CryptomatorCommonCore/FileProviderXPC/VaultLocking.swift +++ b/CryptomatorCommon/Sources/CryptomatorCommonCore/FileProviderXPC/VaultLocking.swift @@ -14,7 +14,6 @@ import Promises func lockVault(domainIdentifier: NSFileProviderDomainIdentifier) func gracefulLockVault(domainIdentifier: NSFileProviderDomainIdentifier, reply: @escaping (Error?) -> Void) func getIsUnlockedVault(domainIdentifier: NSFileProviderDomainIdentifier, reply: @escaping (Bool) -> Void) - func getUnlockedVaultDomainIdentifiers(reply: @escaping ([NSFileProviderDomainIdentifier]) -> Void) } public extension NSFileProviderServiceName { @@ -41,10 +40,4 @@ public extension VaultLocking { self.getIsUnlockedVault(domainIdentifier: domainIdentifier, reply: replyHandler) } } - - func getUnlockedVaultDomainIdentifiers() -> Promise<[NSFileProviderDomainIdentifier]> { - return wrap { replyHandler in - self.getUnlockedVaultDomainIdentifiers(reply: replyHandler) - } - } } diff --git a/CryptomatorFileProvider/Promise+AllIgnoringResult.swift b/CryptomatorCommon/Sources/CryptomatorCommonCore/Promise+AllIgnoringResult.swift similarity index 69% rename from CryptomatorFileProvider/Promise+AllIgnoringResult.swift rename to CryptomatorCommon/Sources/CryptomatorCommonCore/Promise+AllIgnoringResult.swift index 057ba025a..d16ca1db6 100644 --- a/CryptomatorFileProvider/Promise+AllIgnoringResult.swift +++ b/CryptomatorCommon/Sources/CryptomatorCommonCore/Promise+AllIgnoringResult.swift @@ -9,7 +9,7 @@ import Foundation import Promises -func all(ignoringResult promises: Container) -> Promise where Container.Element == Promise { +public func all(ignoringResult promises: Container) -> Promise where Container.Element == Promise { return any(promises).then { _ -> Void in // discard result }.recover { _ -> Void in diff --git a/CryptomatorFileProviderTests/Promise+AllIgnoringResultsTests.swift b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Promise+AllIgnoringResultsTests.swift similarity index 92% rename from CryptomatorFileProviderTests/Promise+AllIgnoringResultsTests.swift rename to CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Promise+AllIgnoringResultsTests.swift index df9833f9a..106e5b744 100644 --- a/CryptomatorFileProviderTests/Promise+AllIgnoringResultsTests.swift +++ b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Promise+AllIgnoringResultsTests.swift @@ -1,14 +1,14 @@ // // Promise+AllIgnoringResultsTests.swift -// CryptomatorFileProviderTests +// CryptomatorCommonCoreTests // // Created by Philipp Schmid on 31.03.22. // Copyright © 2022 Skymatic GmbH. All rights reserved. // +import CryptomatorCommonCore import Promises import XCTest -@testable import CryptomatorFileProvider class Promise_AllIgnoringResultsTests: XCTestCase { func testWaitForAll() throws { diff --git a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/XCTestCase+Promises.swift b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/XCTestCase+Promises.swift index 938c35b74..ef9ccdcd8 100644 --- a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/XCTestCase+Promises.swift +++ b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/XCTestCase+Promises.swift @@ -37,4 +37,13 @@ extension XCTestCase { } wait(for: [expectation], timeout: 1.0) } + + func XCTAssertGetsNotExecuted(_ promise: Promise, timeout seconds: TimeInterval = 1.0, file: StaticString = #filePath, line: UInt = #line) { + let expectation = XCTestExpectation() + expectation.isInverted = true + promise.always { + expectation.fulfill() + } + wait(for: [expectation], timeout: seconds) + } } diff --git a/CryptomatorFileProvider/FileProviderAdapterManager.swift b/CryptomatorFileProvider/FileProviderAdapterManager.swift index d53e08185..fcaaa2c5b 100644 --- a/CryptomatorFileProvider/FileProviderAdapterManager.swift +++ b/CryptomatorFileProvider/FileProviderAdapterManager.swift @@ -141,12 +141,6 @@ public class FileProviderAdapterManager: FileProviderAdapterProviding { return adapterCache.getItem(identifier: domainIdentifier) != nil } - public func getDomainIdentifiersOfUnlockedVaults() -> [NSFileProviderDomainIdentifier] { - let cachedIdentifiers = adapterCache.getAllCachedIdentifiers() - cachedIdentifiers.forEach { updateLockStatus(domainIdentifier: $0) } - return adapterCache.getAllCachedIdentifiers() - } - /** Locks a vault gracefully. @@ -250,7 +244,6 @@ protocol FileProviderAdapterCacheType { func cacheItem(_ item: AdapterCacheItem, identifier: NSFileProviderDomainIdentifier) func removeItem(identifier: NSFileProviderDomainIdentifier) func getItem(identifier: NSFileProviderDomainIdentifier) -> AdapterCacheItem? - func getAllCachedIdentifiers() -> [NSFileProviderDomainIdentifier] } class FileProviderAdapterCache: FileProviderAdapterCacheType { @@ -274,10 +267,4 @@ class FileProviderAdapterCache: FileProviderAdapterCacheType { return cachedAdapters[identifier] } } - - func getAllCachedIdentifiers() -> [NSFileProviderDomainIdentifier] { - queue.sync { - return cachedAdapters.map { $0.key } - } - } } diff --git a/CryptomatorFileProvider/ServiceSource/VaultLockingServiceSource.swift b/CryptomatorFileProvider/ServiceSource/VaultLockingServiceSource.swift index b6e5576f7..96f118126 100644 --- a/CryptomatorFileProvider/ServiceSource/VaultLockingServiceSource.swift +++ b/CryptomatorFileProvider/ServiceSource/VaultLockingServiceSource.swift @@ -35,8 +35,4 @@ public class VaultLockingServiceSource: ServiceSource, VaultLocking { public func getIsUnlockedVault(domainIdentifier: NSFileProviderDomainIdentifier, reply: @escaping (Bool) -> Void) { reply(FileProviderAdapterManager.shared.vaultIsUnlocked(domainIdentifier: domainIdentifier)) } - - public func getUnlockedVaultDomainIdentifiers(reply: @escaping ([NSFileProviderDomainIdentifier]) -> Void) { - reply(FileProviderAdapterManager.shared.getDomainIdentifiersOfUnlockedVaults()) - } } diff --git a/CryptomatorFileProvider/Workflow/WorkflowDependencyFactory.swift b/CryptomatorFileProvider/Workflow/WorkflowDependencyFactory.swift index c35c7f311..9aa0d2fb0 100644 --- a/CryptomatorFileProvider/Workflow/WorkflowDependencyFactory.swift +++ b/CryptomatorFileProvider/Workflow/WorkflowDependencyFactory.swift @@ -8,6 +8,7 @@ import CocoaLumberjackSwift import CryptomatorCloudAccessCore +import CryptomatorCommonCore import Foundation import Promises diff --git a/CryptomatorFileProviderTests/FileProviderAdapterManagerTests.swift b/CryptomatorFileProviderTests/FileProviderAdapterManagerTests.swift index 683b8e843..5838120cb 100644 --- a/CryptomatorFileProviderTests/FileProviderAdapterManagerTests.swift +++ b/CryptomatorFileProviderTests/FileProviderAdapterManagerTests.swift @@ -226,34 +226,4 @@ class FileProviderAdapterManagerTests: XCTestCase { XCTAssertEqual(1, maintenanceManagerMock.disableMaintenanceModeCallsCount) XCTAssert(cache.isEmpty) } - - func testGetDomainIdentifiersOfUnlockedVaults() throws { - let unlockedDomainIdentifier = NSFileProviderDomainIdentifier(rawValue: "1") - let lockedDomainIdentifier = NSFileProviderDomainIdentifier(rawValue: "2") - notificatorManagerMock.getFileProviderNotificatorForReturnValue = fileProviderNotificatorMock - let unlockedVaultMaintenanceManagerMock = MaintenanceManagerMock() - let lockedVaultMaintenanceManagerMock = MaintenanceManagerMock() - let unlockedVaultAdapterCacheItem = AdapterCacheItem(adapter: FileProviderAdapterTypeMock(), maintenanceManager: unlockedVaultMaintenanceManagerMock, workingSetObserver: workingSetObservationMock) - let lockedVaultAdapterCacheItem = AdapterCacheItem(adapter: FileProviderAdapterTypeMock(), maintenanceManager: lockedVaultMaintenanceManagerMock, workingSetObserver: workingSetObservationMock) - - var cache = [NSFileProviderDomainIdentifier: AdapterCacheItem]() - cache[unlockedDomainIdentifier] = unlockedVaultAdapterCacheItem - cache[lockedDomainIdentifier] = lockedVaultAdapterCacheItem - adapterCacheMock.getItemIdentifierClosure = { return cache[$0] } - adapterCacheMock.getAllCachedIdentifiersClosure = { cache.map { $0.key }} - adapterCacheMock.removeItemIdentifierClosure = { - cache[$0] = nil - } - vaultKeepUnlockedHelperMock.shouldAutoLockVaultWithVaultUIDClosure = { $0 != unlockedDomainIdentifier.rawValue } - - XCTAssertEqual([unlockedDomainIdentifier], fileProviderAdapterManager.getDomainIdentifiersOfUnlockedVaults()) - - XCTAssertFalse(unlockedVaultMaintenanceManagerMock.enableMaintenanceModeCalled) - XCTAssertFalse(unlockedVaultMaintenanceManagerMock.disableMaintenanceModeCalled) - XCTAssertEqual(1, lockedVaultMaintenanceManagerMock.enableMaintenanceModeCallsCount) - XCTAssertEqual(1, lockedVaultMaintenanceManagerMock.disableMaintenanceModeCallsCount) - - XCTAssertEqual(1, cache.count) - XCTAssertNotNil(cache[unlockedDomainIdentifier]) - } } diff --git a/CryptomatorFileProviderTests/Mocks/FileProviderAdapterCacheTypeMock.swift b/CryptomatorFileProviderTests/Mocks/FileProviderAdapterCacheTypeMock.swift index 0b597508d..94b1bcb6b 100644 --- a/CryptomatorFileProviderTests/Mocks/FileProviderAdapterCacheTypeMock.swift +++ b/CryptomatorFileProviderTests/Mocks/FileProviderAdapterCacheTypeMock.swift @@ -65,19 +65,4 @@ final class FileProviderAdapterCacheTypeMock: FileProviderAdapterCacheType { getItemIdentifierReceivedInvocations.append(identifier) return getItemIdentifierClosure.map({ $0(identifier) }) ?? getItemIdentifierReturnValue } - - // MARK: - getAllCachedIdentifiers - - var getAllCachedIdentifiersCallsCount = 0 - var getAllCachedIdentifiersCalled: Bool { - getAllCachedIdentifiersCallsCount > 0 - } - - var getAllCachedIdentifiersReturnValue: [NSFileProviderDomainIdentifier]! - var getAllCachedIdentifiersClosure: (() -> [NSFileProviderDomainIdentifier])? - - func getAllCachedIdentifiers() -> [NSFileProviderDomainIdentifier] { - getAllCachedIdentifiersCallsCount += 1 - return getAllCachedIdentifiersClosure.map({ $0() }) ?? getAllCachedIdentifiersReturnValue - } } diff --git a/CryptomatorTests/VaultListViewModelTests.swift b/CryptomatorTests/VaultListViewModelTests.swift index 897506aba..8b465988f 100644 --- a/CryptomatorTests/VaultListViewModelTests.swift +++ b/CryptomatorTests/VaultListViewModelTests.swift @@ -131,10 +131,9 @@ class VaultListViewModelTests: XCTestCase { vaultLockingMock.unlockedVaults.append(NSFileProviderDomainIdentifier("vault1")) vaultListViewModel.refreshVaultLockStates().then { - XCTAssertNil(self.fileProviderConnectorMock.passedDomain) + XCTAssertEqual(self.fileProviderConnectorMock.passedDomainIdentifier?.rawValue, "vault1") XCTAssertEqual(NSFileProviderServiceName("org.cryptomator.ios.vault-locking"), self.fileProviderConnectorMock.passedServiceName) - XCTAssertEqual(1, vaultLockingMock.unlockedVaults.count) let unlockedVaults = vaultListViewModel.getVaults().filter({ $0.vaultIsUnlocked.value }) XCTAssertEqual(1, unlockedVaults.count) XCTAssertTrue(unlockedVaults.contains(where: { $0.vaultUID == "vault1" })) @@ -144,7 +143,7 @@ class VaultListViewModelTests: XCTestCase { expectation.fulfill() } wait(for: [expectation], timeout: 1.0) - XCTAssertEqual(1, fileProviderConnectorMock.xpcInvalidationCallCount) + XCTAssertEqual(2, fileProviderConnectorMock.xpcInvalidationCallCount) } } @@ -245,10 +244,6 @@ class VaultLockingMock: VaultLocking { reply(unlockedVaults.contains(domainIdentifier)) } - func getUnlockedVaultDomainIdentifiers(reply: @escaping ([NSFileProviderDomainIdentifier]) -> Void) { - reply(unlockedVaults) - } - let serviceName = NSFileProviderServiceName("org.cryptomator.ios.vault-locking") func makeListenerEndpoint() throws -> NSXPCListenerEndpoint {