use folk_runtime_embed::php::{PhpInstance, RequestContext};
#[test]
fn test_custom_sapi_boot_and_eval() {
let mut php = PhpInstance::boot_custom_sapi().expect("custom SAPI boot failed");
let mut ctx = RequestContext::new("GET", "/test");
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php
.eval(r#"echo "hello from custom SAPI";"#)
.expect("eval failed");
assert_eq!(result.output, "hello from custom SAPI");
php.request_shutdown();
}
#[test]
fn test_server_request_method() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let mut ctx = RequestContext::new("POST", "/api/users");
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php
.eval(r#"echo $_SERVER['REQUEST_METHOD'];"#)
.expect("eval failed");
assert_eq!(result.output, "POST");
php.request_shutdown();
}
#[test]
fn test_server_request_uri() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let mut ctx = RequestContext::new("GET", "/path/to/resource?foo=bar");
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php
.eval(r#"echo $_SERVER['REQUEST_URI'];"#)
.expect("eval failed");
assert_eq!(result.output, "/path/to/resource?foo=bar");
php.request_shutdown();
}
#[test]
fn test_server_query_string() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let mut ctx = RequestContext::new("GET", "/search?q=test&page=2").query_string("q=test&page=2");
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php
.eval(r#"echo $_SERVER['QUERY_STRING'];"#)
.expect("eval failed");
assert_eq!(result.output, "q=test&page=2");
php.request_shutdown();
}
#[test]
fn test_get_superglobal() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let mut ctx = RequestContext::new("GET", "/search?name=folk&version=1")
.query_string("name=folk&version=1");
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php
.eval(r#"echo $_GET['name'] . ':' . $_GET['version'];"#)
.expect("eval failed");
assert_eq!(result.output, "folk:1");
php.request_shutdown();
}
#[test]
fn test_post_body() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let body = b"username=admin&password=secret";
let mut ctx = RequestContext::new("POST", "/login")
.content_type("application/x-www-form-urlencoded")
.body(body);
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php
.eval(r#"echo $_POST['username'] . ':' . $_POST['password'];"#)
.expect("eval failed");
assert_eq!(result.output, "admin:secret");
php.request_shutdown();
}
#[test]
fn test_raw_post_body() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let json_body = br#"{"key":"value"}"#;
let mut ctx = RequestContext::new("POST", "/api")
.content_type("application/json")
.body(json_body);
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php
.eval(r#"echo file_get_contents('php://input');"#)
.expect("eval failed");
assert_eq!(result.output, r#"{"key":"value"}"#);
php.request_shutdown();
}
#[test]
fn test_cookie_superglobal() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let mut ctx = RequestContext::new("GET", "/").cookie("session_id=abc123; theme=dark");
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php
.eval(r#"echo $_COOKIE['session_id'] . ':' . $_COOKIE['theme'];"#)
.expect("eval failed");
assert_eq!(result.output, "abc123:dark");
php.request_shutdown();
}
#[test]
fn test_http_headers_to_server() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let mut ctx = RequestContext::new("GET", "/")
.header("Host", "example.com")
.header("Accept", "text/html")
.header("X-Custom-Header", "custom-value");
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php
.eval(r#"echo $_SERVER['HTTP_HOST'];"#)
.expect("eval failed");
assert_eq!(result.output, "example.com");
let result = php
.eval(r#"echo $_SERVER['HTTP_ACCEPT'];"#)
.expect("eval failed");
assert!(result.output.contains("text/html"));
let result = php
.eval(r#"echo $_SERVER['HTTP_X_CUSTOM_HEADER'];"#)
.expect("eval failed");
assert!(result.output.contains("custom-value"));
php.request_shutdown();
}
#[test]
fn test_response_header_capture() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let mut ctx = RequestContext::new("GET", "/");
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
php.eval(
r#"
header('Content-Type: application/json');
header('X-Custom: test-value');
echo '{"status":"ok"}';
"#,
)
.expect("eval failed");
let response = php.take_response();
assert_eq!(response.body, r#"{"status":"ok"}"#);
let has_content_type = response
.headers
.iter()
.any(|h| h.contains("Content-Type") && h.contains("application/json"));
let has_custom = response
.headers
.iter()
.any(|h| h.contains("X-Custom") && h.contains("test-value"));
assert!(
has_content_type,
"missing Content-Type header in: {:?}",
response.headers
);
assert!(
has_custom,
"missing X-Custom header in: {:?}",
response.headers
);
php.request_shutdown();
}
#[test]
fn test_response_status_code() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let mut ctx = RequestContext::new("GET", "/not-found");
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
php.eval(
r#"
http_response_code(404);
echo 'Not Found';
"#,
)
.expect("eval failed");
let response = php.take_response();
assert_eq!(response.status_code, 404);
assert_eq!(response.body, "Not Found");
php.request_shutdown();
}
#[test]
fn test_multiple_requests_custom_sapi() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
for i in 0..50 {
let uri = format!("/req/{i}");
let mut ctx = RequestContext::new("GET", &uri);
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php
.eval(r#"echo $_SERVER['REQUEST_URI'];"#)
.expect("eval failed");
assert_eq!(result.output, uri);
php.request_shutdown();
}
}
#[test]
fn test_server_info() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let mut ctx = RequestContext::new("GET", "/")
.server("localhost", 8080)
.protocol("HTTP/1.1");
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php
.eval(r#"echo $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . ' ' . $_SERVER['SERVER_PROTOCOL'];"#)
.expect("eval failed");
assert_eq!(result.output, "localhost:8080 HTTP/1.1");
php.request_shutdown();
}
#[test]
fn test_sapi_name() {
let mut php = PhpInstance::boot_custom_sapi().expect("boot failed");
let mut ctx = RequestContext::new("GET", "/");
php.set_request_context(&mut ctx);
php.request_startup().expect("request startup failed");
let result = php.eval(r#"echo php_sapi_name();"#).expect("eval failed");
assert_eq!(result.output, "folk-embed");
php.request_shutdown();
}