stormchaser_cli/commands/
run.rs1use crate::utils::{handle_run_response, parse_key_val_list, require_token};
2use anyhow::Result;
3use serde_json::json;
4use std::fs;
5use std::path::PathBuf;
6
7pub async fn handle(
8 url: &str,
9 token: Option<&str>,
10 http_client: &reqwest_middleware::ClientWithMiddleware,
11 file: PathBuf,
12 input: Vec<String>,
13 tail: bool,
14 watch: bool,
15) -> Result<()> {
16 let dsl = fs::read_to_string(file)?;
17 let inputs = parse_key_val_list(input);
18 let token = require_token(token)?;
19
20 let res = http_client
21 .post(format!("{}/api/v1/runs/direct", url))
22 .header("Authorization", format!("Bearer {}", token))
23 .json(&json!({ "dsl": dsl, "inputs": inputs }))
24 .send()
25 .await?;
26
27 handle_run_response(http_client, url, token, res, tail, watch).await
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33 use reqwest_middleware::ClientBuilder;
34 use std::io::Write;
35 use tempfile::NamedTempFile;
36 use wiremock::matchers::{header, method, path};
37 use wiremock::{Mock, MockServer, ResponseTemplate};
38
39 #[tokio::test]
40 async fn test_run_handle() {
41 let server = MockServer::start().await;
42 Mock::given(method("POST"))
43 .and(path("/api/v1/runs/direct"))
44 .and(header("Authorization", "Bearer test-token"))
45 .respond_with(ResponseTemplate::new(200).set_body_json(json!({
46 "id": "12345678-1234-1234-1234-123456789012",
47 "status": "queued"
48 })))
49 .mount(&server)
50 .await;
51
52 let client = ClientBuilder::new(reqwest::Client::new()).build();
53
54 let mut temp_file = NamedTempFile::new().unwrap();
55 writeln!(temp_file, "workflow \"test\" {{}}").unwrap();
56
57 let input = vec!["param=value".to_string()];
58
59 let result = handle(
60 &server.uri(),
61 Some("test-token"),
62 &client,
63 temp_file.path().to_path_buf(),
64 input,
65 false,
66 false,
67 )
68 .await;
69
70 assert!(result.is_ok());
71 }
72}