diff --git a/src/js/_enqueues/vendor/plupload/wp-plupload.js b/src/js/_enqueues/vendor/plupload/wp-plupload.js index c0eb570657bf4..3f648e94549f2 100644 --- a/src/js/_enqueues/vendor/plupload/wp-plupload.js +++ b/src/js/_enqueues/vendor/plupload/wp-plupload.js @@ -484,8 +484,14 @@ window.wp = window.wp || {}; return pluploadL10n.file_exceeds_size_limit.replace( '%s', file.name ); }, - 'HTTP_ERROR': function( file ) { - if ( file.type && file.type.indexOf( 'image/' ) === 0 ) { + 'HTTP_ERROR': function( file, error ) { + var status = error && error.status; + + if ( + file.type && + file.type.indexOf( 'image/' ) === 0 && + ! ( status >= 400 && status < 500 ) + ) { return pluploadL10n.http_error_image; } diff --git a/tests/e2e/specs/media-upload.test.js b/tests/e2e/specs/media-upload.test.js index 885dee92c915d..76ea1036df81f 100644 --- a/tests/e2e/specs/media-upload.test.js +++ b/tests/e2e/specs/media-upload.test.js @@ -3,12 +3,25 @@ */ import { test, expect } from '@wordpress/e2e-test-utils-playwright'; -/** - * External dependencies - */ -import path from 'path'; +/** + * External dependencies + */ +import { readFileSync } from 'node:fs'; +import path from 'path'; + +const testImage = { + name: "test'image.jpg", + mimeType: 'image/jpeg', + buffer: readFileSync( + path.join( __dirname, '../../phpunit/data/images/test-image.jpg' ) + ), +}; + +test.afterEach( async ( { requestUtils } ) => { + await requestUtils.deleteAllMedia(); +} ); -test( 'Test dismissing failed upload works correctly', async ({ page, admin, requestUtils }) => { +test( 'Test dismissing failed upload works correctly', async ({ page, admin, requestUtils }) => { // Log in before visiting admin page. await requestUtils.login(); await admin.visitAdminPage( '/media-new.php' ); @@ -31,5 +44,77 @@ test( 'Test dismissing failed upload works correctly', async ({ page, admin, req await page.getByRole('button', { name: 'Dismiss' }).click(); await expect( page.getByText('“sample.svg” has failed to upload.') - ).not.toBeVisible(); -} ); + ).not.toBeVisible(); +} ); + +test( 'uploads an image with an apostrophe in its filename', async ( { + page, + admin, + requestUtils, +} ) => { + await requestUtils.login(); + await requestUtils.deleteAllMedia(); + await admin.visitAdminPage( '/media-new.php' ); + await page.waitForLoadState( 'load' ); + + const input = page.locator( '#plupload-upload-ui input[type="file"]' ); + await input.setInputFiles( testImage ); + + await expect( + page.getByText( 'testimage.jpg', { exact: true } ) + ).toBeVisible(); +} ); + +test( 'uses the generic HTTP error for a rejected image upload', async ( { + page, + admin, + requestUtils, +} ) => { + await requestUtils.login(); + await page.route( '**/wp-admin/async-upload.php', ( route ) => + route.fulfill( { + status: 403, + contentType: 'text/plain', + body: 'Forbidden', + } ) + ); + await admin.visitAdminPage( '/media-new.php' ); + await page.waitForLoadState( 'load' ); + + const input = page.locator( '#plupload-upload-ui input[type="file"]' ); + await input.setInputFiles( testImage ); + + await expect( + page.getByText( 'Unexpected response from the server.' ) + ).toBeVisible(); + await expect( + page.getByText( 'Suggested maximum size is 2560 pixels.' ) + ).not.toBeVisible(); +} ); + +test( 'retains the image processing error for a server failure', async ( { + page, + admin, + requestUtils, +} ) => { + await requestUtils.login(); + await page.route( '**/wp-admin/async-upload.php', ( route ) => + route.fulfill( { + status: 500, + contentType: 'text/plain', + body: 'Internal Server Error', + } ) + ); + await admin.visitAdminPage( '/media-new.php' ); + await page.waitForLoadState( 'load' ); + + const input = page.locator( '#plupload-upload-ui input[type="file"]' ); + await input.setInputFiles( testImage ); + + await expect( + page.getByText( 'The server cannot process the image.' ) + ).toBeVisible(); + await expect( + page.getByText( 'Suggested maximum size is 2560 pixels.' ) + ).toBeVisible(); +} );