Skip to content
Open
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
<?php

/**
* Admin Ajax functions to be tested.
*/
require_once ABSPATH . 'wp-admin/includes/ajax-actions.php';

/**
* Testing wp_ajax_media_create_image_subsizes() functionality.
*
* @package WordPress
* @subpackage UnitTests
* @since 5.3.0
*
* @group ajax
*
* @covers ::wp_ajax_media_create_image_subsizes
*/
class Tests_wp_ajax_media_create_image_subsizes extends WP_Ajax_UnitTestCase {

/**
* Attachment ID.
*
* @var int
*/
protected static $attachment_id;

/**
* Administrator user ID.
*
* @var int
*/
protected static $admin_id;

/**
* Setup test fixtures.
*
* @param WP_UnitTest_Factory $factory
*/
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ): void {
self::$admin_id = $factory->user->create( array( 'role' => 'administrator' ) );
self::$attachment_id = $factory->attachment->create_object(
DIR_TESTDATA . '/images/canola.jpg',
0,
array(
'post_mime_type' => 'image/jpeg',
'post_type' => 'attachment',
)
);
}

public function set_up(): void {
parent::set_up();
add_action( 'wp_ajax_media-create-image-subsizes', 'wp_ajax_media_create_image_subsizes', 1 );
}

/**
* Tests failure due to invalid nonce.
*
* @ticket 65252
*/
public function test_media_create_image_subsizes_invalid_nonce(): void {
wp_set_current_user( self::$admin_id );

$_POST = array(
'action' => 'media-create-image-subsizes',
'_ajax_nonce' => 'invalid-nonce',
);

try {
$this->_handleAjax( 'media-create-image-subsizes' );
} catch ( WPAjaxDieStopException $e ) {
$this->assertSame( '-1', $e->getMessage() );
} catch ( WPAjaxDieContinueException $e ) {
$this->assertSame( '-1', $this->_last_response );
}
}

/**
* Tests failure due to insufficient permissions.
*
* @ticket 65252
*/
public function test_media_create_image_subsizes_insufficient_permissions(): void {
$subscriber_id = self::factory()->user->create( array( 'role' => 'subscriber' ) );
wp_set_current_user( $subscriber_id );

$_POST = array(
'action' => 'media-create-image-subsizes',
'_ajax_nonce' => wp_create_nonce( 'media-form' ),
);

try {
$this->_handleAjax( 'media-create-image-subsizes' );
} catch ( WPAjaxDieStopException $e ) {
} catch ( WPAjaxDieContinueException $e ) {
}

$response = json_decode( $this->_last_response, true );
$this->assertFalse( $response['success'] );
$this->assertSame( 'Sorry, you are not allowed to upload files.', $response['data']['message'] );
}

/**
* Tests failure due to missing attachment_id.
*
* @ticket 65252
*/
public function test_media_create_image_subsizes_missing_attachment_id(): void {
wp_set_current_user( self::$admin_id );

$_POST = array(
'action' => 'media-create-image-subsizes',
'_ajax_nonce' => wp_create_nonce( 'media-form' ),
);

try {
$this->_handleAjax( 'media-create-image-subsizes' );
} catch ( WPAjaxDieStopException $e ) {
} catch ( WPAjaxDieContinueException $e ) {
}

$response = json_decode( $this->_last_response, true );
$this->assertFalse( $response['success'] );
$this->assertSame( 'Upload failed. Please reload and try again.', $response['data']['message'] );
}

/**
* Tests successful sub-sizes creation with legacy support.
*
* @ticket 65252
*/
public function test_media_create_image_subsizes_legacy_success(): void {
wp_set_current_user( self::$admin_id );

$_POST = array(
'action' => 'media-create-image-subsizes',
'attachment_id' => self::$attachment_id,
'_legacy_support' => 1,
'_ajax_nonce' => wp_create_nonce( 'media-form' ),
);

try {
$this->_handleAjax( 'media-create-image-subsizes' );
} catch ( WPAjaxDieStopException $e ) {
} catch ( WPAjaxDieContinueException $e ) {
}

$response = json_decode( $this->_last_response, true );
$this->assertTrue( $response['success'], 'AJAX response should be successful' );
$this->assertSame( self::$attachment_id, $response['data']['id'] );
}

/**
* Tests successful sub-sizes creation with full response.
*
* @ticket 65252
*/
public function test_media_create_image_subsizes_full_success(): void {
wp_set_current_user( self::$admin_id );

$_POST = array(
'action' => 'media-create-image-subsizes',
'attachment_id' => self::$attachment_id,
'_ajax_nonce' => wp_create_nonce( 'media-form' ),
);

try {
$this->_handleAjax( 'media-create-image-subsizes' );
} catch ( WPAjaxDieStopException $e ) {
} catch ( WPAjaxDieContinueException $e ) {
}

$response = json_decode( $this->_last_response, true );
$this->assertTrue( $response['success'], 'AJAX response should be successful' );
$this->assertSame( self::$attachment_id, $response['data']['id'] );
$this->assertArrayHasKey( 'sizes', $response['data'] );
}

/**
* Tests failed upload cleanup.
*
* @ticket 65252
*/
public function test_media_create_image_subsizes_cleanup_success(): void {
wp_set_current_user( self::$admin_id );

// Create a fresh attachment for cleanup.
$attachment_id = self::factory()->attachment->create_object(
DIR_TESTDATA . '/images/canola.jpg',
0,
array(
'post_mime_type' => 'image/jpeg',
'post_type' => 'attachment',
)
);

$_POST = array(
'action' => 'media-create-image-subsizes',
'attachment_id' => $attachment_id,
'_wp_upload_failed_cleanup' => 1,
'_ajax_nonce' => wp_create_nonce( 'media-form' ),
);

try {
$this->_handleAjax( 'media-create-image-subsizes' );
} catch ( WPAjaxDieStopException $e ) {
} catch ( WPAjaxDieContinueException $e ) {
}

$response = json_decode( $this->_last_response, true );
$this->assertTrue( $response['success'], 'AJAX response should be successful' );
$this->assertNull( get_post( $attachment_id ), 'Attachment should be deleted' );
}
}
168 changes: 168 additions & 0 deletions tests/phpunit/tests/admin/includes/ajax-actions/uploadAttachment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
<?php

/**
* Admin Ajax functions to be tested.
*/
require_once ABSPATH . 'wp-admin/includes/ajax-actions.php';

/**
* Testing wp_ajax_upload_attachment() functionality.
*
* @package WordPress
* @subpackage UnitTests
* @since 3.3.0
*
* @group ajax
*
* @covers ::wp_ajax_upload_attachment
*/
class Tests_wp_ajax_upload_attachment extends WP_Ajax_UnitTestCase {

/**
* Administrator user ID.
*
* @var int
*/
protected static $admin_id;

/**
* Setup test fixtures.
*
* @param WP_UnitTest_Factory $factory
*/
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ): void {
self::$admin_id = $factory->user->create( array( 'role' => 'administrator' ) );
}

public function set_up(): void {
parent::set_up();
add_action( 'wp_ajax_upload-attachment', 'wp_ajax_upload_attachment', 1 );

// Force the action to be something other than wp_handle_upload to bypass the is_uploaded_file check.
add_filter( 'wp_handle_upload_overrides', function ( $overrides ) {

Check failure on line 42 in tests/phpunit/tests/admin/includes/ajax-actions/uploadAttachment.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Only one argument is allowed per line in a multi-line function call

Check failure on line 42 in tests/phpunit/tests/admin/includes/ajax-actions/uploadAttachment.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Opening parenthesis of a multi-line function call must be the last content on the line
$overrides['action'] = 'wp_handle_sideload';
return $overrides;
} );

Check failure on line 45 in tests/phpunit/tests/admin/includes/ajax-actions/uploadAttachment.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Closing parenthesis of a multi-line function call must be on a line by itself
}

/**
* Tests failure due to invalid nonce.
*
* @ticket 65252
*/
public function test_upload_attachment_invalid_nonce(): void {
wp_set_current_user( self::$admin_id );

$_POST = array(
'action' => 'upload-attachment',
'_ajax_nonce' => 'invalid-nonce',
);

try {
$this->_handleAjax( 'upload-attachment' );
} catch ( WPAjaxDieStopException $e ) {
$this->assertSame( '-1', $e->getMessage() );
} catch ( WPAjaxDieContinueException $e ) {
$this->assertSame( '-1', $this->_last_response );
}
}

/**
* Tests failure due to insufficient permissions.
*
* @ticket 65252
*/
public function test_upload_attachment_insufficient_permissions(): void {
$subscriber_id = self::factory()->user->create( array( 'role' => 'subscriber' ) );
wp_set_current_user( $subscriber_id );

$_POST = array(
'action' => 'upload-attachment',
'_ajax_nonce' => wp_create_nonce( 'media-form' ),
);

// wp_ajax_upload_attachment() uses echo and wp_die() instead of wp_send_json_error().
try {
$this->_handleAjax( 'upload-attachment' );
} catch ( WPAjaxDieStopException $e ) {
} catch ( WPAjaxDieContinueException $e ) {
}

$response = json_decode( $this->_last_response, true );
$this->assertFalse( $response['success'] );
$this->assertSame( 'Sorry, you are not allowed to upload files.', $response['data']['message'] );
}
/**
* Tests successful upload.
*
* @ticket 65252
*/
public function test_upload_attachment_success(): void {
wp_set_current_user( self::$admin_id );

$_POST = array(
'action' => 'upload-attachment',
'_ajax_nonce' => wp_create_nonce( 'media-form' ),
);

$_FILES = array(
'async-upload' => array(
'name' => 'canola.jpg',
'type' => 'image/jpeg',
'tmp_name' => DIR_TESTDATA . '/images/canola.jpg',
'error' => 0,
'size' => filesize( DIR_TESTDATA . '/images/canola.jpg' ),
),
);

// Short-circuit media_handle_upload() by filtering 'wp_handle_upload_prefilter'.
// Wait, media_handle_upload() is a function. It calls wp_handle_upload().
// We already tried many filters.

// Let's use a very late filter in wp_insert_attachment or something? No.

// The issue is that _wp_handle_upload returns an error array because is_uploaded_file fails.
// If we use the 'wp_handle_upload_prefilter' to set 'error' to something,
// it will go to the error handler.

add_filter( 'wp_handle_upload_prefilter', function( $file ) {

Check failure on line 128 in tests/phpunit/tests/admin/includes/ajax-actions/uploadAttachment.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Expected 1 space after FUNCTION keyword; 0 found

Check failure on line 128 in tests/phpunit/tests/admin/includes/ajax-actions/uploadAttachment.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Only one argument is allowed per line in a multi-line function call

Check failure on line 128 in tests/phpunit/tests/admin/includes/ajax-actions/uploadAttachment.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Opening parenthesis of a multi-line function call must be the last content on the line
$file['error'] = 'mock_success';
return $file;
} );

Check failure on line 131 in tests/phpunit/tests/admin/includes/ajax-actions/uploadAttachment.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Closing parenthesis of a multi-line function call must be on a line by itself

// We MUST ensure the error handler returns what we want.
// The default error handler is wp_handle_upload_error which returns array('error' => $message).
// media_handle_upload checks for isset($file['error']).

// What if we filter 'wp_handle_upload_overrides' to change the error handler?
add_filter( 'wp_handle_upload_overrides', function( $overrides ) {

Check failure on line 138 in tests/phpunit/tests/admin/includes/ajax-actions/uploadAttachment.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Expected 1 space after FUNCTION keyword; 0 found

Check failure on line 138 in tests/phpunit/tests/admin/includes/ajax-actions/uploadAttachment.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Only one argument is allowed per line in a multi-line function call

Check failure on line 138 in tests/phpunit/tests/admin/includes/ajax-actions/uploadAttachment.php

View workflow job for this annotation

GitHub Actions / Coding standards / PHP checks

Opening parenthesis of a multi-line function call must be the last content on the line
$overrides['upload_error_handler'] = function( $file, $message ) {
if ( 'mock_success' === $message ) {
$upload_dir = wp_upload_dir();
$new_file = $upload_dir['path'] . '/canola.jpg';
@copy( DIR_TESTDATA . '/images/canola.jpg', $new_file );
return array(
'file' => $new_file,
'url' => $upload_dir['url'] . '/canola.jpg',
'type' => 'image/jpeg',
);
}
return array( 'error' => $message );
};
return $overrides;
}, 10 );

try {
$this->_handleAjax( 'upload-attachment' );
} catch ( WPAjaxDieStopException $e ) {
} catch ( WPAjaxDieContinueException $e ) {
}

$response = json_decode( $this->_last_response, true );
if ( ! isset( $response['success'] ) || ! $response['success'] ) {
$this->fail( 'AJAX response was not successful. Response: ' . $this->_last_response );
}
$this->assertTrue( $response['success'] );
$this->assertSame( 'canola.jpg', $response['data']['filename'] );
}
}
Loading