From 2cb3e947d022d0fd63fb8d421753975d4f4aaa8a Mon Sep 17 00:00:00 2001 From: Philipp Schmid <25935690+phil1995@users.noreply.github.com> Date: Sun, 1 Oct 2023 00:26:32 +0200 Subject: [PATCH 1/3] Improve injection of main database --- Cryptomator.xcodeproj/project.pbxproj | 7 ++ .../xcshareddata/swiftpm/Package.resolved | 18 ++++ Cryptomator/AppDelegate.swift | 16 +--- Cryptomator/Common/DatabaseManager.swift | 21 ++--- .../VaultDetailUnlockVaultViewModel.swift | 2 +- CryptomatorCommon/Package.swift | 6 +- .../CryptomatorDatabase.swift | 86 +++++++++++++++---- .../CloudProviderAccountDBManager.swift | 17 ++-- .../Manager/VaultAccountDBManager.swift | 19 ++-- .../Manager/VaultDBCache.swift | 15 ++-- .../Manager/VaultDBManager.swift | 2 +- .../S3/S3CredentialManager.swift | 13 +-- .../CloudProviderAccountManagerTests.swift | 18 +--- .../Manager/CloudProviderManagerTests.swift | 17 +--- .../Manager/S3CredentialManagerTests.swift | 7 +- .../Manager/VaultDBCacheTests.swift | 27 +++--- .../Manager/VaultManagerTests.swift | 25 +----- CryptomatorIntents/IntentHandler.swift | 8 -- .../AccountListViewModelTests.swift | 38 +++----- CryptomatorTests/DatabaseManagerTests.swift | 67 ++++++++------- .../VaultListViewModelTests.swift | 29 ++----- .../FileProviderExtension.swift | 30 +++---- .../RootViewController.swift | 15 ---- .../UnlockVaultViewModel.swift | 2 +- 24 files changed, 225 insertions(+), 280 deletions(-) diff --git a/Cryptomator.xcodeproj/project.pbxproj b/Cryptomator.xcodeproj/project.pbxproj index b45695d55..78ca95e2d 100644 --- a/Cryptomator.xcodeproj/project.pbxproj +++ b/Cryptomator.xcodeproj/project.pbxproj @@ -353,6 +353,7 @@ 4AF45359271F38FC00CF1919 /* RenameVaultViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AF45358271F38FC00CF1919 /* RenameVaultViewModelTests.swift */; }; 4AF4535D27205F6200CF1919 /* VaultDetailCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AF4535C27205F6200CF1919 /* VaultDetailCoordinator.swift */; }; 4AF4535F272066A600CF1919 /* RenameVaultViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AF4535E272066A600CF1919 /* RenameVaultViewController.swift */; }; + 4AF91A0F2AC2F025002357BA /* Dependencies in Frameworks */ = {isa = PBXBuildFile; productRef = 4AF91A0E2AC2F025002357BA /* Dependencies */; }; 4AF91CBE25A63FD600ACF01E /* VaultListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AF91CBD25A63FD600ACF01E /* VaultListViewModel.swift */; }; 4AF91CC725A6437000ACF01E /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4AF91CC625A6437000ACF01E /* Colors.xcassets */; }; 4AF91CD025A71C5800ACF01E /* UIImage+CloudProviderType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AF91CCF25A71C5800ACF01E /* UIImage+CloudProviderType.swift */; }; @@ -1095,6 +1096,7 @@ buildActionMask = 2147483647; files = ( 4A91728B2619F1D0003C4043 /* CryptomatorCommonCore in Frameworks */, + 4AF91A0F2AC2F025002357BA /* Dependencies in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2220,6 +2222,7 @@ name = CryptomatorFileProvider; packageProductDependencies = ( 4A91728A2619F1D0003C4043 /* CryptomatorCommonCore */, + 4AF91A0E2AC2F025002357BA /* Dependencies */, ); productName = CryptomatorFileProvider; productReference = 740375D72587AE7A0023FF53 /* libCryptomatorFileProvider.a */; @@ -3705,6 +3708,10 @@ package = 4AED9A6D286B38D900352951 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */; productName = Introspect; }; + 4AF91A0E2AC2F025002357BA /* Dependencies */ = { + isa = XCSwiftPackageProductDependency; + productName = Dependencies; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 4A5E5B212453119100BD6298 /* Project object */; diff --git a/Cryptomator.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Cryptomator.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 6620f8acf..aa74da510 100644 --- a/Cryptomator.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Cryptomator.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -163,6 +163,15 @@ "version": "2.0.0" } }, + { + "package": "Dependencies", + "repositoryURL": "https://github.com/PhilLibs/simple-swift-dependencies", + "state": { + "branch": null, + "revision": "36e2e7732b5fe2bfec76e4af78d2ef532fe09456", + "version": "0.1.0" + } + }, { "package": "swift-log", "repositoryURL": "https://github.com/apple/swift-log.git", @@ -189,6 +198,15 @@ "revision": "5b830d6ce6c34bb4bb976917576ab560e7945037", "version": "3.3.4" } + }, + { + "package": "xctest-dynamic-overlay", + "repositoryURL": "https://github.com/pointfreeco/xctest-dynamic-overlay", + "state": { + "branch": null, + "revision": "23cbf2294e350076ea4dbd7d5d047c1e76b03631", + "version": "1.0.2" + } } ] }, diff --git a/Cryptomator/AppDelegate.swift b/Cryptomator/AppDelegate.swift index 8635e1f1a..7c99f3dd0 100644 --- a/Cryptomator/AppDelegate.swift +++ b/Cryptomator/AppDelegate.swift @@ -29,22 +29,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { setupIAP() // Set up database - guard let dbURL = CryptomatorDatabase.sharedDBURL else { - // MARK: Handle error + DatabaseManager.shared = DatabaseManager() - DDLogError("dbURL is nil") - return false - } - do { - let dbPool = try CryptomatorDatabase.openSharedDatabase(at: dbURL) - CryptomatorDatabase.shared = try CryptomatorDatabase(dbPool) - DatabaseManager.shared = try DatabaseManager(dbPool: dbPool) - } catch { - // MARK: Handle error - - DDLogError("Initializing CryptomatorDatabase failed with error: \(error)") - return false - } VaultDBManager.shared.recoverMissingFileProviderDomains().catch { error in DDLogError("Recover missing FileProvider domains failed with error: \(error)") } diff --git a/Cryptomator/Common/DatabaseManager.swift b/Cryptomator/Common/DatabaseManager.swift index ae54ed371..1b0d9419b 100644 --- a/Cryptomator/Common/DatabaseManager.swift +++ b/Cryptomator/Common/DatabaseManager.swift @@ -8,20 +8,17 @@ import Combine import CryptomatorCommonCore +import Dependencies import Foundation import GRDB class DatabaseManager { public static var shared: DatabaseManager! - let dbPool: DatabasePool - - init(dbPool: DatabasePool) throws { - self.dbPool = dbPool - } + @Dependency(\.database) private var database func getAllVaults() throws -> [VaultInfo] { - try dbPool.read { db in + try database.read { db in let request = VaultAccount.including(required: VaultAccount.delegateAccount).including(required: VaultAccount.vaultListPosition) return try VaultInfo.fetchAll(db, request) } @@ -35,7 +32,7 @@ class DatabaseManager { for i in tempPositions.indices { tempPositions[i].position = nil } - try dbPool.write { db in + try database.write { db in try db.execute(sql: "PRAGMA ignore_check_constraints=YES") for position in tempPositions { try position.update(db) @@ -51,18 +48,18 @@ class DatabaseManager { let observation = ValueObservation .tracking { try VaultAccount.fetchAll($0) } .removeDuplicates() - return observation.start(in: dbPool, scheduling: .immediate, onError: onError, onChange: onChange) + return observation.start(in: database, scheduling: .immediate, onError: onError, onChange: onChange) } func observeVaultAccount(withVaultUID vaultUID: String, onError: @escaping (Error) -> Void, onChange: @escaping (VaultAccount?) -> Void) -> DatabaseCancellable { let observation = ValueObservation.tracking { db in try VaultAccount.fetchOne(db, key: vaultUID) } - return observation.start(in: dbPool, scheduling: .immediate, onError: onError, onChange: onChange) + return observation.start(in: database, scheduling: .immediate, onError: onError, onChange: onChange) } func getAllAccounts(for cloudProviderType: CloudProviderType) throws -> [AccountInfo] { - try dbPool.read { db in + try database.read { db in let accountWithCloudProviderType = AccountListPosition.account.filter(Column("cloudProviderType") == cloudProviderType) let request = AccountListPosition.including(required: accountWithCloudProviderType).order(Column("position")) return try AccountInfo.fetchAll(db, request) @@ -77,7 +74,7 @@ class DatabaseManager { for i in tempPositions.indices { tempPositions[i].position = nil } - try dbPool.write { db in + try database.write { db in try db.execute(sql: "PRAGMA ignore_check_constraints=YES") for position in tempPositions { try position.update(db) @@ -102,7 +99,7 @@ class DatabaseManager { .removeDuplicates() .map { rows in rows.map(AccountWithDisplayName.init(row:)) } .map { annotatedAccounts in annotatedAccounts.map(\.account) } - return observation.start(in: dbPool, scheduling: .immediate, onError: onError, onChange: onChange) + return observation.start(in: database, scheduling: .immediate, onError: onError, onChange: onChange) } } diff --git a/Cryptomator/VaultDetail/VaultDetailUnlockVaultViewModel.swift b/Cryptomator/VaultDetail/VaultDetailUnlockVaultViewModel.swift index faf7451da..83b7d24ae 100644 --- a/Cryptomator/VaultDetail/VaultDetailUnlockVaultViewModel.swift +++ b/Cryptomator/VaultDetail/VaultDetailUnlockVaultViewModel.swift @@ -47,7 +47,7 @@ class VaultDetailUnlockVaultViewModel: SingleSectionTableViewModel, ReturnButton } func unlockVault() throws { - let cachedVault = try VaultDBCache(dbWriter: CryptomatorDatabase.shared.dbPool).getCachedVault(withVaultUID: vault.vaultUID) + let cachedVault = try VaultDBCache().getCachedVault(withVaultUID: vault.vaultUID) let masterkeyFile = try MasterkeyFile.withContentFromData(data: cachedVault.masterkeyFileData) _ = try masterkeyFile.unlock(passphrase: password) try passwordManager.setPassword(password, forVaultUID: vault.vaultUID) diff --git a/CryptomatorCommon/Package.swift b/CryptomatorCommon/Package.swift index 5617494f4..6c5184aee 100644 --- a/CryptomatorCommon/Package.swift +++ b/CryptomatorCommon/Package.swift @@ -27,7 +27,8 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/cryptomator/cloud-access-swift.git", .upToNextMinor(from: "1.7.0")), - .package(url: "https://github.com/CocoaLumberjack/CocoaLumberjack.git", .upToNextMinor(from: "3.8.0")) + .package(url: "https://github.com/CocoaLumberjack/CocoaLumberjack.git", .upToNextMinor(from: "3.8.0")), + .package(url: "https://github.com/PhilLibs/simple-swift-dependencies", .upToNextMajor(from: "0.1.0")) ], targets: [ .target( @@ -41,7 +42,8 @@ let package = Package( name: "CryptomatorCommonCore", dependencies: [ "CocoaLumberjackSwift", - "CryptomatorCloudAccessCore" + "CryptomatorCloudAccessCore", + .product(name: "Dependencies", package: "simple-swift-dependencies") ] ), .testTarget( diff --git a/CryptomatorCommon/Sources/CryptomatorCommonCore/CryptomatorDatabase.swift b/CryptomatorCommon/Sources/CryptomatorCommonCore/CryptomatorDatabase.swift index ae543ed4d..b6c690fd5 100644 --- a/CryptomatorCommon/Sources/CryptomatorCommonCore/CryptomatorDatabase.swift +++ b/CryptomatorCommon/Sources/CryptomatorCommonCore/CryptomatorDatabase.swift @@ -6,31 +6,74 @@ // Copyright © 2020 Skymatic GmbH. All rights reserved. // +import CocoaLumberjackSwift +import Dependencies import Foundation import GRDB +private enum CryptomatorDatabaseKey: DependencyKey { + static let liveValue: DatabaseWriter = CryptomatorDatabase.live + + static var testValue: DatabaseWriter { + let inMemoryDB = DatabaseQueue(configuration: .defaultCryptomatorConfiguration) + do { + try CryptomatorDatabase.migrator.migrate(inMemoryDB) + } catch { + DDLogError("Failed to migrate in-memory database: \(error)") + } + return inMemoryDB + } +} + +public extension DependencyValues { + var database: DatabaseWriter { + get { self[CryptomatorDatabaseKey.self] } + set { self[CryptomatorDatabaseKey.self] = newValue } + } +} + +private enum CryptomatorDatabaseLocationKey: DependencyKey { + static var liveValue: URL? { CryptomatorDatabase.sharedDBURL } + static var testValue: URL? { FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: false) } +} + +public extension DependencyValues { + var databaseLocation: URL? { + get { self[CryptomatorDatabaseLocationKey.self] } + set { self[CryptomatorDatabaseLocationKey.self] = newValue } + } +} + public enum CryptomatorDatabaseError: Error { case dbDoesNotExist case incompleteMigration } public class CryptomatorDatabase { - public static var shared: CryptomatorDatabase! + static var live: DatabaseWriter { + @Dependency(\.databaseLocation) var databaseURL - public static var sharedDBURL: URL? { - let sharedContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: CryptomatorConstants.appGroupName) - return sharedContainer?.appendingPathComponent("db.sqlite") + guard let dbURL = databaseURL else { + fatalError("Could not get URL for shared database") + } + let database: DatabaseWriter + do { + database = try CryptomatorDatabase.openSharedDatabase(at: dbURL) + } catch { + DDLogError("Failed to open shared database: \(error)") + fatalError("Could not open shared database") + } + do { + try CryptomatorDatabase.migrator.migrate(database) + } catch { + DDLogError("Failed to migrate database: \(error)") + } + return database } - public let dbPool: DatabasePool - private static var oldSharedDBURL: URL? { + static var sharedDBURL: URL? { let sharedContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: CryptomatorConstants.appGroupName) - return sharedContainer?.appendingPathComponent("main.sqlite") - } - - public init(_ dbPool: DatabasePool) throws { - self.dbPool = dbPool - try CryptomatorDatabase.migrator.migrate(dbPool) + return sharedContainer?.appendingPathComponent("db.sqlite") } static var migrator: DatabaseMigrator { @@ -48,7 +91,7 @@ public class CryptomatorDatabase { } // swiftlint:disable:next function_body_length - public class func v1Migration(_ db: Database) throws { + class func v1Migration(_ db: Database) throws { // Common try db.create(table: "cloudProviderAccounts") { table in table.column("accountUID", .text).primaryKey() @@ -157,12 +200,10 @@ public class CryptomatorDatabase { var coordinatorError: NSError? var dbPool: DatabasePool? var dbError: Error? - var configuration = Configuration() - // Workaround for a SQLite regression (see https://github.com/groue/GRDB.swift/issues/1171 for more details) - configuration.acceptsDoubleQuotedStringLiterals = true + coordinator.coordinate(writingItemAt: databaseURL, options: .forMerging, error: &coordinatorError, byAccessor: { _ in do { - dbPool = try DatabasePool(path: databaseURL.path, configuration: configuration) + dbPool = try DatabasePool(path: databaseURL.path, configuration: .defaultCryptomatorConfiguration) } catch { dbError = error } @@ -193,7 +234,7 @@ public class CryptomatorDatabase { private static func openReadOnlyDatabase(at databaseURL: URL) throws -> DatabasePool { do { - var configuration = Configuration() + var configuration = Configuration.defaultCryptomatorConfiguration configuration.readonly = true let dbPool = try DatabasePool(path: databaseURL.path, configuration: configuration) @@ -211,3 +252,12 @@ public class CryptomatorDatabase { } } } + +extension Configuration { + static var defaultCryptomatorConfiguration: Configuration { + var configuration = Configuration() + // Workaround for a SQLite regression (see https://github.com/groue/GRDB.swift/issues/1171 for more details) + configuration.acceptsDoubleQuotedStringLiterals = true + return configuration + } +} diff --git a/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/CloudProviderAccountDBManager.swift b/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/CloudProviderAccountDBManager.swift index 2e460699a..5fe7ded1f 100644 --- a/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/CloudProviderAccountDBManager.swift +++ b/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/CloudProviderAccountDBManager.swift @@ -6,6 +6,7 @@ // Copyright © 2020 Skymatic GmbH. All rights reserved. // +import Dependencies import Foundation import GRDB @@ -41,15 +42,11 @@ public protocol CloudProviderAccountManager { } public class CloudProviderAccountDBManager: CloudProviderAccountManager { - public static let shared = CloudProviderAccountDBManager(dbPool: CryptomatorDatabase.shared.dbPool) - private let dbPool: DatabasePool - - init(dbPool: DatabasePool) { - self.dbPool = dbPool - } + @Dependency(\.database) var database + public static let shared = CloudProviderAccountDBManager() public func getCloudProviderType(for accountUID: String) throws -> CloudProviderType { - let cloudAccount = try dbPool.read { db in + let cloudAccount = try database.read { db in return try CloudProviderAccount.fetchOne(db, key: accountUID) } guard let providerType = cloudAccount?.cloudProviderType else { @@ -59,7 +56,7 @@ public class CloudProviderAccountDBManager: CloudProviderAccountManager { } public func getAllAccountUIDs(for type: CloudProviderType) throws -> [String] { - let accounts: [CloudProviderAccount] = try dbPool.read { db in + let accounts: [CloudProviderAccount] = try database.read { db in return try CloudProviderAccount .filter(Column("cloudProviderType") == type) .fetchAll(db) @@ -68,13 +65,13 @@ public class CloudProviderAccountDBManager: CloudProviderAccountManager { } public func saveNewAccount(_ account: CloudProviderAccount) throws { - try dbPool.write { db in + try database.write { db in try account.save(db) } } public func removeAccount(with accountUID: String) throws { - try dbPool.write { db in + try database.write { db in guard try CloudProviderAccount.deleteOne(db, key: accountUID) else { throw CloudProviderAccountError.accountNotFoundError } diff --git a/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultAccountDBManager.swift b/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultAccountDBManager.swift index 018d49060..3069ca55b 100644 --- a/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultAccountDBManager.swift +++ b/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultAccountDBManager.swift @@ -7,6 +7,7 @@ // import CryptomatorCloudAccessCore +import Dependencies import Foundation import GRDB @@ -55,16 +56,12 @@ public enum VaultAccountManagerError: Error { } public class VaultAccountDBManager: VaultAccountManager { - public static let shared = VaultAccountDBManager(dbPool: CryptomatorDatabase.shared.dbPool) - private let dbPool: DatabasePool - - public init(dbPool: DatabasePool) { - self.dbPool = dbPool - } + public static let shared = VaultAccountDBManager() + @Dependency(\.database) private var database public func saveNewAccount(_ account: VaultAccount) throws { do { - try dbPool.write { db in + try database.write { db in try account.save(db) } } catch let error as DatabaseError where error.resultCode == .SQLITE_CONSTRAINT { @@ -73,7 +70,7 @@ public class VaultAccountDBManager: VaultAccountManager { } public func removeAccount(with vaultUID: String) throws { - try dbPool.write { db in + try database.write { db in guard try VaultAccount.deleteOne(db, key: vaultUID) else { throw CloudProviderAccountError.accountNotFoundError } @@ -81,7 +78,7 @@ public class VaultAccountDBManager: VaultAccountManager { } public func getAccount(with vaultUID: String) throws -> VaultAccount { - let fetchedAccount = try dbPool.read { db in + let fetchedAccount = try database.read { db in return try VaultAccount.fetchOne(db, key: vaultUID) } guard let account = fetchedAccount else { @@ -91,13 +88,13 @@ public class VaultAccountDBManager: VaultAccountManager { } public func getAllAccounts() throws -> [VaultAccount] { - try dbPool.read { db in + try database.read { db in try VaultAccount.fetchAll(db) } } public func updateAccount(_ account: VaultAccount) throws { - try dbPool.write { db in + try database.write { db in try account.update(db) } } diff --git a/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultDBCache.swift b/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultDBCache.swift index 52db65392..b97878335 100644 --- a/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultDBCache.swift +++ b/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultDBCache.swift @@ -8,6 +8,7 @@ import CryptomatorCloudAccessCore import CryptomatorCryptoLib +import Dependencies import Foundation import GRDB import Promises @@ -49,20 +50,18 @@ public enum VaultCacheError: Error { } public class VaultDBCache: VaultCache { - private let dbWriter: DatabaseWriter + @Dependency(\.database) var database - public init(dbWriter: DatabaseWriter) { - self.dbWriter = dbWriter - } + public init() {} public func cache(_ entry: CachedVault) throws { - try dbWriter.write({ db in + try database.write({ db in try entry.save(db) }) } public func getCachedVault(withVaultUID vaultUID: String) throws -> CachedVault { - try dbWriter.read({ db in + try database.read({ db in guard let cachedVault = try CachedVault.fetchOne(db, key: vaultUID) else { throw VaultCacheError.vaultNotFound } @@ -83,7 +82,7 @@ public class VaultDBCache: VaultCache { } public func setMasterkeyFileData(_ data: Data, forVaultUID vaultUID: String, lastModifiedDate: Date?) throws { - _ = try dbWriter.write { db in + _ = try database.write { db in try CachedVault.filter(CachedVault.Columns.vaultUID == vaultUID).updateAll(db, CachedVault.Columns.masterkeyFileData.set(to: data), CachedVault.Columns.masterkeyFileLastModifiedDate.set(to: lastModifiedDate)) @@ -153,7 +152,7 @@ public class VaultDBCache: VaultCache { } private func setVaultConfigData(_ data: Data?, forVaultUID vaultUID: String, lastModifiedDate: Date?) throws { - _ = try dbWriter.write { db in + _ = try database.write { db in try CachedVault.filter(CachedVault.Columns.vaultUID == vaultUID).updateAll(db, CachedVault.Columns.vaultConfigToken.set(to: data), CachedVault.Columns.vaultConfigLastModifiedDate.set(to: lastModifiedDate)) diff --git a/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultDBManager.swift b/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultDBManager.swift index 3c00887dd..81505f07c 100644 --- a/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultDBManager.swift +++ b/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultDBManager.swift @@ -36,7 +36,7 @@ public protocol VaultManager { public class VaultDBManager: VaultManager { public static let shared = VaultDBManager(providerManager: CloudProviderDBManager.shared, vaultAccountManager: VaultAccountDBManager.shared, - vaultCache: VaultDBCache(dbWriter: CryptomatorDatabase.shared.dbPool), + vaultCache: VaultDBCache(), passwordManager: VaultPasswordKeychainManager(), masterkeyCacheManager: MasterkeyCacheKeychainManager.shared, masterkeyCacheHelper: VaultKeepUnlockedManager.shared) diff --git a/CryptomatorCommon/Sources/CryptomatorCommonCore/S3/S3CredentialManager.swift b/CryptomatorCommon/Sources/CryptomatorCommonCore/S3/S3CredentialManager.swift index e645ad8dd..5e431b141 100644 --- a/CryptomatorCommon/Sources/CryptomatorCommonCore/S3/S3CredentialManager.swift +++ b/CryptomatorCommon/Sources/CryptomatorCommonCore/S3/S3CredentialManager.swift @@ -6,6 +6,7 @@ // import CryptomatorCloudAccessCore +import Dependencies import Foundation import GRDB @@ -41,13 +42,13 @@ public extension CloudProviderAccount { } public struct S3CredentialManager: S3CredentialManagerType { - public static let shared = S3CredentialManager(dbWriter: CryptomatorDatabase.shared.dbPool, keychain: CryptomatorKeychain.s3) - let dbWriter: DatabaseWriter + @Dependency(\.database) var database + public static let shared = S3CredentialManager(keychain: CryptomatorKeychain.s3) let keychain: CryptomatorKeychainType public func save(credential: S3Credential, displayName: String) throws { do { - try dbWriter.write { db in + try database.write { db in let entry = S3DisplayName(id: credential.identifier, displayName: displayName) try entry.save(db) try keychain.saveS3Credential(credential) @@ -56,14 +57,14 @@ public struct S3CredentialManager: S3CredentialManagerType { } public func removeCredential(with identifier: String) throws { - try dbWriter.write { db in + try database.write { db in try S3DisplayName.deleteOne(db, key: ["id": identifier]) try keychain.delete(identifier) } } public func getDisplayName(for identifier: String) throws -> String? { - try dbWriter.read { db in + try database.read { db in let entry = try S3DisplayName.fetchOne(db, key: ["id": identifier]) return entry?.displayName } @@ -84,5 +85,5 @@ extension S3CredentialManager { return inMemoryDB } - public static let demo = S3CredentialManager(dbWriter: inMemoryDB, keychain: CryptomatorKeychain(service: "s3CredentialDemo")) + public static let demo = S3CredentialManager(keychain: CryptomatorKeychain(service: "s3CredentialDemo")) } diff --git a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/CloudProviderAccountManagerTests.swift b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/CloudProviderAccountManagerTests.swift index c25acb343..ce7b48842 100644 --- a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/CloudProviderAccountManagerTests.swift +++ b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/CloudProviderAccountManagerTests.swift @@ -10,27 +10,13 @@ import Foundation import GRDB import XCTest @testable import CryptomatorCommonCore +@testable import Dependencies class CloudProviderAccountManagerTests: XCTestCase { var accountManager: CloudProviderAccountDBManager! - var tmpDir: URL! override func setUpWithError() throws { - tmpDir = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) - try FileManager.default.createDirectory(at: tmpDir, withIntermediateDirectories: true, attributes: nil) - let dbPool = try DatabasePool(path: tmpDir.appendingPathComponent("db.sqlite").path) - try dbPool.write { db in - try db.create(table: CloudProviderAccount.databaseTableName) { table in - table.column(CloudProviderAccount.accountUIDKey, .text).primaryKey() - table.column(CloudProviderAccount.cloudProviderTypeKey, .text).notNull() - } - } - accountManager = CloudProviderAccountDBManager(dbPool: dbPool) - } - - override func tearDownWithError() throws { - accountManager = nil - try FileManager.default.removeItem(at: tmpDir) + accountManager = CloudProviderAccountDBManager() } func testSaveAccount() throws { diff --git a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/CloudProviderManagerTests.swift b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/CloudProviderManagerTests.swift index 782e06ba9..be08fd73c 100644 --- a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/CloudProviderManagerTests.swift +++ b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/CloudProviderManagerTests.swift @@ -15,25 +15,12 @@ import XCTest class CloudProviderManagerTests: XCTestCase { var manager: CloudProviderDBManager! var accountManager: CloudProviderAccountDBManager! - var tmpDir: URL! + override func setUpWithError() throws { - tmpDir = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) - try FileManager.default.createDirectory(at: tmpDir, withIntermediateDirectories: true, attributes: nil) - let dbPool = try DatabasePool(path: tmpDir.appendingPathComponent("db.sqlite").path) - try dbPool.write { db in - try db.create(table: CloudProviderAccount.databaseTableName) { table in - table.column(CloudProviderAccount.accountUIDKey, .text).primaryKey() - table.column(CloudProviderAccount.cloudProviderTypeKey, .text).notNull() - } - } - accountManager = CloudProviderAccountDBManager(dbPool: dbPool) + accountManager = CloudProviderAccountDBManager() manager = CloudProviderDBManager(accountManager: accountManager) } - override func tearDownWithError() throws { - try FileManager.default.removeItem(at: tmpDir) - } - func testCreateProviderCachesTheProvider() throws { DropboxSetup.constants = DropboxSetup(appKey: "", sharedContainerIdentifier: nil, keychainService: nil, forceForegroundSession: false) let account = CloudProviderAccount(accountUID: UUID().uuidString, cloudProviderType: .dropbox) diff --git a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/S3CredentialManagerTests.swift b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/S3CredentialManagerTests.swift index 1cc629adf..8012a5806 100644 --- a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/S3CredentialManagerTests.swift +++ b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/S3CredentialManagerTests.swift @@ -16,13 +16,8 @@ class S3CredentialManagerTests: XCTestCase { let displayName = "Cryptomator S3" override func setUpWithError() throws { - var configuration = Configuration() - // Workaround for a SQLite regression (see https://github.com/groue/GRDB.swift/issues/1171 for more details) - configuration.acceptsDoubleQuotedStringLiterals = true - let inMemoryDB = DatabaseQueue(configuration: configuration) - try CryptomatorDatabase.migrator.migrate(inMemoryDB) cryptomatorKeychainMock = CryptomatorKeychainMock() - manager = S3CredentialManager(dbWriter: inMemoryDB, keychain: cryptomatorKeychainMock) + manager = S3CredentialManager(keychain: cryptomatorKeychainMock) } func testSaveCredential() throws { diff --git a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/VaultDBCacheTests.swift b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/VaultDBCacheTests.swift index 78f2de195..5a47c5185 100644 --- a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/VaultDBCacheTests.swift +++ b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/VaultDBCacheTests.swift @@ -6,6 +6,7 @@ // Copyright © 2020 Skymatic GmbH. All rights reserved. // +import Dependencies import Foundation import GRDB import Promises @@ -21,7 +22,6 @@ class VaultDBCacheTests: XCTestCase { private let vaultPath = CloudPath("/Vault") private lazy var vaultAccount: VaultAccount = .init(vaultUID: vaultUID, delegateAccountUID: account.accountUID, vaultPath: vaultPath, vaultName: "Vault") private let cloudProviderMock = CloudProviderMock() - private var inMemoryDB: DatabaseQueue! private var masterkeyFileData: Data! private var updatedMasterkeyFileData: Data! private let masterkey = Masterkey.createFromRaw(aesMasterKey: [UInt8](repeating: 0x55, count: 32), macMasterKey: [UInt8](repeating: 0x77, count: 32)) @@ -40,16 +40,9 @@ class VaultDBCacheTests: XCTestCase { vaultConfigData = try vaultConfig.toToken(keyId: "masterkeyfile:masterkey.cryptomator", rawKey: masterkey.rawKey) updatedVaultConfigData = try vaultConfig.toToken(keyId: "masterkeyfile:masterkey.cryptomator", rawKey: updatedMasterkey.rawKey) defaultCachedVault = CachedVault(vaultUID: vaultUID, masterkeyFileData: masterkeyFileData, vaultConfigToken: vaultConfigData, lastUpToDateCheck: Date(timeIntervalSince1970: 0), masterkeyFileLastModifiedDate: Date(timeIntervalSince1970: 0), vaultConfigLastModifiedDate: Date(timeIntervalSince1970: 0)) - var configuration = Configuration() - // Workaround for a SQLite regression (see https://github.com/groue/GRDB.swift/issues/1171 for more details) - configuration.acceptsDoubleQuotedStringLiterals = true - inMemoryDB = DatabaseQueue(configuration: configuration) - vaultCache = VaultDBCache(dbWriter: inMemoryDB) - try CryptomatorDatabase.migrator.migrate(inMemoryDB) - try inMemoryDB.write { db in - try account.save(db) - try vaultAccount.save(db) - } + + vaultCache = VaultDBCache() + try prepareDatabase() } func testCacheVault() throws { @@ -74,9 +67,11 @@ class VaultDBCacheTests: XCTestCase { } func testCascadeOnVaultAccountDeletion() throws { + @Dependency(\.database) var database + try vaultCache.cache(defaultCachedVault) - _ = try inMemoryDB.write { db in + _ = try database.write { db in try vaultAccount.delete(db) } XCTAssertThrowsError(try vaultCache.getCachedVault(withVaultUID: vaultUID)) { error in @@ -304,4 +299,12 @@ class VaultDBCacheTests: XCTestCase { private func assertDownloadedOnlyMasterkey() { XCTAssertEqual([CloudPath("/Vault/masterkey.cryptomator")], cloudProviderMock.downloadFileFromToReceivedInvocations.map { $0.cloudPath }) } + + private func prepareDatabase() throws { + @Dependency(\.database) var database + try database.write { db in + try account.save(db) + try vaultAccount.save(db) + } + } } diff --git a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/VaultManagerTests.swift b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/VaultManagerTests.swift index bd12cf3cc..2a75305a2 100644 --- a/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/VaultManagerTests.swift +++ b/CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/VaultManagerTests.swift @@ -61,8 +61,6 @@ class VaultManagerTests: XCTestCase { var masterkeyCacheManagerMock: MasterkeyCacheManagerMock! var masterkeyCacheHelperMock: MasterkeyCacheHelperMock! var cloudProviderMock: CloudProviderMock! - var tmpDir: URL! - var dbPool: DatabasePool! let vaultUID = "VaultUID-12345" let passphrase = "PW" let delegateAccountUID = UUID().uuidString @@ -74,17 +72,10 @@ class VaultManagerTests: XCTestCase { override func setUpWithError() throws { cloudProviderMock = CloudProviderMock() - tmpDir = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) - try FileManager.default.createDirectory(at: tmpDir, withIntermediateDirectories: true, attributes: nil) - var configuration = Configuration() - // Workaround for a SQLite regression (see https://github.com/groue/GRDB.swift/issues/1171 for more details) - configuration.acceptsDoubleQuotedStringLiterals = true - dbPool = try DatabasePool(path: tmpDir.appendingPathComponent("db.sqlite").path, configuration: configuration) - try CryptomatorDatabase.migrator.migrate(dbPool) - - providerAccountManager = CloudProviderAccountDBManager(dbPool: dbPool) + + providerAccountManager = CloudProviderAccountDBManager() providerManager = CloudProviderManagerMock(provider: cloudProviderMock, accountManager: providerAccountManager) - accountManager = VaultAccountDBManager(dbPool: dbPool) + accountManager = VaultAccountDBManager() vaultCacheMock = VaultCacheMock() vaultCacheMock.refreshVaultCacheForWithReturnValue = Promise(()) passwordManagerMock = VaultPasswordManagerMock() @@ -94,16 +85,6 @@ class VaultManagerTests: XCTestCase { manager = VaultManagerMock(providerManager: providerManager, vaultAccountManager: accountManager, vaultCache: vaultCacheMock, passwordManager: passwordManagerMock, masterkeyCacheManager: masterkeyCacheManagerMock, masterkeyCacheHelper: masterkeyCacheHelperMock) } - override func tearDownWithError() throws { - // Set all objects related to the sqlite database to nil to avoid warnings about database integrity when deleting the test database. - manager = nil - providerAccountManager = nil - providerManager = nil - accountManager = nil - dbPool = nil - try FileManager.default.removeItem(at: tmpDir) - } - func testCreateNewVault() throws { let expectation = XCTestExpectation() let delegateAccountUID = UUID().uuidString diff --git a/CryptomatorIntents/IntentHandler.swift b/CryptomatorIntents/IntentHandler.swift index 8f3ed8101..9f4202b02 100644 --- a/CryptomatorIntents/IntentHandler.swift +++ b/CryptomatorIntents/IntentHandler.swift @@ -34,13 +34,5 @@ class IntentHandler: INExtension { private static var oneTimeSetup: () -> Void = { // Set up logger LoggerSetup.oneTimeSetup() - if let dbURL = CryptomatorDatabase.sharedDBURL { - do { - let dbPool = try CryptomatorDatabase.openSharedDatabase(at: dbURL) - CryptomatorDatabase.shared = try CryptomatorDatabase(dbPool) - } catch { - DDLogError("Open shared database at \(dbURL) failed with error: \(error)") - } - } } } diff --git a/CryptomatorTests/AccountListViewModelTests.swift b/CryptomatorTests/AccountListViewModelTests.swift index ec447d042..c3e3ddf7c 100644 --- a/CryptomatorTests/AccountListViewModelTests.swift +++ b/CryptomatorTests/AccountListViewModelTests.swift @@ -13,27 +13,9 @@ import XCTest @testable import CryptomatorCommonCore class AccountListViewModelTests: XCTestCase { - var tmpDir: URL! - var dbPool: DatabasePool! - var cryptomatorDB: CryptomatorDatabase! - override func setUpWithError() throws { - tmpDir = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) - try FileManager.default.createDirectory(at: tmpDir, withIntermediateDirectories: true, attributes: nil) - let dbURL = tmpDir.appendingPathComponent("db.sqlite") - dbPool = try CryptomatorDatabase.openSharedDatabase(at: dbURL) - cryptomatorDB = try CryptomatorDatabase(dbPool) - _ = try DatabaseManager(dbPool: dbPool) - } - - override func tearDownWithError() throws { - dbPool = nil - cryptomatorDB = nil - try FileManager.default.removeItem(at: tmpDir) - } - func testMoveRow() throws { - let dbManagerMock = try DatabaseManagerMock(dbPool: dbPool) - let accountManager = CloudProviderAccountDBManager(dbPool: dbPool) + let dbManagerMock = try DatabaseManagerMock() + let accountManager = CloudProviderAccountDBManager() let cloudAuthenticatorMock = CloudAuthenticatorMock(accountManager: accountManager) let accountListViewModel = AccountListViewModelMock(with: .dropbox, dbManager: dbManagerMock, cloudAuthenticator: cloudAuthenticatorMock) try accountListViewModel.refreshItems() @@ -57,8 +39,8 @@ class AccountListViewModelTests: XCTestCase { } func testRemoveRow() throws { - let dbManagerMock = try DatabaseManagerMock(dbPool: dbPool) - let accountManager = CloudProviderAccountDBManager(dbPool: dbPool) + let dbManagerMock = DatabaseManagerMock() + let accountManager = CloudProviderAccountDBManager() let cloudAuthenticatorMock = CloudAuthenticatorMock(accountManager: accountManager) let accountListViewModel = AccountListViewModelMock(with: .dropbox, dbManager: dbManagerMock, cloudAuthenticator: cloudAuthenticatorMock) try accountListViewModel.refreshItems() @@ -78,8 +60,8 @@ class AccountListViewModelTests: XCTestCase { } func testWebDAVAccountCellContent() throws { - let dbManagerMock = try DatabaseManagerMock(dbPool: dbPool) - let accountManager = CloudProviderAccountDBManager(dbPool: dbPool) + let dbManagerMock = DatabaseManagerMock() + let accountManager = CloudProviderAccountDBManager() let cloudAuthenticatorMock = CloudAuthenticatorMock(accountManager: accountManager) let accountListViewModel = AccountListViewModel(with: .dropbox, dbManager: dbManagerMock, cloudAuthenticator: cloudAuthenticatorMock) let baseURL = URL(string: "https://www.example.com")! @@ -90,8 +72,8 @@ class AccountListViewModelTests: XCTestCase { } func testWebDAVAccountCellContentWithPathInDetailLabel() throws { - let dbManagerMock = try DatabaseManagerMock(dbPool: dbPool) - let accountManager = CloudProviderAccountDBManager(dbPool: dbPool) + let dbManagerMock = DatabaseManagerMock() + let accountManager = CloudProviderAccountDBManager() let cloudAuthenticatorMock = CloudAuthenticatorMock(accountManager: accountManager) let accountListViewModel = AccountListViewModel(with: .dropbox, dbManager: dbManagerMock, cloudAuthenticator: cloudAuthenticatorMock) let baseURL = URL(string: "https://www.example.com/path")! @@ -102,8 +84,8 @@ class AccountListViewModelTests: XCTestCase { } func testWebDAVAccountCellContentWithUnknownHost() throws { - let dbManagerMock = try DatabaseManagerMock(dbPool: dbPool) - let accountManager = CloudProviderAccountDBManager(dbPool: dbPool) + let dbManagerMock = DatabaseManagerMock() + let accountManager = CloudProviderAccountDBManager() let cloudAuthenticatorMock = CloudAuthenticatorMock(accountManager: accountManager) let accountListViewModel = AccountListViewModel(with: .dropbox, dbManager: dbManagerMock, cloudAuthenticator: cloudAuthenticatorMock) let baseURL = URL(string: "www")! diff --git a/CryptomatorTests/DatabaseManagerTests.swift b/CryptomatorTests/DatabaseManagerTests.swift index 15671a1b4..5faa9892d 100644 --- a/CryptomatorTests/DatabaseManagerTests.swift +++ b/CryptomatorTests/DatabaseManagerTests.swift @@ -11,39 +11,38 @@ import GRDB import XCTest @testable import Cryptomator @testable import CryptomatorCommonCore +@testable import Dependencies class DatabaseManagerTests: XCTestCase { var tmpDir: URL! - var dbPool: DatabasePool! var dbManager: DatabaseManager! - var cryptomatorDB: CryptomatorDatabase! + override func setUpWithError() throws { tmpDir = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) try FileManager.default.createDirectory(at: tmpDir, withIntermediateDirectories: true, attributes: nil) let dbURL = tmpDir.appendingPathComponent("db.sqlite") - dbPool = try CryptomatorDatabase.openSharedDatabase(at: dbURL) - cryptomatorDB = try CryptomatorDatabase(dbPool) - dbManager = try DatabaseManager(dbPool: dbPool) + + DependencyValues.mockDependency(\.databaseLocation, with: dbURL) + DependencyValues.mockDependency(\.database, with: CryptomatorDatabase.live) + dbManager = DatabaseManager() } override func tearDownWithError() throws { - dbPool = nil - cryptomatorDB = nil - dbManager = nil try FileManager.default.removeItem(at: tmpDir) } // MARK: VaultListPosition func testCreatePositionTrigger() throws { - let cloudAccountManager = CloudProviderAccountDBManager(dbPool: dbPool) - let vaultAccountManager = VaultAccountDBManager(dbPool: dbPool) + @Dependency(\.database) var database + let cloudAccountManager = CloudProviderAccountDBManager() + let vaultAccountManager = VaultAccountDBManager() let cloudProviderAccount = CloudProviderAccount(accountUID: "1", cloudProviderType: .dropbox) try cloudAccountManager.saveNewAccount(cloudProviderAccount) let vaultAccount = VaultAccount(vaultUID: "Vault1", delegateAccountUID: cloudProviderAccount.accountUID, vaultPath: CloudPath("/Vault1"), vaultName: "Vault1") try vaultAccountManager.saveNewAccount(vaultAccount) - let firstVaultListPosition = try dbPool.read { db in + let firstVaultListPosition = try database.read { db in try VaultListPosition.filter(Column("vaultUID") == "Vault1").fetchOne(db) } XCTAssertNotNil(firstVaultListPosition) @@ -53,7 +52,7 @@ class DatabaseManagerTests: XCTestCase { let secondVaultAccount = VaultAccount(vaultUID: "Vault2", delegateAccountUID: cloudProviderAccount.accountUID, vaultPath: CloudPath("/Vault2"), vaultName: "Vault2") try vaultAccountManager.saveNewAccount(secondVaultAccount) - let secondVaultListPosition = try dbPool.read { db in + let secondVaultListPosition = try database.read { db in try VaultListPosition.filter(Column("vaultUID") == "Vault2").fetchOne(db) } XCTAssertNotNil(secondVaultListPosition) @@ -62,8 +61,10 @@ class DatabaseManagerTests: XCTestCase { } func testDeleteVaultAccountUpdatesPositions() throws { - let cloudAccountManager = CloudProviderAccountDBManager(dbPool: dbPool) - let vaultAccountManager = VaultAccountDBManager(dbPool: dbPool) + @Dependency(\.database) var database + + let cloudAccountManager = CloudProviderAccountDBManager() + let vaultAccountManager = VaultAccountDBManager() let cloudProviderAccount = CloudProviderAccount(accountUID: "1", cloudProviderType: .dropbox) try cloudAccountManager.saveNewAccount(cloudProviderAccount) @@ -74,22 +75,22 @@ class DatabaseManagerTests: XCTestCase { let thirdVaultAccount = VaultAccount(vaultUID: "Vault3", delegateAccountUID: cloudProviderAccount.accountUID, vaultPath: CloudPath("/Vault3"), vaultName: "Vault3") try vaultAccountManager.saveNewAccount(thirdVaultAccount) - _ = try dbPool.write { db in + _ = try database.write { db in try vaultAccount.delete(db) } - let vaultListPositionEntryForVault1 = try dbPool.read { db in + let vaultListPositionEntryForVault1 = try database.read { db in try VaultListPosition.filter(Column("vaultUID") == "Vault1").fetchOne(db) } XCTAssertNil(vaultListPositionEntryForVault1) - let firstVaultListPosition = try dbPool.read { db in + let firstVaultListPosition = try database.read { db in try VaultListPosition.filter(Column("vaultUID") == "Vault2").fetchOne(db) } XCTAssertNotNil(firstVaultListPosition) XCTAssertEqual(0, firstVaultListPosition?.position) - let secondVaultListPosition = try dbPool.read { db in + let secondVaultListPosition = try database.read { db in try VaultListPosition.filter(Column("vaultUID") == "Vault3").fetchOne(db) } XCTAssertNotNil(secondVaultListPosition) @@ -97,8 +98,8 @@ class DatabaseManagerTests: XCTestCase { } func testUpdateVaultListPositions() throws { - let cloudAccountManager = CloudProviderAccountDBManager(dbPool: dbPool) - let vaultAccountManager = VaultAccountDBManager(dbPool: dbPool) + let cloudAccountManager = CloudProviderAccountDBManager() + let vaultAccountManager = VaultAccountDBManager() let cloudProviderAccount = CloudProviderAccount(accountUID: "1", cloudProviderType: .dropbox) try cloudAccountManager.saveNewAccount(cloudProviderAccount) @@ -130,7 +131,8 @@ class DatabaseManagerTests: XCTestCase { // MARK: AccountListPosition func testCreateAccountListPositionTrigger() throws { - let cloudAccountManager = CloudProviderAccountDBManager(dbPool: dbPool) + @Dependency(\.database) var database + let cloudAccountManager = CloudProviderAccountDBManager() let firstWebdavCloudProviderAccount = CloudProviderAccount(accountUID: "firstWebdavCloudProviderAccount", cloudProviderType: .webDAV(type: .custom)) try cloudAccountManager.saveNewAccount(firstWebdavCloudProviderAccount) @@ -141,21 +143,21 @@ class DatabaseManagerTests: XCTestCase { let firstDropboxCloudProviderAccount = CloudProviderAccount(accountUID: "firstDropboxCloudProviderAccount", cloudProviderType: .dropbox) try cloudAccountManager.saveNewAccount(firstDropboxCloudProviderAccount) - let firstWebDAVAccountListPosition = try dbPool.read { db in + let firstWebDAVAccountListPosition = try database.read { db in try AccountListPosition.filter(Column("accountUID") == "firstWebdavCloudProviderAccount" && Column("cloudProviderType") == CloudProviderType.webDAV(type: .custom)).fetchOne(db) } XCTAssertNotNil(firstWebDAVAccountListPosition) XCTAssertEqual(0, firstWebDAVAccountListPosition?.position) XCTAssertEqual(1, firstWebDAVAccountListPosition?.id) - let secondWebDAVAccountListPosition = try dbPool.read { db in + let secondWebDAVAccountListPosition = try database.read { db in try AccountListPosition.filter(Column("accountUID") == "secondWebdavCloudProviderAccount" && Column("cloudProviderType") == CloudProviderType.webDAV(type: .custom)).fetchOne(db) } XCTAssertNotNil(secondWebDAVAccountListPosition) XCTAssertEqual(1, secondWebDAVAccountListPosition?.position) XCTAssertEqual(2, secondWebDAVAccountListPosition?.id) - let firstDropboxAccountListPosition = try dbPool.read { db in + let firstDropboxAccountListPosition = try database.read { db in try AccountListPosition.filter(Column("accountUID") == "firstDropboxCloudProviderAccount" && Column("cloudProviderType") == CloudProviderType.dropbox).fetchOne(db) } XCTAssertNotNil(firstDropboxAccountListPosition) @@ -164,7 +166,8 @@ class DatabaseManagerTests: XCTestCase { } func testDeleteCloudProviderAccountUpdatesPositions() throws { - let cloudAccountManager = CloudProviderAccountDBManager(dbPool: dbPool) + @Dependency(\.database) var database + let cloudAccountManager = CloudProviderAccountDBManager() let firstWebdavCloudProviderAccount = CloudProviderAccount(accountUID: "firstWebdavCloudProviderAccount", cloudProviderType: .webDAV(type: .custom)) try cloudAccountManager.saveNewAccount(firstWebdavCloudProviderAccount) @@ -178,28 +181,28 @@ class DatabaseManagerTests: XCTestCase { let firstDropboxCloudProviderAccount = CloudProviderAccount(accountUID: "firstDropboxCloudProviderAccount", cloudProviderType: .dropbox) try cloudAccountManager.saveNewAccount(firstDropboxCloudProviderAccount) - _ = try dbPool.write { db in + _ = try database.write { db in try firstWebdavCloudProviderAccount.delete(db) } - let accountListPositionEntryForFirstWebDAVAccount = try dbPool.read { db in + let accountListPositionEntryForFirstWebDAVAccount = try database.read { db in try AccountListPosition.filter(Column("accountUID") == "firstWebdavCloudProviderAccount").fetchOne(db) } XCTAssertNil(accountListPositionEntryForFirstWebDAVAccount) - let firstAccountListPositionForWebDAV = try dbPool.read { db in + let firstAccountListPositionForWebDAV = try database.read { db in try AccountListPosition.filter(Column("accountUID") == "secondWebdavCloudProviderAccount").fetchOne(db) } XCTAssertNotNil(firstAccountListPositionForWebDAV) XCTAssertEqual(0, firstAccountListPositionForWebDAV?.position) - let secondAccountListPositionForWebDAV = try dbPool.read { db in + let secondAccountListPositionForWebDAV = try database.read { db in try AccountListPosition.filter(Column("accountUID") == "thirdWebdavCloudProviderAccount").fetchOne(db) } XCTAssertNotNil(secondAccountListPositionForWebDAV) XCTAssertEqual(1, secondAccountListPositionForWebDAV?.position) - let firstAccountListPositionForDropbox = try dbPool.read { db in + let firstAccountListPositionForDropbox = try database.read { db in try AccountListPosition.filter(Column("accountUID") == "firstDropboxCloudProviderAccount").fetchOne(db) } XCTAssertNotNil(firstAccountListPositionForDropbox) @@ -207,7 +210,7 @@ class DatabaseManagerTests: XCTestCase { } func testUpdateAccountListPositions() throws { - let cloudAccountManager = CloudProviderAccountDBManager(dbPool: dbPool) + let cloudAccountManager = CloudProviderAccountDBManager() let firstWebdavCloudProviderAccount = CloudProviderAccount(accountUID: "firstWebdavCloudProviderAccount", cloudProviderType: .webDAV(type: .custom)) try cloudAccountManager.saveNewAccount(firstWebdavCloudProviderAccount) @@ -239,7 +242,7 @@ class DatabaseManagerTests: XCTestCase { } func testGetAllAccountsIsFiltered() throws { - let cloudAccountManager = CloudProviderAccountDBManager(dbPool: dbPool) + let cloudAccountManager = CloudProviderAccountDBManager() let firstWebdavCloudProviderAccount = CloudProviderAccount(accountUID: "firstWebdavCloudProviderAccount", cloudProviderType: .webDAV(type: .custom)) try cloudAccountManager.saveNewAccount(firstWebdavCloudProviderAccount) diff --git a/CryptomatorTests/VaultListViewModelTests.swift b/CryptomatorTests/VaultListViewModelTests.swift index eb317c003..afcac5d0f 100644 --- a/CryptomatorTests/VaultListViewModelTests.swift +++ b/CryptomatorTests/VaultListViewModelTests.swift @@ -15,38 +15,23 @@ import XCTest @testable import CryptomatorCommonCore class VaultListViewModelTests: XCTestCase { - var tmpDir: URL! - var dbPool: DatabasePool! - var cryptomatorDB: CryptomatorDatabase! private var vaultManagerMock: VaultDBManagerMock! private var vaultAccountManagerMock: VaultAccountManagerMock! private var passwordManagerMock: VaultPasswordManagerMock! private var vaultCacheMock: VaultCacheMock! private var fileProviderConnectorMock: FileProviderConnectorMock! - override func setUpWithError() throws { - tmpDir = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) - try FileManager.default.createDirectory(at: tmpDir, withIntermediateDirectories: true, attributes: nil) - let dbURL = tmpDir.appendingPathComponent("db.sqlite") - dbPool = try CryptomatorDatabase.openSharedDatabase(at: dbURL) - cryptomatorDB = try CryptomatorDatabase(dbPool) - let cloudProviderManager = CloudProviderDBManager(accountManager: CloudProviderAccountDBManager(dbPool: dbPool)) + override func setUpWithError() throws { + let cloudProviderManager = CloudProviderDBManager(accountManager: CloudProviderAccountDBManager()) vaultAccountManagerMock = VaultAccountManagerMock() passwordManagerMock = VaultPasswordManagerMock() vaultCacheMock = VaultCacheMock() vaultManagerMock = VaultDBManagerMock(providerManager: cloudProviderManager, vaultAccountManager: vaultAccountManagerMock, vaultCache: vaultCacheMock, passwordManager: passwordManagerMock, masterkeyCacheManager: MasterkeyCacheManagerMock(), masterkeyCacheHelper: MasterkeyCacheHelperMock()) fileProviderConnectorMock = FileProviderConnectorMock() - _ = try DatabaseManager(dbPool: dbPool) - } - - override func tearDownWithError() throws { - dbPool = nil - cryptomatorDB = nil - try FileManager.default.removeItem(at: tmpDir) } func testRefreshVaultsIsSorted() throws { - let dbManagerMock = try DatabaseManagerMock(dbPool: dbPool) + let dbManagerMock = DatabaseManagerMock() let vaultListViewModel = VaultListViewModel(dbManager: dbManagerMock, vaultManager: vaultManagerMock, fileProviderConnector: fileProviderConnectorMock) XCTAssert(vaultListViewModel.getVaults().isEmpty) try vaultListViewModel.refreshItems() @@ -59,7 +44,7 @@ class VaultListViewModelTests: XCTestCase { } func testMoveRow() throws { - let dbManagerMock = try DatabaseManagerMock(dbPool: dbPool) + let dbManagerMock = DatabaseManagerMock() let vaultListViewModel = VaultListViewModel(dbManager: dbManagerMock, vaultManager: vaultManagerMock, fileProviderConnector: fileProviderConnectorMock) try vaultListViewModel.refreshItems() @@ -82,7 +67,7 @@ class VaultListViewModelTests: XCTestCase { let cachedVault = CachedVault(vaultUID: "vault2", masterkeyFileData: "".data(using: .utf8)!, vaultConfigToken: nil, lastUpToDateCheck: Date(), masterkeyFileLastModifiedDate: nil, vaultConfigLastModifiedDate: nil) try vaultCacheMock.cache(cachedVault) - let dbManagerMock = try DatabaseManagerMock(dbPool: dbPool) + let dbManagerMock = DatabaseManagerMock() let vaultListViewModel = VaultListViewModel(dbManager: dbManagerMock, vaultManager: vaultManagerMock, fileProviderConnector: fileProviderConnectorMock) try vaultListViewModel.refreshItems() @@ -105,7 +90,7 @@ class VaultListViewModelTests: XCTestCase { func testLockVault() throws { let expectation = XCTestExpectation() - let dbManagerMock = try DatabaseManagerMock(dbPool: dbPool) + let dbManagerMock = DatabaseManagerMock() let vaultListViewModel = VaultListViewModel(dbManager: dbManagerMock, vaultManager: vaultManagerMock, fileProviderConnector: fileProviderConnectorMock) let vaultInfo = VaultInfo(vaultAccount: VaultAccount(vaultUID: "vault1", delegateAccountUID: "1", vaultPath: CloudPath("/vault1"), vaultName: "vault1"), cloudProviderAccount: CloudProviderAccount(accountUID: "1", cloudProviderType: .dropbox), @@ -131,7 +116,7 @@ class VaultListViewModelTests: XCTestCase { func testRefreshVaultLockedStates() throws { let expectation = XCTestExpectation() - let dbManagerMock = try DatabaseManagerMock(dbPool: dbPool) + let dbManagerMock = DatabaseManagerMock() let vaultListViewModel = VaultListViewModel(dbManager: dbManagerMock, vaultManager: vaultManagerMock, fileProviderConnector: fileProviderConnectorMock) try vaultListViewModel.refreshItems() diff --git a/FileProviderExtension/FileProviderExtension.swift b/FileProviderExtension/FileProviderExtension.swift index 51f0e2ce4..a4004ad4d 100644 --- a/FileProviderExtension/FileProviderExtension.swift +++ b/FileProviderExtension/FileProviderExtension.swift @@ -25,27 +25,19 @@ class FileProviderExtension: NSFileProviderExtension { LoggerSetup.oneTimeSetup() FileProviderExtension.setupIAP() if !FileProviderExtension.sharedDatabaseInitialized { - if let dbURL = CryptomatorDatabase.sharedDBURL { - do { - let dbPool = try CryptomatorDatabase.openSharedDatabase(at: dbURL) - CryptomatorDatabase.shared = try CryptomatorDatabase(dbPool) - FileProviderExtension.sharedDatabaseInitialized = true - DropboxSetup.constants = DropboxSetup(appKey: CloudAccessSecrets.dropboxAppKey, sharedContainerIdentifier: CryptomatorConstants.appGroupName, keychainService: CryptomatorConstants.mainAppBundleId, forceForegroundSession: false) - GoogleDriveSetup.constants = GoogleDriveSetup(clientId: CloudAccessSecrets.googleDriveClientId, redirectURL: CloudAccessSecrets.googleDriveRedirectURL!, sharedContainerIdentifier: CryptomatorConstants.appGroupName) - OneDriveSetup.sharedContainerIdentifier = CryptomatorConstants.appGroupName - let oneDriveConfiguration = MSALPublicClientApplicationConfig(clientId: CloudAccessSecrets.oneDriveClientId, redirectUri: CloudAccessSecrets.oneDriveRedirectURI, authority: nil) - oneDriveConfiguration.cacheConfig.keychainSharingGroup = CryptomatorConstants.mainAppBundleId - OneDriveSetup.clientApplication = try MSALPublicClientApplication(configuration: oneDriveConfiguration) - } catch { - // MARK: Handle error - - FileProviderExtension.databaseError = error - DDLogError("Failed to initialize FPExt sharedDB: \(error)") - } - } else { + do { + FileProviderExtension.sharedDatabaseInitialized = true + DropboxSetup.constants = DropboxSetup(appKey: CloudAccessSecrets.dropboxAppKey, sharedContainerIdentifier: CryptomatorConstants.appGroupName, keychainService: CryptomatorConstants.mainAppBundleId, forceForegroundSession: false) + GoogleDriveSetup.constants = GoogleDriveSetup(clientId: CloudAccessSecrets.googleDriveClientId, redirectURL: CloudAccessSecrets.googleDriveRedirectURL!, sharedContainerIdentifier: CryptomatorConstants.appGroupName) + OneDriveSetup.sharedContainerIdentifier = CryptomatorConstants.appGroupName + let oneDriveConfiguration = MSALPublicClientApplicationConfig(clientId: CloudAccessSecrets.oneDriveClientId, redirectUri: CloudAccessSecrets.oneDriveRedirectURI, authority: nil) + oneDriveConfiguration.cacheConfig.keychainSharingGroup = CryptomatorConstants.mainAppBundleId + OneDriveSetup.clientApplication = try MSALPublicClientApplication(configuration: oneDriveConfiguration) + } catch { // MARK: Handle error - DDLogError("FPExt - dbURL is nil") + FileProviderExtension.databaseError = error + DDLogError("Failed to initialize FPExt sharedDB: \(error)") } } diff --git a/FileProviderExtensionUI/RootViewController.swift b/FileProviderExtensionUI/RootViewController.swift index 2da0ac122..1da46a054 100644 --- a/FileProviderExtensionUI/RootViewController.swift +++ b/FileProviderExtensionUI/RootViewController.swift @@ -56,22 +56,7 @@ class RootViewController: FPUIActionExtensionViewController { static var oneTimeSetup: () -> Void = { // Set up logger LoggerSetup.oneTimeSetup() - // Set up database - guard let dbURL = CryptomatorDatabase.sharedDBURL else { - // MARK: Handle error - DDLogError("dbURL is nil") - return {} - } - do { - let dbPool = try CryptomatorDatabase.openSharedDatabase(at: dbURL) - CryptomatorDatabase.shared = try CryptomatorDatabase(dbPool) - } catch { - // MARK: Handle error - - DDLogError("Initializing CryptomatorDatabase failed with error: \(error)") - return {} - } // Set up cloud storage services CloudProviderDBManager.shared.useBackgroundSession = false DropboxSetup.constants = DropboxSetup(appKey: CloudAccessSecrets.dropboxAppKey, sharedContainerIdentifier: nil, keychainService: CryptomatorConstants.mainAppBundleId, forceForegroundSession: true) diff --git a/FileProviderExtensionUI/UnlockVaultViewModel.swift b/FileProviderExtensionUI/UnlockVaultViewModel.swift index 10b46d3aa..1654283a4 100644 --- a/FileProviderExtensionUI/UnlockVaultViewModel.swift +++ b/FileProviderExtensionUI/UnlockVaultViewModel.swift @@ -119,7 +119,7 @@ class UnlockVaultViewModel { passwordManager: VaultPasswordKeychainManager(), vaultAccountManager: VaultAccountDBManager.shared, providerManager: CloudProviderDBManager.shared, - vaultCache: VaultDBCache(dbWriter: CryptomatorDatabase.shared.dbPool)) + vaultCache: VaultDBCache()) } init(domain: NSFileProviderDomain, wrongBiometricalPassword: Bool, fileProviderConnector: FileProviderConnector, passwordManager: VaultPasswordManager, vaultAccountManager: VaultAccountManager, providerManager: CloudProviderManager, vaultCache: VaultCache) { From c8899705a1513aea6c667c07e32be8cf8a4420df Mon Sep 17 00:00:00 2001 From: Philipp Schmid <25935690+phil1995@users.noreply.github.com> Date: Sun, 1 Oct 2023 00:36:33 +0200 Subject: [PATCH 2/3] Fix swiftlint unneeded_synthesized_initializer warning --- CryptomatorFileProvider/DatabaseURLProvider.swift | 4 ---- CryptomatorFileProvider/FileProviderItemList.swift | 5 ----- 2 files changed, 9 deletions(-) diff --git a/CryptomatorFileProvider/DatabaseURLProvider.swift b/CryptomatorFileProvider/DatabaseURLProvider.swift index 987b7d22c..554d9a1b1 100644 --- a/CryptomatorFileProvider/DatabaseURLProvider.swift +++ b/CryptomatorFileProvider/DatabaseURLProvider.swift @@ -13,10 +13,6 @@ public struct DatabaseURLProvider { public static let shared = DatabaseURLProvider(documentStorageURLProvider: NSFileProviderManager.default) let documentStorageURLProvider: DocumentStorageURLProvider - init(documentStorageURLProvider: DocumentStorageURLProvider) { - self.documentStorageURLProvider = documentStorageURLProvider - } - public func getDatabaseURL(for domain: NSFileProviderDomain) -> URL { let documentStorageURL = documentStorageURLProvider.documentStorageURL let domainURL = documentStorageURL.appendingPathComponent(domain.pathRelativeToDocumentStorage, isDirectory: true) diff --git a/CryptomatorFileProvider/FileProviderItemList.swift b/CryptomatorFileProvider/FileProviderItemList.swift index fb728d004..5530b2015 100644 --- a/CryptomatorFileProvider/FileProviderItemList.swift +++ b/CryptomatorFileProvider/FileProviderItemList.swift @@ -12,9 +12,4 @@ import Foundation public struct FileProviderItemList { public let items: [FileProviderItem] public let nextPageToken: NSFileProviderPage? - - init(items: [FileProviderItem], nextPageToken: NSFileProviderPage?) { - self.items = items - self.nextPageToken = nextPageToken - } } From 26698c656436a1e1f190cbdc8055828e35dd2e95 Mon Sep 17 00:00:00 2001 From: Philipp Schmid <25935690+phil1995@users.noreply.github.com> Date: Sun, 1 Oct 2023 00:40:00 +0200 Subject: [PATCH 3/3] Run swiftformat --- Cryptomator/Common/Cells/BindableTableViewCellViewModel.swift | 2 +- Cryptomator/Onboarding/OnboardingViewController.swift | 2 +- .../FileProviderXPC/FileProviderConnector.swift | 2 +- .../CryptomatorCommonCore/Manager/VaultPasswordManager.swift | 2 +- .../CryptomatorCommonCore/S3/CryptomatorKeychain+S3.swift | 2 +- CryptomatorFileProvider/FileProviderAdapterError.swift | 2 +- CryptomatorFileProvider/LocalURLProviderType.swift | 2 +- CryptomatorFileProvider/Promise+AllIgnoringResult.swift | 2 +- .../Mocks/CustomCloudProviderMockTests.swift | 2 +- CryptomatorTests/Mocks/IAPManagerMock.swift | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cryptomator/Common/Cells/BindableTableViewCellViewModel.swift b/Cryptomator/Common/Cells/BindableTableViewCellViewModel.swift index 28318c8c7..7c12f3b90 100644 --- a/Cryptomator/Common/Cells/BindableTableViewCellViewModel.swift +++ b/Cryptomator/Common/Cells/BindableTableViewCellViewModel.swift @@ -1,5 +1,5 @@ // -// TableViewCellViewModel.swift +// BindableTableViewCellViewModel.swift // Cryptomator // // Created by Philipp Schmid on 29.07.21. diff --git a/Cryptomator/Onboarding/OnboardingViewController.swift b/Cryptomator/Onboarding/OnboardingViewController.swift index 3a28097eb..2f74cca8f 100644 --- a/Cryptomator/Onboarding/OnboardingViewController.swift +++ b/Cryptomator/Onboarding/OnboardingViewController.swift @@ -1,5 +1,5 @@ // -// OnboardingWelcomeViewController.swift +// OnboardingViewController.swift // Cryptomator // // Created by Tobias Hagemann on 08.09.21. diff --git a/CryptomatorCommon/Sources/CryptomatorCommonCore/FileProviderXPC/FileProviderConnector.swift b/CryptomatorCommon/Sources/CryptomatorCommonCore/FileProviderXPC/FileProviderConnector.swift index c394a04b6..60eb802f6 100644 --- a/CryptomatorCommon/Sources/CryptomatorCommonCore/FileProviderXPC/FileProviderConnector.swift +++ b/CryptomatorCommon/Sources/CryptomatorCommonCore/FileProviderXPC/FileProviderConnector.swift @@ -1,5 +1,5 @@ // -// File.swift +// FileProviderConnector.swift // CryptomatorCommonCore // // Created by Philipp Schmid on 26.07.21. diff --git a/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultPasswordManager.swift b/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultPasswordManager.swift index 43503810b..d63b54831 100644 --- a/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultPasswordManager.swift +++ b/CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultPasswordManager.swift @@ -1,5 +1,5 @@ // -// VaultPasswordKeychainManager.swift +// VaultPasswordManager.swift // CryptomatorCommonCore // // Created by Philipp Schmid on 09.07.21. diff --git a/CryptomatorCommon/Sources/CryptomatorCommonCore/S3/CryptomatorKeychain+S3.swift b/CryptomatorCommon/Sources/CryptomatorCommonCore/S3/CryptomatorKeychain+S3.swift index dc58d48bc..fcabacf2b 100644 --- a/CryptomatorCommon/Sources/CryptomatorCommonCore/S3/CryptomatorKeychain+S3.swift +++ b/CryptomatorCommon/Sources/CryptomatorCommonCore/S3/CryptomatorKeychain+S3.swift @@ -1,5 +1,5 @@ // -// CryptomatorKeychain+S3.swift.swift +// CryptomatorKeychain+S3.swift // // // Created by Philipp Schmid on 29.06.22. diff --git a/CryptomatorFileProvider/FileProviderAdapterError.swift b/CryptomatorFileProvider/FileProviderAdapterError.swift index 3e427f9a1..a2e23434f 100644 --- a/CryptomatorFileProvider/FileProviderAdapterError.swift +++ b/CryptomatorFileProvider/FileProviderAdapterError.swift @@ -1,5 +1,5 @@ // -// FileProviderDecoratorError.swift +// FileProviderAdapterError.swift // CryptomatorFileProvider // // Created by Philipp Schmid on 24.06.20. diff --git a/CryptomatorFileProvider/LocalURLProviderType.swift b/CryptomatorFileProvider/LocalURLProviderType.swift index 653dcc0f5..5295b3795 100644 --- a/CryptomatorFileProvider/LocalURLProviderType.swift +++ b/CryptomatorFileProvider/LocalURLProviderType.swift @@ -1,5 +1,5 @@ // -// LocalURLProvider.swift +// LocalURLProviderType.swift // CryptomatorFileProvider // // Created by Philipp Schmid on 03.03.22. diff --git a/CryptomatorFileProvider/Promise+AllIgnoringResult.swift b/CryptomatorFileProvider/Promise+AllIgnoringResult.swift index 23573f67b..057ba025a 100644 --- a/CryptomatorFileProvider/Promise+AllIgnoringResult.swift +++ b/CryptomatorFileProvider/Promise+AllIgnoringResult.swift @@ -1,5 +1,5 @@ // -// Promises+FinishedAll.swift +// Promise+AllIgnoringResult.swift // CryptomatorFileProvider // // Created by Philipp Schmid on 31.03.22. diff --git a/CryptomatorFileProviderTests/Mocks/CustomCloudProviderMockTests.swift b/CryptomatorFileProviderTests/Mocks/CustomCloudProviderMockTests.swift index 3cceb3b4b..38cb1f9c0 100644 --- a/CryptomatorFileProviderTests/Mocks/CustomCloudProviderMockTests.swift +++ b/CryptomatorFileProviderTests/Mocks/CustomCloudProviderMockTests.swift @@ -1,5 +1,5 @@ // -// CloudProviderMockTests.swift +// CustomCloudProviderMockTests.swift // CryptomatorFileProviderTests // // Created by Philipp Schmid on 01.07.20. diff --git a/CryptomatorTests/Mocks/IAPManagerMock.swift b/CryptomatorTests/Mocks/IAPManagerMock.swift index b073d22c4..f3a70b405 100644 --- a/CryptomatorTests/Mocks/IAPManagerMock.swift +++ b/CryptomatorTests/Mocks/IAPManagerMock.swift @@ -1,5 +1,5 @@ // -// IAPManager.swift +// IAPManagerMock.swift // CryptomatorTests // // Created by Philipp Schmid on 26.11.21.