Make WordPress Core

Changeset 62622


Ignore:
Timestamp:
07/02/2026 02:47:17 AM (3 months ago)
Author:
adamsilverstein
Message:

REST API: Add test coverage for the sideload convert_format boolean arg.

The sideload route declares convert_format as a boolean (default true) and sideload_item() suppresses the image_editor_output_format filter when it is false, both added when client-side media processing was reintroduced in [61703]. This adds the regression coverage that was missing.

See https://github.com/WordPress/gutenberg/pull/77565.

Props jamesbregenzer, westonruter, andrewserong.
Fixes #65329.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/rest-api/rest-attachments-controller.php

    r62619 r62622  
    42664266
    42674267        /**
     4268         * Tests that the sideload route declares `convert_format` as a boolean arg.
     4269         *
     4270         * Without this declaration, multipart/form-data requests deliver the value as
     4271         * a string ("false") which evaluates truthy in PHP, so the sideload handler's
     4272         * `if ( ! $request['convert_format'] )` check never fires and the
     4273         * `image_editor_output_format` filter is never suppressed - meaning the
     4274         * server still performs the format conversion the client opted out of.
     4275         *
     4276         * @ticket 65329
     4277         * @covers WP_REST_Attachments_Controller::register_routes
     4278         */
     4279        public function test_sideload_route_declares_convert_format_boolean() {
     4280                $this->enable_client_side_media_processing();
     4281
     4282                $routes   = rest_get_server()->get_routes();
     4283                $endpoint = '/wp/v2/media/(?P<id>[\d]+)/sideload';
     4284                $this->assertArrayHasKey( $endpoint, $routes, 'Sideload route should exist.' );
     4285
     4286                $args = $routes[ $endpoint ][0]['args'];
     4287
     4288                $this->assertArrayHasKey( 'convert_format', $args, 'Route should declare convert_format.' );
     4289                $this->assertSame( 'boolean', $args['convert_format']['type'], 'convert_format should be a boolean.' );
     4290                $this->assertTrue( $args['convert_format']['default'], 'convert_format should default to true.' );
     4291        }
     4292
     4293        /**
     4294         * Tests that sideloading with `convert_format=false` (sent as the string
     4295         * "false", matching multipart/form-data semantics) suppresses the
     4296         * alt-extension collision check in `wp_unique_filename()`, so a companion
     4297         * file sharing the attachment basename does not get a numeric suffix.
     4298         *
     4299         * Mirrors the HEIC companion upload flow: a JPEG derivative is created via
     4300         * the media endpoint, then the original is sideloaded under the same stem.
     4301         * Without the arg declared as boolean, "false" coerces truthy, the filter
     4302         * is never added, and the companion is bumped to `-1` while the JPEG stays
     4303         * unsuffixed. PNG stands in for HEIC because core's default
     4304         * `image_editor_output_format` only maps HEIC/HEIF to JPEG; a local filter
     4305         * adds a PNG to JPEG mapping to trigger the same alt-ext check.
     4306         *
     4307         * @ticket 65329
     4308         * @covers WP_REST_Attachments_Controller::sideload_item
     4309         * @covers WP_REST_Attachments_Controller::register_routes
     4310         * @requires function imagejpeg
     4311         */
     4312        public function test_sideload_convert_format_false_suppresses_alt_ext_suffix() {
     4313                $this->enable_client_side_media_processing();
     4314
     4315                wp_set_current_user( self::$author_id );
     4316
     4317                // Upload a JPEG "parent" attachment the way client-side uploads do.
     4318                $request = new WP_REST_Request( 'POST', '/wp/v2/media' );
     4319                $request->set_header( 'Content-Type', 'image/jpeg' );
     4320                $request->set_header( 'Content-Disposition', 'attachment; filename=heic-companion.jpg' );
     4321                $request->set_param( 'generate_sub_sizes', false );
     4322                $request->set_body( (string) file_get_contents( self::$test_file ) );
     4323
     4324                $response      = rest_get_server()->dispatch( $request );
     4325                $attachment_id = $response->get_data()['id'];
     4326                $this->assertSame( 201, $response->get_status() );
     4327
     4328                /*
     4329                 * Simulate an alt-ext conversion mapping so an alt-extension companion
     4330                 * (PNG here, HEIC in production) would otherwise get a `-1` suffix.
     4331                 */
     4332                $add_png_mapping = static function ( $formats ) {
     4333                        $formats['image/png'] = 'image/jpeg';
     4334                        return $formats;
     4335                };
     4336                add_filter( 'image_editor_output_format', $add_png_mapping, 5 );
     4337
     4338                /*
     4339                 * Sideload a companion sharing the same basename. Use the source-format
     4340                 * original size: a source-format companion (HEIC in production, PNG
     4341                 * here) kept beside its JPEG derivative is exactly what this size
     4342                 * represents, and it is exempt from the sideload dimension validation
     4343                 * that would otherwise reject a companion whose dimensions differ from
     4344                 * the derivative. Pass convert_format as the string "false" to match
     4345                 * multipart/form-data request semantics.
     4346                 */
     4347                $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/sideload" );
     4348                $request->set_header( 'Content-Type', 'image/png' );
     4349                $request->set_header( 'Content-Disposition', 'attachment; filename=heic-companion.png' );
     4350                $request->set_param( 'image_size', WP_REST_Attachments_Controller::IMAGE_SIZE_SOURCE_ORIGINAL );
     4351                $request->set_param( 'convert_format', 'false' );
     4352                $request->set_body( (string) file_get_contents( DIR_TESTDATA . '/images/one-blue-pixel-100x100.png' ) );
     4353
     4354                $response = rest_get_server()->dispatch( $request );
     4355
     4356                remove_filter( 'image_editor_output_format', $add_png_mapping, 5 );
     4357
     4358                $this->assertSame( 200, $response->get_status() );
     4359
     4360                $data = $response->get_data();
     4361                $this->assertSame(
     4362                        'heic-companion.png',
     4363                        $data['file'],
     4364                        'Companion file should share the attachment basename without a numeric suffix.'
     4365                );
     4366        }
     4367
     4368        /**
    42684369         * Tests that sideloading with an array of image sizes registers the single
    42694370         * file under each size name when finalized.
Note: See TracChangeset for help on using the changeset viewer.