Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions tests/phpunit/tests/rest-api/rest-attachments-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -2854,6 +2854,104 @@ public function test_create_item_with_data_exceeds_multisite_site_upload_space()
$this->assertErrorResponse( 'rest_upload_limited_space', $response, 400 );
}

/**
* Tests that sub-sizes generated on the server are not limited to the
* network's allowed upload file types.
*
* The image editor writes sub-sizes straight to disk, so a network that
* does not allow WebP uploads still gets WebP sub-sizes when an
* `image_editor_output_format` filter asks for them. This is the
* baseline for test_sideload_sub_size_in_output_format_not_allowed_by_network().
*
* @group multisite
* @group ms-required
* @covers ::wp_generate_attachment_metadata
*/
public function test_server_sub_sizes_in_output_format_not_allowed_by_network(): void {
if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {
$this->markTestSkipped( 'This test requires an image editor that can save WebP.' );
}

/*
* Networks created before WordPress 5.8 have no `webp` in this list,
* and upgrades never add it. This is also the list
* check_upload_mimes() falls back to.
*/
update_site_option( 'upload_filetypes', 'jpg jpeg png gif' );
$this->assertNotContains( 'image/webp', get_allowed_mime_types(), 'The network should not allow WebP uploads.' );

add_filter( 'image_editor_output_format', array( $this, 'filter_output_format_jpeg_to_webp' ) );

$attachment_id = self::factory()->attachment->create_upload_object( DIR_TESTDATA . '/images/canola.jpg' );
$metadata = wp_get_attachment_metadata( $attachment_id );

$this->assertArrayHasKey( 'thumbnail', $metadata['sizes'], 'The server should generate a thumbnail.' );
$this->assertSame( 'image/webp', $metadata['sizes']['thumbnail']['mime-type'], 'The thumbnail should be a WebP.' );
}

/**
* Tests that a client-generated sub-size can be sideloaded in an output
* format the network does not allow for upload.
*
* With client-side media processing, the browser transcodes each sub-size
* to the `image_output_format` returned by the upload, then sideloads it.
* The server generates the same sub-size itself on the classic path (see
* test_server_sub_sizes_in_output_format_not_allowed_by_network()), so the
* sideload should not be rejected for its file type.
*
* @group multisite
* @group ms-required
* @covers WP_REST_Attachments_Controller::sideload_item
*/
public function test_sideload_sub_size_in_output_format_not_allowed_by_network(): void {
$this->enable_client_side_media_processing();

wp_set_current_user( self::$author_id );

// See test_server_sub_sizes_in_output_format_not_allowed_by_network().
update_site_option( 'upload_filetypes', 'jpg jpeg png gif' );
$this->assertNotContains( 'image/webp', get_allowed_mime_types(), 'The network should not allow WebP uploads.' );

add_filter( 'image_editor_output_format', array( $this, 'filter_output_format_jpeg_to_webp' ) );

$request = new WP_REST_Request( 'POST', '/wp/v2/media' );
$request->set_header( 'Content-Type', 'image/jpeg' );
$request->set_header( 'Content-Disposition', 'attachment; filename=canola.jpg' );
$request->set_param( 'generate_sub_sizes', false );
$request->set_body( file_get_contents( self::$test_file ) );
$response = rest_get_server()->dispatch( $request );

$this->assertSame( 201, $response->get_status(), 'The original upload should succeed.' );

$attachment_id = $response->get_data()['id'];

// A WebP thumbnail, as the client would sideload it.
$request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/sideload" );
$request->set_header( 'Content-Type', 'image/webp' );
$request->set_header( 'Content-Disposition', 'attachment; filename=canola-50x50.webp' );
$request->set_param( 'image_size', 'thumbnail' );
$request->set_param( 'convert_format', false );
$request->set_body( file_get_contents( DIR_TESTDATA . '/images/test-image.webp' ) );
$response = rest_get_server()->dispatch( $request );

$this->assertSame(
200,
$response->get_status(),
'Sideloading a WebP sub-size should succeed. Response: ' . wp_json_encode( $response->get_data() )
);
}

/**
* Maps JPEG output to WebP, as image format plugins do.
*
* @param array<string, string> $formats Output formats keyed by source mime type.
* @return array<string, string> The filtered output formats.
*/
public function filter_output_format_jpeg_to_webp( $formats ) {
$formats['image/jpeg'] = 'image/webp';
return $formats;
}

/**
* Ensure the `rest_after_insert_attachment` and `rest_insert_attachment` hooks only fire
* once when attachments are created.
Expand Down
Loading