mockforge_import/import/
postman_environment.rs1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9#[derive(Debug, Deserialize)]
11pub struct PostmanEnvironment {
12 pub id: Option<String>,
14 pub name: Option<String>,
16 #[serde(default)]
18 pub values: Vec<EnvironmentValue>,
19}
20
21#[derive(Debug, Deserialize)]
23pub struct EnvironmentValue {
24 pub key: String,
26 pub value: Option<String>,
28 pub description: Option<String>,
30 #[serde(default = "default_enabled")]
32 pub enabled: bool,
33}
34
35#[derive(Debug)]
37pub struct EnvironmentImportResult {
38 pub name: String,
40 pub variables: HashMap<String, EnvironmentVariable>,
42 pub enabled_count: usize,
44 pub total_count: usize,
46}
47
48#[derive(Debug, Serialize, Clone)]
50pub struct EnvironmentVariable {
51 pub value: String,
53 pub description: Option<String>,
55 pub enabled: bool,
57 pub source: VariableSource,
59}
60
61#[derive(Debug, Serialize, Clone)]
63pub enum VariableSource {
64 Environment(String),
66 Collection,
68}
69
70fn default_enabled() -> bool {
71 true
72}
73
74pub fn import_postman_environment(content: &str) -> Result<EnvironmentImportResult, String> {
76 let environment: PostmanEnvironment = serde_json::from_str(content)
77 .map_err(|e| format!("Failed to parse Postman environment: {}", e))?;
78
79 let mut variables = HashMap::new();
80 let mut enabled_count = 0;
81 let mut total_count = 0;
82
83 let env_name = environment.name.unwrap_or_else(|| "Unnamed Environment".to_string());
84
85 for env_value in environment.values {
86 total_count += 1;
87
88 if env_value.enabled && env_value.value.is_some() {
89 enabled_count += 1;
90 let variable = EnvironmentVariable {
91 value: env_value.value.unwrap(),
92 description: env_value.description,
93 enabled: env_value.enabled,
94 source: VariableSource::Environment(env_name.clone()),
95 };
96 variables.insert(env_value.key, variable);
97 }
98 }
99
100 Ok(EnvironmentImportResult {
101 name: env_name,
102 variables,
103 enabled_count,
104 total_count,
105 })
106}
107
108pub fn is_postman_environment_json(content: &str) -> bool {
110 if let Ok(json) = serde_json::from_str::<serde_json::Value>(content) {
111 if let Some(obj) = json.as_object() {
112 let has_values = obj.contains_key("values");
114 let has_name_or_id = obj.contains_key("name") || obj.contains_key("id");
115
116 let values_is_array = if let Some(values) = obj.get("values") {
118 values.is_array()
119 } else {
120 false
121 };
122
123 if has_values && has_name_or_id && values_is_array {
124 if let Some(values_array) = obj.get("values") {
126 if let Some(arr) = values_array.as_array() {
127 if !arr.is_empty() {
128 if let Some(first_item) = arr.first() {
130 if let Some(item_obj) = first_item.as_object() {
131 let has_key = item_obj.contains_key("key");
132 let has_value = item_obj.contains_key("value")
133 || item_obj.contains_key("enabled");
134 return has_key && has_value;
135 }
136 }
137 }
138 }
139 }
140 }
141 }
142 }
143 false
144}
145
146#[cfg(test)]
147mod tests {
148 use super::*;
149
150 #[test]
151 fn test_parse_postman_environment() {
152 let env_json = r#"{
153 "id": "env-123",
154 "name": "Development Environment",
155 "values": [
156 {
157 "key": "base_url",
158 "value": "https://api.dev.example.com",
159 "description": "API base URL",
160 "enabled": true
161 },
162 {
163 "key": "api_key",
164 "value": "dev-key-123",
165 "enabled": true
166 },
167 {
168 "key": "disabled_var",
169 "value": "should_not_import",
170 "enabled": false
171 }
172 ]
173 }"#;
174
175 let result = import_postman_environment(env_json).unwrap();
176
177 assert_eq!(result.name, "Development Environment");
178 assert_eq!(result.total_count, 3);
179 assert_eq!(result.enabled_count, 2);
180 assert_eq!(result.variables.len(), 2);
181
182 let base_url_var = result.variables.get("base_url").unwrap();
184 assert_eq!(base_url_var.value, "https://api.dev.example.com");
185 assert_eq!(base_url_var.description.as_ref().unwrap(), "API base URL");
186 assert!(base_url_var.enabled);
187
188 let api_key_var = result.variables.get("api_key").unwrap();
190 assert_eq!(api_key_var.value, "dev-key-123");
191 assert!(api_key_var.enabled);
192 }
193
194 #[test]
195 fn test_detect_postman_environment() {
196 let env_json = r#"{
197 "id": "env-123",
198 "name": "Test Environment",
199 "values": [
200 {
201 "key": "test_var",
202 "value": "test_value",
203 "enabled": true
204 }
205 ]
206 }"#;
207
208 assert!(is_postman_environment_json(env_json));
209
210 let not_env_json = r#"{
211 "info": {
212 "name": "Test Collection"
213 },
214 "item": []
215 }"#;
216
217 assert!(!is_postman_environment_json(not_env_json));
218 }
219
220 #[test]
221 fn test_parse_minimal_environment() {
222 let minimal_env_json = r#"{
223 "values": [
224 {
225 "key": "minimal_var",
226 "value": "minimal_value",
227 "enabled": true
228 }
229 ]
230 }"#;
231
232 let result = import_postman_environment(minimal_env_json).unwrap();
233
234 assert_eq!(result.name, "Unnamed Environment");
235 assert_eq!(result.total_count, 1);
236 assert_eq!(result.enabled_count, 1);
237 assert_eq!(result.variables.len(), 1);
238 }
239}