Skip to content

Commit

Permalink
Added OrcaSwap tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sidorov-panda committed May 16, 2022
1 parent 65d7100 commit f00b28d
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 87 deletions.
8 changes: 4 additions & 4 deletions Sources/OrcaSwapSwift/OrcaSwap/OrcaSwap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
import Foundation
import SolanaSwift

public class OrcaSwap: OrcaSwapType {
public class OrcaSwap<APIClient: SolanaAPIClient, BlockchainClient :SolanaBlockchainClient>: OrcaSwapType {
// MARK: - Properties
private var cache: SwapInfo?
let apiClient: OrcaSwapAPIClient
let blockchainClient: SolanaBlockchainClient
let solanaClient: SolanaAPIClient
let blockchainClient: BlockchainClient
let solanaClient: APIClient
let accountStorage: SolanaAccountStorage

var info: SwapInfo?
Expand All @@ -23,7 +23,7 @@ public class OrcaSwap: OrcaSwapType {
// MARK: - Initializer
public init(
apiClient: OrcaSwapAPIClient,
solanaClient: SolanaAPIClient,
solanaClient: APIClient,
blockchainClient: BlockchainClient,
accountStorage: SolanaAccountStorage
) {
Expand Down
33 changes: 33 additions & 0 deletions Tests/OrcaSwapSwiftTests/Models/PoolsTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import XCTest
@testable import SolanaSwift
@testable import OrcaSwapSwift

class PoolsTestsTests: XCTestCase {

override func setUp() async throws {}

func testGetInputAmount() async throws {
let api = APIClient(configsProvider: MockConfigsProvider())
let pools = try await api.getPools()
var pool = pools.values.first!
pool.tokenABalance = .init(amount: 1, decimals: 1)
pool.tokenBBalance = .init(amount: 2, decimals: 1)
let estimatedAmount2: UInt64 = 1
let result = try pool.getInputAmount(fromEstimatedAmount: estimatedAmount2)
XCTAssertEqual(result, 1)
}

func testGetBaseOutputAmount() async throws {
let api = APIClient(configsProvider: MockConfigsProvider())
let pools = try await api.getPools()
var pool = pools.values.first!
pool.tokenABalance = .init(amount: 1, decimals: 1)
pool.tokenBBalance = .init(amount: 2, decimals: 1)
let result = try pool.getBaseOutputAmount(inputAmount: 1)
XCTAssertEqual(result, 2)
let result1 = try pool.getBaseOutputAmount(inputAmount: 2)
XCTAssertEqual(result1, 4)
}

}

24 changes: 4 additions & 20 deletions Tests/OrcaSwapSwiftTests/OrcaSwap/OrcaSwapPreparationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ class OrcaSwapPreparationTests: XCTestCase {
let ethMint = "2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk"
let socnMint = "5oVNBeEEQvYi1cX3ir8Dx5n1P7pdxydbGF2X4TxVusJm"

fileprivate var orcaSwap: OrcaSwap<MockSolanaAPIClient, BlockchainClient<MockSolanaAPIClient>>!
fileprivate var orcaSwap: OrcaSwap<MockSolanaAPIClient, BlockchainClient>!

var swapInfo: SwapInfo {
orcaSwap.info!
}

override func setUp() async throws {
let solanaAPIClient = MockSolanaAPIClient()
let solanaAPIClient = MockSolanaAPIClient(endpoint: .init(address: "", network: .devnet))
let blockchainClient = BlockchainClient(apiClient: solanaAPIClient)
orcaSwap = OrcaSwap(
apiClient: APIClient(configsProvider: MockConfigsProvider()),
Expand Down Expand Up @@ -157,24 +157,8 @@ class OrcaSwapPreparationTests: XCTestCase {
}
}

private class MockSolanaAPIClient: SolanaAPIClient {
var endpoint: APIEndPoint {
fatalError()
}

func request<Entity>(with request: JSONRPCAPIClientRequest<AnyDecodable>) async throws -> AnyResponse<Entity> where Entity : Decodable {
fatalError()
}

func request(with requests: [JSONRPCAPIClientRequest<AnyDecodable>]) async throws -> [AnyResponse<AnyDecodable>] {
fatalError()
}

typealias RequestEncoder = JSONRPCRequestEncoder
}

extension MockSolanaAPIClient {
func getTokenAccountBalance(pubkey: String, commitment: Commitment?) async throws -> TokenAccountBalance {
private class MockSolanaAPIClient: JSONRPCAPIClient {
override func getTokenAccountBalance(pubkey: String, commitment: Commitment?) async throws -> TokenAccountBalance {
// BTC/ETH
if pubkey == "81w3VGbnszMKpUwh9EzAF9LpRzkKxc5XYCW64fuYk1jH" {
return.init(amount: 0.001014, decimals: 6)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import SolanaSwift

final class SwapIntegrationTests: XCTestCase {
// MARK: - Properties
var orcaSwap: OrcaSwap<JSONRPCAPIClient, BlockchainClient<JSONRPCAPIClient>>!
var orcaSwap: OrcaSwap<JSONRPCAPIClient, BlockchainClient>!

// MARK: - Setup
override func setUp() async throws {
Expand Down
94 changes: 32 additions & 62 deletions Tests/OrcaSwapSwiftTests/OrcaSwap/SwapTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import XCTest

final class SwapTests: XCTestCase {
// MARK: - Properties
fileprivate var orcaSwap: OrcaSwap<MockSolanaAPIClient2, BlockchainClient<MockSolanaAPIClient2>>!
fileprivate var orcaSwap: OrcaSwap<MockSolanaAPIClient2, BlockchainClient>!

// MARK: - Setup
override func setUp() async throws {
Expand Down Expand Up @@ -43,9 +43,7 @@ final class SwapTests: XCTestCase {
}

func testTransitiveSwapSOLToNonCreatedSPL() async throws {
let test = try await doTest(testJSONFile: "transitive-swap-tests", testName: "solToNonCreatedSpl", isSimulation: true)

try closeAssociatedToken(mint: test.toMint)
try await doTest(testJSONFile: "transitive-swap-tests", testName: "solToNonCreatedSpl", isSimulation: true)
}

func testTransitiveSwapSPLToSOL() async throws {
Expand All @@ -57,21 +55,16 @@ final class SwapTests: XCTestCase {
}

func testTransitiveSwapSPLToNonCreatedSPL() async throws {
let test = try await doTest(testJSONFile: "transitive-swap-tests", testName: "splToNonCreatedSpl", isSimulation: true)

try closeAssociatedToken(mint: test.toMint)
try await doTest(testJSONFile: "transitive-swap-tests", testName: "splToNonCreatedSpl", isSimulation: true)
}


// MARK: - Helpers
@discardableResult
func doTest(testJSONFile: String, testName: String, isSimulation: Bool) async throws -> SwapTest {
let test = try getDataFromJSONTestResourceFile(fileName: testJSONFile, decodedTo: [String: SwapTest].self)[testName]!

let network = Network.mainnetBeta
let orcaSwapNetwork = network == .mainnetBeta ? "mainnet": network.cluster

let solanaAPIClient = MockSolanaAPIClient2(endpoint: .init(address: test.endpoint, network: network, additionalQuery: test.endpointAdditionalQuery))
let solanaAPIClient = MockSolanaAPIClient2(endpoint: .init(address: test.endpoint, network: network, additionalQuery: test.endpointAdditionalQuery), networkManager: URLSession.shared)
let blockchainClient = BlockchainClient(apiClient: solanaAPIClient)
orcaSwap = OrcaSwap(
apiClient: APIClient(configsProvider: MockConfigsProvider()),
Expand All @@ -98,31 +91,6 @@ final class SwapTests: XCTestCase {
return test
}

func closeAssociatedToken(mint: String) throws {
let associatedTokenAddress = try PublicKey.associatedTokenAddress(
walletAddress: orcaSwap.accountStorage.account!.publicKey,
tokenMintAddress: try PublicKey(string: mint)
)

// let _ = try orcaSwap.solanaClient.closeTokenAccount(
// tokenPubkey: associatedTokenAddress.base58EncodedString
// )
// .retry { errors in
// errors.enumerated().flatMap{ (index, error) -> Observable<Int64> in
// let error = error as! SolanaError
// switch error {
// case .invalidResponse(let error) where error.data?.logs?.contains("Program log: Error: InvalidAccountData") == true:
// return .timer(.seconds(1), scheduler: MainScheduler.instance)
// default:
// break
// }
// return .error(error)
// }
// }
// .timeout(.seconds(60), scheduler: MainScheduler.instance)
// .toBlocking().first()
}

// MARK: - Helper
func fillPoolsBalancesAndSwap(
fromWalletPubkey: String,
Expand Down Expand Up @@ -180,51 +148,53 @@ private struct MockAccountStorage: SolanaAccountStorage {
}
}

public class MockSolanaAPIClient2: SolanaAPIClient {
init(endpoint: APIEndPoint) {
self.endpoint = endpoint
}

public var endpoint: APIEndPoint

public func request<Entity>(with request: JSONRPCAPIClientRequest<AnyDecodable>) async throws -> AnyResponse<Entity> where Entity : Decodable {
fatalError()
}

public func request(with requests: [JSONRPCAPIClientRequest<AnyDecodable>]) async throws -> [AnyResponse<AnyDecodable>] {
fatalError()
}
public class MockSolanaAPIClient2: BaseMockSolanaAPIClient {

public typealias ResponseDecoder = JSONRPCResponseDecoder
public typealias RequestEncoder = JSONRPCRequestEncoder

}

public extension MockSolanaAPIClient2 {
func getTokenAccountBalance(pubkey: String, commitment: Commitment?) async throws -> TokenAccountBalance {
public override func getTokenAccountBalance(pubkey: String, commitment: Commitment?) async throws -> TokenAccountBalance {
switch pubkey {
case "FdiTt7XQ94fGkgorywN1GuXqQzmURHCDgYtUutWRcy4q":
return TokenAccountBalance(amount: 389.627856679, decimals: 9)
case "7VcwKUtdKnvcgNhZt5BQHsbPrXLxhdVomsgrr7k2N5P5":
return TokenAccountBalance(amount: 27053.369728, decimals: 6)
case "DTb8NKsfhEJGY1TrA7RXN6MBiTrjnkdMAfjPEjtmTT3M":
return TokenAccountBalance(amount: 27053.369728, decimals: 6)
case "E8erPjPEorykpPjFV9yUYMYigEWKQUxuGfL2rJKLJ3KU":
return TokenAccountBalance(amount: 27053.369728, decimals: 6)
default:
fatalError()
return TokenAccountBalance(amount: 27053.369728, decimals: 6)
}
}

func getMinimumBalanceForRentExemption(dataLength: UInt64, commitment: Commitment? = "recent") async throws -> UInt64 {
public override func getMinimumBalanceForRentExemption(dataLength: UInt64, commitment: Commitment? = "recent") async throws -> UInt64 {
2039280
}

func getMinimumBalanceForRentExemption(span: UInt64) async throws -> UInt64 {
public func getMinimumBalanceForRentExemption(span: UInt64) async throws -> UInt64 {
2039280
}

func getFees(commitment: Commitment? = nil) async throws -> Fee {
public override func getFees(commitment: Commitment? = nil) async throws -> Fee {
.init(feeCalculator: .init(lamportsPerSignature: 5000), feeRateGovernor: nil, blockhash: "ADZgUVaAfUx5ehFXivdaUSHucpNdk4VqGSdN4TjttWgr", lastValidSlot: 133257026)
}

func getRecentBlockhash(commitment: Commitment? = nil) async throws -> String {
public override func getRecentBlockhash(commitment: Commitment? = nil) async throws -> String {
"NS37crgkUQQwwFjdEdWNQFCyatLGN68F55FG2Hv4FFS"
}

public override func sendTransaction(transaction: String, configs: RequestConfiguration = RequestConfiguration(encoding: "base64")!) async throws -> TransactionID {
return ""
}
}

public class MockNetworkManager: NetworkManager {
public func requestData(request: URLRequest) async throws -> Data {
// Simulate transaction json
return "{\"jsonrpc\":\"2.0\",\"result\":{\"context\":{\"slot\":133610519},\"value\":{\"accounts\":null,\"err\":null,\"logs\":[\"Program 11111111111111111111111111111111 invoke [1]\",\"Program 11111111111111111111111111111111 success\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]\",\"Program log: Instruction: InitializeAccount\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3392 of 200000 compute units\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success\",\"Program DjVE6JNiYqPL2QXyCUUh8rNjHrbz9hXHNYt99MQ59qw1 invoke [1]\",\"Program log: Instruction: Swap\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]\",\"Program log: Instruction: Transfer\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2755 of 182466 compute units\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]\",\"Program log: Instruction: Transfer\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2643 of 176749 compute units\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success\",\"Program DjVE6JNiYqPL2QXyCUUh8rNjHrbz9hXHNYt99MQ59qw1 consumed 26775 of 200000 compute units\",\"Program DjVE6JNiYqPL2QXyCUUh8rNjHrbz9hXHNYt99MQ59qw1 success\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]\",\"Program log: Instruction: CloseAccount\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1713 of 200000 compute units\",\"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success\"],\"unitsConsumed\":31880}},\"id\":\"345443BB-2FC6-4935-8F52-7D031BAE345B\"}\n".data(using: .utf8) ?? Data()
}
}

public class BaseMockSolanaAPIClient: JSONRPCAPIClient {
public override init(endpoint: APIEndPoint, networkManager: NetworkManager) {
super.init(endpoint: endpoint, networkManager: MockNetworkManager())
}
}
Empty file.
Empty file.

0 comments on commit f00b28d

Please sign in to comment.