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