diff --git a/Package.resolved b/Package.resolved index 0bc1cf5d..1657463c 100644 --- a/Package.resolved +++ b/Package.resolved @@ -123,8 +123,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-snapshot-testing", "state" : { - "revision" : "cc051f1c07a414cf36b3d45fc8d00f2a8086ca5e", - "version" : "1.18.8" + "revision" : "bf8d8c27f0f0c6d5e77bff0db76ab68f2050d15d", + "version" : "1.18.9" } }, { diff --git a/Sources/SQLiteData/CloudKit/Internal/DataManager.swift b/Sources/SQLiteData/CloudKit/Internal/DataManager.swift index 0bf280c4..1b6a5442 100644 --- a/Sources/SQLiteData/CloudKit/Internal/DataManager.swift +++ b/Sources/SQLiteData/CloudKit/Internal/DataManager.swift @@ -77,7 +77,7 @@ } package var temporaryDirectory: URL { - URL(fileURLWithPath: "/") + URL(fileURLWithPath: "/tmp") } } @@ -86,6 +86,9 @@ static var liveValue: any DataManager { LiveDataManager() } + static var previewValue: any DataManager { + InMemoryDataManager() + } static var testValue: any DataManager { InMemoryDataManager() } diff --git a/Sources/SQLiteData/CloudKit/Internal/MockCloudDatabase.swift b/Sources/SQLiteData/CloudKit/Internal/MockCloudDatabase.swift index ae093dd5..50f20237 100644 --- a/Sources/SQLiteData/CloudKit/Internal/MockCloudDatabase.swift +++ b/Sources/SQLiteData/CloudKit/Internal/MockCloudDatabase.swift @@ -60,7 +60,7 @@ for key in record.allKeys() { guard let assetData = state.assets[AssetID(recordID: record.recordID, key: key)] else { continue } - let url = URL(filePath: UUID().uuidString.lowercased()) + let url = dataManager.wrappedValue.temporaryDirectory.appending(path: UUID().uuidString) try dataManager.wrappedValue.save(assetData, to: url) record[key] = CKAsset(fileURL: url) } diff --git a/Tests/SQLiteDataTests/CloudKitTests/AssetsTests.swift b/Tests/SQLiteDataTests/CloudKitTests/AssetsTests.swift index 7744f34b..95d1204d 100644 --- a/Tests/SQLiteDataTests/CloudKitTests/AssetsTests.swift +++ b/Tests/SQLiteDataTests/CloudKitTests/AssetsTests.swift @@ -37,7 +37,7 @@ coverImage_hash: Data(32 bytes), remindersListID: 1, coverImage: CKAsset( - fileURL: URL(file:///6105d6cc76af400325e94d588ce511be5bfdbb73b437dc51eca43917d7a43e3d), + fileURL: URL(file:///tmp/6105d6cc76af400325e94d588ce511be5bfdbb73b437dc51eca43917d7a43e3d), dataString: "image" ) ), @@ -61,7 +61,7 @@ inMemoryDataManager.storage.withValue { storage in let url = URL( - string: "file:///6105d6cc76af400325e94d588ce511be5bfdbb73b437dc51eca43917d7a43e3d" + string: "file:///tmp/6105d6cc76af400325e94d588ce511be5bfdbb73b437dc51eca43917d7a43e3d" )! #expect(storage[url] == Data("image".utf8)) } @@ -93,7 +93,7 @@ coverImage_hash: Data(32 bytes), remindersListID: 1, coverImage: CKAsset( - fileURL: URL(file:///97e67a5645969953f1a4cfe2ea75649864ff99789189cdd3f6db03e59f8a8ebf), + fileURL: URL(file:///tmp/97e67a5645969953f1a4cfe2ea75649864ff99789189cdd3f6db03e59f8a8ebf), dataString: "new-image" ) ), @@ -117,7 +117,7 @@ inMemoryDataManager.storage.withValue { storage in let url = URL( - string: "file:///97e67a5645969953f1a4cfe2ea75649864ff99789189cdd3f6db03e59f8a8ebf" + string: "file:///tmp/97e67a5645969953f1a4cfe2ea75649864ff99789189cdd3f6db03e59f8a8ebf" )! #expect(storage[url] == Data("new-image".utf8)) } diff --git a/Tests/SQLiteDataTests/CloudKitTests/MockCloudDatabaseTests.swift b/Tests/SQLiteDataTests/CloudKitTests/MockCloudDatabaseTests.swift index ecd50cc2..d019ae9e 100644 --- a/Tests/SQLiteDataTests/CloudKitTests/MockCloudDatabaseTests.swift +++ b/Tests/SQLiteDataTests/CloudKitTests/MockCloudDatabaseTests.swift @@ -46,6 +46,30 @@ #expect(error == CKError(.unknownItem)) } + @available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) + @Test func assetsUseTemporaryDirectory() async throws { + let recordID = CKRecord.ID(recordName: "record") + let record = CKRecord(recordType: "Record", recordID: recordID) + let sourceURL = URL(fileURLWithPath: "/sqlite-data-test-assets/asset.jpg") + try inMemoryDataManager.save(Data("image".utf8), to: sourceURL) + record["asset"] = CKAsset(fileURL: sourceURL) + + let database = syncEngine.private.database + let (saveResults, _) = try database.modifyRecords( + saving: [record], + deleting: [] + ) + _ = try saveResults[recordID]?.get() + + let fetched = try database.record(for: recordID) + let asset = fetched["asset"] as? CKAsset + let assetDirectory = try #require(asset?.fileURL?.path()) + #expect( + assetDirectory + .hasPrefix(inMemoryDataManager.temporaryDirectory.path()) + ) + } + @available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) @Test func saveTransaction_ChildBeforeParent() async throws { let parent = CKRecord(recordType: "A", recordID: CKRecord.ID(recordName: "A")) diff --git a/Tests/SQLiteDataTests/Internal/TemporaryDirectoryDataManager.swift b/Tests/SQLiteDataTests/Internal/TemporaryDirectoryDataManager.swift new file mode 100644 index 00000000..92a8bc05 --- /dev/null +++ b/Tests/SQLiteDataTests/Internal/TemporaryDirectoryDataManager.swift @@ -0,0 +1,30 @@ +#if canImport(CloudKit) + import ConcurrencyExtras + import Foundation + import SQLiteData + + @available(iOS 17, macOS 14, tvOS 17, watchOS 10, *) + struct TemporaryDirectoryDataManager: DataManager { + let temporaryDirectory: URL + let storage = LockIsolated<[URL: Data]>([:]) + + func load(_ url: URL) throws -> Data { + try storage.withValue { storage in + guard let data = storage[url] + else { + struct FileNotFound: Error {} + throw FileNotFound() + } + return data + } + } + + func save(_ data: Data, to url: URL) throws { + storage.withValue { $0[url] = data } + } + + func sha256(of fileURL: URL) -> Data? { + nil + } + } +#endif