Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tests] #250 Session Request integration tests re-enabled #398

Merged
merged 6 commits into from
Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion Example/ExampleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
765056272821989600F9AE79 /* Color+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765056262821989600F9AE79 /* Color+Extension.swift */; };
76744CF726FE4D5400B77ED9 /* ActiveSessionItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76744CF626FE4D5400B77ED9 /* ActiveSessionItem.swift */; };
76744CF926FE4D7400B77ED9 /* ActiveSessionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76744CF826FE4D7400B77ED9 /* ActiveSessionCell.swift */; };
767DC83528997F8E00080FA9 /* EthSendTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 767DC83428997F8E00080FA9 /* EthSendTransaction.swift */; };
7694A5262874296A0001257E /* RegistryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7694A5252874296A0001257E /* RegistryTests.swift */; };
76B149F02821C03B00F05F91 /* Proposal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76B149EF2821C03B00F05F91 /* Proposal.swift */; };
76B6E39F2807A3B6004DF775 /* WalletViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76B6E39E2807A3B6004DF775 /* WalletViewController.swift */; };
Expand Down Expand Up @@ -182,6 +183,7 @@
765056262821989600F9AE79 /* Color+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extension.swift"; sourceTree = "<group>"; };
76744CF626FE4D5400B77ED9 /* ActiveSessionItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSessionItem.swift; sourceTree = "<group>"; };
76744CF826FE4D7400B77ED9 /* ActiveSessionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSessionCell.swift; sourceTree = "<group>"; };
767DC83428997F8E00080FA9 /* EthSendTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthSendTransaction.swift; sourceTree = "<group>"; };
7694A5252874296A0001257E /* RegistryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistryTests.swift; sourceTree = "<group>"; };
76B149EF2821C03B00F05F91 /* Proposal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Proposal.swift; sourceTree = "<group>"; };
76B6E39E2807A3B6004DF775 /* WalletViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -436,6 +438,15 @@
name = Frameworks;
sourceTree = "<group>";
};
767DC83328997F7600080FA9 /* Helpers */ = {
isa = PBXGroup;
children = (
A5E03DF8286465C700888481 /* ClientDelegate.swift */,
767DC83428997F8E00080FA9 /* EthSendTransaction.swift */,
);
path = Helpers;
sourceTree = "<group>";
};
8460DCFD274F98A90081F94C /* Request */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -862,7 +873,7 @@
A5E03E0928646A8100888481 /* Sign */ = {
isa = PBXGroup;
children = (
A5E03DF8286465C700888481 /* ClientDelegate.swift */,
767DC83328997F7600080FA9 /* Helpers */,
A5E03DF9286465C700888481 /* SignClientTests.swift */,
);
path = Sign;
Expand Down Expand Up @@ -1248,6 +1259,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
767DC83528997F8E00080FA9 /* EthSendTransaction.swift in Sources */,
A5E03DFB286465C700888481 /* ClientDelegate.swift in Sources */,
A5E03E03286466F400888481 /* ChatTests.swift in Sources */,
7694A5262874296A0001257E /* RegistryTests.swift in Sources */,
Expand Down
26 changes: 26 additions & 0 deletions Example/IntegrationTests/Sign/Helpers/EthSendTransaction.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Foundation

struct EthSendTransaction: Codable, Equatable {
let from: String
let data: String
let value: String
let to: String
let gasPrice: String
let nonce: String

static func stub() -> EthSendTransaction {
try! JSONDecoder().decode(EthSendTransaction.self, from: ethSendTransactionJSON.data(using: .utf8)!)
}

private static let ethSendTransactionJSON = """
{
"from":"0xb60e8dd61c5d32be8058bb8eb970870f07233155",
"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"data":"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675",
"gas":"0x76c0",
"gasPrice":"0x9184e72a000",
"value":"0x9184e72a",
"nonce":"0x117"
}
"""
}
230 changes: 110 additions & 120 deletions Example/IntegrationTests/Sign/SignClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ final class SignClientTests: XCTestCase {

let defaultTimeout: TimeInterval = 5

var proposer: ClientDelegate!
var responder: ClientDelegate!
var dapp: ClientDelegate!
var wallet: ClientDelegate!

static private func makeClientDelegate(
name: String,
Expand Down Expand Up @@ -40,39 +40,41 @@ final class SignClientTests: XCTestCase {
private func listenForConnection() async {
let group = DispatchGroup()
group.enter()
proposer.onConnected = {
dapp.onConnected = {
group.leave()
}
group.enter()
responder.onConnected = {
wallet.onConnected = {
group.leave()
}
group.wait()
return
}

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

override func tearDown() {
proposer = nil
responder = nil
dapp = nil
wallet = 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
wallet.onSessionProposal = { [unowned self] proposal in
Task(priority: .high) {
do { try await wallet.client.approve(proposalId: proposal.id, namespaces: sessionNamespaces) } catch { XCTFail("\(error)") }
do {
try await wallet.client.approve(proposalId: proposal.id, namespaces: sessionNamespaces)
} catch {
XCTFail("\(error)")
}
}
}
dapp.onSessionSettled = { _ in
Expand All @@ -88,8 +90,6 @@ final class SignClientTests: XCTestCase {
}

func testSessionReject() async throws {
let dapp = proposer!
let wallet = responder!
let sessionRejectExpectation = expectation(description: "Proposer is notified on session rejection")

class Store { var rejectedProposal: Session.Proposal? }
Expand All @@ -98,7 +98,7 @@ final class SignClientTests: XCTestCase {
let uri = try await dapp.client.connect(requiredNamespaces: ProposalNamespace.stubRequired())
try await wallet.client.pair(uri: uri!)

wallet.onSessionProposal = { proposal in
wallet.onSessionProposal = { [unowned self] proposal in
Task(priority: .high) {
do {
try await wallet.client.reject(proposalId: proposal.id, reason: .disapprovedChains) // TODO: Review reason
Expand All @@ -114,18 +114,16 @@ final class SignClientTests: XCTestCase {
}

func testSessionDelete() async throws {
let dapp = proposer!
let wallet = responder!
let sessionDeleteExpectation = expectation(description: "Wallet expects session to be deleted")
let requiredNamespaces = ProposalNamespace.stubRequired()
let sessionNamespaces = SessionNamespace.make(toRespond: requiredNamespaces)

wallet.onSessionProposal = { proposal in
wallet.onSessionProposal = { [unowned self] proposal in
Task(priority: .high) {
do { try await wallet.client.approve(proposalId: proposal.id, namespaces: sessionNamespaces) } catch { XCTFail("\(error)") }
}
}
dapp.onSessionSettled = { settledSession in
dapp.onSessionSettled = { [unowned self] settledSession in
Task(priority: .high) {
try await dapp.client.disconnect(topic: settledSession.topic)
}
Expand All @@ -140,8 +138,6 @@ final class SignClientTests: XCTestCase {
}

func testNewPairingPing() async throws {
let dapp = proposer!
let wallet = responder!
let pongResponseExpectation = expectation(description: "Ping sender receives a pong response")

let uri = try await dapp.client.connect(requiredNamespaces: ProposalNamespace.stubRequired())!
Expand All @@ -155,6 +151,99 @@ final class SignClientTests: XCTestCase {
wait(for: [pongResponseExpectation], timeout: defaultTimeout)
}

func testSessionRequest() async throws {
let requestExpectation = expectation(description: "Wallet expects to receive a request")
let responseExpectation = expectation(description: "Dapp expects to receive a response")
let requiredNamespaces = ProposalNamespace.stubRequired()
let sessionNamespaces = SessionNamespace.make(toRespond: requiredNamespaces)

let requestMethod = "eth_sendTransaction"
let requestParams = [EthSendTransaction.stub()]
let responseParams = "0xdeadbeef"
let chain = Blockchain("eip155:1")!

wallet.onSessionProposal = { [unowned self] proposal in
Task(priority: .high) {
do {
try await wallet.client.approve(proposalId: proposal.id, namespaces: sessionNamespaces) }
catch {
XCTFail("\(error)")
}
}
}
dapp.onSessionSettled = { [unowned self] settledSession in
Task(priority: .high) {
let request = Request(id: 0, topic: settledSession.topic, method: requestMethod, params: requestParams, chainId: chain)
try await dapp.client.request(params: request)
}
}
wallet.onSessionRequest = { [unowned self] sessionRequest in
let receivedParams = try! sessionRequest.params.get([EthSendTransaction].self)
XCTAssertEqual(receivedParams, requestParams)
XCTAssertEqual(sessionRequest.method, requestMethod)
requestExpectation.fulfill()
Task(priority: .high) {
let jsonrpcResponse = JSONRPCResponse<AnyCodable>(id: sessionRequest.id, result: AnyCodable(responseParams))
try await wallet.client.respond(topic: sessionRequest.topic, response: .response(jsonrpcResponse))
}
}
dapp.onSessionResponse = { response in
switch response.result {
case .response(let response):
XCTAssertEqual(try! response.result.get(String.self), responseParams)
case .error:
XCTFail()
}
responseExpectation.fulfill()
}

let uri = try await dapp.client.connect(requiredNamespaces: requiredNamespaces)
try await wallet.client.pair(uri: uri!)
wait(for: [requestExpectation, responseExpectation], timeout: defaultTimeout)
}

func testSessionRequestFailureResponse() async throws {
let expectation = expectation(description: "Dapp expects to receive an error response")
let requiredNamespaces = ProposalNamespace.stubRequired()
let sessionNamespaces = SessionNamespace.make(toRespond: requiredNamespaces)

let requestMethod = "eth_sendTransaction"
let requestParams = [EthSendTransaction.stub()]
let error = JSONRPCErrorResponse.Error(code: 0, message: "error")
let chain = Blockchain("eip155:1")!

wallet.onSessionProposal = { [unowned self] proposal in
Task(priority: .high) {
try await wallet.client.approve(proposalId: proposal.id, namespaces: sessionNamespaces)
}
}
dapp.onSessionSettled = { [unowned self] settledSession in
Task(priority: .high) {
let request = Request(id: 0, topic: settledSession.topic, method: requestMethod, params: requestParams, chainId: chain)
try await dapp.client.request(params: request)
}
}
wallet.onSessionRequest = { [unowned self] sessionRequest in
Task(priority: .high) {
let response = JSONRPCErrorResponse(id: sessionRequest.id, error: error)
try await wallet.client.respond(topic: sessionRequest.topic, response: .error(response))
}
}
dapp.onSessionResponse = { response in
switch response.result {
case .response:
XCTFail()
case .error(let errorResponse):
XCTAssertEqual(error, errorResponse.error)
}
expectation.fulfill()
}

let uri = try await dapp.client.connect(requiredNamespaces: requiredNamespaces)
try await wallet.client.pair(uri: uri!)
wait(for: [expectation], timeout: defaultTimeout)
}

//
// func testNewSessionOnExistingPairing() async {
// await waitClientsConnected()
Expand Down Expand Up @@ -186,82 +275,6 @@ final class SignClientTests: XCTestCase {
// wait(for: [proposerSettlesSessionExpectation, responderSettlesSessionExpectation], timeout: defaultTimeout)
// }
//
//
// func testProposerRequestSessionRequest() async {
// await waitClientsConnected()
// let requestExpectation = expectation(description: "Responder receives request")
// let responseExpectation = expectation(description: "Proposer receives response")
// let method = "eth_sendTransaction"
// let params = [try! JSONDecoder().decode(EthSendTransaction.self, from: ethSendTransaction.data(using: .utf8)!)]
// let responseParams = "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c"
// let uri = try! await proposer.client.connect(namespaces: [Namespace.stub(methods: [method])])!
//
// _ = try! await responder.client.pair(uri: uri)
// responder.onSessionProposal = {[unowned self] proposal in
// try? self.responder.client.approve(proposalId: proposal.id, accounts: [], namespaces: proposal.namespaces)
// }
// proposer.onSessionSettled = {[unowned self] settledSession in
// let requestParams = Request(id: 0, topic: settledSession.topic, method: method, params: AnyCodable(params), chainId: Blockchain("eip155:1")!)
// Task {
// try await self.proposer.client.request(params: requestParams)
// }
// }
// proposer.onSessionResponse = { response in
// switch response.result {
// case .response(let jsonRpcResponse):
// let response = try! jsonRpcResponse.result.get(String.self)
// XCTAssertEqual(response, responseParams)
// responseExpectation.fulfill()
// case .error(_):
// XCTFail()
// }
// }
// responder.onSessionRequest = {[unowned self] sessionRequest in
// XCTAssertEqual(sessionRequest.method, method)
// let ethSendTrancastionParams = try! sessionRequest.params.get([EthSendTransaction].self)
// XCTAssertEqual(ethSendTrancastionParams, params)
// let jsonrpcResponse = JSONRPCResponse<AnyCodable>(id: sessionRequest.id, result: AnyCodable(responseParams))
// self.responder.client.respond(topic: sessionRequest.topic, response: .response(jsonrpcResponse))
// requestExpectation.fulfill()
// }
// wait(for: [requestExpectation, responseExpectation], timeout: defaultTimeout)
// }
//
//
// func testSessionRequestFailureResponse() async {
// await waitClientsConnected()
// let failureResponseExpectation = expectation(description: "Proposer receives failure response")
// let method = "eth_sendTransaction"
// let params = [try! JSONDecoder().decode(EthSendTransaction.self, from: ethSendTransaction.data(using: .utf8)!)]
// let error = JSONRPCErrorResponse.Error(code: 0, message: "error_message")
// let uri = try! await proposer.client.connect(namespaces: [Namespace.stub(methods: [method])])!
// _ = try! await responder.client.pair(uri: uri)
// responder.onSessionProposal = {[unowned self] proposal in
// try? self.responder.client.approve(proposalId: proposal.id, accounts: [], namespaces: proposal.namespaces)
// }
// proposer.onSessionSettled = {[unowned self] settledSession in
// let requestParams = Request(id: 0, topic: settledSession.topic, method: method, params: AnyCodable(params), chainId: Blockchain("eip155:1")!)
// Task {
// try await self.proposer.client.request(params: requestParams)
// }
// }
// proposer.onSessionResponse = { response in
// switch response.result {
// case .response(_):
// XCTFail()
// case .error(let errorResponse):
// XCTAssertEqual(error, errorResponse.error)
// failureResponseExpectation.fulfill()
// }
//
// }
// responder.onSessionRequest = {[unowned self] sessionRequest in
// let jsonrpcErrorResponse = JSONRPCErrorResponse(id: sessionRequest.id, error: error)
// self.responder.client.respond(topic: sessionRequest.topic, response: .error(jsonrpcErrorResponse))
// }
// wait(for: [failureResponseExpectation], timeout: defaultTimeout)
// }
//
// func testSessionPing() async {
// await waitClientsConnected()
// let proposerReceivesPingResponseExpectation = expectation(description: "Proposer receives ping response")
Expand Down Expand Up @@ -368,26 +381,3 @@ final class SignClientTests: XCTestCase {
// wait(for: [proposerReceivesEventExpectation], timeout: defaultTimeout)
// }
}

// public struct EthSendTransaction: Codable, Equatable {
// public let from: String
// public let data: String
// public let value: String
// public let to: String
// public let gasPrice: String
// public let nonce: String
// }
//
//
// fileprivate let ethSendTransaction = """
// {
// "from":"0xb60e8dd61c5d32be8058bb8eb970870f07233155",
// "to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567",
// "data":"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675",
// "gas":"0x76c0",
// "gasPrice":"0x9184e72a000",
// "value":"0x9184e72a",
// "nonce":"0x117"
// }
// """
//
Loading