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