bitsors 1.1.16

A Rust wrapper for the Bitso API
Documentation
extern crate bitsors;
extern crate mockito;

use bitsors::client::{Bitso, OptionalParams};
use mockito::{mock, Matcher};

/// Test unsuccesful request and error parsing
#[tokio::test]
async fn test_error_parsing() {
    let _mock = mock("GET", "/v3/ticker/")
        .match_query(Matcher::UrlEncoded("book".into(), "FAKEORDERBOOK".into()))
        .with_status(400)
        .with_body(
            r#"{
            "success": false,
            "error": {
                "code": "0301",
                "message": "Unknown OrderBook FAKEORDERBOOK"
            }
        }"#,
        )
        .create();
    let bitso = Bitso::default()
        .prefix(mockito::server_url().as_str())
        .build();
    let result = bitso.get_ticker("FAKEORDERBOOK").await;
    assert!(result.is_err());
    println!("{:?}", result);
    assert_eq!(
        result.unwrap_err().to_string(),
        "Bitso API error code 0301: Unknown OrderBook FAKEORDERBOOK"
    );
}

/// Test successful request to get available books
#[tokio::test]
async fn test_available_books() {
    let _mock = mock("GET", "/v3/available_books/")
        .with_status(200)
        .with_body(
            r#"{
            "success": true,
            "payload": [{
                "book": "btc_mxn",
                "minimum_amount": ".003",
                "maximum_amount": "1000.00",
                "minimum_price": "100.00",
                "maximum_price": "1000000.00",
                "minimum_value": "25.00",
                "maximum_value": "1000000.00"
            }, {
                "book": "eth_mxn",
                "minimum_amount": ".003",
                "maximum_amount": "1000.00",
                "minimum_price": "100.0",
                "maximum_price": "1000000.0",
                "minimum_value": "25.0",
                "maximum_value": "1000000.0"
            }]
        }"#,
        )
        .create();
    let bitso = Bitso::default()
        .prefix(mockito::server_url().as_str())
        .build();
    let result = bitso.get_available_books().await;
    assert!(result.is_ok());
    println!("{:?}", result);
}

/// Test successful request to get ticker
#[tokio::test]
async fn test_ticker() {
    let _mock = mock("GET", "/v3/ticker/")
        .match_query(Matcher::UrlEncoded("book".into(), "btc_mxn".into()))
        .with_status(200)
        .with_body(
            r#"{
            "success": true,
            "payload": {
                "book": "btc_mxn",
                "volume": "22.31349615",
                "high": "5750.00",
                "last": "5633.98",
                "low": "5450.00",
                "vwap": "5393.45",
                "ask": "5632.24",
                "bid": "5520.01",
                "created_at": "2016-04-08T17:52:31.000+00:00"
            }
        }"#,
        )
        .create();
    let bitso = Bitso::default()
        .prefix(mockito::server_url().as_str())
        .build();
    let result = bitso.get_ticker("btc_mxn").await;
    assert!(result.is_ok());
    println!("{:?}", result);
}

/// Test successful request to get order book
#[tokio::test]
async fn test_order_book() {
    let _mock = mock("GET", "/v3/order_book/")
        .match_query(Matcher::AllOf(vec![
            Matcher::UrlEncoded("book".into(), "btc_mxn".into()),
            Matcher::UrlEncoded("aggregate".into(), "false".into()),
        ]))
        .with_status(200)
        .with_body(
            r#"{
            "success": true,
            "payload": {
                "asks": [{
                    "book": "btc_mxn",
                    "price": "5632.24",
                    "amount": "1.34491802"
                },{
                    "book": "btc_mxn",
                    "price": "5633.44",
                    "amount": "0.4259"
                },{
                    "book": "btc_mxn",
                    "price": "5642.14",
                    "amount": "1.21642"
                }],
                "bids": [{
                    "book": "btc_mxn",
                    "price": "6123.55",
                    "amount": "1.12560000"
                },{
                    "book": "btc_mxn",
                    "price": "6121.55",
                    "amount": "2.23976"
                }],
                "updated_at": "2016-04-08T17:52:31.000+00:00",
                "sequence": "27214"
            }
        }"#,
        )
        .create();
    let bitso = Bitso::default()
        .prefix(mockito::server_url().as_str())
        .build();
    let result = bitso.get_order_book("btc_mxn", false).await;
    assert!(result.is_ok());
    println!("{:?}", result);
}

/// Test successful request to get order book, with aggregate data
#[tokio::test]
async fn test_order_book_with_optional_params() {
    let _mock = mock("GET", "/v3/order_book/")
        .match_query(Matcher::AllOf(vec![
            Matcher::UrlEncoded("book".into(), "btc_mxn".into()),
            Matcher::UrlEncoded("aggregate".into(), "true".into()),
        ]))
        .with_status(200)
        .with_body(
            r#"{
            "success": true,
            "payload": {
                "asks": [{
                    "book": "btc_mxn",
                    "price": "5632.24",
                    "amount": "1.34491802"
                },{
                    "book": "btc_mxn",
                    "price": "5633.44",
                    "amount": "0.4259"
                },{
                    "book": "btc_mxn",
                    "price": "5642.14",
                    "amount": "1.21642"
                }],
                "bids": [{
                    "book": "btc_mxn",
                    "price": "6123.55",
                    "amount": "1.12560000"
                },{
                    "book": "btc_mxn",
                    "price": "6121.55",
                    "amount": "2.23976"
                }],
                "updated_at": "2016-04-08T17:52:31.000+00:00",
                "sequence": "27214"
            }
        }"#,
        )
        .create();
    let bitso = Bitso::default()
        .prefix(mockito::server_url().as_str())
        .build();
    let result = bitso.get_order_book("btc_mxn", true).await;
    assert!(result.is_ok());
    println!("{:?}", result);
}

/// Test successful request to get trades
#[tokio::test]
async fn test_trades() {
    let _mock = mock("GET", "/v3/trades/")
        .match_query(Matcher::UrlEncoded("book".into(), "btc_mxn".into()))
        .with_status(200)
        .with_body(
            r#"{
            "success": true,
            "payload": [{
                "book": "btc_mxn",
                "created_at": "2016-04-08T17:52:31.000+00:00",
                "amount": "0.02000000",
                "maker_side": "buy",
                "price": "5545.01",
                "tid": 55845
            }, {
                "book": "btc_mxn",
                "created_at": "2016-04-08T17:52:31.000+00:00",
                "amount": "0.33723939",
                "maker_side": "sell",
                "price": "5633.98",
                "tid": 55844
            }]
        }"#,
        )
        .create();
    let bitso = Bitso::default()
        .prefix(mockito::server_url().as_str())
        .build();
    let result = bitso.get_trades("btc_mxn", None).await;
    assert!(result.is_ok());
    println!("{:?}", result);
}

/// Test successful request to get trades with optional parameters
#[tokio::test]
async fn test_trades_with_optional_params() {
    let _mock = mock("GET", "/v3/trades/")
        .match_query(Matcher::AllOf(vec![
            Matcher::UrlEncoded("book".into(), "btc_mxn".into()),
            Matcher::UrlEncoded("marker".into(), "55844".into()),
            Matcher::UrlEncoded("sort".into(), "asc".into()),
            Matcher::UrlEncoded("limit".into(), "1".into()),
        ]))
        .match_query(Matcher::UrlEncoded("book".into(), "btc_mxn".into()))
        .with_status(200)
        .with_body(
            r#"{
            "success": true,
            "payload": [{
                "book": "btc_mxn",
                "created_at": "2016-04-08T17:52:31.000+00:00",
                "amount": "0.02000000",
                "maker_side": "buy",
                "price": "5545.01",
                "tid": 55845
            }]
        }"#,
        )
        .create();
    let bitso = Bitso::default()
        .prefix(mockito::server_url().as_str())
        .build();
    let optional_params = OptionalParams {
        marker: Some(&55844),
        sort: Some("asc"),
        limit: Some(&1),
    };
    let result = bitso.get_trades("btc_mxn", Some(optional_params)).await;
    assert!(result.is_ok());
    println!("{:?}", result);
}

/// Test proper handling of errors external to the library
#[tokio::test]
async fn extern_errors() {
    let bitso = Bitso::default().prefix("bad prefix").build();
    let result = bitso.get_ticker("eth_mxn").await;
    println!("{:?}", result);
    assert_eq!(
        result.unwrap_err().to_string(),
        "builder error: relative URL without a base"
    );
}