dfcadc5339
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
50 lines
1.5 KiB
PHP
50 lines
1.5 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace WPMultiCity\Tests;
|
|
|
|
use WPMultiCity\RestUrlFilter;
|
|
|
|
final class RestUrlFilterTest extends TestCase
|
|
{
|
|
public function test_register_attaches_rest_url_filter(): void
|
|
{
|
|
RestUrlFilter::register();
|
|
|
|
self::assertNotFalse(
|
|
has_filter('rest_url', [RestUrlFilter::class, 'preserve_host']),
|
|
'RestUrlFilter::register() must hook rest_url'
|
|
);
|
|
}
|
|
|
|
public function test_preserve_host_replaces_host_when_http_host_set(): void
|
|
{
|
|
$_SERVER['HTTP_HOST'] = 'site.com';
|
|
|
|
self::assertSame(
|
|
'https://site.com/wp-json/wp/v2/posts',
|
|
RestUrlFilter::preserve_host('http://other.example/wp-json/wp/v2/posts')
|
|
);
|
|
}
|
|
|
|
public function test_preserve_host_returns_url_unchanged_when_http_host_missing(): void
|
|
{
|
|
unset($_SERVER['HTTP_HOST']);
|
|
|
|
$url = 'https://other.example/wp-json/wp/v2/posts';
|
|
self::assertSame($url, RestUrlFilter::preserve_host($url));
|
|
}
|
|
|
|
public function test_preserve_host_does_not_interpret_replacement_metachars_in_host(): void
|
|
{
|
|
// $_SERVER['HTTP_HOST'] is attacker-controlled (Host header).
|
|
// The replacement string must not interpret $0/\\1 as backreferences.
|
|
$_SERVER['HTTP_HOST'] = 'evil$0.com';
|
|
|
|
self::assertSame(
|
|
'https://evil$0.com/wp-json/wp/v2/posts',
|
|
RestUrlFilter::preserve_host('http://example.org/wp-json/wp/v2/posts')
|
|
);
|
|
}
|
|
}
|