ic-query 0.91.0

Internet Computer query library for CloudEngine, NNS, SNS, ICRC, system canisters, and public network metadata
Documentation
use super::*;
use crate::icrc::live::tests::{query_content, query_fixture};
use ic_platform::agent::{AgentError, RejectCode};
use serde_cbor::Value;
use std::collections::BTreeMap;

#[tokio::test(flavor = "current_thread")]
async fn capability_probe_retains_reject_metadata_through_the_ledger_transport() {
    for (error_code, message, expected) in [
        (
            "IC0536",
            "fixture missing method",
            IcrcCapabilityStatus::Unsupported,
        ),
        (
            "IC0502",
            "IC0536 method not found",
            IcrcCapabilityStatus::Error,
        ),
    ] {
        let body = Value::Map(BTreeMap::from([
            (Value::Text("status".into()), Value::Text("rejected".into())),
            (Value::Text("reject_code".into()), Value::Integer(5)),
            (
                Value::Text("reject_message".into()),
                Value::Text(message.into()),
            ),
            (
                Value::Text("error_code".into()),
                Value::Text(error_code.into()),
            ),
        ]));
        let (server, agent) = query_fixture(&body, 8 * 1024 * 1024);
        let row = fetch_index_capability(&agent, &Principal::anonymous()).await;
        let raw = server.finish().unwrap();
        let content = query_content(&raw);
        assert_eq!(
            content[&Value::Text("method_name".into())],
            Value::Text(ICRC106_GET_INDEX_PRINCIPAL_METHOD.into())
        );
        assert_eq!(row.status, expected);
        let diagnostic = row.error.unwrap();
        assert!(diagnostic.contains(message));
        assert!(diagnostic.contains(error_code));
    }
}

#[test]
fn capability_failures_classify_protocol_codes_and_preserve_diagnostics() {
    for certified in [false, true] {
        for (code, error_code, message, expected) in [
            (
                RejectCode::CanisterError,
                Some("IC0536"),
                "method unavailable",
                IcrcCapabilityStatus::Unsupported,
            ),
            (
                RejectCode::CanisterError,
                Some("IC0502"),
                "IC0536: method not found",
                IcrcCapabilityStatus::Error,
            ),
            (
                RejectCode::CanisterError,
                None,
                "Canister has no query method",
                IcrcCapabilityStatus::Error,
            ),
            (
                RejectCode::CanisterReject,
                Some("IC0536"),
                "method not found",
                IcrcCapabilityStatus::Error,
            ),
        ] {
            let reject = ic_platform::agent::RejectResponse {
                reject_code: code,
                reject_message: message.to_string(),
                error_code: error_code.map(str::to_string),
            };
            let error = if certified {
                AgentError::CertifiedReject {
                    reject,
                    operation: None,
                }
            } else {
                AgentError::UncertifiedReject {
                    reject,
                    operation: None,
                }
            };
            let original = IcrcError::AgentCall {
                method: ICRC3_GET_BLOCKS_METHOD,
                reason: error.to_string(),
            }
            .to_string();
            let row = error_capability_row(
                "ICRC-3 block history",
                ICRC3_GET_BLOCKS_METHOD,
                CapabilityQueryError::agent_call(ICRC3_GET_BLOCKS_METHOD, error.into()),
            );
            assert_eq!(row.status, expected);
            assert_eq!(row.error.as_deref(), Some(original.as_str()));
        }
    }
    let error = CapabilityQueryError::candid_decode(
        ICRC3_GET_BLOCKS_METHOD,
        "method not found IC0536".into(),
    );
    assert_eq!(
        error_capability_row("blocks", ICRC3_GET_BLOCKS_METHOD, error).status,
        IcrcCapabilityStatus::Error
    );
}