1use crate::Error;
7use mockforge_core::{
8 request_logger::get_global_logger, verify_at_least, verify_never, verify_requests,
9 verify_sequence, VerificationCount, VerificationRequest, VerificationResult,
10};
11
12pub trait Verification {
14 async fn verify(
42 &self,
43 pattern: &VerificationRequest,
44 expected: VerificationCount,
45 ) -> Result<VerificationResult, Error>;
46
47 async fn verify_never(
75 &self,
76 pattern: &VerificationRequest,
77 ) -> Result<VerificationResult, Error>;
78
79 async fn verify_at_least(
107 &self,
108 pattern: &VerificationRequest,
109 min: usize,
110 ) -> Result<VerificationResult, Error>;
111
112 async fn verify_sequence(
149 &self,
150 patterns: &[VerificationRequest],
151 ) -> Result<VerificationResult, Error>;
152}
153
154impl Verification for crate::server::MockServer {
155 async fn verify(
156 &self,
157 pattern: &VerificationRequest,
158 expected: VerificationCount,
159 ) -> Result<VerificationResult, Error> {
160 let logger = get_global_logger()
161 .ok_or_else(|| Error::General("Request logger not initialized".to_string()))?;
162
163 Ok(verify_requests(logger, pattern, expected).await)
164 }
165
166 async fn verify_never(
167 &self,
168 pattern: &VerificationRequest,
169 ) -> Result<VerificationResult, Error> {
170 let logger = get_global_logger()
171 .ok_or_else(|| Error::General("Request logger not initialized".to_string()))?;
172
173 Ok(verify_never(logger, pattern).await)
174 }
175
176 async fn verify_at_least(
177 &self,
178 pattern: &VerificationRequest,
179 min: usize,
180 ) -> Result<VerificationResult, Error> {
181 let logger = get_global_logger()
182 .ok_or_else(|| Error::General("Request logger not initialized".to_string()))?;
183
184 Ok(verify_at_least(logger, pattern, min).await)
185 }
186
187 async fn verify_sequence(
188 &self,
189 patterns: &[VerificationRequest],
190 ) -> Result<VerificationResult, Error> {
191 let logger = get_global_logger()
192 .ok_or_else(|| Error::General("Request logger not initialized".to_string()))?;
193
194 Ok(verify_sequence(logger, patterns).await)
195 }
196}
197
198#[cfg(test)]
199mod tests {
200 use super::*;
201 use std::collections::HashMap;
202
203 fn create_verification_request(method: &str, path: &str) -> VerificationRequest {
205 VerificationRequest {
206 method: Some(method.to_string()),
207 path: Some(path.to_string()),
208 query_params: HashMap::new(),
209 headers: HashMap::new(),
210 body_pattern: None,
211 }
212 }
213
214 #[test]
215 fn test_verification_request_creation() {
216 let request = create_verification_request("GET", "/api/users");
217 assert_eq!(request.method, Some("GET".to_string()));
218 assert_eq!(request.path, Some("/api/users".to_string()));
219 assert!(request.query_params.is_empty());
220 assert!(request.headers.is_empty());
221 assert!(request.body_pattern.is_none());
222 }
223
224 #[test]
225 fn test_verification_request_with_query_params() {
226 let mut query_params = HashMap::new();
227 query_params.insert("page".to_string(), "1".to_string());
228 query_params.insert("limit".to_string(), "10".to_string());
229
230 let request = VerificationRequest {
231 method: Some("GET".to_string()),
232 path: Some("/api/users".to_string()),
233 query_params,
234 headers: HashMap::new(),
235 body_pattern: None,
236 };
237
238 assert_eq!(request.query_params.len(), 2);
239 assert_eq!(request.query_params.get("page"), Some(&"1".to_string()));
240 assert_eq!(request.query_params.get("limit"), Some(&"10".to_string()));
241 }
242
243 #[test]
244 fn test_verification_request_with_headers() {
245 let mut headers = HashMap::new();
246 headers.insert("Authorization".to_string(), "Bearer token".to_string());
247 headers.insert("Content-Type".to_string(), "application/json".to_string());
248
249 let request = VerificationRequest {
250 method: Some("POST".to_string()),
251 path: Some("/api/users".to_string()),
252 query_params: HashMap::new(),
253 headers,
254 body_pattern: None,
255 };
256
257 assert_eq!(request.headers.len(), 2);
258 assert_eq!(request.headers.get("Authorization"), Some(&"Bearer token".to_string()));
259 }
260
261 #[test]
262 fn test_verification_request_with_body_pattern() {
263 let request = VerificationRequest {
264 method: Some("POST".to_string()),
265 path: Some("/api/users".to_string()),
266 query_params: HashMap::new(),
267 headers: HashMap::new(),
268 body_pattern: Some(r#"{"name":".*"}"#.to_string()),
269 };
270
271 assert_eq!(request.body_pattern, Some(r#"{"name":".*"}"#.to_string()));
272 }
273
274 #[test]
275 fn test_verification_count_exactly() {
276 let count = VerificationCount::Exactly(3);
277 match count {
278 VerificationCount::Exactly(n) => assert_eq!(n, 3),
279 _ => panic!("Expected Exactly variant"),
280 }
281 }
282
283 #[test]
284 fn test_verification_count_at_least() {
285 let count = VerificationCount::AtLeast(2);
286 match count {
287 VerificationCount::AtLeast(n) => assert_eq!(n, 2),
288 _ => panic!("Expected AtLeast variant"),
289 }
290 }
291
292 #[test]
293 fn test_verification_count_at_most() {
294 let count = VerificationCount::AtMost(5);
295 match count {
296 VerificationCount::AtMost(n) => assert_eq!(n, 5),
297 _ => panic!("Expected AtMost variant"),
298 }
299 }
300
301 #[test]
302 fn test_verification_count_never() {
303 let count = VerificationCount::Never;
304 match count {
305 VerificationCount::Never => (),
306 _ => panic!("Expected Never variant"),
307 }
308 }
309
310 #[tokio::test]
311 async fn test_verify_error_when_logger_not_initialized() {
312 let server = crate::server::MockServer::default();
313 let request = create_verification_request("GET", "/api/test");
314
315 let result = server.verify(&request, VerificationCount::Exactly(1)).await;
317
318 if result.is_err() {
321 match result {
322 Err(Error::General(msg)) => {
323 assert!(msg.contains("Request logger not initialized"));
324 }
325 _ => panic!("Expected General error about logger"),
326 }
327 }
328 }
329
330 #[tokio::test]
331 async fn test_verify_never_error_when_logger_not_initialized() {
332 let server = crate::server::MockServer::default();
333 let request = create_verification_request("DELETE", "/api/users/1");
334
335 let result = server.verify_never(&request).await;
336
337 if result.is_err() {
338 match result {
339 Err(Error::General(msg)) => {
340 assert!(msg.contains("Request logger not initialized"));
341 }
342 _ => panic!("Expected General error about logger"),
343 }
344 }
345 }
346
347 #[tokio::test]
348 async fn test_verify_at_least_error_when_logger_not_initialized() {
349 let server = crate::server::MockServer::default();
350 let request = create_verification_request("POST", "/api/orders");
351
352 let result = server.verify_at_least(&request, 2).await;
353
354 if result.is_err() {
355 match result {
356 Err(Error::General(msg)) => {
357 assert!(msg.contains("Request logger not initialized"));
358 }
359 _ => panic!("Expected General error about logger"),
360 }
361 }
362 }
363
364 #[tokio::test]
365 async fn test_verify_sequence_error_when_logger_not_initialized() {
366 let server = crate::server::MockServer::default();
367 let patterns = vec![
368 create_verification_request("POST", "/api/users"),
369 create_verification_request("GET", "/api/users/1"),
370 ];
371
372 let result = server.verify_sequence(&patterns).await;
373
374 if result.is_err() {
375 match result {
376 Err(Error::General(msg)) => {
377 assert!(msg.contains("Request logger not initialized"));
378 }
379 _ => panic!("Expected General error about logger"),
380 }
381 }
382 }
383
384 #[test]
385 fn test_verification_request_all_fields() {
386 let mut query_params = HashMap::new();
387 query_params.insert("id".to_string(), "123".to_string());
388
389 let mut headers = HashMap::new();
390 headers.insert("X-Custom".to_string(), "value".to_string());
391
392 let request = VerificationRequest {
393 method: Some("PUT".to_string()),
394 path: Some("/api/users/123".to_string()),
395 query_params,
396 headers,
397 body_pattern: Some(r#"{"name":"test"}"#.to_string()),
398 };
399
400 assert_eq!(request.method, Some("PUT".to_string()));
401 assert_eq!(request.path, Some("/api/users/123".to_string()));
402 assert_eq!(request.query_params.len(), 1);
403 assert_eq!(request.headers.len(), 1);
404 assert!(request.body_pattern.is_some());
405 }
406
407 #[test]
408 fn test_verification_request_minimal() {
409 let request = VerificationRequest {
410 method: None,
411 path: None,
412 query_params: HashMap::new(),
413 headers: HashMap::new(),
414 body_pattern: None,
415 };
416
417 assert!(request.method.is_none());
418 assert!(request.path.is_none());
419 assert!(request.query_params.is_empty());
420 assert!(request.headers.is_empty());
421 assert!(request.body_pattern.is_none());
422 }
423
424 #[test]
425 fn test_verification_sequence_empty() {
426 let patterns: Vec<VerificationRequest> = vec![];
427 assert_eq!(patterns.len(), 0);
428 }
429
430 #[test]
431 fn test_verification_sequence_single() {
432 let patterns = vec![create_verification_request("GET", "/api/test")];
433 assert_eq!(patterns.len(), 1);
434 }
435
436 #[test]
437 fn test_verification_sequence_multiple() {
438 let patterns = vec![
439 create_verification_request("POST", "/api/users"),
440 create_verification_request("GET", "/api/users/1"),
441 create_verification_request("PUT", "/api/users/1"),
442 create_verification_request("DELETE", "/api/users/1"),
443 ];
444 assert_eq!(patterns.len(), 4);
445 }
446
447 #[test]
448 fn test_verification_with_complex_pattern() {
449 let mut query_params = HashMap::new();
450 query_params.insert("filter".to_string(), "active".to_string());
451 query_params.insert("sort".to_string(), "name".to_string());
452
453 let mut headers = HashMap::new();
454 headers.insert("Accept".to_string(), "application/json".to_string());
455 headers.insert("X-API-Key".to_string(), "secret".to_string());
456
457 let request = VerificationRequest {
458 method: Some("GET".to_string()),
459 path: Some("/api/users".to_string()),
460 query_params,
461 headers,
462 body_pattern: None,
463 };
464
465 assert_eq!(request.method, Some("GET".to_string()));
466 assert_eq!(request.query_params.len(), 2);
467 assert_eq!(request.headers.len(), 2);
468 }
469}