wordpress-develop/tests/phpunit/tests/admin/includesFile.php
Jb Audras 8fbe21a37a HTTP API: Fix request header inconsistencies.
This changeset improves the consistency in capitalization of fetching and outputting of request headers. It also updates occurrences found in some docblocks.

Props johnjamesjacoby, costdev, audrasjb, petitphp, mhkuu, SergeyBiryukov.
Fixes #54225.


git-svn-id: https://develop.svn.wordpress.org/trunk@55210 602fd350-edb4-49c9-b593-d223f7449a82
2023-02-03 13:33:18 +00:00

385 lines
12 KiB
PHP

<?php
/**
* @group file
* @group admin
*/
class Tests_Admin_IncludesFile extends WP_UnitTestCase {
/**
* @ticket 20449
*
* @covers ::get_home_path
*/
public function test_get_home_path() {
$home = get_option( 'home' );
$siteurl = get_option( 'siteurl' );
$sfn = $_SERVER['SCRIPT_FILENAME'];
$this->assertSame( str_replace( '\\', '/', ABSPATH ), get_home_path() );
update_option( 'home', 'http://localhost' );
update_option( 'siteurl', 'http://localhost/wp' );
$_SERVER['SCRIPT_FILENAME'] = 'D:\root\vhosts\site\httpdocs\wp\wp-admin\options-permalink.php';
$this->assertSame( 'D:/root/vhosts/site/httpdocs/', get_home_path() );
$_SERVER['SCRIPT_FILENAME'] = '/Users/foo/public_html/trunk/wp/wp-admin/options-permalink.php';
$this->assertSame( '/Users/foo/public_html/trunk/', get_home_path() );
$_SERVER['SCRIPT_FILENAME'] = 'S:/home/wordpress/trunk/wp/wp-admin/options-permalink.php';
$this->assertSame( 'S:/home/wordpress/trunk/', get_home_path() );
update_option( 'home', $home );
update_option( 'siteurl', $siteurl );
$_SERVER['SCRIPT_FILENAME'] = $sfn;
}
/**
* @ticket 43329
*
* @covers ::download_url
*/
public function test_download_url_non_200_response_code() {
add_filter( 'pre_http_request', array( $this, '_fake_download_url_non_200_response_code' ), 10, 3 );
$error = download_url( 'test_download_url_non_200' );
$this->assertWPError( $error );
$this->assertSame(
array(
'code' => 418,
'body' => 'This is an unexpected error message from your favorite server.',
),
$error->get_error_data()
);
add_filter( 'download_url_error_max_body_size', array( $this, '__return_5' ) );
$error = download_url( 'test_download_url_non_200' );
$this->assertWPError( $error );
$this->assertSame(
array(
'code' => 418,
'body' => 'This ',
),
$error->get_error_data()
);
remove_filter( 'download_url_error_max_body_size', array( $this, '__return_5' ) );
remove_filter( 'pre_http_request', array( $this, '_fake_download_url_non_200_response_code' ) );
}
public function _fake_download_url_non_200_response_code( $response, $parsed_args, $url ) {
file_put_contents( $parsed_args['filename'], 'This is an unexpected error message from your favorite server.' );
return array(
'response' => array(
'code' => 418,
'message' => "I'm a teapot!",
),
);
}
public function __return_5() {
return 5;
}
/**
* @ticket 38231
* @dataProvider data_download_url_should_respect_filename_from_content_disposition_header
*
* @covers ::download_url
*
* @param $filter A callback containing a fake Content-Disposition header.
*/
public function test_download_url_should_respect_filename_from_content_disposition_header( $filter ) {
add_filter( 'pre_http_request', array( $this, $filter ), 10, 3 );
$filename = download_url( 'url_with_content_disposition_header' );
$this->assertStringContainsString( 'filename-from-content-disposition-header', $filename );
$this->assertFileExists( $filename );
$this->unlink( $filename );
remove_filter( 'pre_http_request', array( $this, $filter ) );
}
/**
* Data provider for test_download_url_should_respect_filename_from_content_disposition_header.
*
* @return array
*/
public function data_download_url_should_respect_filename_from_content_disposition_header() {
return array(
'valid parameters' => array( 'filter_content_disposition_header_with_filename' ),
'path traversal' => array( 'filter_content_disposition_header_with_filename_with_path_traversal' ),
'no quotes' => array( 'filter_content_disposition_header_with_filename_without_quotes' ),
);
}
/**
* @ticket 55109
* @dataProvider data_save_to_temp_directory_when_getting_filename_from_content_disposition_header
*
* @covers ::download_url
*
* @param $filter A callback containing a fake Content-Disposition header.
*/
public function test_save_to_temp_directory_when_getting_filename_from_content_disposition_header( $filter ) {
add_filter( 'pre_http_request', array( $this, $filter ), 10, 3 );
$filename = download_url( 'url_with_content_disposition_header' );
$this->assertStringContainsString( get_temp_dir(), $filename );
$this->unlink( $filename );
remove_filter( 'pre_http_request', array( $this, $filter ) );
}
/**
* Data provider for test_save_to_temp_directory_when_getting_filename_from_content_disposition_header.
*
* @return array
*/
public function data_save_to_temp_directory_when_getting_filename_from_content_disposition_header() {
return array(
'valid parameters' => array( 'filter_content_disposition_header_with_filename' ),
);
}
/**
* Filter callback for data_download_url_should_respect_filename_from_content_disposition_header.
*
* @since 5.9.0
*
* @return array
*/
public function filter_content_disposition_header_with_filename( $response, $parsed_args, $url ) {
return array(
'response' => array(
'code' => 200,
),
'headers' => array(
'Content-Disposition' => 'attachment; filename="filename-from-content-disposition-header.txt"',
),
);
}
/**
* Filter callback for data_download_url_should_respect_filename_from_content_disposition_header.
*
* @since 5.9.0
*
* @return array
*/
public function filter_content_disposition_header_with_filename_with_path_traversal( $response, $parsed_args, $url ) {
return array(
'response' => array(
'code' => 200,
),
'headers' => array(
'Content-Disposition' => 'attachment; filename="../../filename-from-content-disposition-header.txt"',
),
);
}
/**
* Filter callback for data_download_url_should_respect_filename_from_content_disposition_header.
*
* @since 5.9.0
*
* @return array
*/
public function filter_content_disposition_header_with_filename_without_quotes( $response, $parsed_args, $url ) {
return array(
'response' => array(
'code' => 200,
),
'headers' => array(
'Content-Disposition' => 'attachment; filename=filename-from-content-disposition-header.txt',
),
);
}
/**
* @ticket 38231
* @dataProvider data_download_url_should_reject_filename_from_invalid_content_disposition_header
*
* @covers ::download_url
*
* @param $filter A callback containing a fake Content-Disposition header.
*/
public function test_download_url_should_reject_filename_from_invalid_content_disposition_header( $filter ) {
add_filter( 'pre_http_request', array( $this, $filter ), 10, 3 );
$filename = download_url( 'url_with_content_disposition_header' );
$this->assertStringContainsString( 'url_with_content_disposition_header', $filename );
$this->unlink( $filename );
remove_filter( 'pre_http_request', array( $this, $filter ) );
}
/**
* Data provider for test_download_url_should_reject_filename_from_invalid_content_disposition_header.
*
* @return array
*/
public function data_download_url_should_reject_filename_from_invalid_content_disposition_header() {
return array(
'no context' => array( 'filter_content_disposition_header_with_filename_without_context' ),
'inline context' => array( 'filter_content_disposition_header_with_filename_with_inline_context' ),
'form-data context' => array( 'filter_content_disposition_header_with_filename_with_form_data_context' ),
);
}
/**
* Filter callback for data_download_url_should_reject_filename_from_invalid_content_disposition_header.
*
* @since 5.9.0
*
* @return array
*/
public function filter_content_disposition_header_with_filename_without_context( $response, $parsed_args, $url ) {
return array(
'response' => array(
'code' => 200,
),
'headers' => array(
'Content-Disposition' => 'filename="filename-from-content-disposition-header.txt"',
),
);
}
/**
* Filter callback for data_download_url_should_reject_filename_from_invalid_content_disposition_header.
*
* @since 5.9.0
*
* @return array
*/
public function filter_content_disposition_header_with_filename_with_inline_context( $response, $parsed_args, $url ) {
return array(
'response' => array(
'code' => 200,
),
'headers' => array(
'Content-Disposition' => 'inline; filename="filename-from-content-disposition-header.txt"',
),
);
}
/**
* Filter callback for data_download_url_should_reject_filename_from_invalid_content_disposition_header.
*
* @since 5.9.0
*
* @return array
*/
public function filter_content_disposition_header_with_filename_with_form_data_context( $response, $parsed_args, $url ) {
return array(
'response' => array(
'code' => 200,
),
'headers' => array(
'Content-Disposition' => 'form-data; name="file"; filename="filename-from-content-disposition-header.txt"',
),
);
}
/**
* Verify that a WP_Error object is returned when invalid input is passed as the `$url` parameter.
*
* @covers ::download_url
* @dataProvider data_download_url_empty_url
*
* @param mixed $url Input URL.
*/
public function test_download_url_empty_url( $url ) {
$error = download_url( $url );
$this->assertWPError( $error );
$this->assertSame( 'http_no_url', $error->get_error_code() );
$this->assertSame( 'Invalid URL Provided.', $error->get_error_message() );
}
/**
* Data provider.
*
* @return array
*/
public function data_download_url_empty_url() {
return array(
'null' => array( null ),
'false' => array( false ),
'integer 0' => array( 0 ),
'empty string' => array( '' ),
'string 0' => array( '0' ),
);
}
/**
* Test that PHP 8.1 "passing null to non-nullable" deprecation notice
* is not thrown when the `$url` does not have a path component.
*
* @ticket 53635
* @covers ::download_url
*/
public function test_download_url_no_warning_for_url_without_path() {
// Hook a mocked HTTP request response.
add_filter( 'pre_http_request', array( $this, 'mock_http_request' ), 10, 3 );
$result = download_url( 'https://example.com' );
$this->assertIsString( $result );
$this->assertNotEmpty( $result ); // File path will be generated, but will never be empty.
}
/**
* Test that PHP 8.1 "passing null to non-nullable" deprecation notice
* is not thrown when the `$url` does not have a path component,
* and signature verification via a local file is requested.
*
* @ticket 53635
* @covers ::download_url
*/
public function test_download_url_no_warning_for_url_without_path_with_signature_verification() {
// Hook a mocked HTTP request response.
add_filter( 'pre_http_request', array( $this, 'mock_http_request' ), 10, 3 );
add_filter(
'wp_signature_hosts',
static function( $urls ) {
$urls[] = 'example.com';
return $urls;
}
);
$error = download_url( 'https://example.com', 300, true );
/*
* Note: This test is not testing the signature verification itself.
* There is no signature available for the domain used in the test,
* which is why an error is expected and that's fine.
* The point of the test is to verify that the call to `verify_file_signature()`
* is actually reached and that no PHP deprecation notice is thrown
* before this point.
*/
$this->assertWPError( $error );
$this->assertSame( 'signature_verification_no_signature', $error->get_error_code() );
}
/**
* Mock the HTTP request response.
*
* @param false|array|WP_Error $response A preemptive return value of an HTTP request. Default false.
* @param array $parsed_args HTTP request arguments.
* @param string $url The request URL.
* @return false|array|WP_Error Response data.
*/
public function mock_http_request( $response, $parsed_args, $url ) {
if ( 'https://example.com' === $url ) {
return array(
'response' => array(
'code' => 200,
),
);
}
return $response;
}
}