use koios_sdk::{
models::{block::BlockTransaction, BlockTxInfoRequest},
Client,
};
use pretty_assertions::assert_eq;
use serde_json::json;
use wiremock::{
matchers::{body_json, header, method, path},
Mock, MockServer, ResponseTemplate,
};
async fn setup_test_client() -> (MockServer, Client) {
let mock_server = MockServer::start().await;
let client = Client::builder()
.base_url(mock_server.uri())
.build()
.unwrap();
(mock_server, client)
}
#[tokio::test]
async fn test_get_blocks() {
let (mock_server, client) = setup_test_client().await;
let mock_response = json!([{
"hash": "f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e",
"epoch_no": 321,
"abs_slot": 53384091,
"epoch_slot": 85691,
"block_height": 7017300,
"block_size": 4318,
"block_time": 1630106091,
"tx_count": 8,
"vrf_key": "vrf_vk1gn7g0xjwhxhm9pv4m0pfz4qw8fj95h5qkkc9zhl02wsm6v0urq9qgug5fx",
"op_cert_counter": 1,
"proto_major": 6,
"proto_minor": 0,
"parent_hash": "43c66ecb78f5938d7a3bf2cef6b575acda9c86a7c0c27dd91cdcd9e2f0f6e683"
}]);
Mock::given(method("GET"))
.and(path("/blocks"))
.respond_with(ResponseTemplate::new(200).set_body_json(&mock_response))
.mount(&mock_server)
.await;
let response = client.get_blocks().await.unwrap();
assert_eq!(response.len(), 1);
assert_eq!(
response[0].hash,
"f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e"
);
assert_eq!(response[0].epoch_no, 321);
assert_eq!(response[0].block_height.unwrap(), 7017300);
assert_eq!(response[0].tx_count, 8);
assert_eq!(response[0].proto_major, 6);
assert_eq!(response[0].proto_minor, 0);
}
#[tokio::test]
async fn test_get_block_info() {
let (mock_server, client) = setup_test_client().await;
let block_hashes =
vec!["f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e".to_string()];
let mock_response = json!([{
"hash": "f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e",
"epoch_no": 321,
"abs_slot": 53384091,
"epoch_slot": 85691,
"block_height": 7017300,
"block_size": 4318,
"block_time": 1630106091,
"tx_count": 8,
"vrf_key": "vrf_vk1gn7g0xjwhxhm9pv4m0pfz4qw8fj95h5qkkc9zhl02wsm6v0urq9qgug5fx",
"op_cert": "d05c10588ed1153be128c44d26241a229c5181c789067bf245e5ea7c28d5f05f",
"op_cert_counter": 1,
"pool": "pool1pu5jlj4q9w9jlxeu370a3c9myx47md5j5m2str0naunn2q3lkdy",
"proto_major": 6,
"proto_minor": 0,
"total_output": "42000000",
"total_fees": "1000000",
"num_confirmations": 100,
"parent_hash": "43c66ecb78f5938d7a3bf2cef6b575acda9c86a7c0c27dd91cdcd9e2f0f6e683",
"child_hash": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}]);
Mock::given(method("POST"))
.and(path("/block_info"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": block_hashes
})))
.respond_with(ResponseTemplate::new(200).set_body_json(&mock_response))
.mount(&mock_server)
.await;
let response = client.get_block_info(&block_hashes).await.unwrap();
assert_eq!(response.len(), 1);
assert_eq!(response[0].hash, block_hashes[0]);
assert_eq!(response[0].epoch_no, 321);
assert_eq!(response[0].block_height.unwrap(), 7017300);
assert_eq!(response[0].tx_count, 8);
assert_eq!(response[0].total_output.as_ref().unwrap(), "42000000");
assert_eq!(response[0].total_fees.as_ref().unwrap(), "1000000");
assert_eq!(response[0].num_confirmations, 100);
}
#[tokio::test]
async fn test_get_block_transactions() {
let (mock_server, client) = setup_test_client().await;
let block_hashes =
vec!["f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e".to_string()];
let mock_response = json!([{
"block_hash": "f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e",
"tx_hash": "6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541",
"epoch_no": 321,
"block_height": 7017300,
"block_time": 1630106091
}]);
Mock::given(method("POST"))
.and(path("/block_txs"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": block_hashes
})))
.respond_with(ResponseTemplate::new(200).set_body_json(&mock_response))
.mount(&mock_server)
.await;
let response = client.get_block_transactions(&block_hashes).await.unwrap();
assert_eq!(response.len(), 1);
assert_eq!(response[0].block_hash, block_hashes[0]);
assert_eq!(
response[0].tx_hash,
"6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541"
);
assert_eq!(response[0].epoch_no, 321);
assert_eq!(response[0].block_height, 7017300);
}
#[tokio::test]
async fn test_get_block_transaction_cbor() {
let (mock_server, client) = setup_test_client().await;
let block_hashes =
vec!["f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e".to_string()];
let mock_response = json!([{
"tx_hash": "6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541",
"block_hash": "f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e",
"block_height": 7017300,
"epoch_no": 321,
"absolute_slot": 53384091,
"tx_timestamp": 1630106091,
"cbor": "84a400828258204e3a6e7fdcb0d0994757897993c4cd3881f946b5927b1f72e33b991f6..."
}]);
Mock::given(method("POST"))
.and(path("/block_tx_cbor"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": block_hashes
})))
.respond_with(ResponseTemplate::new(200).set_body_json(&mock_response))
.mount(&mock_server)
.await;
let response = client
.get_block_transaction_cbor(&block_hashes)
.await
.unwrap();
assert_eq!(response.len(), 1);
assert_eq!(
response[0].tx_hash,
"6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541"
);
assert_eq!(response[0].block_hash, block_hashes[0]);
assert_eq!(response[0].block_height, 7017300);
assert_eq!(response[0].epoch_no, 321);
assert!(!response[0].cbor.is_empty());
}
#[tokio::test]
async fn test_get_block_transaction_info() {
let (mock_server, client) = setup_test_client().await;
let options = BlockTxInfoRequest {
block_hashes: vec![
"f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e".to_string(),
],
inputs: Some(true),
metadata: Some(true),
assets: Some(true),
withdrawals: Some(true),
certs: Some(true),
scripts: Some(true),
bytecode: Some(true),
};
let mock_response = json!([{
"tx_hash": "6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541",
"block_hash": "f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e",
"block_height": 7017300,
"epoch_no": 321,
"epoch_slot": 85691,
"absolute_slot": 53384091,
"tx_timestamp": 1630106091,
"tx_block_index": 1,
"tx_size": 292,
"total_output": "42000000",
"fee": "168273",
"treasury_donation": "0",
"deposit": "0",
"invalid_before": null,
"invalid_after": null,
"inputs": [],
"outputs": [],
"withdrawals": null,
"assets_minted": null,
"metadata": null,
"certificates": null,
"native_scripts": null,
"plutus_contracts": null
}]);
Mock::given(method("POST"))
.and(path("/block_tx_info"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": options.block_hashes,
"_inputs": options.inputs,
"_metadata": options.metadata,
"_assets": options.assets,
"_withdrawals": options.withdrawals,
"_certs": options.certs,
"_scripts": options.scripts,
"_bytecode": options.bytecode
})))
.respond_with(ResponseTemplate::new(200).set_body_json(&mock_response))
.mount(&mock_server)
.await;
#[allow(deprecated)]
let response = client.get_block_transaction_info(&options).await.unwrap();
assert_eq!(response.len(), 1);
assert_eq!(
response[0].tx_hash,
"6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541"
);
assert_eq!(response[0].block_height, 7017300);
assert_eq!(response[0].total_output, "42000000");
assert_eq!(response[0].fee, "168273");
}
#[tokio::test]
async fn test_invalid_block_hash() {
let (mock_server, client) = setup_test_client().await;
let block_hashes = vec!["invalid_hash".to_string()];
Mock::given(method("POST"))
.and(path("/block_info"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": block_hashes
})))
.respond_with(ResponseTemplate::new(400).set_body_string("Invalid block hash format"))
.mount(&mock_server)
.await;
let error = client.get_block_info(&block_hashes).await.unwrap_err();
match error {
koios_sdk::error::Error::Api { status, message } => {
assert_eq!(status, 400);
assert_eq!(message, "Invalid block hash format");
}
_ => panic!("Expected API error"),
}
}
#[tokio::test]
async fn test_block_not_found() {
let (mock_server, client) = setup_test_client().await;
let block_hashes =
vec!["f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e".to_string()];
Mock::given(method("POST"))
.and(path("/block_info"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": block_hashes
})))
.respond_with(ResponseTemplate::new(404).set_body_string("Block not found"))
.mount(&mock_server)
.await;
let error = client.get_block_info(&block_hashes).await.unwrap_err();
match error {
koios_sdk::error::Error::Api { status, message } => {
assert_eq!(status, 404);
assert_eq!(message, "Block not found");
}
_ => panic!("Expected API error"),
}
}
#[tokio::test]
async fn test_block_server_error() {
let (mock_server, client) = setup_test_client().await;
let block_hashes =
vec!["f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e".to_string()];
Mock::given(method("POST"))
.and(path("/block_info"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": block_hashes
})))
.respond_with(ResponseTemplate::new(500).set_body_string("Internal server error"))
.mount(&mock_server)
.await;
let error = client.get_block_info(&block_hashes).await.unwrap_err();
match error {
koios_sdk::error::Error::Api { status, message } => {
assert_eq!(status, 500);
assert_eq!(message, "Internal server error");
}
_ => panic!("Expected API error"),
}
}
#[tokio::test]
async fn test_empty_block_hash_list() {
let (mock_server, client) = setup_test_client().await;
let block_hashes: Vec<String> = vec![];
Mock::given(method("POST"))
.and(path("/block_info"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": block_hashes
})))
.respond_with(ResponseTemplate::new(400).set_body_string("Empty block hash list"))
.mount(&mock_server)
.await;
let error = client.get_block_info(&block_hashes).await.unwrap_err();
match error {
koios_sdk::error::Error::Api { status, message } => {
assert_eq!(status, 400);
assert_eq!(message, "Empty block hash list");
}
_ => panic!("Expected API error"),
}
}
#[tokio::test]
async fn test_block_info_and_transactions_integration() {
let (mock_server, client) = setup_test_client().await;
let block_hashes =
vec!["f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e".to_string()];
let info_response = json!([{
"hash": block_hashes[0],
"epoch_no": 321,
"abs_slot": 53384091,
"epoch_slot": 85691,
"block_height": 7017300,
"block_size": 4318,
"block_time": 1630106091,
"tx_count": 2,
"vrf_key": "vrf_vk1gn7g0xjwhxhm9pv4m0pfz4qw8fj95h5qkkc9zhl02wsm6v0urq9qgug5fx",
"op_cert": "d05c10588ed1153be128c44d26241a229c5181c789067bf245e5ea7c28d5f05f",
"op_cert_counter": 1,
"pool": "pool1pu5jlj4q9w9jlxeu370a3c9myx47md5j5m2str0naunn2q3lkdy",
"proto_major": 6,
"proto_minor": 0,
"total_output": "42000000",
"total_fees": "1000000",
"num_confirmations": 100,
"parent_hash": "43c66ecb78f5938d7a3bf2cef6b575acda9c86a7c0c27dd91cdcd9e2f0f6e683",
"child_hash": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}]);
Mock::given(method("POST"))
.and(path("/block_info"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": &block_hashes
})))
.respond_with(ResponseTemplate::new(200).set_body_json(&info_response))
.mount(&mock_server)
.await;
let tx_response = json!([
{
"block_hash": block_hashes[0],
"tx_hash": "6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541",
"epoch_no": 321,
"block_height": 7017300,
"block_time": 1630106091
},
{
"block_hash": block_hashes[0],
"tx_hash": "7ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6542",
"epoch_no": 321,
"block_height": 7017300,
"block_time": 1630106091
}
]);
Mock::given(method("POST"))
.and(path("/block_txs"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": &block_hashes
})))
.respond_with(ResponseTemplate::new(200).set_body_json(&tx_response))
.mount(&mock_server)
.await;
let (info, transactions) = tokio::join!(
client.get_block_info(&block_hashes),
client.get_block_transactions(&block_hashes)
);
let info = info.unwrap();
let transactions = transactions.unwrap();
assert_eq!(info.len(), 1);
assert_eq!(transactions.len(), 2);
assert_eq!(info[0].hash, block_hashes[0]);
assert_eq!(info[0].tx_count, 2); assert_eq!(info[0].epoch_no, 321);
assert_eq!(info[0].block_height.unwrap(), 7017300);
for tx in transactions.iter() {
assert_eq!(tx.block_hash, block_hashes[0]);
assert_eq!(tx.epoch_no, info[0].epoch_no);
assert_eq!(tx.block_height, info[0].block_height.unwrap());
assert_eq!(tx.block_time, info[0].block_time);
}
}
#[tokio::test]
async fn test_batch_block_operations() {
let (mock_server, client) = setup_test_client().await;
let block_hashes = vec![
"f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e".to_string(),
"43c66ecb78f5938d7a3bf2cef6b575acda9c86a7c0c27dd91cdcd9e2f0f6e683".to_string(),
];
let info_response = json!([
{
"hash": block_hashes[0],
"epoch_no": 321,
"abs_slot": 53384091,
"epoch_slot": 85691,
"block_height": 7017300,
"block_size": 4318,
"block_time": 1630106091,
"tx_count": 2,
"vrf_key": "vrf_vk1gn7g0xjwhxhm9pv4m0pfz4qw8fj95h5qkkc9zhl02wsm6v0urq9qgug5fx",
"op_cert": "d05c10588ed1153be128c44d26241a229c5181c789067bf245e5ea7c28d5f05f",
"op_cert_counter": 1,
"pool": "pool1pu5jlj4q9w9jlxeu370a3c9myx47md5j5m2str0naunn2q3lkdy",
"proto_major": 6,
"proto_minor": 0,
"total_output": "42000000",
"total_fees": "1000000",
"num_confirmations": 100,
"parent_hash": block_hashes[1],
"child_hash": "" },
{
"hash": block_hashes[1],
"epoch_no": 321,
"abs_slot": 53384090,
"epoch_slot": 85690,
"block_height": 7017299,
"block_size": 3218,
"block_time": 1630106090,
"tx_count": 1,
"vrf_key": "vrf_vk1gn7g0xjwhxhm9pv4m0pfz4qw8fj95h5qkkc9zhl02wsm6v0urq9qgug5fx",
"op_cert": "d05c10588ed1153be128c44d26241a229c5181c789067bf245e5ea7c28d5f05f",
"op_cert_counter": 1,
"pool": "pool1pu5jlj4q9w9jlxeu370a3c9myx47md5j5m2str0naunn2q3lkdy",
"proto_major": 6,
"proto_minor": 0,
"total_output": "21000000",
"total_fees": "500000",
"num_confirmations": 101,
"parent_hash": "previous_hash",
"child_hash": block_hashes[0]
}
]);
Mock::given(method("POST"))
.and(path("/block_info"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": &block_hashes
})))
.respond_with(ResponseTemplate::new(200).set_body_json(&info_response))
.mount(&mock_server)
.await;
let tx_response = json!([
{
"block_hash": &block_hashes[0],
"tx_hash": "6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541",
"epoch_no": 321,
"block_height": 7017300,
"block_time": 1630106091
},
{
"block_hash": &block_hashes[0],
"tx_hash": "7ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6542",
"epoch_no": 321,
"block_height": 7017300,
"block_time": 1630106091
},
{
"block_hash": &block_hashes[1],
"tx_hash": "8ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6543",
"epoch_no": 321,
"block_height": 7017299,
"block_time": 1630106090
}
]);
Mock::given(method("POST"))
.and(path("/block_txs"))
.and(header("Content-Type", "application/json"))
.and(body_json(json!({
"_block_hashes": &block_hashes
})))
.respond_with(ResponseTemplate::new(200).set_body_json(&tx_response))
.mount(&mock_server)
.await;
let (info, transactions) = tokio::join!(
client.get_block_info(&block_hashes),
client.get_block_transactions(&block_hashes)
);
let info = info.unwrap();
let transactions = transactions.unwrap();
assert_eq!(info.len(), 2);
assert_eq!(transactions.len(), 3);
let block1 = &info[0];
assert_eq!(block1.hash, block_hashes[0]);
assert_eq!(block1.tx_count, 2);
assert_eq!(block1.parent_hash, block_hashes[1]);
assert!(block1.child_hash.is_empty());
let block2 = &info[1];
assert_eq!(block2.hash, block_hashes[1]);
assert_eq!(block2.tx_count, 1);
assert_eq!(block2.child_hash, block_hashes[0]);
assert_eq!(block2.block_height.unwrap(), 7017299);
let block1_txs: Vec<&BlockTransaction> = transactions
.iter()
.filter(|tx| tx.block_hash == block_hashes[0])
.collect();
let block2_txs: Vec<&BlockTransaction> = transactions
.iter()
.filter(|tx| tx.block_hash == block_hashes[1])
.collect();
assert_eq!(block1_txs.len(), 2);
assert_eq!(block2_txs.len(), 1);
for tx in block1_txs {
assert_eq!(tx.epoch_no, block1.epoch_no);
assert_eq!(tx.block_height, block1.block_height.unwrap());
assert_eq!(tx.block_time, block1.block_time);
}
for tx in block2_txs {
assert_eq!(tx.epoch_no, block2.epoch_no);
assert_eq!(tx.block_height, block2.block_height.unwrap());
assert_eq!(tx.block_time, block2.block_time);
}
}
#[tokio::test]
async fn test_pagination_handling() {
let (mock_server, client) = setup_test_client().await;
let first_page_response = json!([{
"hash": "f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e",
"epoch_no": 321,
"abs_slot": 53384091,
"epoch_slot": 85691,
"block_height": 7017300,
"block_size": 4318,
"block_time": 1630106091,
"tx_count": 8,
"vrf_key": "vrf_vk1gn7g0xjwhxhm9pv4m0pfz4qw8fj95h5qkkc9zhl02wsm6v0urq9qgug5fx",
"op_cert_counter": 1,
"proto_major": 6,
"proto_minor": 0,
"parent_hash": "43c66ecb78f5938d7a3bf2cef6b575acda9c86a7c0c27dd91cdcd9e2f0f6e683"
}]);
Mock::given(method("GET"))
.and(path("/blocks"))
.respond_with(
ResponseTemplate::new(200)
.set_body_json(&first_page_response)
.insert_header("X-Page-Count", "2"),
)
.mount(&mock_server)
.await;
let response = client.get_blocks().await.unwrap();
assert_eq!(response.len(), 1);
assert_eq!(response[0].block_height.unwrap(), 7017300);
}
#[tokio::test]
async fn test_malformed_response_handling() {
let (mock_server, client) = setup_test_client().await;
let block_hashes =
vec!["f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e".to_string()];
Mock::given(method("POST"))
.and(path("/block_info"))
.respond_with(ResponseTemplate::new(200).set_body_string("invalid json"))
.mount(&mock_server)
.await;
match client.get_block_info(&block_hashes).await {
Err(koios_sdk::error::Error::Json(_)) | Err(koios_sdk::error::Error::HttpClient(_)) => {}
other => panic!("Expected Json or HttpClient error, got {:?}", other),
}
}
#[tokio::test]
async fn test_concurrent_block_requests() {
let (mock_server, client) = setup_test_client().await;
let block_hash = "f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e";
let block_hashes = vec![block_hash.to_string()];
let info_response = json!([{
"hash": block_hash,
"epoch_no": 321,
"abs_slot": 53384091,
"epoch_slot": 85691,
"block_height": 7017300,
"block_size": 4318,
"block_time": 1630106091,
"tx_count": 1,
"vrf_key": "vrf_vk1gn7g0xjwhxhm9pv4m0pfz4qw8fj95h5qkkc9zhl02wsm6v0urq9qgug5fx",
"op_cert": "d05c10588ed1153be128c44d26241a229c5181c789067bf245e5ea7c28d5f05f",
"op_cert_counter": 1,
"pool": "pool1pu5jlj4q9w9jlxeu370a3c9myx47md5j5m2str0naunn2q3lkdy",
"proto_major": 6,
"proto_minor": 0,
"total_output": "42000000",
"total_fees": "1000000",
"num_confirmations": 100,
"parent_hash": "43c66ecb78f5938d7a3bf2cef6b575acda9c86a7c0c27dd91cdcd9e2f0f6e683",
"child_hash": "" }]);
let tx_response = json!([{
"block_hash": block_hash,
"tx_hash": "6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541",
"epoch_no": 321,
"block_height": 7017300,
"block_time": 1630106091
}]);
let cbor_response = json!([{
"tx_hash": "6ed09ba58a56c6e946668038ba4d3cef8eb97a20cbf76c5970e1402e8a8d6541",
"block_hash": block_hash,
"block_height": 7017300,
"epoch_no": 321,
"absolute_slot": 53384091,
"tx_timestamp": 1630106091,
"cbor": "84a400828258204e3a6e7fdcb0d0994757897993c4cd3881f946b5927b1f72e33b991f6..."
}]);
Mock::given(method("POST"))
.and(path("/block_info"))
.respond_with(ResponseTemplate::new(200).set_body_json(&info_response))
.mount(&mock_server)
.await;
Mock::given(method("POST"))
.and(path("/block_txs"))
.respond_with(ResponseTemplate::new(200).set_body_json(&tx_response))
.mount(&mock_server)
.await;
Mock::given(method("POST"))
.and(path("/block_tx_cbor"))
.respond_with(ResponseTemplate::new(200).set_body_json(&cbor_response))
.mount(&mock_server)
.await;
let (info, txs, cbor) = tokio::join!(
client.get_block_info(&block_hashes),
client.get_block_transactions(&block_hashes),
client.get_block_transaction_cbor(&block_hashes)
);
let info = info.unwrap();
let txs = txs.unwrap();
let cbor = cbor.unwrap();
assert_eq!(info[0].hash, block_hash);
assert_eq!(txs[0].block_hash, block_hash);
assert_eq!(cbor[0].block_hash, block_hash);
assert_eq!(info[0].epoch_no, txs[0].epoch_no);
assert_eq!(txs[0].epoch_no, cbor[0].epoch_no);
assert_eq!(info[0].block_height.unwrap(), txs[0].block_height);
assert_eq!(txs[0].block_height, cbor[0].block_height);
}