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),
false,
Some("sk-dev-test-1234567890"),
false,
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() {
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"),
true,
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();
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");
}