use armature_openapi::*;
#[test]
fn test_openapi_builder_creation() {
let builder = OpenApiBuilder::new("My API", "1.0.0");
let spec = builder.build();
assert_eq!(spec.openapi, "3.0.0");
assert_eq!(spec.info.title, "My API");
assert_eq!(spec.info.version, "1.0.0");
}
#[test]
fn test_openapi_builder_with_description() {
let builder = OpenApiBuilder::new("My API", "1.0.0").description("API Description");
let spec = builder.build();
assert_eq!(spec.info.description, Some("API Description".to_string()));
}
#[test]
fn test_openapi_builder_with_server() {
let builder = OpenApiBuilder::new("My API", "1.0.0")
.server("https://api.example.com", Some("Production".to_string()));
let spec = builder.build();
assert_eq!(spec.servers.len(), 1);
assert_eq!(spec.servers[0].url, "https://api.example.com");
}
#[test]
fn test_openapi_builder_with_path() {
let builder = OpenApiBuilder::new("My API", "1.0.0").path("/users", PathItem::default());
let spec = builder.build();
assert!(spec.paths.contains_key("/users"));
}
#[test]
fn test_openapi_info_creation() {
let info = Info {
title: "Test API".to_string(),
version: "1.0.0".to_string(),
description: Some("Description".to_string()),
terms_of_service: None,
contact: None,
license: None,
};
assert_eq!(info.title, "Test API");
assert_eq!(info.version, "1.0.0");
}
#[test]
fn test_server_creation() {
let server = Server {
url: "https://api.example.com".to_string(),
description: Some("Production".to_string()),
};
assert_eq!(server.url, "https://api.example.com");
}
#[test]
fn test_path_item_default() {
let path = PathItem::default();
assert!(path.get.is_none());
assert!(path.post.is_none());
}
#[test]
fn test_operation_default() {
let op = Operation::default();
assert!(op.tags.is_empty());
assert!(op.summary.is_none());
}
#[test]
fn test_schema_creation() {
let schema = Schema {
schema_type: Some("string".to_string()),
format: None,
description: Some("A string field".to_string()),
properties: None,
required: vec![],
items: None,
reference: None,
};
assert_eq!(schema.schema_type, Some("string".to_string()));
}
#[test]
fn test_swagger_config_creation() {
let spec = OpenApiBuilder::new("My API", "1.0.0").build();
let config = SwaggerConfig::new("/api-docs", spec);
assert_eq!(config.path, "/api-docs");
assert_eq!(config.title, "API Documentation");
}
#[test]
fn test_swagger_config_with_title() {
let spec = OpenApiBuilder::new("My API", "1.0.0").build();
let config = SwaggerConfig::new("/docs", spec).with_title("My API Docs");
assert_eq!(config.path, "/docs");
assert_eq!(config.title, "My API Docs");
}
#[test]
fn test_swagger_ui_response() {
let spec = OpenApiBuilder::new("My API", "1.0.0").build();
let config = SwaggerConfig::new("/api-docs", spec);
let result = swagger_ui_response(&config);
assert!(result.is_ok());
let response = result.unwrap();
let body = String::from_utf8_lossy(&response.body);
assert!(body.contains("<!DOCTYPE html>"));
assert!(body.contains("swagger-ui"));
}
#[test]
fn test_swagger_ui_response_escapes_script_but_not_backslashes() {
let spec = OpenApiBuilder::new("My API", "1.0.0")
.description(r"regex \d+ break</script>injection")
.build();
let config = SwaggerConfig::new("/api-docs", spec);
let body_bytes = swagger_ui_response(&config).unwrap().body;
let body = String::from_utf8(body_bytes.to_vec()).unwrap();
assert!(
body.contains(r"\\d+"),
"expected single JSON-escaped backslash for the \\d+ pattern"
);
assert!(
!body.contains(r"\\\\d+"),
"backslash was double-escaped, corrupting the rendered data"
);
assert!(
body.contains(r"break<\/script>injection"),
"the spec's </script> was not escaped to <\\/script>"
);
assert!(
!body.contains("break</script>injection"),
"a raw </script> from the spec data leaked into the page"
);
}
#[test]
fn test_openapi_spec_serialization() {
let builder = OpenApiBuilder::new("My API", "1.0.0");
let spec = builder.build();
let json = serde_json::to_string(&spec);
assert!(json.is_ok());
let json_str = json.unwrap();
assert!(json_str.contains("My API"));
assert!(json_str.contains("1.0.0"));
}