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