Skip to content

Commit

Permalink
#250 Integration Tests: Re-enable session propose-approve test case (#…
Browse files Browse the repository at this point in the history
…268)

* Enabled session approve test, failing

* Workaround fix test

* Refactor working session approve test

* Renamed test to SignClientTests

* Removed controller flag from tests

Co-authored-by: André Vants
  • Loading branch information
André Vants authored and llbartekll committed Jul 5, 2022
1 parent 147e100 commit 4b5f6dc
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 86 deletions.
4 changes: 3 additions & 1 deletion Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ private extension ApproveEngine {
)
settlingProposal = proposal

Task { try? await networkingInteractor.subscribe(topic: sessionTopic) }
Task(priority: .background) {
try? await networkingInteractor.subscribe(topic: sessionTopic)
}
}
catch {
guard let error = error as? JSONRPCErrorResponse else {
Expand Down
4 changes: 2 additions & 2 deletions Sources/WalletConnectSign/Namespace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public struct ProposalNamespace: Equatable, Codable {
}
}

public init(chains: Set<Blockchain>, methods: Set<String>, events: Set<String>, extensions: [ProposalNamespace.Extension]?) {
public init(chains: Set<Blockchain>, methods: Set<String>, events: Set<String>, extensions: [ProposalNamespace.Extension]? = nil) {
self.chains = chains
self.methods = methods
self.events = events
Expand All @@ -46,7 +46,7 @@ public struct SessionNamespace: Equatable, Codable {
}
}

public init(accounts: Set<Account>, methods: Set<String>, events: Set<String>, extensions: [SessionNamespace.Extension]?) {
public init(accounts: Set<Account>, methods: Set<String>, events: Set<String>, extensions: [SessionNamespace.Extension]? = nil) {
self.accounts = accounts
self.methods = methods
self.events = events
Expand Down
4 changes: 3 additions & 1 deletion Sources/WalletConnectSign/Sign/SignClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ import UIKit
/// - delegate: The object that acts as the delegate of WalletConnect Client
/// - logger: An object for logging messages
public final class SignClient {

public weak var delegate: SignClientDelegate?

public let logger: ConsoleLogging
private var publishers = [AnyCancellable]()
private let metadata: AppMetadata
private let pairingEngine: PairingEngine
private let pairEngine: PairEngine
Expand All @@ -35,6 +36,7 @@ public final class SignClient {
private let kms: KeyManagementService
private let history: JsonRpcHistory
private let cleanupService: CleanupService
private var publishers = [AnyCancellable]()

// MARK: - Initializers

Expand Down
1 change: 0 additions & 1 deletion Sources/WalletConnectUtils/KeyValueStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public protocol KeyValueStorage {

extension UserDefaults: KeyValueStorage {}

// TODO: Move to test target
public final class RuntimeKeyValueStorage: KeyValueStorage {
private var storage: [String : Any] = [:]
private let queue = DispatchQueue(label: "com.walletconnect.sdk.runtimestorage")
Expand Down
24 changes: 24 additions & 0 deletions Tests/IntegrationTests/Helpers/Stubs.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import WalletConnectSign

extension ProposalNamespace {
static func stubRequired() -> [String: ProposalNamespace] {
return [
"eip155": ProposalNamespace(
chains: [Blockchain("eip155:1")!],
methods: ["personal_sign"],
events: [])
]
}
}

extension SessionNamespace {
static func make(toRespond namespaces: [String: ProposalNamespace]) -> [String: SessionNamespace] {
return namespaces.mapValues { proposalNamespace in
SessionNamespace(
accounts: Set(proposalNamespace.chains.map { Account(blockchain: $0, address: "0x00")! }),
methods: proposalNamespace.methods,
events: proposalNamespace.events
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,52 +1,81 @@
//
//import Foundation
//import XCTest
//import WalletConnectUtils
//import TestingUtils
//@testable import WalletConnectSign
//@testable import WalletConnectKMS
//
//
//final class ClientTests: XCTestCase {
//
// let defaultTimeout: TimeInterval = 5.0
//
// let relayHost = "relay.walletconnect.com"
// let projectId = "8ba9ee138960775e5231b70cc5ef1c3a"
// var proposer: ClientDelegate!
// var responder: ClientDelegate!
//
// override func setUp() {
// proposer = Self.makeClientDelegate(isController: false, relayHost: relayHost, prefix: "🍏P", projectId: projectId)
// responder = Self.makeClientDelegate(isController: true, relayHost: relayHost, prefix: "🍎R", projectId: projectId)
// }
//
// static func makeClientDelegate(isController: Bool, relayHost: String, prefix: String, projectId: String) -> ClientDelegate {
// let logger = ConsoleLogger(suffix: prefix, loggingLevel: .debug)
// let keychain = KeychainStorage(keychainService: KeychainServiceFake(), serviceIdentifier: "")
// let client = SignClient(
// metadata: AppMetadata(name: prefix, description: "", url: "", icons: [""]),
// projectId: projectId,
// relayHost: relayHost,
// logger: logger,
// kms: KeyManagementService(keychain: keychain),
// keyValueStorage: RuntimeKeyValueStorage())
// return ClientDelegate(client: client)
// }
//
// private func waitClientsConnected() async {
// let group = DispatchGroup()
// group.enter()
// proposer.onConnected = {
// group.leave()
// }
// group.enter()
// responder.onConnected = {
// group.leave()
// }
// group.wait()
// return
// }
import XCTest
import WalletConnectUtils
import TestingUtils
@testable import WalletConnectKMS
@testable import WalletConnectSign

final class SignClientTests: XCTestCase {

let defaultTimeout: TimeInterval = 5.0

var proposer: ClientDelegate!
var responder: ClientDelegate!

static private func makeClientDelegate(
name: String,
relayHost: String = "relay.walletconnect.com",
projectId: String = "8ba9ee138960775e5231b70cc5ef1c3a"
) -> ClientDelegate {
let logger = ConsoleLogger(suffix: name, loggingLevel: .debug)
let keychain = KeychainStorage(keychainService: KeychainServiceFake(), serviceIdentifier: "")
let client = SignClient(
metadata: AppMetadata(name: name, description: "", url: "", icons: [""]),
projectId: projectId,
relayHost: relayHost,
logger: logger,
kms: KeyManagementService(keychain: keychain),
keyValueStorage: RuntimeKeyValueStorage())
return ClientDelegate(client: client)
}

private func listenForConnection() async {
let group = DispatchGroup()
group.enter()
proposer.onConnected = {
group.leave()
}
group.enter()
responder.onConnected = {
group.leave()
}
group.wait()
return
}

override func setUp() async throws {
proposer = Self.makeClientDelegate(name: "🍏P")
responder = Self.makeClientDelegate(name: "🍎R")
await listenForConnection()
}

override func tearDown() {
proposer = nil
responder = nil
}

func testSessionPropose() async throws {
let dapp = proposer!
let wallet = responder!
let dappSettlementExpectation = expectation(description: "Dapp expects to settle a session")
let walletSettlementExpectation = expectation(description: "Wallet expects to settle a session")
let requiredNamespaces = ProposalNamespace.stubRequired()
let sessionNamespaces = SessionNamespace.make(toRespond: requiredNamespaces)

wallet.onSessionProposal = { proposal in
do { try wallet.client.approve(proposalId: proposal.id, namespaces: sessionNamespaces) }
catch { XCTFail("\(error)") }
}
dapp.onSessionSettled = { _ in
dappSettlementExpectation.fulfill()
}
wallet.onSessionSettled = { _ in
walletSettlementExpectation.fulfill()
}

let uri = try await dapp.client.connect(requiredNamespaces: requiredNamespaces)
try await wallet.client.pair(uri: uri!)
wait(for: [dappSettlementExpectation, walletSettlementExpectation], timeout: defaultTimeout)
}
//
// func testNewPairingPing() async {
// let responderReceivesPingResponseExpectation = expectation(description: "Responder receives ping response")
Expand All @@ -63,29 +92,6 @@
// wait(for: [responderReceivesPingResponseExpectation], timeout: defaultTimeout)
// }
//
// func testNewSession() async {
// await waitClientsConnected()
// let proposerSettlesSessionExpectation = expectation(description: "Proposer settles session")
// let responderSettlesSessionExpectation = expectation(description: "Responder settles session")
// let account = Account("eip155:1:0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb")!
//
// let uri = try! await proposer.client.connect(namespaces: [Namespace.stub()])!
// try! await responder.client.pair(uri: uri)
// responder.onSessionProposal = { [unowned self] proposal in
// try? self.responder.client.approve(proposalId: proposal.id, accounts: [account], namespaces: [])
// }
// responder.onSessionSettled = { sessionSettled in
// // FIXME: Commented assertion
//// XCTAssertEqual(account, sessionSettled.state.accounts[0])
// responderSettlesSessionExpectation.fulfill()
// }
// proposer.onSessionSettled = { sessionSettled in
// // FIXME: Commented assertion
//// XCTAssertEqual(account, sessionSettled.state.accounts[0])
// proposerSettlesSessionExpectation.fulfill()
// }
// wait(for: [proposerSettlesSessionExpectation, responderSettlesSessionExpectation], timeout: defaultTimeout)
// }
//
// func testNewSessionOnExistingPairing() async {
// await waitClientsConnected()
Expand Down Expand Up @@ -332,8 +338,8 @@
// }
// wait(for: [proposerReceivesEventExpectation], timeout: defaultTimeout)
// }
//}
//
}

//public struct EthSendTransaction: Codable, Equatable {
// public let from: String
// public let data: String
Expand All @@ -356,8 +362,4 @@
// }
//"""
//
//extension Namespace {
// static func stub(methods: Set<String> = ["method"]) -> Namespace {
// Namespace(chains: [Blockchain("eip155:1")!], methods: methods, events: ["event"])
// }
//}

7 changes: 5 additions & 2 deletions Tests/TestingUtils/Mocks/KeychainServiceFake.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import Foundation
@testable import WalletConnectKMS

// This file is a copy from the one in unit tests target, would be nice to figure out a way to share it between targets.
final public class KeychainServiceFake: KeychainServiceProtocol {

var errorStatus: OSStatus?

private var storage: [String: Data] = [:]
private var storage: [String: Data]

public init() {
self.storage = [:]
}

public func add(_ attributes: CFDictionary, _ result: UnsafeMutablePointer<CFTypeRef?>?) -> OSStatus {
if let forceError = errorStatus {
Expand Down

0 comments on commit 4b5f6dc

Please sign in to comment.