use super::{generate_mock_server_code, CodegenConfig, MockDataStrategy};
use crate::openapi::spec::OpenApiSpec;
use serde_json::json;
fn create_test_spec() -> OpenApiSpec {
let spec_json = json!({
"openapi": "3.0.0",
"info": {
"title": "Test API",
"version": "1.0.0"
},
"paths": {
"/users": {
"get": {
"operationId": "listUsers",
"responses": {
"200": {
"description": "List of users",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {"type": "integer"},
"name": {"type": "string"}
}
}
}
}
}
}
}
},
"post": {
"operationId": "createUser",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"}
}
}
}
}
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {"type": "integer"},
"name": {"type": "string"}
}
}
}
}
}
}
}
},
"/users/{id}": {
"get": {
"operationId": "getUserById",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "User found",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {"type": "string"},
"name": {"type": "string"}
}
}
}
}
}
}
}
}
}
});
OpenApiSpec::from_json(spec_json).unwrap()
}
#[test]
fn test_generate_rust_code() {
let spec = create_test_spec();
let config = CodegenConfig::default();
let result = generate_mock_server_code(&spec, "rs", &config);
assert!(result.is_ok());
let code = result.unwrap();
assert!(code.contains("pub struct GeneratedMockServer"));
assert!(code.contains("impl GeneratedMockServer"));
assert!(code.contains("pub fn new()"));
assert!(code.contains("pub fn router"));
assert!(code.contains("pub async fn start"));
assert!(
code.contains("listusers") || code.contains("list_users") || code.contains("handle_get")
);
assert!(
code.contains("createuser") || code.contains("create_user") || code.contains("handle_post")
);
assert!(
code.contains("getuserbyid")
|| code.contains("get_user_by_id")
|| code.contains("users/:id")
);
assert!(code.contains("use axum::"));
assert!(code.contains("use serde::"));
assert!(code.contains(".route("));
}
#[test]
fn test_generate_rust_code_with_path_parameters() {
let spec = create_test_spec();
let config = CodegenConfig::default();
let result = generate_mock_server_code(&spec, "rs", &config);
assert!(result.is_ok());
let code = result.unwrap();
assert!(code.contains("/users/:id") || code.contains("/users/{id}"));
}
#[test]
fn test_generate_rust_code_includes_all_methods() {
let spec = create_test_spec();
let config = CodegenConfig::default();
let result = generate_mock_server_code(&spec, "rs", &config);
assert!(result.is_ok());
let code = result.unwrap();
assert!(code.contains(".route(\"/users\"") || code.contains("get(") || code.contains("post("));
}
#[test]
fn test_generate_rust_code_with_config() {
let spec = create_test_spec();
let config = CodegenConfig {
port: Some(8080),
enable_cors: true,
default_delay_ms: Some(100),
mock_data_strategy: MockDataStrategy::Examples,
};
let result = generate_mock_server_code(&spec, "rs", &config);
assert!(result.is_ok());
let code = result.unwrap();
assert!(code.contains("8080"));
if config.default_delay_ms.is_some() {
assert!(code.contains("tokio::time::sleep") || code.contains("Duration::from_millis"));
}
}
#[test]
fn test_generate_typescript_code_with_config() {
let spec = create_test_spec();
let config = CodegenConfig {
port: Some(8080),
enable_cors: true,
default_delay_ms: Some(100),
mock_data_strategy: MockDataStrategy::Examples,
};
let result = generate_mock_server_code(&spec, "ts", &config);
assert!(result.is_ok());
let code = result.unwrap();
assert!(code.contains("8080"));
assert!(code.contains("Access-Control-Allow-Origin"));
if config.default_delay_ms.is_some() {
assert!(code.contains("setTimeout") || code.contains("delay"));
}
}
#[test]
fn test_generate_typescript_code() {
let spec = create_test_spec();
let config = CodegenConfig::default();
let result = generate_mock_server_code(&spec, "ts", &config);
assert!(result.is_ok());
let code = result.unwrap();
assert!(code.contains("export class GeneratedMockServer"));
assert!(code.contains("import express"));
assert!(code.contains("async start()"));
assert!(code.contains("setupRoutes"));
assert!(code.contains("private async handle_"));
assert!(code.contains(".get(") || code.contains(".post("));
}
#[test]
fn test_unsupported_language() {
let spec = create_test_spec();
let config = CodegenConfig::default();
let result = generate_mock_server_code(&spec, "python", &config);
assert!(result.is_err());
let error = result.unwrap_err();
assert!(error.to_string().contains("Unsupported language"));
}
#[test]
fn test_codegen_config_defaults() {
let config = CodegenConfig::default();
assert_eq!(config.mock_data_strategy, MockDataStrategy::ExamplesOrRandom);
assert_eq!(config.port, None);
assert!(!config.enable_cors);
assert_eq!(config.default_delay_ms, None);
}
#[test]
fn test_generate_handler_signatures() {
let spec = create_test_spec();
let config = CodegenConfig::default();
let result = generate_mock_server_code(&spec, "rs", &config);
assert!(result.is_ok());
let code = result.unwrap();
assert!(code.contains("async fn handle_"));
assert!(code.contains("Json<Value>") || code.contains("Json<"));
assert!(code.contains("Json(body)") || code.contains("body"));
}
#[test]
fn test_main_function_generated() {
let spec = create_test_spec();
let config = CodegenConfig::default();
let result = generate_mock_server_code(&spec, "rs", &config);
assert!(result.is_ok());
let code = result.unwrap();
assert!(code.contains("#[tokio::main]"));
assert!(code.contains("async fn main"));
assert!(code.contains("GeneratedMockServer::new()"));
assert!(code.contains("server.start()"));
}