diff --git a/Sources/ConnectAccounts/APIKeyController.swift b/Sources/ConnectAccounts/APIKeyController.swift index 8fc725a..ab33f79 100644 --- a/Sources/ConnectAccounts/APIKeyController.swift +++ b/Sources/ConnectAccounts/APIKeyController.swift @@ -9,6 +9,10 @@ public class APIKeyController { /// The list of API keys. public private(set) var apiKeys: [APIKey]? /// The currently selected API key. + /// + /// Deprecated: The concept of a "selected API key" will be removed in a future version. + /// Persist and manage selection state outside of APIKeyController. + @available(*, deprecated, message: "The concept of a selected API key is deprecated and will be removed in a future version. Persist and manage selection outside of APIKeyController.") public var selectedAPIKey: APIKey? { didSet { if let selectedAPIKey { @@ -38,6 +42,9 @@ public class APIKeyController { } /// Loads the API keys from the keychain. + /// + /// Note: This method currently auto-selects an API key if one is available (matching the persisted selection, or the first key). + /// The auto-selection side effect is deprecated and will be removed in a future version. Do not rely on it. public func loadAPIKeys() throws { let apiKeys = try keychain.listGenericPasswords(forService: service) .map { password -> APIKey in @@ -56,8 +63,14 @@ public class APIKeyController { Adds a new API key to the keychain. - Parameter apiKey: The API key to add. + + Note: This method currently auto-selects the key if it is the first one added. + The auto-selection side effect is deprecated and will be removed in a future version. Do not rely on it. */ public func addAPIKey(_ apiKey: APIKey) throws { + if apiKeys == nil { + try loadAPIKeys() + } do { try keychain.addGenericPassword(forService: service, password: apiKey.getGenericPassword()) } catch KeychainError.duplicatePassword { @@ -79,6 +92,9 @@ public class APIKeyController { - Parameter apiKey: The API key to delete. */ public func deleteAPIKey(_ apiKey: APIKey) throws { + if apiKeys == nil { + try loadAPIKeys() + } try keychain.deleteGenericPassword(forService: service, password: apiKey.getGenericPassword()) guard var apiKeys, let index = apiKeys.firstIndex(where: { $0.keyId == apiKey.keyId }) else { return diff --git a/Tests/ConnectAccountsTests/AddAPIKeyTests.swift b/Tests/ConnectAccountsTests/AddAPIKeyTests.swift index 5ff3ecb..5e4ca70 100644 --- a/Tests/ConnectAccountsTests/AddAPIKeyTests.swift +++ b/Tests/ConnectAccountsTests/AddAPIKeyTests.swift @@ -20,29 +20,27 @@ struct AddAPIKeyTests { let mockKeychain = MockKeychain() let controller = APIKeyController(keychainServiceName: "AppStoreConnectKit", keychain: mockKeychain) #expect(controller.apiKeys == nil) - #expect(controller.selectedAPIKey == nil) #expect(mockKeychain.genericPasswordsInKeychain.isEmpty) // Act try controller.addAPIKey(apiKey) // Assert #expect(controller.apiKeys == [apiKey]) - #expect(controller.selectedAPIKey == apiKey) #expect(try mockKeychain.genericPasswordsInKeychain == [apiKey.getGenericPassword()]) } @Test("Add API Key - Duplicate error") - func addAPIKey_Duplicate() { + func addAPIKey_Duplicate() throws { // Arrange let mockKeychain = MockKeychain() - mockKeychain.returnStatusForAdd = errSecDuplicateItem let controller = APIKeyController(keychainServiceName: "AppStoreConnectKit", keychain: mockKeychain) + try controller.addAPIKey(apiKey) + #expect(controller.apiKeys == [apiKey]) // Act #expect(throws: APIKeyError.duplicateAPIKey) { try controller.addAPIKey(apiKey) } // Assert - #expect(controller.apiKeys == nil) - #expect(controller.selectedAPIKey == nil) + #expect(controller.apiKeys == [apiKey]) } @Test("Add API Key - Unknown error") @@ -52,12 +50,12 @@ struct AddAPIKeyTests { let mockKeychain = MockKeychain() mockKeychain.returnStatusForAdd = status let controller = APIKeyController(keychainServiceName: "AppStoreConnectKit", keychain: mockKeychain) + #expect(controller.apiKeys == nil) // Act #expect(throws: APIKeyError.failedAddingAPIKey(status)) { try controller.addAPIKey(apiKey) } // Assert - #expect(controller.apiKeys == nil) - #expect(controller.selectedAPIKey == nil) + #expect(controller.apiKeys == []) } }