use super::snapshot;
use crate::boundary::dispatch::{Deps, prompt};
use crate::bz_host::store::WallCredStore;
use crate::cli_outbound::Cli;
use crate::config_edit::brazen::BrazenPaths;
use crate::git_tree::tests::fixture::Fixture;
use crate::opslog::Origin;
use crate::start::Prepared;
use crate::test_support::world_under;
use crate::ui_state::UiState;
use brazen::{Cred, CredStore as _, Secret};
use std::path::PathBuf;
use std::sync::Arc;
const REFUSAL: &str = "sign in first";
const TABLE: &str = "[[provider]]\nname = \"keyed\"\nprotocol = \"openai_chat\"\n\
base_url = \"https://keyed.test\"\nauth = \"api_key\"\n\
api_header = { name = \"x-api-key\", scheme = \"raw\" }\n\n\
[[provider]]\nname = \"other\"\nprotocol = \"openai_chat\"\n\
base_url = \"https://other.test\"\nauth = \"api_key\"\n\
api_header = { name = \"x-api-key\", scheme = \"raw\" }\n\n\
[[provider]]\nname = \"local\"\nprotocol = \"openai_chat\"\n\
base_url = \"http://localhost:1\"\nauth = \"none\"\n";
struct Wall {
fixture: Fixture,
world: crate::xdg::Env,
state: PathBuf,
}
impl Wall {
fn new() -> Self {
let fixture = Fixture::new();
let world = world_under(&fixture.path.join("world"));
let paths = BrazenPaths::in_wall(&crate::world::wall::root_of(&world, &fixture.path));
std::fs::create_dir_all(paths.config.parent().expect("brazen dir")).unwrap();
std::fs::write(&paths.config, TABLE).unwrap();
Self {
state: fixture.path.join("state"),
fixture,
world,
}
}
fn workspace(&self) -> PathBuf {
self.fixture.path.clone()
}
fn sign_in(&self) {
let paths =
BrazenPaths::in_wall(&crate::world::wall::root_of(&self.world, &self.workspace()));
WallCredStore::new(paths.credentials_dir, self.world.clone())
.put(
"keyed",
&Cred::ApiKey {
key: Secret::new("k-notreal"),
},
)
.unwrap();
}
fn deps(&self) -> Deps {
let ws = self.workspace();
Deps {
litany: Cli::new("/no/such/litany"),
bl: Cli::new("/no/such/bl"),
state_root: self.state.clone(),
yog_binary: PathBuf::from("/no/such/yog"),
world: self.world.clone(),
home: self.fixture.path.join("home"),
yog_data_root: self.fixture.path.join("data"),
snapshot: Arc::new(snapshot(&ws, "alba", vec![], vec![])),
caller: crate::boundary::dispatch::Caller::default(),
}
}
fn fire(&self) -> Result<String, String> {
let ui = UiState::open(PathBuf::from("/nonexistent/ui.json"));
prompt(
&self.deps(),
&ui,
"T1",
&self.workspace(),
&prepared(),
"do the thing",
None,
)
}
fn trail(&self) -> bool {
self.state.join("ops.jsonl").exists()
}
}
fn prepared() -> Prepared {
Prepared {
workspace: "alba".to_owned(),
binding: None,
lineage: None,
role: None,
goal: String::new(),
origin: Origin::Conversation,
}
}
#[test]
fn an_unsigned_wall_refuses_the_fire_and_pays_nothing() {
let wall = Wall::new();
let refusal = wall.fire().unwrap_err();
assert!(refusal.starts_with(REFUSAL), "{refusal}");
assert!(refusal.contains("/login"), "{refusal}");
assert!(refusal.contains("keyed"), "the rows are named: {refusal}");
assert!(!wall.trail(), "a refused fire costs no trail row");
}
#[test]
fn a_signed_wall_passes_the_gate() {
let wall = Wall::new();
wall.sign_in();
let past = wall.fire().unwrap_err();
assert!(!past.contains(REFUSAL), "{past}");
assert!(wall.trail(), "the fire reached the spawn and left its row");
}
#[test]
fn a_role_naming_a_keyless_row_readies_the_wall() {
let wall = Wall::new();
assert!(wall.fire().unwrap_err().starts_with(REFUSAL));
wall.fixture.commit_other(
"providers.yaml",
"roles:\n worker:\n provider: local\n model: tiny\n",
);
let past = wall.fire().unwrap_err();
assert!(!past.contains(REFUSAL), "{past}");
}
#[test]
fn a_role_naming_an_unsigned_keyed_row_is_still_refused() {
let wall = Wall::new();
wall.fixture.commit_other(
"providers.yaml",
"roles:\n worker:\n provider: keyed\n model: big\n",
);
assert!(wall.fire().unwrap_err().starts_with(REFUSAL));
assert!(!wall.trail());
}
#[test]
fn a_credential_on_a_row_no_role_names_readies_nothing() {
let wall = Wall::new();
wall.sign_in();
wall.fixture.commit_other(
"providers.yaml",
"roles:\n worker:\n provider: other\n model: big\n",
);
let refusal = wall.fire().unwrap_err();
assert!(refusal.starts_with(REFUSAL), "{refusal}");
assert!(
refusal.contains("`worker` resolves provider `other`"),
"{refusal}"
);
assert!(!wall.trail(), "a refused fire costs no trail row");
}
#[test]
fn a_role_naming_a_row_the_wall_lacks_is_not_a_sign_in() {
let wall = Wall::new();
wall.sign_in();
wall.fixture.commit_other(
"providers.yaml",
"roles:\n worker:\n provider: nowhere\n model: big\n",
);
let refusal = wall.fire().unwrap_err();
assert!(refusal.contains("declares no such row"), "{refusal}");
assert!(!refusal.contains("/login"), "{refusal}");
assert!(refusal.contains("/config brazen"), "{refusal}");
assert!(!wall.trail(), "a refused fire costs no trail row");
}
#[test]
fn an_unanswerable_table_refuses_nothing() {
let wall = Wall::new();
let paths = BrazenPaths::in_wall(&crate::world::wall::root_of(&wall.world, &wall.workspace()));
std::fs::write(&paths.config, "[[provider]\nthis is not toml\n").unwrap();
let past = wall.fire().unwrap_err();
assert!(!past.contains(REFUSAL), "{past}");
}