Files
WP-Content-Sync/tests/bootstrap.php
T
2026-04-28 12:38:59 -05:00

533 lines
13 KiB
PHP

<?php
/**
* PHPUnit and PHPStan bootstrap for isolated plugin tests.
*
* @package WPContentSync
*/
// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- WordPress class and function stubs share this test bootstrap.
require_once dirname( __DIR__ ) . '/vendor/autoload.php';
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', dirname( __DIR__ ) . '/' );
}
if ( ! defined( 'WPCS_PLUGIN_DIR' ) ) {
define( 'WPCS_PLUGIN_DIR', dirname( __DIR__ ) . '/' );
}
if ( ! defined( 'WPCS_PLUGIN_URL' ) ) {
define( 'WPCS_PLUGIN_URL', 'https://example.test/wp-content/plugins/wp-content-sync/' );
}
if ( ! defined( 'WPCS_VERSION' ) ) {
define( 'WPCS_VERSION', '0.1.0' );
}
if ( ! class_exists( 'WP_Error' ) ) {
class WP_Error {
private string $message;
public function __construct( string $code, string $message ) {
$this->message = $message;
}
public function get_error_message(): string {
return $this->message;
}
}
}
if ( ! function_exists( 'sanitize_text_field' ) ) {
/**
* Minimal WordPress-compatible text sanitizer for unit tests.
*
* @param mixed $value Value to sanitize.
* @return string
*/
function sanitize_text_field( $value ) {
return trim( preg_replace( '/[\r\n\t]+/', ' ', wp_strip_all_tags( (string) $value ) ) );
}
}
if ( ! function_exists( 'wp_strip_all_tags' ) ) {
/**
* Minimal tag stripper for unit tests.
*
* @param string $value Value to strip.
* @return string
*/
function wp_strip_all_tags( $value ) {
return preg_replace( '/<[^>]*>/', '', $value );
}
}
if ( ! function_exists( 'wp_unslash' ) ) {
/**
* Minimal slashes remover for unit tests.
*
* @param mixed $value Value to unslash.
* @return mixed
*/
function wp_unslash( $value ) {
if ( is_array( $value ) ) {
return array_map( 'wp_unslash', $value );
}
return is_string( $value ) ? stripslashes( $value ) : $value;
}
}
if ( ! function_exists( 'esc_html' ) ) {
/**
* Minimal HTML escaper for unit tests.
*
* @param mixed $value Value to escape.
* @return string
*/
function esc_html( $value ) {
return htmlspecialchars( (string) $value, ENT_QUOTES, 'UTF-8' );
}
}
if ( ! function_exists( '__' ) ) {
/**
* Minimal translation helper for unit tests.
*
* @param string $text Text to translate.
* @param string $domain Text domain.
* @return string
*/
function __( $text, $domain = 'default' ) {
$GLOBALS['wpcs_test_text_domain'] = $domain;
return $text;
}
}
if ( ! function_exists( 'esc_html__' ) ) {
/**
* Minimal translated HTML escaper for unit tests.
*
* @param string $text Text to translate and escape.
* @param string $domain Text domain.
* @return string
*/
function esc_html__( $text, $domain = 'default' ) {
$GLOBALS['wpcs_test_text_domain'] = $domain;
return esc_html( $text );
}
}
if ( ! function_exists( 'esc_attr' ) ) {
/**
* Minimal attribute escaper for unit tests.
*
* @param mixed $value Value to escape.
* @return string
*/
function esc_attr( $value ) {
return htmlspecialchars( (string) $value, ENT_QUOTES, 'UTF-8' );
}
}
if ( ! function_exists( 'esc_url' ) ) {
/**
* Minimal URL sanitizer for unit tests.
*
* @param mixed $value Value to sanitize.
* @return string
*/
function esc_url( $value ) {
return filter_var( (string) $value, FILTER_SANITIZE_URL );
}
}
if ( ! function_exists( 'esc_url_raw' ) ) {
/**
* Minimal raw URL sanitizer for unit tests.
*
* @param mixed $value Value to sanitize.
* @return string
*/
function esc_url_raw( $value ) {
return filter_var( (string) $value, FILTER_SANITIZE_URL );
}
}
if ( ! function_exists( 'wp_parse_url' ) ) {
/**
* Minimal URL parser for unit tests.
*
* @param string $url URL to parse.
* @return array<string, mixed>|false
*/
function wp_parse_url( $url ) {
// phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url -- Test stub for WordPress' wp_parse_url().
return parse_url( $url );
}
}
if ( ! function_exists( 'wp_json_encode' ) ) {
/**
* Minimal JSON encoder for unit tests.
*
* @param mixed $value Value to encode.
* @param int $flags JSON encoding flags.
* @return string|false
*/
function wp_json_encode( $value, $flags = 0 ) {
// phpcs:ignore -- Test stub for WordPress' wp_json_encode().
return json_encode( $value, $flags );
}
}
if ( ! function_exists( 'get_option' ) ) {
/**
* Minimal WordPress option reader for unit tests.
*
* @param string $name Option name.
* @param mixed $default_value Default value.
* @return mixed
*/
function get_option( $name, $default_value = false ) {
return $GLOBALS['wpcs_test_options'][ $name ] ?? $default_value;
}
}
if ( ! function_exists( 'update_option' ) ) {
/**
* Minimal WordPress option writer for unit tests.
*
* @param string $name Option name.
* @param mixed $value Option value.
* @param mixed $autoload Autoload flag.
* @return bool
*/
function update_option( $name, $value, $autoload = null ) {
$GLOBALS['wpcs_test_options'][ $name ] = $value;
$GLOBALS['wpcs_test_option_autoloads'][ $name ] = $autoload;
return true;
}
}
if ( ! function_exists( 'delete_transient' ) ) {
/**
* Minimal WordPress transient deleter for unit tests.
*
* @param string $name Transient name.
* @return bool
*/
function delete_transient( $name ) {
unset( $GLOBALS['wpcs_test_transients'][ $name ] );
return true;
}
}
if ( ! function_exists( 'plugin_dir_path' ) ) {
/**
* Minimal plugin path helper for static analysis.
*
* @param string $file Plugin file.
* @return string
*/
function plugin_dir_path( $file ) {
return trailingslashit( dirname( $file ) );
}
}
if ( ! function_exists( 'plugin_dir_url' ) ) {
/**
* Minimal plugin URL helper for static analysis.
*
* @param string $file Plugin file.
* @return string
*/
function plugin_dir_url( $file ) {
return 'http://example.org/wp-content/plugins/' . basename( dirname( $file ) ) . '/';
}
}
if ( ! function_exists( 'trailingslashit' ) ) {
/**
* Minimal trailing slash helper for static analysis.
*
* @param string $value Value to slash.
* @return string
*/
function trailingslashit( $value ) {
return rtrim( $value, '/\\' ) . DIRECTORY_SEPARATOR;
}
}
if ( ! function_exists( 'register_activation_hook' ) ) {
/**
* Minimal activation hook registrar for static analysis.
*
* @param string $file Plugin file.
* @param callable $callback Activation callback.
* @return void
*/
function register_activation_hook( $file, $callback ) {
$GLOBALS['wpcs_test_activation_hooks'][ $file ] = $callback;
}
}
if ( ! function_exists( 'register_deactivation_hook' ) ) {
/**
* Minimal deactivation hook registrar for static analysis.
*
* @param string $file Plugin file.
* @param callable $callback Deactivation callback.
* @return void
*/
function register_deactivation_hook( $file, $callback ) {
$GLOBALS['wpcs_test_deactivation_hooks'][ $file ] = $callback;
}
}
if ( ! function_exists( 'add_action' ) ) {
/**
* Minimal action registrar for static analysis.
*
* @param string $hook_name Hook name.
* @param callable $callback Hook callback.
* @return bool
*/
function add_action( $hook_name, $callback ) {
$GLOBALS['wpcs_test_actions'][ $hook_name ][] = $callback;
return true;
}
}
if ( ! function_exists( 'add_management_page' ) ) {
/**
* Minimal management page registrar for static analysis.
*
* @param string $page_title Page title.
* @param string $menu_title Menu title.
* @param string $capability Capability required.
* @param string $menu_slug Menu slug.
* @param callable $callback Page callback.
* @return string
*/
function add_management_page( $page_title, $menu_title, $capability, $menu_slug, $callback ) {
$GLOBALS['wpcs_test_admin_pages'][ $menu_slug ] = array(
'page_title' => $page_title,
'menu_title' => $menu_title,
'capability' => $capability,
'callback' => $callback,
);
return $menu_slug;
}
}
if ( ! function_exists( 'register_setting' ) ) {
/**
* Minimal setting registrar for static analysis.
*
* @param string $option_group Option group.
* @param string $option_name Option name.
* @param array<string, mixed> $args Setting arguments.
* @return bool
*/
function register_setting( $option_group, $option_name, $args = array() ) {
$GLOBALS['wpcs_test_registered_settings'][ $option_name ] = array(
'option_group' => $option_group,
'args' => $args,
);
return true;
}
}
if ( ! function_exists( 'current_user_can' ) ) {
/**
* Minimal capability checker for static analysis.
*
* @param string $capability Capability to check.
* @return bool
*/
function current_user_can( $capability ) {
return $GLOBALS['wpcs_current_user_can'][ $capability ] ?? 'manage_options' === $capability;
}
}
if ( ! function_exists( 'check_admin_referer' ) ) {
/**
* Minimal nonce checker for unit tests.
*
* @param string $action Nonce action.
* @param string $query_arg Nonce request field.
* @return bool
*/
function check_admin_referer( $action, $query_arg = '_wpnonce' ) {
return $GLOBALS['wpcs_nonce_valid'][ $action ][ $query_arg ] ?? true;
}
}
if ( ! function_exists( 'wp_safe_redirect' ) ) {
/**
* Minimal safe redirect helper for unit tests.
*
* @param string $location Redirect location.
* @return bool
*/
function wp_safe_redirect( $location ) {
$GLOBALS['wpcs_redirect_location'] = $location;
return true;
}
}
if ( ! function_exists( 'wp_remote_get' ) ) {
/**
* Minimal HTTP GET helper for unit tests.
*
* @param string $url Request URL.
* @param array<string, mixed> $args Request arguments.
* @return array<string, mixed>|\WP_Error
*/
function wp_remote_get( $url, array $args = array() ) {
$GLOBALS['wpcs_last_http_request'] = array(
'method' => 'GET',
'url' => $url,
'args' => $args,
);
return $GLOBALS['wpcs_http_response'] ?? array(
'response' => array( 'code' => 200 ),
'body' => '{"ok":true}',
);
}
}
if ( ! function_exists( 'wp_remote_post' ) ) {
/**
* Minimal HTTP POST helper for unit tests.
*
* @param string $url Request URL.
* @param array<string, mixed> $args Request arguments.
* @return array<string, mixed>|\WP_Error
*/
function wp_remote_post( $url, array $args = array() ) {
$GLOBALS['wpcs_last_http_request'] = array(
'method' => 'POST',
'url' => $url,
'args' => $args,
);
return $GLOBALS['wpcs_http_response'] ?? array(
'response' => array( 'code' => 200 ),
'body' => '{"accepted":true}',
);
}
}
if ( ! function_exists( 'wp_remote_retrieve_response_code' ) ) {
/**
* Minimal response code helper for unit tests.
*
* @param array<string, mixed> $response HTTP response.
* @return int
*/
function wp_remote_retrieve_response_code( array $response ) {
return (int) ( $response['response']['code'] ?? 0 );
}
}
if ( ! function_exists( 'wp_remote_retrieve_body' ) ) {
/**
* Minimal response body helper for unit tests.
*
* @param array<string, mixed> $response HTTP response.
* @return string
*/
function wp_remote_retrieve_body( array $response ) {
return (string) ( $response['body'] ?? '' );
}
}
if ( ! function_exists( 'is_wp_error' ) ) {
/**
* Minimal WP_Error checker for unit tests.
*
* @param mixed $value Value to check.
* @return bool
*/
function is_wp_error( $value ) {
return $value instanceof WP_Error;
}
}
if ( ! function_exists( 'admin_url' ) ) {
/**
* Minimal admin URL helper for unit tests.
*
* @param string $path Admin path.
* @return string
*/
function admin_url( $path = '' ) {
return 'https://example.test/wp-admin/' . ltrim( $path, '/' );
}
}
if ( ! function_exists( 'add_query_arg' ) ) {
/**
* Minimal query arg helper for unit tests.
*
* @param array<string, string> $args Query args.
* @param string $url URL.
* @return string
*/
function add_query_arg( array $args, $url ) {
return $url . ( false === strpos( $url, '?' ) ? '?' : '&' ) . http_build_query( $args );
}
}
if ( ! function_exists( 'wp_nonce_field' ) ) {
/**
* Minimal nonce field renderer for unit tests.
*
* @param string $action Nonce action.
* @param string $name Field name.
* @return void
*/
function wp_nonce_field( $action, $name ) {
echo '<input type="hidden" name="' . esc_attr( $name ) . '" value="' . esc_attr( $action ) . '" />';
}
}
if ( ! function_exists( 'submit_button' ) ) {
/**
* Minimal submit button renderer for unit tests.
*
* @param string $text Button text.
* @param string $type Button type.
* @return void
*/
function submit_button( $text, $type = 'primary' ) {
echo '<button class="button button-' . esc_attr( $type ) . '" type="submit">' . esc_html( $text ) . '</button>';
}
}
if ( ! function_exists( 'wp_die' ) ) {
/**
* Minimal WordPress die handler for unit tests.
*
* @param mixed $message Message to die with.
* @return void
*
* @throws \RuntimeException Always throws with the provided message.
*/
function wp_die( $message ) {
throw new \RuntimeException( esc_html( $message ) );
}
}