feat(persistence): add FileVault with complete file protection
按 W2 plan Task 3 落地原图加密存储: - writeJPEG / loadImage / remove / wipe 四个核心操作 - Application Support/Vault/ 目录全程 .completeFileProtection - 文件写入用 .completeFileProtection options(双保险) - FileVault(rootURL:) 注入便于测试隔离 - shared 单例用真实 App Support 路径 测试 3 条:roundtrip / remove / wipe。 注:.swift 文件需用户在 Xcode 拖入 target(Persistence group + 体己Tests), 之后 ⌘U 跑测试,若全绿再 amend 提交 .pbxproj。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
48
体己Tests/FileVaultTests.swift
Normal file
48
体己Tests/FileVaultTests.swift
Normal file
@@ -0,0 +1,48 @@
|
||||
import Testing
|
||||
import UIKit
|
||||
@testable import 体己
|
||||
|
||||
@MainActor
|
||||
struct FileVaultTests {
|
||||
|
||||
private func makeIsolatedVault() throws -> FileVault {
|
||||
let temp = FileManager.default.temporaryDirectory
|
||||
.appendingPathComponent(UUID().uuidString, isDirectory: true)
|
||||
return try FileVault(rootURL: temp)
|
||||
}
|
||||
|
||||
@Test func writeAndReadJPEGRoundtrip() throws {
|
||||
let vault = try makeIsolatedVault()
|
||||
let image = UIImage(systemName: "doc")!
|
||||
|
||||
let saved = try vault.writeJPEG(image, quality: 0.8)
|
||||
|
||||
#expect(saved.bytes > 0)
|
||||
#expect(saved.relativePath.hasSuffix(".jpg"))
|
||||
|
||||
let loaded = try vault.loadImage(relativePath: saved.relativePath)
|
||||
#expect(loaded.size != .zero)
|
||||
}
|
||||
|
||||
@Test func removeMakesFileGone() throws {
|
||||
let vault = try makeIsolatedVault()
|
||||
let saved = try vault.writeJPEG(UIImage(systemName: "doc")!)
|
||||
|
||||
try vault.remove(relativePath: saved.relativePath)
|
||||
|
||||
#expect(throws: (any Error).self) {
|
||||
_ = try vault.loadImage(relativePath: saved.relativePath)
|
||||
}
|
||||
}
|
||||
|
||||
@Test func wipeRemovesAllFiles() throws {
|
||||
let vault = try makeIsolatedVault()
|
||||
let a = try vault.writeJPEG(UIImage(systemName: "doc")!)
|
||||
let b = try vault.writeJPEG(UIImage(systemName: "folder")!)
|
||||
|
||||
try vault.wipe()
|
||||
|
||||
#expect(throws: (any Error).self) { _ = try vault.loadImage(relativePath: a.relativePath) }
|
||||
#expect(throws: (any Error).self) { _ = try vault.loadImage(relativePath: b.relativePath) }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user