Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Threema/Keychain/Tests/Helper/   (Social Medium ©)  Datei vom 26.9.2026 mit Größe 6 kB image not shown  

Quelle  KeychainProviderMock.swift   Sprache: JAVA

 

import Foundation
import ThreemaEssentials
@testable import Keychain

// MARK: - KeychainItem + Hashable

extension KeychainItem: Hashable {
    public func hash(into hasher: inout Hasher) {
        hasher.combine(label)
        hasher.combine(accessibility as String)
    }
    
    public static func == (lhs: KeychainItem, rhs: KeychainItem) -> Bool {
        lhs.label == rhs.label && lhs.accessibility as String == rhs.accessibility as String
    }
}

final class KeychainProviderMock: KeychainProviding, @unchecked Sendable {
    
    enum ErrorType {
        case loadError(Error)
        case storeError(Error)
        case deleteError(Error)
    }
    
    struct LoadOperation: Hashable, Sendable {
        let searchItem: KeychainItem?
        let searchAccount: String?
        
        init(searchItem: KeychainItem?, searchAccount: String? = nil) {
            self.searchItem = searchItem
            self.searchAccount = searchAccount
        }
    }
    
    struct StoreOperation: Hashable, Sendable {
        let searchItem: KeychainItem?
        let searchAccount: String?
        let item: KeychainItem
        let account: String?
        let password: Data?
        let generic: Data?
        let service: String?
        
        init(
            searchItem: KeychainItem?,
            searchAccount: String?,
            item: KeychainItem,
            account: String?,
            password: Data?,
            generic: Data?,
            service: String?
        ) {
            self.searchItem = searchItem
            self.searchAccount = searchAccount
            self.item = item
            self.account = account
            self.password = password
            self.generic = generic
            self.service = service
        }
    }
    
    enum OperationType: Hashable, Sendable {
        case load(LoadOperation)
        case store(StoreOperation)
        case delete(KeychainItem)
        
        static func == (lhs: OperationType, rhs: OperationType) -> Bool {
            switch (lhs, rhs) {
            case let (.load(lhsOperation), .load(rhsOperation)):
                lhsOperation == rhsOperation
            case let (.store(lhsOperation), .store(rhsOperation)):
                lhsOperation == rhsOperation
            case let (.delete(lhsItem), .delete(rhsItem)):
                lhsItem == rhsItem
            default:
                false
            }
        }
        
        func hash(into hasher: inout Hasher) {
            switch self {
            case let .load(operation):
                hasher.combine("load")
                hasher.combine(operation)
            case let .store(operation):
                hasher.combine("store")
                hasher.combine(operation)
            case let .delete(item):
                hasher.combine("delete")
                hasher.combine(item)
            }
        }
        
        var isLoading: Bool {
            if case .load = self {
                true
            }
            else {
                false
            }
        }
        
        var isStoring: Bool {
            if case .store = self {
                true
            }
            else {
                false
            }
        }
        
        var isDeleting: Bool {
            if case .delete = self {
                true
            }
            else {
                false
            }
        }
    }
    
    @Atomic
    private(set) var loadError: Error?
    
    @Atomic
    private(set) var storeError: Error?
    
    @Atomic
    private(set) var deleteError: Error?
    
    @Atomic
    private(set) var calls = [OperationType]()

    // Key is the lable of the keychain item
    @Atomic
    private var storage = [String: KeychainItemData]()

    var loadCalls: [LoadOperation] {
        calls.compactMap { operation in
            if case let .load(loadOperation) = operation {
                return loadOperation
            }
            return nil
        }
    }
    
    var storeCalls: [StoreOperation] {
        calls.compactMap { operation in
            if case let .store(storeOperation) = operation {
                return storeOperation
            }
            return nil
        }
    }
    
    var deleteCalls: [KeychainItem] {
        calls.compactMap { operation in
            if case let .delete(item) = operation {
                return item
            }
            return nil
        }
    }
    
    func load(
        _ searchItem: KeychainItem?,
        searchAccount: String?
    ) throws -> KeychainItemData? {
        let operation = LoadOperation(searchItem: searchItem, searchAccount: searchAccount)
        $calls.append(.load(operation))
        
        if let error = loadError {
            throw error
        }
        
        let keychainItemData = storedData(for: searchItem)
        
        return keychainItemData
    }
    
    func store(
        searchItem: KeychainItem?,
        searchAccount: String?,
        _ item: KeychainItem,
        account: String?,
        password: Data?,
        generic: Data?,
        service: String?
    ) throws {
        let operation = StoreOperation(
            searchItem: searchItem,
            searchAccount: searchAccount,
            item: item,
            account: account,
            password: password,
            generic: generic,
            service: service
        )
        $calls.append(.store(operation))
        
        if let error = storeError {
            throw error
        }
        
        let data = KeychainItemData(
            accessibility: item.accessibility,
            label: item.label,
            account: account,
            password: password,
            generic: generic,
            service: service
        )
        $storage.set(searchItem?.label ?? item.label, data)
    }
    
    func delete(_ searchItem: Keychain.KeychainItem) throws {
        $calls.append(.delete(searchItem))
        
        if let error = deleteError {
            throw error
        }
        
        $storage.removeValue(forKey: searchItem.label)
    }
    
    /// Clear all stored data and call history
    func reset() {
        $storage.removeAll()
        $calls.removeAll()
        loadError = nil
        storeError = nil
        deleteError = nil
    }
    
    func storedData(for item: Keychain.KeychainItem?) -> KeychainItemData? {
        guard let item else {
            return nil
        }

        return storage[item.label]
    }
    
    func updateError(_ errorType: KeychainProviderMock.ErrorType) {
        switch errorType {
        case let .loadError(error):
            loadError = error
        case let .storeError(error):
            storeError = error
        case let .deleteError(error):
            deleteError = error
        }
    }
}

Messung
CHZG
839610093

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.