PGPInterface can encrypt with multiple keys, PGPAgent can encrypt with all keys

This commit is contained in:
Lysann Tranvouez 2026-03-11 00:21:30 +01:00
parent 8d4f3af475
commit 84eaf4ad7d
7 changed files with 158 additions and 19 deletions

View file

@ -536,12 +536,13 @@ final class PGPAgentLowLevelTests: XCTestCase {
_ = try agent.encrypt(plainData: testDecryptedData, keyID: shortID)
XCTAssertEqual(mockPGP.containsPublicKeyCalls, [shortID])
XCTAssertEqual(mockPGP.encryptCalls[0].keyID, shortID)
XCTAssertEqual(mockPGP.encryptMultiKeyCalls.count, 1)
XCTAssertEqual(mockPGP.encryptMultiKeyCalls[0].keyIDs, [shortID])
}
// MARK: - Encrypt passthrough tests (for completeness of mock interaction)
/// encrypt(plainData:keyID:) calls containsPublicKey and passes data through.
/// encrypt(plainData:keyID:) calls containsPublicKey and passes data through via encrypt(plainData:keyIDs:).
func testEncryptWithKeyID_keyFound_callsInterface() throws {
let longFingerprint = "4712286271220db299883ea7062e678da1024dae"
mockPGP.publicKeyIDs = [longFingerprint]
@ -549,9 +550,9 @@ final class PGPAgentLowLevelTests: XCTestCase {
let result = try agent.encrypt(plainData: testDecryptedData, keyID: longFingerprint)
XCTAssertEqual(result, mockPGP.encryptResult)
XCTAssertEqual(mockPGP.encryptCalls.count, 1)
XCTAssertEqual(mockPGP.encryptCalls[0].keyID, longFingerprint)
XCTAssertEqual(mockPGP.encryptCalls[0].plainData, testDecryptedData)
XCTAssertEqual(mockPGP.encryptMultiKeyCalls.count, 1)
XCTAssertEqual(mockPGP.encryptMultiKeyCalls[0].keyIDs, [longFingerprint])
XCTAssertEqual(mockPGP.encryptMultiKeyCalls[0].plainData, testDecryptedData)
}
/// encrypt with unknown key and single available key falls back.
@ -565,7 +566,7 @@ final class PGPAgentLowLevelTests: XCTestCase {
XCTAssertEqual(result, mockPGP.encryptResult)
XCTAssertEqual(mockPGP.containsPublicKeyCalls, [shortID])
XCTAssertEqual(mockPGP.encryptCalls[0].keyID, longFingerprint)
XCTAssertEqual(mockPGP.encryptMultiKeyCalls[0].keyIDs, [longFingerprint])
}
/// encrypt with unknown key and multiple keys throws.
@ -576,10 +577,10 @@ final class PGPAgentLowLevelTests: XCTestCase {
XCTAssertThrowsError(try agent.encrypt(plainData: testDecryptedData, keyID: "a1024dae")) { error in
XCTAssertEqual(error as? AppError, AppError.pgpPublicKeyNotFound(keyID: "a1024dae"))
}
XCTAssertEqual(mockPGP.encryptCalls.count, 0)
XCTAssertEqual(mockPGP.encryptMultiKeyCalls.count, 0)
}
/// encrypt(plainData:) without keyID passes nil to interface.
/// encrypt(plainData:) without keyID passes nil to the deprecated interface method.
func testEncryptNoKeyID_passesNilToInterface() throws {
let result = try agent.encrypt(plainData: testDecryptedData)
@ -599,4 +600,39 @@ final class PGPAgentLowLevelTests: XCTestCase {
XCTAssertEqual(error as? AppError, AppError.encryption)
}
}
// MARK: - encryptWithAllKeys
/// encryptWithAllKeys delegates to pgpInterface.encryptWithAllKeys.
func testEncryptWithAllKeys_callsInterface() throws {
mockPGP.encryptResult = Data("all-keys-encrypted".utf8)
let result = try agent.encryptWithAllKeys(plainData: testDecryptedData)
XCTAssertEqual(result, Data("all-keys-encrypted".utf8))
XCTAssertEqual(mockPGP.encryptWithAllKeysCalls.count, 1)
XCTAssertEqual(mockPGP.encryptWithAllKeysCalls[0].plainData, testDecryptedData)
// Does not call containsPublicKey or the single/multi-key encrypt methods.
XCTAssertEqual(mockPGP.containsPublicKeyCalls.count, 0)
XCTAssertEqual(mockPGP.encryptCalls.count, 0)
XCTAssertEqual(mockPGP.encryptMultiKeyCalls.count, 0)
}
/// encryptWithAllKeys propagates errors from interface.
func testEncryptWithAllKeys_interfaceThrows_propagatesError() {
mockPGP.encryptError = AppError.encryption
XCTAssertThrowsError(try agent.encryptWithAllKeys(plainData: testDecryptedData)) { error in
XCTAssertEqual(error as? AppError, AppError.encryption)
}
}
/// encryptWithAllKeys throws encryption error when pgpInterface is nil (checkAndInit fails).
func testEncryptWithAllKeys_checkAndInit_requiresPGPKeyPassphraseInKeystore() throws {
keychain.removeContent(for: Globals.pgpKeyPassphrase)
XCTAssertThrowsError(try agent.encryptWithAllKeys(plainData: testDecryptedData)) { error in
XCTAssertEqual(error as? AppError, AppError.keyImport)
}
}
}