use std::fs;
use std::process::Command;
use tempfile::TempDir;
fn devboy_bin() -> std::path::PathBuf {
let mut path = std::env::current_exe().unwrap();
path.pop(); path.pop();
let bin_name = format!("devboy{}", std::env::consts::EXE_SUFFIX);
path.push(bin_name);
path
}
fn create_local_config(temp_dir: &TempDir, owner: &str, repo: &str) {
let config_content = format!(
r#"[github]
owner = "{}"
repo = "{}"
"#,
owner, repo
);
fs::write(temp_dir.path().join(".devboy.toml"), config_content).unwrap();
}
#[test]
fn test_issues_uses_local_config() {
let temp_dir = TempDir::new().unwrap();
create_local_config(&temp_dir, "local-owner", "local-repo");
let output = Command::new(devboy_bin())
.args(["issues"])
.env("DEVBOY_SKIP_KEYCHAIN", "1")
.current_dir(temp_dir.path())
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
let config_was_loaded = stderr.contains("GitHub token not set")
|| stderr.contains("Failed to get token")
|| stderr.contains("Failed to fetch issues")
|| stderr.contains("404");
assert!(
config_was_loaded,
"Should load local config and attempt GitHub API. stdout: {}, stderr: {}",
stdout, stderr
);
assert!(
!stdout.contains("No provider configured"),
"Should have found GitHub config from local .devboy.toml"
);
}
#[test]
fn test_mrs_uses_local_config() {
let temp_dir = TempDir::new().unwrap();
create_local_config(&temp_dir, "local-owner-mr", "local-repo-mr");
let output = Command::new(devboy_bin())
.args(["mrs"])
.env("DEVBOY_SKIP_KEYCHAIN", "1")
.current_dir(temp_dir.path())
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
let config_was_loaded = stderr.contains("GitHub token not set")
|| stderr.contains("Failed to get token")
|| stderr.contains("Failed to fetch PRs")
|| stderr.contains("404");
assert!(
config_was_loaded,
"Should load local config and attempt GitHub API. stdout: {}, stderr: {}",
stdout, stderr
);
assert!(
!stdout.contains("No provider configured"),
"Should have found GitHub config from local .devboy.toml"
);
}
#[test]
fn test_test_command_uses_local_config() {
let temp_dir = TempDir::new().unwrap();
create_local_config(&temp_dir, "test-local-owner", "test-local-repo");
let output = Command::new(devboy_bin())
.args(["test", "github"])
.env("DEVBOY_SKIP_KEYCHAIN", "1")
.current_dir(temp_dir.path())
.output()
.expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
let config_was_loaded = stderr.contains("GitHub token not set")
|| stderr.contains("Failed to get token")
|| stdout.contains("Testing GitHub connection")
|| stdout.contains("test-local-owner/test-local-repo");
assert!(
config_was_loaded,
"Should load local config. stdout: {}, stderr: {}",
stdout, stderr
);
assert!(
!stderr.contains("GitHub not configured"),
"Should have found GitHub config from local .devboy.toml"
);
}
#[test]
fn test_local_config_takes_priority_over_global() {
let temp_dir = TempDir::new().unwrap();
let fake_home = TempDir::new().unwrap();
#[cfg(target_os = "windows")]
let global_config_dir = fake_home.path().join("devboy-tools");
#[cfg(not(target_os = "windows"))]
let global_config_dir = fake_home.path().join(".config").join("devboy-tools");
fs::create_dir_all(&global_config_dir).unwrap();
let global_config = r#"# Global config without github
"#;
fs::write(global_config_dir.join("config.toml"), global_config).unwrap();
let local_config = r#"[github]
owner = "local-priority-owner"
repo = "local-priority-repo"
"#;
fs::write(temp_dir.path().join(".devboy.toml"), local_config).unwrap();
let mut cmd = Command::new(devboy_bin());
cmd.args(["issues"])
.env("DEVBOY_SKIP_KEYCHAIN", "1")
.env("HOME", fake_home.path())
.env("USERPROFILE", fake_home.path())
.current_dir(temp_dir.path());
#[cfg(target_os = "windows")]
cmd.env("APPDATA", fake_home.path());
#[cfg(not(target_os = "windows"))]
cmd.env("XDG_CONFIG_HOME", fake_home.path().join(".config"));
let output = cmd.output().expect("Failed to execute command");
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
let local_config_was_used = stderr.contains("GitHub token not set")
|| stderr.contains("Failed to get token")
|| stderr.contains("Failed to fetch issues")
|| stderr.contains("404");
assert!(
local_config_was_used,
"Should use local config (with github section), not global. stdout: {}, stderr: {}",
stdout, stderr
);
assert!(
!stdout.contains("No provider configured"),
"Local config should take priority over global config"
);
}