Skip to content

REST API: Add tests for the sideload convert_format boolean arg - #12002

Closed
adamsilverstein wants to merge 11 commits into
WordPress:trunkfrom
adamsilverstein:backport/75888-sideload-finalize
Closed

REST API: Add tests for the sideload convert_format boolean arg#12002
adamsilverstein wants to merge 11 commits into
WordPress:trunkfrom
adamsilverstein:backport/75888-sideload-finalize

Conversation

@adamsilverstein

@adamsilverstein adamsilverstein commented May 28, 2026

Copy link
Copy Markdown
Member

What

Adds the convert_format boolean-arg test coverage from Gutenberg #77565 — Media uploading: declare convert_format as boolean arg on sideload route.

Part of the post-restore client-side-media backport stack (see #11324).

Note: This PR originally backported the GB #75888 finalize-metadata refactor (Trac #65329). That production code and its finalize tests have since landed in trunk, so the PR has been reduced to the remaining convert_format test coverage. Diff shown against trunk for standalone-mergeability.

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 ([61703]), 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 strictly enforces the registered-size enum.
  • Validated locally with php -l and PHPCS (WordPress-Core).

Trac ticket: https://core.trac.wordpress.org/ticket/65329


Proposed commit message

65329

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

The sideload route already 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 still missing.

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

Props adamsilverstein, andrewserong.
Fixes #65329.

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.
@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props adamsilverstein, westonruter.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@westonruter

Copy link
Copy Markdown
Member

This also seems to have much of the same code as #12003, which I've reviewed in depth, so I guess that should be committed first before proceeding here.

Moving sideload metadata writing to the finalize endpoint adds a
sub_sizes argument to that endpoint's schema. Regenerate
tests/qunit/fixtures/wp-api-generated.js so the "fixtures are up to
date" CI guard (git diff --exit-code) passes.
@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Backports the convert_format test coverage from Gutenberg PR #77565.
The convert_format argument and its handling already exist in core; this
adds the missing test coverage, folding it into this sideload-finalize
PR because the second test asserts the sideload response shape introduced
here (a top-level file key on the lightweight sub-size response).

Supersedes the separate backport PR for GB #77565, whose unique
contribution was only these two tests.
@adamsilverstein

Copy link
Copy Markdown
Member Author

Added the convert_format boolean-arg test coverage here in 1b41141 (backport of Gutenberg #77565), folding in the former #12003. The argument itself already exists in core; these two tests assert it is declared as a boolean and that convert_format=false suppresses the alt-extension suffix on companion files — which relies on the sub-size response shape this PR introduces.

Convert stacked // line comments into /* ... */ block comments for the
multi-line explanatory comments added in this change.
@adamsilverstein

Copy link
Copy Markdown
Member Author

This also seems to have much of the same code as #12003, which I've reviewed in depth, so I guess that should be committed first before proceeding here.

@westonruter - that other pr was closed in favor of this one, apologies for any confusion.

adamsilverstein added a commit to adamsilverstein/wordpress-develop that referenced this pull request Jul 1, 2026
Resolve conflicts in the sideload endpoint after the finalize refactor
(WordPress#12002) changed sideload_item to return sub-size data instead of writing
attachment metadata inline.

Keep the dimension-validation feature: read and reject unreadable images
up front, and validate scalar image sizes. Guard the
validate_image_dimensions() call behind a scalar check since trunk now
allows an array image_size (multiple registered sizes sharing one file),
which the string-typed validator cannot accept; array sizes are handled
by the per-size branch below.
adamsilverstein and others added 2 commits July 1, 2026 13:45
…oad-finalize

# Conflicts:
#	src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
#	tests/phpunit/tests/rest-api/rest-attachments-controller.php
#	tests/qunit/fixtures/wp-api-generated.js
@adamsilverstein

Copy link
Copy Markdown
Member Author

Only tests remain in this PR. Once I confirm they pass against trunk I'll go ahead and commit.

@adamsilverstein adamsilverstein changed the title REST API: Move sideload metadata writing to the finalize endpoint (backport GB #75888) REST API: Add tests for the sideload convert_format boolean arg Jul 1, 2026
…panion test

The convert_format alt-ext-suffix test sideloaded a 100x100 PNG companion
under image_size 'original' against a 640x480 JPEG parent. The sideload
dimension validation added for the client-side-media route now rejects an
'original' whose dimensions do not match the attachment's recorded
dimensions, so the request returned 400 instead of 200 and the test failed
across the whole matrix.

Sideload the companion as the source-format original size instead. A
source-format companion kept beside its JPEG derivative is exactly what
that size represents, and it is exempt from dimension validation, so the
100x100 PNG stand-in is accepted. The convert_format suppression the test
exercises runs before the size branching, so the test's intent is
unchanged.
These tests ride on the sideload-metadata-to-finalize backport PR, which
is tracked under #65329 (the ticket that owns this PR). Align their
@ticket annotations with that ticket, matching the finalize tests already
filed under #65329.
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 62622
GitHub commit: d73908f

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Jul 2, 2026
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.

2 participants