use super::{ProviderRow, provider_rows, row_views};
const LIVE_LISTING: &str = r#"{"providers":[
{"auth":"oauth2","credential":"stored","name":"codex","protocol":"openai_responses"},
{"auth":"none","credential":"not required","name":"local","protocol":"ollama_chat"},
{"auth":"none","credential":"not required","name":"claude-code","protocol":"claude_code"},
{"auth":"oauth2","credential":"ambient","name":"claude-session-direct","protocol":"anthropic_messages"},
{"auth":"api_key","credential":"missing","name":"anthropic","protocol":"anthropic_messages"}
]}"#;
#[test]
fn the_tool_capability_is_read_off_the_protocol_column() {
let rows = provider_rows(LIVE_LISTING);
assert_eq!(rows[2].protocol, "claude_code");
let why = rows[2].tools_blocked().expect("claude_code declines tools");
assert!(why.starts_with("claude_code declares no tools"), "{why}");
assert!(why.contains("`clients` tool"), "{why}");
assert!(why.contains("can serve no role"), "{why}");
for i in [0, 1, 3, 4] {
assert_eq!(rows[i].tools_blocked(), None, "row {i} carries tools");
}
}
#[test]
fn an_unspellable_protocol_answers_nothing_about_tools() {
let rows = provider_rows(
r#"{"providers":[{"name":"x","protocol":"mystery_wire","auth":"none"},{"name":"y","auth":"none"}]}"#,
);
assert_eq!(rows[0].tools_blocked(), None);
assert_eq!(
rows[1].tools_blocked(),
None,
"an absent column asks nothing"
);
}
#[test]
fn the_context_caveat_is_read_off_the_same_column() {
let rows = provider_rows(LIVE_LISTING);
assert_eq!(rows[1].protocol, "ollama_chat");
let caveat = rows[1]
.context_caveat()
.expect("ollama_chat declares no context size");
assert!(
caveat.starts_with("ollama_chat declares no context size"),
"{caveat}"
);
assert!(
caveat.contains("the server's own default governs"),
"{caveat}"
);
assert!(
caveat.contains("tool payload alone can exhaust it"),
"{caveat}"
);
for i in [0, 2, 3, 4] {
assert_eq!(
rows[i].context_caveat(),
None,
"row {i} carries its own context size"
);
}
}
#[test]
fn the_context_remedy_carries_both_halves() {
let remedy = super::CONTEXT_REMEDY;
assert!(
remedy.contains("unsupported_body_keys = [\"max_tokens\"]"),
"{remedy}"
);
assert!(remedy.contains("num_ctx = <your context>"), "{remedy}");
assert!(
remedy.contains("num_predict = <your output cap>"),
"{remedy}"
);
assert!(remedy.contains("dropped whole and silently"), "{remedy}");
}
#[test]
fn an_unspellable_protocol_answers_nothing_about_context() {
let rows =
provider_rows(r#"{"providers":[{"name":"x","protocol":"mystery_wire","auth":"none"}]}"#);
assert_eq!(rows[0].context_caveat(), None);
}
#[test]
fn provider_rows_reads_name_and_auth_in_listing_order() {
let rows = provider_rows(LIVE_LISTING);
assert_eq!(
rows.iter().map(|r| r.name.clone()).collect::<Vec<_>>(),
[
"codex",
"local",
"claude-code",
"claude-session-direct",
"anthropic"
]
);
assert_eq!(rows[0].auth, "oauth2");
assert_eq!(rows[1].auth, "none");
}
#[test]
fn login_is_blocked_for_every_row_without_an_oauth_block() {
let rows = provider_rows(LIVE_LISTING);
assert_eq!(rows[0].login_blocked(), None, "codex is oauth2");
assert_eq!(
rows[3].login_blocked(),
None,
"claude-session-direct is oauth2"
);
assert_eq!(
rows[1].login_blocked().as_deref(),
Some("keyless — nothing to log in")
);
assert_eq!(
rows[2].login_blocked().as_deref(),
Some("keyless — nothing to log in")
);
assert_eq!(
rows[4].login_blocked().as_deref(),
Some("api-key provider — set the key in Config")
);
}
#[test]
fn a_bearer_row_is_told_where_its_token_lives() {
let rows = provider_rows(r#"{"providers":[{"name":"vertex","auth":"bearer"}]}"#);
assert_eq!(
rows[0].login_blocked().as_deref(),
Some("bearer-token provider — set the token in Config")
);
}
#[test]
fn an_unrecognized_auth_spelling_names_itself_rather_than_guessing() {
let rows = provider_rows(r#"{"providers":[{"name":"x","auth":"mtls"},{"name":"y"}]}"#);
let why = rows[0].login_blocked().expect("not oauth2");
assert!(why.contains("mtls"), "reason quotes the spelling: {why}");
assert!(why.contains("oauth2"), "and names what bz can serve: {why}");
assert!(
rows[1].login_blocked().is_some(),
"an empty column is not oauth2"
);
}
#[test]
fn row_views_state_the_credential_fact_in_words() {
let rows = provider_rows(LIVE_LISTING);
let creds = vec![
("codex".to_string(), true),
("local".to_string(), true),
("claude-code".to_string(), false),
("claude-session-direct".to_string(), false),
("anthropic".to_string(), false),
];
let views = row_views(&rows, &creds);
assert_eq!(
views.iter().map(|v| v.fact.clone()).collect::<Vec<_>>(),
[
"auth oauth2 · signed in",
"auth none · no credential needed",
"auth none · no credential needed",
"auth oauth2 · not signed in",
"auth api_key · no credential stored",
]
);
assert_eq!(views[0].name, "codex");
assert_eq!(
views
.iter()
.map(|v| v.blocked.is_none())
.collect::<Vec<_>>(),
[true, false, false, true, false]
);
assert_eq!(views[4].blocked, rows[4].login_blocked());
}
#[test]
fn a_keyed_row_with_a_credential_file_reports_it_stored_not_signed_in() {
let rows = provider_rows(r#"{"providers":[{"name":"anthropic","auth":"api_key"}]}"#);
let views = row_views(&rows, &[("anthropic".to_string(), true)]);
assert_eq!(views[0].fact, "auth api_key · credential stored");
}
#[test]
fn a_row_the_presence_read_omits_is_credential_less_not_a_hole() {
let rows = provider_rows(r#"{"providers":[{"name":"codex","auth":"oauth2"}]}"#);
let views = row_views(&rows, &[]);
assert_eq!(views[0].fact, "auth oauth2 · not signed in");
assert_eq!(
row_views(&[], &[("codex".to_string(), true)]).len(),
0,
"the table names the rows; the presence list only answers about them"
);
}
#[test]
fn a_shapeless_listing_folds_to_no_rows() {
assert_eq!(provider_rows(""), Vec::new());
assert_eq!(provider_rows("MalformedFile at line 3"), Vec::new());
assert_eq!(provider_rows("{}"), Vec::new());
assert_eq!(provider_rows(r#"{"providers":7}"#), Vec::new());
}
#[test]
fn a_row_missing_a_column_degrades_to_empty_not_loginable() {
let rows = provider_rows(r#"{"providers":[{"nome":"x"},{"name":7,"auth":"oauth2"}]}"#);
assert_eq!(
rows,
[
ProviderRow {
name: String::new(),
protocol: String::new(),
auth: String::new(),
},
ProviderRow {
name: String::new(),
protocol: String::new(),
auth: "oauth2".to_owned(),
},
]
);
assert!(rows[0].login_blocked().is_some());
}
#[test]
fn row_names_projects_the_name_column_in_listing_order() {
let rows = provider_rows(
r#"{"providers":[{"name":"codex","auth":"oauth2"},{"name":"claude-session-direct","auth":"oauth2"}]}"#,
);
assert_eq!(
super::row_names(&rows),
vec!["codex".to_string(), "claude-session-direct".to_string()]
);
assert!(super::row_names(&[]).is_empty());
}