zilliz 1.4.3

TUI and CLI tool for managing Zilliz Cloud clusters and Milvus operations
Documentation
use std::collections::HashMap;

use serde_json::{json, Value};
use zilliz::service::executor::build_request;

fn op_from_json(s: &str) -> zilliz::model::types::Operation {
    serde_json::from_str(s).expect("parse op")
}

#[test]
fn body_passthrough_preserves_undeclared_keys() {
    // Mirrors `collection create`: declares flat params, but no `schema`/`indexParams`.
    let op = op_from_json(
        r#"{
            "http": {"method": "POST", "path": "/v2/vectordb/collections/create"},
            "params": [
                {"name": "collectionName", "type": "string", "cli": "--name", "required": true},
                {"name": "dimension",      "type": "integer", "cli": "--dimension"}
            ],
            "bodyParam": "--body"
        }"#,
    );

    let mut values: HashMap<String, Value> = HashMap::new();
    values.insert("collectionName".into(), json!("foo"));
    values.insert(
        "schema".into(),
        json!({"fields": [{"fieldName": "id", "dataType": "Int64", "isPrimary": true}]}),
    );
    values.insert(
        "indexParams".into(),
        json!([{"fieldName": "vec", "indexType": "AUTOINDEX"}]),
    );

    let (path_params, body) = build_request(&op, &values);
    assert!(path_params.is_empty(), "no path params expected");
    let body = body.expect("body present").as_object().cloned().unwrap();

    assert_eq!(body.get("collectionName"), Some(&json!("foo")));
    assert_eq!(
        body.get("schema")
            .and_then(|v| v.get("fields"))
            .and_then(|v| v.as_array())
            .map(|a| a.len()),
        Some(1),
        "undeclared `schema` must pass through"
    );
    assert_eq!(
        body.get("indexParams")
            .and_then(|v| v.as_array())
            .map(|a| a.len()),
        Some(1),
        "undeclared `indexParams` must pass through"
    );
}

#[test]
fn body_passthrough_skips_path_params_and_nulls() {
    // Path params must NOT leak into body even if the user somehow set them via --body.
    let op = op_from_json(
        r#"{
            "http": {"method": "DELETE", "path": "/v1/things/{id}"},
            "params": [
                {"name": "id", "type": "string", "cli": "--id", "position": "path", "required": true}
            ],
            "bodyParam": "--body"
        }"#,
    );

    let mut values: HashMap<String, Value> = HashMap::new();
    values.insert("id".into(), json!("abc"));
    values.insert("note".into(), json!("hello"));
    values.insert("ignored_null".into(), Value::Null);

    let (path_params, body) = build_request(&op, &values);
    assert_eq!(path_params.get("id"), Some(&"abc".to_string()));
    let body = body.expect("body present").as_object().cloned().unwrap();
    assert!(
        !body.contains_key("id"),
        "path param must not appear in body"
    );
    assert!(
        !body.contains_key("ignored_null"),
        "null extras must be skipped"
    );
    assert_eq!(body.get("note"), Some(&json!("hello")));
}

#[test]
fn declared_param_overrides_passthrough_default_no_duplication() {
    // When a key is declared, the declared-loop owns it; passthrough must not double-insert.
    let op = op_from_json(
        r#"{
            "http": {"method": "POST", "path": "/x"},
            "params": [
                {"name": "name", "type": "string", "cli": "--name"}
            ],
            "bodyParam": "--body"
        }"#,
    );
    let mut values: HashMap<String, Value> = HashMap::new();
    values.insert("name".into(), json!("from-flag"));

    let (_p, body) = build_request(&op, &values);
    let body = body.expect("body present").as_object().cloned().unwrap();
    assert_eq!(body.get("name"), Some(&json!("from-flag")));
    assert_eq!(body.len(), 1);
}