openzeppelin_monitor/services/trigger/script/
validation.rs1use crate::models::{ConfigError, ScriptLanguage};
6use std::path::Path;
7
8#[allow(clippy::result_large_err)]
19pub fn validate_script_config(
20 script_path: &str,
21 language: &ScriptLanguage,
22 timeout_ms: &u32,
23) -> Result<(), ConfigError> {
24 if !Path::new(script_path).exists() {
26 return Err(ConfigError::validation_error(
27 format!("Script path does not exist: {}", script_path),
28 None,
29 None,
30 ));
31 }
32
33 let script_path_instance = Path::new(script_path);
34 let extension = script_path_instance
36 .extension()
37 .and_then(|ext| ext.to_str())
38 .unwrap_or("");
39
40 let valid_extension = match language {
41 ScriptLanguage::Python => extension == "py",
42 ScriptLanguage::JavaScript => extension == "js",
43 ScriptLanguage::Bash => extension == "sh",
44 };
45
46 if !valid_extension {
47 return Err(ConfigError::validation_error(
48 format!(
49 "Script file extension does not match specified language {:?}: {}",
50 language, script_path
51 ),
52 None,
53 None,
54 ));
55 }
56
57 if *timeout_ms == 0 {
59 return Err(ConfigError::validation_error(
60 "Timeout must be greater than 0".to_string(),
61 None,
62 None,
63 ));
64 }
65
66 Ok(())
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use std::fs;
73 use tempfile::NamedTempFile;
74
75 #[test]
76 fn test_validate_script_config_valid_python() {
77 let temp_file = NamedTempFile::new().unwrap();
78 let path = temp_file.path().to_str().unwrap().to_string();
79 let python_path = path + ".py";
80 fs::rename(temp_file.path(), &python_path).unwrap();
81
82 let result = validate_script_config(&python_path, &ScriptLanguage::Python, &1000);
83
84 assert!(result.is_ok());
85 fs::remove_file(python_path).unwrap();
86 }
87
88 #[test]
89 fn test_validate_script_config_invalid_path() {
90 let result =
91 validate_script_config("nonexistent_script.py", &ScriptLanguage::Python, &1000);
92
93 assert!(result.is_err());
94 if let Err(e) = result {
95 assert!(e.to_string().contains("Script path does not exist"));
96 }
97 }
98
99 #[test]
100 fn test_validate_script_config_wrong_extension() {
101 let temp_file = NamedTempFile::new().unwrap();
102 let path = temp_file.path().to_str().unwrap().to_string();
103 let wrong_path = path + ".py";
104 fs::rename(temp_file.path(), &wrong_path).unwrap();
105
106 let result = validate_script_config(&wrong_path, &ScriptLanguage::JavaScript, &1000);
107
108 assert!(result.is_err());
109 if let Err(e) = result {
110 assert!(e.to_string().contains("does not match specified language"));
111 }
112 fs::remove_file(wrong_path).unwrap();
113 }
114
115 #[test]
116 fn test_validate_script_config_zero_timeout() {
117 let temp_file = NamedTempFile::new().unwrap();
118 let path = temp_file.path().to_str().unwrap().to_string();
119 let python_path = path + ".py";
120 fs::rename(temp_file.path(), &python_path).unwrap();
121
122 let result = validate_script_config(&python_path, &ScriptLanguage::Python, &0);
123
124 assert!(result.is_err());
125 if let Err(e) = result {
126 assert!(e.to_string().contains("Timeout must be greater than 0"));
127 }
128 fs::remove_file(python_path).unwrap();
129 }
130}