mod common;
use predicates::prelude::*;
use tempfile::TempDir;
use wiremock::matchers::{method, path};
use wiremock::{Mock, MockServer, ResponseTemplate};
use common::{dkp_cmd, scaffold_pack};
#[tokio::test]
async fn generate_missing_api_key_fails_without_any_network_call() {
let tmp = TempDir::new().unwrap();
let pack = scaffold_pack(tmp.path(), "gen-pack", "testing");
dkp_cmd()
.arg("generate")
.arg(&pack)
.env_remove("DKP_GEN_API_KEY")
.env("HOME", tmp.path()) .assert()
.failure()
.stderr(predicate::str::contains("API key required"));
}
#[tokio::test]
async fn generate_against_mock_server_writes_generated_assets() {
let tmp = TempDir::new().unwrap();
let pack = scaffold_pack(tmp.path(), "gen-mock-pack", "testing");
let server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/chat/completions"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"choices": [{"message": {"content": "{\"terms\":[],\"rules\":[],\"entity_types\":[],\"edge_cases\":[],\"anti_patterns\":[],\"hard_limits\":[],\"trees\":[]}"}}]
})))
.mount(&server)
.await;
dkp_cmd()
.arg("generate")
.arg(&pack)
.arg("--api-key")
.arg("test-key")
.arg("--base-url")
.arg(server.uri())
.arg("--overwrite")
.arg("--no-tools")
.assert()
.success();
let content = std::fs::read_to_string(pack.join("machine/rules.json")).unwrap();
let rules: serde_json::Value = serde_json::from_str(&content).unwrap();
assert_eq!(rules["rules"].as_array().unwrap().len(), 0);
}
#[tokio::test]
async fn generate_with_tools_enabled_but_no_search_key_fails_fast() {
let tmp = TempDir::new().unwrap();
let pack = scaffold_pack(tmp.path(), "gen-no-search-key-pack", "testing");
dkp_cmd()
.arg("generate")
.arg(&pack)
.arg("--api-key")
.arg("test-key")
.env_remove("DKP_GEN_SEARCH_API_KEY")
.env("HOME", tmp.path()) .assert()
.failure()
.stderr(predicate::str::contains("no search API key is set"));
}