Skip to content
Draft
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
92 changes: 66 additions & 26 deletions src/js/_enqueues/wp/updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -1330,13 +1330,23 @@
* decorated with an abort() method.
*/
wp.updates.deletePlugin = function( args ) {
var $link = $( '[data-plugin="' + args.plugin + '"]' ).find( '.row-actions a.delete' );
var errorCallback,
$link = $( '[data-plugin="' + args.plugin + '"]' ).find( '.row-actions a.delete' );

args = _.extend( {
success: wp.updates.deletePluginSuccess,
error: wp.updates.deletePluginError
}, args );

errorCallback = args.error;
if ( errorCallback ) {
args.error = function() {
$link.html( $link.data( 'originaltext' ) );

errorCallback.apply( this, arguments );
};
}

if ( $link.html() !== __( 'Deleting...' ) ) {
$link
.data( 'originaltext', $link.html() )
Expand Down Expand Up @@ -1488,12 +1498,7 @@
* @param {string} response.errorMessage The error that occurred.
*/
wp.updates.deletePluginError = function( response ) {
var $plugin, $pluginUpdateRow,
pluginUpdateRow = wp.template( 'item-update-row' ),
noticeContent = wp.updates.adminNotice( {
className: 'update-message notice-error notice-alt',
message: response.errorMessage
} );
var $deleteLink, $plugin, $pluginUpdateRow, noticeContent, pluginUpdateRow;

if ( response.plugin ) {
$plugin = $( 'tr.inactive[data-plugin="' + response.plugin + '"]' );
Expand All @@ -1503,6 +1508,9 @@
$pluginUpdateRow = $plugin.siblings( '[data-slug="' + response.slug + '"]' );
}

$deleteLink = $plugin.find( '.row-actions a.delete' );
$deleteLink.text( $deleteLink.data( 'originaltext' ) );

if ( ! wp.updates.isValidResponse( response, 'delete' ) ) {
return;
}
Expand All @@ -1511,6 +1519,12 @@
return;
}

pluginUpdateRow = wp.template( 'item-update-row' );
noticeContent = wp.updates.adminNotice( {
className: 'update-message notice-error notice-alt',
message: response.errorMessage
} );

// Add a plugin update row if it doesn't exist yet.
if ( ! $pluginUpdateRow.length ) {
$plugin.addClass( 'update' ).after(
Expand Down Expand Up @@ -1908,7 +1922,7 @@
* decorated with an abort() method.
*/
wp.updates.deleteTheme = function( args ) {
var $button;
var $button, errorCallback;

if ( 'themes' === pagenow ) {
$button = $( '.theme-actions .delete-theme' );
Expand All @@ -1921,6 +1935,17 @@
error: wp.updates.deleteThemeError
}, args );

errorCallback = args.error;
if ( errorCallback ) {
args.error = function() {
if ( $button ) {
$button.html( $button.data( 'originaltext' ) );
}

errorCallback.apply( this, arguments );
};
}

if ( $button && $button.html() !== __( 'Deleting...' ) ) {
$button
.data( 'originaltext', $button.html() )
Expand Down Expand Up @@ -2034,24 +2059,37 @@
* @param {string} response.errorMessage The error that occurred.
*/
wp.updates.deleteThemeError = function( response ) {
var $themeRow = $( 'tr.inactive[data-slug="' + response.slug + '"]' ),
$button = $( '.theme-actions .delete-theme' ),
updateRow = wp.template( 'item-update-row' ),
$updateRow = $themeRow.siblings( '#' + response.slug + '-update' ),
errorMessage = sprintf(
/* translators: %s: Error string for a failed deletion. */
__( 'Deletion failed: %s' ),
response.errorMessage
),
$message = wp.updates.adminNotice( {
className: 'update-message notice-error notice-alt',
message: errorMessage
} );
var $button, $message, errorMessage, updateRow,
$themeRow = $( 'tr.inactive[data-slug="' + response.slug + '"]' ),
$updateRow = $themeRow.siblings( '#' + response.slug + '-update' );

if ( 'themes-network' === pagenow ) {
$button = $themeRow.find( '.row-actions a.delete' );
} else {
$button = $( '.theme-actions .delete-theme' );
}

$button.html( $button.data( 'originaltext' ) );

if ( ! wp.updates.isValidResponse( response, 'delete' ) ) {
return;
}

if ( wp.updates.maybeHandleCredentialError( response, 'delete-theme' ) ) {
return;
}

updateRow = wp.template( 'item-update-row' );
errorMessage = sprintf(
/* translators: %s: Error string for a failed deletion. */
__( 'Deletion failed: %s' ),
response.errorMessage
);
$message = wp.updates.adminNotice( {
className: 'update-message notice-error notice-alt',
message: errorMessage
} );

if ( 'themes-network' === pagenow ) {
if ( ! $updateRow.length ) {
$themeRow.addClass( 'update' ).after(
Expand All @@ -2070,8 +2108,6 @@
$( '.theme-info .theme-description' ).before( $message );
}

$button.html( $button.data( 'originaltext' ) );

wp.a11y.speak( errorMessage, 'assertive' );

$document.trigger( 'wp-theme-delete-error', response );
Expand Down Expand Up @@ -3418,7 +3454,7 @@
if ( response.data && response.data.error ) {
errorMessage = response.data.error;
} else {
errorMessage = __( 'The request could not be completed.' );
errorMessage = __( 'The request could not be completed. Please try again.' );
}

$parent.find( '.notice.notice-error' ).removeClass( 'hidden' ).find( 'p' ).text( errorMessage );
Expand Down Expand Up @@ -3482,11 +3518,15 @@
$parent.find( '.notice.notice-error' )
.removeClass( 'hidden' )
.find( 'p' )
.text( __( 'The request could not be completed.' ) );
.text( __( 'The request could not be completed. Please try again.' ) );

wp.a11y.speak( __( 'The request could not be completed.' ), 'assertive' );
wp.a11y.speak( __( 'The request could not be completed. Please try again.' ), 'assertive' );
} )
.always( function() {
if ( action === $toggler.attr( 'data-wp-action' ) ) {
$label.text( 'enable' === action ? __( 'Enable auto-updates' ) : __( 'Disable auto-updates' ) );
}

$toggler.removeAttr( 'data-doing-ajax' ).find( '.dashicons-update' ).addClass( 'hidden' );
} );
}
Expand Down
93 changes: 93 additions & 0 deletions tests/qunit/wp-admin/js/updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,24 @@ jQuery( function( $ ) {
assert.equal( jQuery.ajax.getCall( 0 ).args[0].data.slug, 'jetpack' );
} );

/**
* @ticket 55368
*/
QUnit.test( 'A failed plugin deletion should restore the delete link', function( assert ) {
var $pluginRow = $(
'<table><tbody><tr class="inactive" data-plugin="jetpack/jetpack.php" data-slug="jetpack">' +
'<td><div class="row-actions"><a class="delete">Delete</a></div></td>' +
'</tr></tbody></table>'
).appendTo( '#qunit-fixture' ).find( 'tr' );

sinon.stub( wp.ajax, 'send' ).returns( jQuery.Deferred().promise() );

wp.updates.deletePlugin( { slug: 'jetpack', plugin: 'jetpack/jetpack.php' } );
wp.ajax.send.firstCall.args[ 0 ].error( 'Briefly unavailable for scheduled maintenance.' );

assert.strictEqual( $pluginRow.find( 'a.delete' ).text(), 'Delete', 'The delete link text is restored.' );
} );

// QUnit.test( 'A successful update changes the message?', function( assert ) {} );
// QUnit.test( 'A failed update changes the message?', function( assert ) {} );

Expand Down Expand Up @@ -174,6 +192,81 @@ jQuery( function( $ ) {
assert.equal( jQuery.ajax.getCall( 0 ).args[0].data.slug, 'twentyeleven' );
} );

/**
* @ticket 55368
*/
QUnit.test( 'A failed theme deletion should restore the delete button', function( assert ) {
var $button = $( '<div class="theme-actions"><button class="delete-theme">Delete</button></div>' )
.appendTo( '#qunit-fixture' )
.find( '.delete-theme' );

var sendStub = sinon.stub( wp.ajax, 'send' ).returns( jQuery.Deferred().promise() );

wp.updates.deleteTheme( { slug: 'twentyeleven' } );
wp.ajax.send.firstCall.args[ 0 ].error( 'Briefly unavailable for scheduled maintenance.' );

assert.strictEqual( $button.text(), 'Delete', 'The delete button text is restored.' );

sendStub.restore();
} );

// QUnit.test( 'A successful update changes the message?', function( assert ) {} );
// QUnit.test( 'A failed update changes the message?', function( assert ) {} );

QUnit.module( 'wp.updates.autoUpdates', {
beforeEach: function() {
this.oldPagenow = window.pagenow;
window.pagenow = 'plugins';
this.request = jQuery.Deferred();
sinon.stub( jQuery, 'post' ).returns( this.request.promise() );
this.$column = $(
'<div class="column-auto-updates">' +
'<div class="notice notice-error hidden"><p></p></div>' +
'<button class="toggle-auto-update" data-wp-action="enable">' +
'<span class="dashicons-update hidden"></span>' +
'<span class="label">Enable auto-updates</span>' +
'</button>' +
'</div>'
).appendTo( '#qunit-fixture' );
},
afterEach: function() {
window.pagenow = this.oldPagenow;
}
} );

/**
* @ticket 55368
*/
QUnit.test( 'A failed auto-update request should restore the toggle label', function( assert ) {
var $toggler = this.$column.find( '.toggle-auto-update' );

$toggler.trigger( 'click' );
assert.strictEqual( $toggler.find( '.label' ).text(), 'Enabling...', 'The pending label is shown.' );

this.request.reject();

assert.strictEqual( $toggler.find( '.label' ).text(), 'Enable auto-updates', 'The toggle label is restored.' );
assert.strictEqual(
this.$column.find( '.notice-error p' ).text(),
'The request could not be completed. Please try again.',
'The error message suggests retrying the request.'
);
} );

/**
* @ticket 55368
*/
QUnit.test( 'An invalid auto-update response should restore the toggle label', function( assert ) {
var $toggler = this.$column.find( '.toggle-auto-update' );

$toggler.trigger( 'click' );
this.request.resolve( 'Briefly unavailable for scheduled maintenance.' );

assert.strictEqual( $toggler.find( '.label' ).text(), 'Enable auto-updates', 'The toggle label is restored.' );
assert.strictEqual(
this.$column.find( '.notice-error p' ).text(),
'The request could not be completed. Please try again.',
'The error message suggests retrying the request.'
);
} );
});
Loading