use crate::mock_generator::{MockDataGenerator, MockGeneratorConfig};
use crate::mock_server::{MockServer, MockServerBuilder, MockServerConfig};
use serde_json::{json, Value};
fn create_test_openapi_spec() -> Value {
json!({
"openapi": "3.0.3",
"info": {
"title": "Test API",
"version": "1.0.0",
"description": "A test API for mock data generation"
},
"paths": {
"/api/users": {
"get": {
"summary": "List users",
"responses": {
"200": {
"description": "List of users",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"users": {
"type": "array",
"items": {
"$ref": "#/components/schemas/User"
}
},
"total": {
"type": "integer",
"minimum": 0
}
},
"required": ["users", "total"]
}
}
}
}
}
},
"post": {
"summary": "Create user",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateUserRequest"
}
}
}
},
"responses": {
"201": {
"description": "User created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/User"
}
}
}
}
}
}
},
"/api/users/{id}": {
"get": {
"summary": "Get user by ID",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "User details",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/User"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"User": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 18,
"maximum": 120
},
"active": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"profile": {
"$ref": "#/components/schemas/UserProfile"
}
},
"required": ["id", "name", "email", "age", "active", "created_at"]
},
"UserProfile": {
"type": "object",
"properties": {
"bio": {
"type": "string",
"maxLength": 500
},
"avatar_url": {
"type": "string",
"format": "uri"
},
"location": {
"type": "string"
},
"website": {
"type": "string",
"format": "uri"
}
}
},
"CreateUserRequest": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 18,
"maximum": 120
}
},
"required": ["name", "email", "age"]
}
}
}
})
}
fn create_test_json_schema() -> Value {
json!({
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 50
},
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 18,
"maximum": 100
},
"active": {
"type": "boolean"
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"maxItems": 5
},
"metadata": {
"type": "object",
"properties": {
"created_at": {
"type": "string",
"format": "date-time"
},
"last_login": {
"type": "string",
"format": "date-time"
}
}
}
},
"required": ["id", "name", "email", "age", "active"]
})
}
#[cfg(test)]
mod mock_generator_tests {
use super::*;
#[test]
fn test_mock_generator_config_default() {
let config = MockGeneratorConfig::default();
assert!(config.realistic_mode);
assert_eq!(config.default_array_size, 3);
assert_eq!(config.max_array_size, 10);
assert!(config.include_optional_fields);
assert!(config.validate_generated_data);
assert!(config.field_mappings.is_empty());
}
#[test]
fn test_mock_generator_config_builder() {
let config = MockGeneratorConfig::new()
.realistic_mode(false)
.default_array_size(5)
.max_array_size(20)
.include_optional_fields(false)
.field_mapping("email".to_string(), "email".to_string())
.validate_generated_data(false);
assert!(!config.realistic_mode);
assert_eq!(config.default_array_size, 5);
assert_eq!(config.max_array_size, 20);
assert!(!config.include_optional_fields);
assert!(!config.validate_generated_data);
assert!(config.field_mappings.contains_key("email"));
}
#[test]
fn test_mock_data_generator_new() {
let _generator = MockDataGenerator::new();
}
#[test]
fn test_mock_data_generator_with_config() {
let config = MockGeneratorConfig::new().realistic_mode(false).default_array_size(10);
let _generator = MockDataGenerator::with_config(config);
}
#[test]
fn test_generate_from_json_schema_simple() {
let mut generator = MockDataGenerator::new();
let schema = json!({
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" },
"email": { "type": "string" }
},
"required": ["name", "age"]
});
let result = generator.generate_from_json_schema(&schema).unwrap();
assert!(result.is_object());
let obj = result.as_object().unwrap();
assert!(obj.contains_key("name"));
assert!(obj.contains_key("age"));
assert!(obj.contains_key("email"));
}
#[test]
fn test_generate_from_json_schema_with_constraints() {
let mut generator = MockDataGenerator::new();
let schema = json!({
"type": "object",
"properties": {
"age": {
"type": "integer",
"minimum": 18,
"maximum": 65
},
"name": {
"type": "string",
"minLength": 5,
"maxLength": 20
}
}
});
let result = generator.generate_from_json_schema(&schema).unwrap();
assert!(result.is_object());
let obj = result.as_object().unwrap();
if let Some(age) = obj.get("age") {
if let Some(age_num) = age.as_i64() {
assert!(age_num >= 18);
assert!(age_num <= 65);
}
}
}
#[test]
fn test_generate_from_json_schema_with_enum() {
let mut generator = MockDataGenerator::new();
let schema = json!({
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["active", "inactive", "pending"]
}
}
});
let result = generator.generate_from_json_schema(&schema).unwrap();
assert!(result.is_object());
let obj = result.as_object().unwrap();
if let Some(status) = obj.get("status") {
if let Some(status_str) = status.as_str() {
assert!(["active", "inactive", "pending"].contains(&status_str));
}
}
}
#[test]
fn test_generate_from_json_schema_with_array() {
let mut generator = MockDataGenerator::new();
let schema = json!({
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 2,
"maxItems": 5
}
}
});
let result = generator.generate_from_json_schema(&schema).unwrap();
assert!(result.is_object());
let obj = result.as_object().unwrap();
if let Some(tags) = obj.get("tags") {
if let Some(tags_array) = tags.as_array() {
assert!(tags_array.len() >= 2);
assert!(tags_array.len() <= 5);
}
}
}
#[test]
fn test_generate_from_json_schema_nested_object() {
let mut generator = MockDataGenerator::new();
let schema = json!({
"type": "object",
"properties": {
"user": {
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string", "format": "email" }
},
"required": ["name", "email"]
}
}
});
let result = generator.generate_from_json_schema(&schema).unwrap();
assert!(result.is_object());
let obj = result.as_object().unwrap();
if let Some(user) = obj.get("user") {
assert!(user.is_object());
let user_obj = user.as_object().unwrap();
assert!(user_obj.contains_key("name"));
assert!(user_obj.contains_key("email"));
}
}
#[test]
fn test_generate_from_openapi_spec() {
let mut generator = MockDataGenerator::new();
let spec = create_test_openapi_spec();
let result = generator.generate_from_openapi_spec(&spec).unwrap();
assert!(!result.schemas.is_empty());
assert!(!result.responses.is_empty());
assert_eq!(result.spec_info.title, "Test API");
assert_eq!(result.spec_info.version, "1.0.0");
}
#[test]
fn test_generate_from_openapi_spec_with_validation() {
let config = MockGeneratorConfig::new().validate_generated_data(true).realistic_mode(true);
let mut generator = MockDataGenerator::with_config(config);
let spec = create_test_openapi_spec();
let result = generator.generate_from_openapi_spec(&spec).unwrap();
assert!(!result.schemas.is_empty());
assert!(!result.responses.is_empty());
assert!(result.schemas.contains_key("User"));
assert!(result.schemas.contains_key("UserProfile"));
}
#[test]
fn test_field_pattern_matching() {
let _generator = MockDataGenerator::new();
}
#[test]
fn test_custom_field_mapping() {
let config = MockGeneratorConfig::new()
.field_mapping("custom_field".to_string(), "email".to_string());
let _generator = MockDataGenerator::with_config(config);
}
#[test]
fn test_optional_fields_exclusion() {
let config = MockGeneratorConfig::new().include_optional_fields(false);
let mut generator = MockDataGenerator::with_config(config);
let schema = json!({
"type": "object",
"properties": {
"required_field": { "type": "string" },
"optional_field": { "type": "string" }
},
"required": ["required_field"]
});
let result = generator.generate_from_json_schema(&schema).unwrap();
assert!(result.is_object());
let obj = result.as_object().unwrap();
assert!(obj.contains_key("required_field"));
assert!(!obj.contains_key("optional_field"));
}
#[test]
fn test_optional_fields_inclusion() {
let config = MockGeneratorConfig::new().include_optional_fields(true);
let mut generator = MockDataGenerator::with_config(config);
let schema = json!({
"type": "object",
"properties": {
"required_field": { "type": "string" },
"optional_field": { "type": "string" }
},
"required": ["required_field"]
});
let result = generator.generate_from_json_schema(&schema).unwrap();
assert!(result.is_object());
let obj = result.as_object().unwrap();
assert!(obj.contains_key("required_field"));
assert!(obj.contains_key("optional_field"));
}
}
#[cfg(test)]
mod mock_server_tests {
use super::*;
#[test]
fn test_mock_server_config_default() {
let spec = create_test_openapi_spec();
let config = MockServerConfig::new(spec);
assert_eq!(config.port, 3000);
assert_eq!(config.host, "127.0.0.1");
assert!(config.enable_cors);
assert!(config.log_requests);
assert!(config.response_delays.is_empty());
}
#[test]
fn test_mock_server_config_builder() {
let spec = create_test_openapi_spec();
let config = MockServerConfig::new(spec)
.port(8080)
.host("0.0.0.0".to_string())
.enable_cors(false)
.response_delay("/api/users".to_string(), 100)
.log_requests(false);
assert_eq!(config.port, 8080);
assert_eq!(config.host, "0.0.0.0");
assert!(!config.enable_cors);
assert!(!config.log_requests);
assert!(config.response_delays.contains_key("/api/users"));
assert_eq!(config.response_delays.get("/api/users"), Some(&100));
}
#[test]
fn test_mock_server_builder() {
let spec = create_test_openapi_spec();
let _builder = MockServerBuilder::new(spec)
.port(8080)
.host("0.0.0.0".to_string())
.enable_cors(false);
}
#[test]
fn test_mock_server_creation() {
let spec = create_test_openapi_spec();
let config = MockServerConfig::new(spec);
let server = MockServer::new(config);
assert!(server.is_ok());
}
#[test]
fn test_endpoints_match_exact() {
assert!(MockServer::endpoints_match("GET /api/users", "GET /api/users"));
assert!(!MockServer::endpoints_match("GET /api/users", "POST /api/users"));
assert!(!MockServer::endpoints_match("GET /api/users", "GET /api/products"));
}
#[test]
fn test_endpoints_match_with_params() {
assert!(MockServer::endpoints_match("GET /api/users/:id", "GET /api/users/123"));
assert!(MockServer::endpoints_match("GET /api/users/:id", "GET /api/users/abc"));
}
}
#[cfg(test)]
mod integration_tests {
use super::*;
#[test]
fn test_full_openapi_generation_workflow() {
let spec = create_test_openapi_spec();
let config = MockGeneratorConfig::new()
.realistic_mode(true)
.include_optional_fields(true)
.validate_generated_data(true);
let mut generator = MockDataGenerator::with_config(config);
let result = generator.generate_from_openapi_spec(&spec).unwrap();
assert!(!result.schemas.is_empty());
assert!(result.schemas.contains_key("User"));
assert!(result.schemas.contains_key("UserProfile"));
assert!(result.schemas.contains_key("CreateUserRequest"));
assert!(!result.responses.is_empty());
if let Some(user_data) = result.schemas.get("User") {
assert!(user_data.is_object());
let user_obj = user_data.as_object().unwrap();
if let Some(email) = user_obj.get("email") {
if let Some(email_str) = email.as_str() {
assert!(email_str.contains('@'));
}
}
if let Some(age) = user_obj.get("age") {
if let Some(age_num) = age.as_i64() {
assert!(age_num >= 18);
assert!(age_num <= 120);
}
}
}
}
#[test]
fn test_complex_nested_schema_generation() {
let schema = json!({
"type": "object",
"properties": {
"user": {
"type": "object",
"properties": {
"id": { "type": "string", "format": "uuid" },
"profile": {
"type": "object",
"properties": {
"name": { "type": "string" },
"contact": {
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" },
"phone": { "type": "string" }
}
}
}
}
}
},
"metadata": {
"type": "object",
"properties": {
"created_at": { "type": "string", "format": "date-time" },
"tags": {
"type": "array",
"items": { "type": "string" }
}
}
}
}
});
let mut generator = MockDataGenerator::new();
let result = generator.generate_from_json_schema(&schema).unwrap();
assert!(result.is_object());
let obj = result.as_object().unwrap();
if let Some(user) = obj.get("user") {
assert!(user.is_object());
let user_obj = user.as_object().unwrap();
if let Some(profile) = user_obj.get("profile") {
assert!(profile.is_object());
let profile_obj = profile.as_object().unwrap();
if let Some(contact) = profile_obj.get("contact") {
assert!(contact.is_object());
let contact_obj = contact.as_object().unwrap();
if let Some(email) = contact_obj.get("email") {
if let Some(email_str) = email.as_str() {
assert!(email_str.contains('@'));
}
}
}
}
}
if let Some(metadata) = obj.get("metadata") {
assert!(metadata.is_object());
let metadata_obj = metadata.as_object().unwrap();
if let Some(tags) = metadata_obj.get("tags") {
assert!(tags.is_array());
}
}
}
#[test]
fn test_schema_validation_with_constraints() {
let schema = json!({
"type": "object",
"properties": {
"score": {
"type": "number",
"minimum": 0.0,
"maximum": 100.0
},
"name": {
"type": "string",
"minLength": 3,
"maxLength": 20
},
"status": {
"type": "string",
"enum": ["active", "inactive", "pending"]
}
},
"required": ["score", "name", "status"]
});
let config = MockGeneratorConfig::new().validate_generated_data(true);
let mut generator = MockDataGenerator::with_config(config);
let result = generator.generate_from_json_schema(&schema).unwrap();
assert!(result.is_object());
let obj = result.as_object().unwrap();
if let Some(score) = obj.get("score") {
if let Some(score_num) = score.as_f64() {
assert!(score_num >= 0.0);
assert!(score_num <= 100.0);
}
}
if let Some(name) = obj.get("name") {
if let Some(name_str) = name.as_str() {
assert!(name_str.len() >= 3);
assert!(name_str.len() <= 20);
}
}
if let Some(status) = obj.get("status") {
if let Some(status_str) = status.as_str() {
assert!(["active", "inactive", "pending"].contains(&status_str));
}
}
}
#[test]
fn test_array_generation_with_constraints() {
let schema = json!({
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"value": { "type": "number" }
}
},
"minItems": 2,
"maxItems": 5
}
}
});
let mut generator = MockDataGenerator::new();
let result = generator.generate_from_json_schema(&schema).unwrap();
assert!(result.is_object());
let obj = result.as_object().unwrap();
if let Some(items) = obj.get("items") {
if let Some(items_array) = items.as_array() {
assert!(items_array.len() >= 2);
assert!(items_array.len() <= 5);
for item in items_array {
assert!(item.is_object());
let item_obj = item.as_object().unwrap();
assert!(item_obj.contains_key("id"));
assert!(item_obj.contains_key("value"));
}
}
}
}
}
#[cfg(test)]
mod performance_tests {
use super::*;
use std::time::Instant;
#[test]
fn test_generation_performance() {
let schema = create_test_json_schema();
let mut generator = MockDataGenerator::new();
let start = Instant::now();
let result = generator.generate_from_json_schema(&schema).unwrap();
let duration = start.elapsed();
assert!(duration.as_millis() < 100);
assert!(result.is_object());
}
#[test]
fn test_openapi_generation_performance() {
let spec = create_test_openapi_spec();
let mut generator = MockDataGenerator::new();
let start = Instant::now();
let result = generator.generate_from_openapi_spec(&spec).unwrap();
let duration = start.elapsed();
assert!(duration.as_millis() < 500);
assert!(!result.schemas.is_empty());
assert!(!result.responses.is_empty());
}
#[test]
fn test_batch_generation_performance() {
let schema = create_test_json_schema();
let mut generator = MockDataGenerator::new();
let start = Instant::now();
let mut results = Vec::new();
for _ in 0..100 {
let result = generator.generate_from_json_schema(&schema).unwrap();
results.push(result);
}
let duration = start.elapsed();
assert!(duration.as_millis() < 1000);
assert_eq!(results.len(), 100);
for result in results {
assert!(result.is_object());
}
}
}