Summary: - Sources: update Helpers, Protocols, Services - Tests: update tests for EncryptionHelperTests.swift, KeychainHelperTests.swift, LocalDataTests.swift (+2 more) Stats: - 9 files changed, 205 insertions(+), 103 deletions(-)
154 lines
4.6 KiB
Swift
154 lines
4.6 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import LocalData
|
|
|
|
@Suite(.serialized)
|
|
struct KeychainHelperTests {
|
|
private let testService = "LocalDataTests.Keychain.\(UUID().uuidString)"
|
|
private let keychain = MockKeychainHelper()
|
|
|
|
// MARK: - Basic Round Trip
|
|
|
|
@Test func keychainRoundTrip() async throws {
|
|
let key = "test.credential"
|
|
let data = Data("secret-password".utf8)
|
|
|
|
defer {
|
|
let k = keychain
|
|
let s = testService
|
|
Task { try? await k.delete(service: s, key: key) }
|
|
}
|
|
|
|
try await keychain.set(
|
|
data,
|
|
service: testService,
|
|
key: key,
|
|
accessibility: .afterFirstUnlock
|
|
)
|
|
|
|
let retrieved = try await keychain.get(service: testService, key: key)
|
|
#expect(retrieved == data)
|
|
}
|
|
|
|
@Test func keychainNotFoundReturnsNil() async throws {
|
|
let result = try await keychain.get(
|
|
service: testService,
|
|
key: "nonexistent.\(UUID().uuidString)"
|
|
)
|
|
#expect(result == nil)
|
|
}
|
|
|
|
@Test func keychainDeleteNonexistentDoesNotThrow() async throws {
|
|
// Should not throw even if item doesn't exist
|
|
try await keychain.delete(
|
|
service: testService,
|
|
key: "nonexistent.\(UUID().uuidString)"
|
|
)
|
|
}
|
|
|
|
@Test func keychainExists() async throws {
|
|
let key = "test.exists.\(UUID().uuidString)"
|
|
let data = Data("test".utf8)
|
|
|
|
defer {
|
|
let k = keychain
|
|
let s = testService
|
|
Task { try? await k.delete(service: s, key: key) }
|
|
}
|
|
|
|
let beforeExists = try await keychain.exists(service: testService, key: key)
|
|
#expect(beforeExists == false)
|
|
|
|
try await keychain.set(
|
|
data,
|
|
service: testService,
|
|
key: key,
|
|
accessibility: .whenUnlocked
|
|
)
|
|
|
|
let afterExists = try await keychain.exists(service: testService, key: key)
|
|
#expect(afterExists == true)
|
|
}
|
|
|
|
@Test func keychainUpdateReplacesData() async throws {
|
|
let key = "test.update.\(UUID().uuidString)"
|
|
let originalData = Data("original".utf8)
|
|
let updatedData = Data("updated".utf8)
|
|
|
|
defer {
|
|
let k = keychain
|
|
let s = testService
|
|
Task { try? await k.delete(service: s, key: key) }
|
|
}
|
|
|
|
try await keychain.set(
|
|
originalData,
|
|
service: testService,
|
|
key: key,
|
|
accessibility: .afterFirstUnlock
|
|
)
|
|
|
|
try await keychain.set(
|
|
updatedData,
|
|
service: testService,
|
|
key: key,
|
|
accessibility: .afterFirstUnlock
|
|
)
|
|
|
|
let retrieved = try await keychain.get(service: testService, key: key)
|
|
#expect(retrieved == updatedData)
|
|
}
|
|
|
|
@Test func keychainDeleteAll() async throws {
|
|
let deleteAllService = "LocalDataTests.DeleteAll.\(UUID().uuidString)"
|
|
let data = Data("test".utf8)
|
|
|
|
// Create multiple items
|
|
for i in 0..<3 {
|
|
try await keychain.set(
|
|
data,
|
|
service: deleteAllService,
|
|
key: "key\(i)",
|
|
accessibility: .afterFirstUnlock
|
|
)
|
|
}
|
|
|
|
// Verify they exist
|
|
let exists0 = try await keychain.exists(service: deleteAllService, key: "key0")
|
|
#expect(exists0 == true)
|
|
|
|
// Delete all
|
|
try await keychain.deleteAll(service: deleteAllService)
|
|
|
|
// Verify they're gone
|
|
for i in 0..<3 {
|
|
let exists = try await keychain.exists(service: deleteAllService, key: "key\(i)")
|
|
#expect(exists == false)
|
|
}
|
|
}
|
|
|
|
// MARK: - Accessibility Options
|
|
|
|
@Test(arguments: KeychainAccessibility.allCases)
|
|
func keychainAccessibilityOptions(accessibility: KeychainAccessibility) async throws {
|
|
let key = "test.accessibility.\(accessibility).\(UUID().uuidString)"
|
|
let data = Data("data-for-\(accessibility)".utf8)
|
|
|
|
defer {
|
|
let k = keychain
|
|
let s = testService
|
|
Task { try? await k.delete(service: s, key: key) }
|
|
}
|
|
|
|
try await keychain.set(
|
|
data,
|
|
service: testService,
|
|
key: key,
|
|
accessibility: accessibility
|
|
)
|
|
|
|
let retrieved = try await keychain.get(service: testService, key: key)
|
|
#expect(retrieved == data)
|
|
}
|
|
}
|