zilliz 1.4.2

TUI and CLI tool for managing Zilliz Cloud clusters and Milvus operations
Documentation
//! Integration tests for UAT (dev) login (`zilliz login --dev`) and the
//! persisted control-plane endpoint.

use tempfile::TempDir;
use zilliz::cli::auth;
use zilliz::config::manager::ConfigManager;
use zilliz::model::types::{
    AuthConfig, DEFAULT_CN_CONTROL_PLANE_ENDPOINT, DEFAULT_DEV_CONTROL_PLANE_ENDPOINT,
};

fn temp_mgr() -> (TempDir, ConfigManager) {
    let dir = tempfile::tempdir().unwrap();
    let mgr = ConfigManager::new(Some(dir.path().to_path_buf())).unwrap();
    (dir, mgr)
}

fn dummy_auth() -> AuthConfig {
    AuthConfig {
        auth0_domain: "https://should-not-be-called.example.com".to_string(),
        client_id: "should-not-be-called".to_string(),
        login_api: "https://should-not-be-called.example.com".to_string(),
    }
}

#[tokio::test]
async fn dev_login_with_api_key_value_persists_uat_endpoint() {
    let (_dir, mgr) = temp_mgr();
    let auth_cfg = dummy_auth();

    auth::login(
        &mgr,
        Some(&auth_cfg),
        /* no_browser */ false,
        Some("sk-dev-test-1234567890"),
        /* cn */ false,
        /* dev */ true,
    )
    .await
    .expect("dev login with --api-key value should succeed");

    assert_eq!(
        mgr.get_credential("api_key").as_deref(),
        Some("sk-dev-test-1234567890")
    );
    assert_eq!(
        mgr.get_control_plane_endpoint().as_deref(),
        Some(DEFAULT_DEV_CONTROL_PLANE_ENDPOINT)
    );
}

#[tokio::test]
async fn dev_login_does_not_call_auth0() {
    // If `--dev` ever fell through to the browser flow, it would try to hit
    // the unreachable auth0_domain. Success here implies we never went near it.
    let (_dir, mgr) = temp_mgr();
    let auth_cfg = dummy_auth();

    auth::login(
        &mgr,
        Some(&auth_cfg),
        false,
        Some("sk-dev-another-1234567890"),
        false,
        true,
    )
    .await
    .expect("dev login must not attempt Auth0 and must succeed");
}

#[tokio::test]
async fn dev_and_cn_combined_is_rejected() {
    let (_dir, mgr) = temp_mgr();
    let auth_cfg = dummy_auth();

    let err = auth::login(
        &mgr,
        Some(&auth_cfg),
        false,
        Some("sk-should-not-store"),
        /* cn */ true,
        /* dev */ true,
    )
    .await
    .expect_err("--cn and --dev together must fail");

    assert!(
        err.to_string().contains("--cn") && err.to_string().contains("--dev"),
        "error message should mention both flags: {err}"
    );
    assert!(
        mgr.get_credential("api_key").is_none(),
        "rejected login must not persist credentials"
    );
    assert!(
        mgr.get_control_plane_endpoint().is_none(),
        "rejected login must not persist endpoint"
    );
}

#[tokio::test]
async fn global_login_clears_persisted_dev_endpoint() {
    let (_dir, mgr) = temp_mgr();
    // Simulate a prior dev session.
    mgr.set_control_plane_endpoint(DEFAULT_DEV_CONTROL_PLANE_ENDPOINT)
        .unwrap();
    assert!(mgr.get_control_plane_endpoint().is_some());

    let auth_cfg = dummy_auth();
    auth::login(
        &mgr,
        Some(&auth_cfg),
        false,
        Some("sk-global-after-dev-1234567890"),
        false,
        false,
    )
    .await
    .expect("plain global login should succeed");

    assert!(
        mgr.get_control_plane_endpoint().is_none(),
        "plain login must reset the persisted UAT endpoint"
    );
}

#[tokio::test]
async fn logout_clears_persisted_endpoint_after_dev_login() {
    let (_dir, mgr) = temp_mgr();
    let auth_cfg = dummy_auth();

    auth::login(
        &mgr,
        Some(&auth_cfg),
        false,
        Some("sk-dev-logout-1234567890"),
        false,
        true,
    )
    .await
    .unwrap();

    assert_eq!(
        mgr.get_control_plane_endpoint().as_deref(),
        Some(DEFAULT_DEV_CONTROL_PLANE_ENDPOINT)
    );

    auth::logout(&mgr).expect("logout should succeed");

    assert!(
        mgr.get_control_plane_endpoint().is_none(),
        "logout must clear the persisted endpoint"
    );
    assert!(
        mgr.get_credential("api_key").is_none(),
        "logout must clear the credential"
    );
}

#[test]
fn persisted_dev_endpoint_drives_control_plane_resolver() {
    use zilliz::cli::endpoint::resolve_control_plane_url;
    use zilliz::model::loader::ModelLoader;

    let (_dir, mgr) = temp_mgr();
    mgr.set_control_plane_endpoint(DEFAULT_DEV_CONTROL_PLANE_ENDPOINT)
        .unwrap();

    let models = ModelLoader::load_builtin().unwrap();
    let resolved = resolve_control_plane_url(&mgr, &models.control_plane, None);
    assert_eq!(resolved, DEFAULT_DEV_CONTROL_PLANE_ENDPOINT);
}

#[test]
fn explicit_endpoint_overrides_persisted_dev() {
    use zilliz::cli::endpoint::resolve_control_plane_url;
    use zilliz::model::loader::ModelLoader;

    let (_dir, mgr) = temp_mgr();
    mgr.set_control_plane_endpoint(DEFAULT_DEV_CONTROL_PLANE_ENDPOINT)
        .unwrap();

    let models = ModelLoader::load_builtin().unwrap();
    let resolved = resolve_control_plane_url(
        &mgr,
        &models.control_plane,
        Some("https://staging.example.com"),
    );
    assert_eq!(resolved, "https://staging.example.com");
}

#[test]
fn dev_endpoint_constants_are_distinct() {
    assert_ne!(
        DEFAULT_DEV_CONTROL_PLANE_ENDPOINT,
        DEFAULT_CN_CONTROL_PLANE_ENDPOINT
    );
}

#[test]
fn clap_rejects_dev_and_cn_together() {
    use clap::Parser;
    use zilliz::cli::args::Cli;

    let result = Cli::try_parse_from(["zilliz", "login", "--dev", "--cn"]);
    assert!(
        result.is_err(),
        "clap must reject `login --dev --cn` due to conflicts_with"
    );
}

#[test]
fn clap_accepts_dev_alone() {
    use clap::Parser;
    use zilliz::cli::args::Cli;

    Cli::try_parse_from(["zilliz", "login", "--dev", "--api-key", "sk-x"])
        .expect("`login --dev --api-key sk-x` must parse");
}