mockforge_core/
openapi.rs

1//! OpenAPI specification handling and utilities
2//!
3//! This module has been refactored into sub-modules for better organization:
4//! - spec: OpenAPI specification loading and parsing
5//! - schema: Schema validation and handling
6//! - route: Route generation from OpenAPI paths
7//! - validation: Request/response validation against schemas
8//! - response: Mock response generation based on schemas
9
10// Re-export sub-modules for backward compatibility
11pub mod response;
12pub mod response_selection;
13pub mod route;
14pub mod schema;
15pub mod spec;
16pub mod validation;
17
18// Re-export commonly used types (avoiding conflicts)
19pub use response::*;
20pub use response_selection::*;
21pub use route::*;
22pub use schema::*;
23pub use spec::*;
24pub use validation::*;
25
26/// Wrapper for OpenAPI operation with enhanced metadata
27#[derive(Debug, Clone)]
28pub struct OpenApiOperation {
29    /// HTTP method (GET, POST, PUT, etc.)
30    pub method: String,
31    /// API path (e.g., "/api/users/{id}")
32    pub path: String,
33    /// OpenAPI operation specification
34    pub operation: openapiv3::Operation,
35    /// Security requirements for this operation
36    pub security: Option<Vec<openapiv3::SecurityRequirement>>,
37}
38
39impl OpenApiOperation {
40    /// Create a new OpenAPI operation wrapper
41    pub fn new(method: String, path: String, operation: openapiv3::Operation) -> Self {
42        Self {
43            method,
44            path,
45            operation: operation.clone(),
46            security: operation.security.clone(),
47        }
48    }
49
50    /// Create an operation from an OpenAPI operation reference
51    pub fn from_operation(
52        method: &str,
53        path: String,
54        operation: &openapiv3::Operation,
55        _spec: &OpenApiSpec,
56    ) -> Self {
57        Self::new(method.to_string(), path, operation.clone())
58    }
59}
60
61/// Type alias for OpenAPI security requirements
62pub type OpenApiSecurityRequirement = openapiv3::SecurityRequirement;
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn test_openapi_operation_new() {
70        let operation = openapiv3::Operation::default();
71        let op = OpenApiOperation::new("GET".to_string(), "/test".to_string(), operation);
72
73        assert_eq!(op.method, "GET");
74        assert_eq!(op.path, "/test");
75        assert!(op.security.is_none());
76    }
77
78    #[test]
79    fn test_openapi_operation_with_security() {
80        let operation = openapiv3::Operation {
81            security: Some(vec![]),
82            ..Default::default()
83        };
84
85        let op = OpenApiOperation::new("POST".to_string(), "/secure".to_string(), operation);
86
87        assert_eq!(op.method, "POST");
88        assert_eq!(op.path, "/secure");
89        assert!(op.security.is_some());
90    }
91
92    #[test]
93    fn test_openapi_operation_from_operation() {
94        let operation = openapiv3::Operation::default();
95        let spec = OpenApiSpec::from_json(serde_json::json!({
96            "openapi": "3.0.0",
97            "info": {"title": "Test", "version": "1.0.0"},
98            "paths": {}
99        }))
100        .unwrap();
101
102        let op =
103            OpenApiOperation::from_operation("PUT", "/resource".to_string(), &operation, &spec);
104
105        assert_eq!(op.method, "PUT");
106        assert_eq!(op.path, "/resource");
107    }
108
109    #[test]
110    fn test_openapi_operation_clone() {
111        let operation = openapiv3::Operation::default();
112        let op1 = OpenApiOperation::new("GET".to_string(), "/test".to_string(), operation);
113        let op2 = op1.clone();
114
115        assert_eq!(op1.method, op2.method);
116        assert_eq!(op1.path, op2.path);
117    }
118}