Skip to content

REST API: Add tests for the sideload convert_format boolean arg (backport GB #77565)#50

Closed
adamsilverstein wants to merge 5 commits into
trunkfrom
backport/77565-convert-format
Closed

REST API: Add tests for the sideload convert_format boolean arg (backport GB #77565)#50
adamsilverstein wants to merge 5 commits into
trunkfrom
backport/77565-convert-format

Conversation

@adamsilverstein
Copy link
Copy Markdown
Owner

What

Core backport of Gutenberg #77565 — Media uploading: declare convert_format as boolean arg on sideload route.

Stacked on #49 (GB #77036) → #48 (GB #75888) → reintroduce-client-side-media (#11324).

Why

The sideload handler reads $request['convert_format'], and the client sends convert_format: false in additionalData when uploading a HEIC companion. With multipart/form-data, an undeclared arg arrives as the string "false", which is truthy in PHP — so if ( ! $request['convert_format'] ) never fires and add_filter( 'image_editor_output_format', '__return_empty_array', 100 ) is skipped. The default HEIC→JPEG output mapping then survives and wp_unique_filename()'s alt-extension collision check bumps the original to -1 while the JPEG derivative stays unsuffixed, so the two companion files drift apart on repeat uploads. Declaring the arg as boolean lets REST coerce "false" → PHP false, the filter fires, and the companions keep a shared basename.

How

The controller change is already in Core. When client-side media processing was reintroduced (WordPress#11324), the sideload route already declared convert_format as a boolean (default true) and sideload_item() already suppresses image_editor_output_format when it is false. So this backport is tests only — it adds the coverage from GB #77565 to tests/phpunit/tests/rest-api/rest-attachments-controller.php:

  • test_sideload_route_declares_convert_format_boolean — asserts the sideload route declares convert_format as a boolean defaulting to true.
  • test_sideload_convert_format_false_suppresses_alt_ext_suffix — simulates the HEIC companion flow (PNG stand-in + a local PNG→JPEG mapping) and verifies that passing convert_format as the string "false" keeps the companion's shared basename with no numeric suffix.

Notes

  • Adapted to Core conventions: self::$author_id, self::$test_file, $this->enable_client_side_media_processing(), and : void-style test setup. The behavior test uses image_size => 'original' (a valid enum value) rather than the Gutenberg test's 'original-heic', since Core's image_size validation (added by GB #77036 / REST API: Support registering one sideloaded file under multiple sizes (backport GB #77036) #49) strictly enforces the registered-size enum.
  • Validated locally with php -l and PHPCS (WordPress-Core). The full PHPUnit suite was not run locally (the wordpress-develop test env is not currently provisioned, and the suite does not run in CI on fork PRs to a non-default base branch).

Part of the post-restore client-side-media backport stack.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fe053485-b4d3-4f52-94e7-9dc630f70311

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch backport/77565-convert-format

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Backport of Gutenberg PR #75888. Eliminate the read-modify-write race
between concurrent sideloads for the same attachment by no longer
writing attachment metadata in the sideload endpoint. Instead, sideload
returns lightweight sub-size data (dimensions, filename, filesize) which
the client accumulates and passes to the finalize endpoint, which writes
all collected sub-sizes in a single metadata update.

This matches how core generates sub-sizes (one metadata write after all
sizes exist) and replaces the earlier per-attachment locking approach
that the merged Gutenberg PR ultimately abandoned.
The three sub-size finalize tests added in this backport used the
placeholder ticket 62243 (the original client-side media feature ticket)
before a dedicated ticket existed. Trac #65329 now tracks this change, so
update those @ticket annotations. Pre-existing finalize tests keep 62243.
This backport changes the scaled-image sideload behavior (sideload now
returns sub-size data and metadata is written at finalize), so add a
65329 ticket reference alongside the existing 64737.
Backport of Gutenberg PR #77036. When several registered image sizes
share the same dimensions, the client generates a single physical file
and sends its size names as an array, so the file is registered once and
referenced under every matching size.

The sideload endpoint's `image_size` parameter (and the finalize
endpoint's `sub_sizes[].image_size`) now accept a string or an array of
strings. Because rest_is_array() treats scalar strings as single-element
lists, the enum is enforced via a validate_callback rather than a oneOf
schema. sideload_item() and finalize_item() register the file under each
name when an array is given.
@adamsilverstein adamsilverstein force-pushed the backport/77036-multi-size branch from 93c823b to 9fd5b2e Compare May 28, 2026 15:32
Backport of Gutenberg PR #77565. The convert_format boolean arg on the
sideload route is already present in core (it was included when client-side
media processing was reintroduced), so this backport adds the test coverage
from the Gutenberg PR:

- test_sideload_route_declares_convert_format_boolean asserts the route
  schema declares convert_format as a boolean defaulting to true.
- test_sideload_convert_format_false_suppresses_alt_ext_suffix verifies that
  passing convert_format as the string "false" (multipart/form-data
  semantics) coerces to PHP false, suppressing the image_editor_output_format
  filter so a companion file sharing the attachment basename is not given a
  numeric suffix.
@adamsilverstein adamsilverstein force-pushed the backport/77565-convert-format branch from 00738dc to cb8b288 Compare May 28, 2026 15:32
@adamsilverstein adamsilverstein changed the base branch from backport/77036-multi-size to trunk May 28, 2026 15:59
@adamsilverstein
Copy link
Copy Markdown
Owner Author

Closing in favor of upstream PR (re-opening on WordPress/wordpress-develop with same head branch).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant