2026-03-11 11:36:36 +01:00
|
|
|
//
|
|
|
|
|
// MockPGPInterface.swift
|
|
|
|
|
// passKitTests
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
@testable import passKit
|
|
|
|
|
|
|
|
|
|
class MockPGPInterface: PGPInterface {
|
|
|
|
|
// MARK: - Configuration
|
|
|
|
|
|
|
|
|
|
var publicKeyIDs: Set<String> = []
|
|
|
|
|
var privateKeyIDs: Set<String> = []
|
|
|
|
|
|
|
|
|
|
var decryptResult: Data?
|
|
|
|
|
var decryptError: Error?
|
|
|
|
|
var encryptResult = Data()
|
|
|
|
|
var encryptError: Error?
|
|
|
|
|
|
2026-03-10 17:14:11 +01:00
|
|
|
/// When set, the mock calls `passPhraseForKey` with this key ID during `decrypt`,
|
|
|
|
|
/// simulating the PGP backend selecting a key and requesting its passphrase.
|
|
|
|
|
var selectedKeyForPassphrase: String?
|
|
|
|
|
|
2026-03-11 11:36:36 +01:00
|
|
|
// MARK: - Call tracking
|
|
|
|
|
|
|
|
|
|
struct DecryptCall {
|
|
|
|
|
let encryptedData: Data
|
|
|
|
|
let keyID: String?
|
2026-03-10 17:14:11 +01:00
|
|
|
let passPhraseForKey: (String) -> String
|
2026-03-11 11:36:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct EncryptCall {
|
|
|
|
|
let plainData: Data
|
|
|
|
|
let keyID: String?
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-11 00:21:30 +01:00
|
|
|
struct EncryptMultiKeyCall {
|
|
|
|
|
let plainData: Data
|
|
|
|
|
let keyIDs: [String]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct EncryptWithAllKeysCall {
|
|
|
|
|
let plainData: Data
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-11 11:36:36 +01:00
|
|
|
var decryptCalls: [DecryptCall] = []
|
2026-03-10 17:14:11 +01:00
|
|
|
var resolvedPassphrases: [String] = []
|
2026-03-11 00:21:30 +01:00
|
|
|
var encryptMultiKeyCalls: [EncryptMultiKeyCall] = []
|
|
|
|
|
var encryptWithAllKeysCalls: [EncryptWithAllKeysCall] = []
|
2026-03-11 11:36:36 +01:00
|
|
|
var containsPublicKeyCalls: [String] = []
|
|
|
|
|
var containsPrivateKeyCalls: [String] = []
|
|
|
|
|
|
|
|
|
|
// MARK: - PGPInterface
|
|
|
|
|
|
2026-03-10 22:16:42 +01:00
|
|
|
func decrypt(encryptedData: Data, keyIDHint keyID: String?, passPhraseForKey: @escaping (String) -> String) throws -> Data? {
|
2026-03-10 17:14:11 +01:00
|
|
|
decryptCalls.append(DecryptCall(encryptedData: encryptedData, keyID: keyID, passPhraseForKey: passPhraseForKey))
|
|
|
|
|
if let selectedKey = selectedKeyForPassphrase {
|
|
|
|
|
resolvedPassphrases.append(passPhraseForKey(selectedKey))
|
|
|
|
|
}
|
2026-03-11 11:36:36 +01:00
|
|
|
if let error = decryptError {
|
|
|
|
|
throw error
|
|
|
|
|
}
|
|
|
|
|
return decryptResult
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-11 00:21:30 +01:00
|
|
|
func encryptWithAllKeys(plainData: Data) throws -> Data {
|
|
|
|
|
encryptWithAllKeysCalls.append(EncryptWithAllKeysCall(plainData: plainData))
|
|
|
|
|
if let error = encryptError {
|
|
|
|
|
throw error
|
|
|
|
|
}
|
|
|
|
|
return encryptResult
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func encrypt(plainData: Data, keyIDs: [String]) throws -> Data {
|
|
|
|
|
encryptMultiKeyCalls.append(EncryptMultiKeyCall(plainData: plainData, keyIDs: keyIDs))
|
|
|
|
|
if let error = encryptError {
|
|
|
|
|
throw error
|
|
|
|
|
}
|
|
|
|
|
return encryptResult
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-11 11:36:36 +01:00
|
|
|
func containsPublicKey(with keyID: String) -> Bool {
|
|
|
|
|
containsPublicKeyCalls.append(keyID)
|
|
|
|
|
return publicKeyIDs.contains { $0.hasSuffix(keyID.lowercased()) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func containsPrivateKey(with keyID: String) -> Bool {
|
|
|
|
|
containsPrivateKeyCalls.append(keyID)
|
|
|
|
|
return privateKeyIDs.contains { $0.hasSuffix(keyID.lowercased()) }
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-11 16:15:49 +01:00
|
|
|
var keyID: [String] { [] } // currently not relevant in these tests
|
|
|
|
|
var shortKeyID: [String] { [] } // currently not relevant in these tests
|
2026-03-11 11:36:36 +01:00
|
|
|
}
|