diff --git a/src/js/_enqueues/wp/updates.js b/src/js/_enqueues/wp/updates.js index 9f3b80b843d46..458da2de79f47 100644 --- a/src/js/_enqueues/wp/updates.js +++ b/src/js/_enqueues/wp/updates.js @@ -1379,6 +1379,16 @@ * @type {Object} */ plugins = settings.plugins, + /** + * Plugin groups that Core handles on its own. + * + * @type {Array} + */ + coreGroups = [ + 'all', 'search', 'upgrade', 'active', 'inactive', + 'recently_activated', 'mustuse', 'dropins', 'paused', + 'auto-update-enabled', 'auto-update-disabled' + ], remainingCount; // Add a success message after deleting a plugin. @@ -1447,6 +1457,24 @@ } } + // Remove from custom groups added through the `plugins_list` filter. + _.each( _.keys( plugins ), function( group ) { + var $view; + + if ( -1 !== _.indexOf( coreGroups, group ) || ! _.isArray( plugins[ group ] ) || -1 === _.indexOf( plugins[ group ], response.plugin ) ) { + return; + } + + plugins[ group ] = _.without( plugins[ group ], response.plugin ); + $view = $views.children( 'li.' + $.escapeSelector( group ) ); + + if ( plugins[ group ].length ) { + $view.find( '.count' ).text( '(' + plugins[ group ].length + ')' ); + } else { + $view.remove(); + } + } ); + plugins.all = _.without( plugins.all, response.plugin ); if ( plugins.all.length ) { @@ -1460,6 +1488,9 @@ } } + // Remove the trailing separator left on the last view when the view after it was removed. + $views.find( 'li:last' ).html( function() { return $( this ).children(); } ); + if ( $itemsCount.length && $currentView.length ) { remainingCount = plugins[ $currentView.parent( 'li' ).attr('class') ].length; $itemsCount.text( diff --git a/tests/qunit/wp-admin/js/updates.js b/tests/qunit/wp-admin/js/updates.js index 9d3948811abfd..500d74a63afed 100644 --- a/tests/qunit/wp-admin/js/updates.js +++ b/tests/qunit/wp-admin/js/updates.js @@ -122,6 +122,78 @@ jQuery( function( $ ) { assert.equal( jQuery.ajax.getCall( 0 ).args[0].data.action, 'delete-plugin' ); assert.equal( jQuery.ajax.getCall( 0 ).args[0].data.slug, 'jetpack' ); } ); + QUnit.test( 'Deleting a plugin should update the counts of custom plugin groups', function( assert ) { + var plugins = window._wpUpdatesSettings.plugins; + + $( '#qunit-fixture' ).append( + '' + + '' + + '
' + + '' + + '
' + ); + + window._wpUpdatesSettings.plugins = { + all: [ 'custom-a/custom-a.php', 'custom-b/custom-b.php', 'other/other.php' ], + demo_group: [ 'custom-a/custom-a.php', 'custom-b/custom-b.php' ], + single_group: [ 'custom-a/custom-a.php' ] + }; + + // Run the fade out callback right away. + sinon.stub( $.fn, 'fadeOut' ).callsFake( function( speed, callback ) { + return this.each( callback ); + } ); + + wp.updates.deletePluginSuccess( { slug: 'custom-a', plugin: 'custom-a/custom-a.php', pluginName: 'Custom A' } ); + + $.fn.fadeOut.restore(); + + assert.equal( $( '.subsubsub .all .count' ).text(), '(2)', 'The All count should go down.' ); + assert.equal( $( '.subsubsub .demo_group .count' ).text(), '(1)', 'The custom group count should go down.' ); + assert.strictEqual( $( '.subsubsub .single_group' ).length, 0, 'An empty custom group should be removed.' ); + assert.strictEqual( $( '.subsubsub .all' ).text(), 'All (2) |', 'Separators between views should be kept.' ); + assert.strictEqual( $( '.subsubsub .demo_group' ).text(), 'Demo Group (1)', 'The new last view should not end with a separator.' ); + assert.deepEqual( window._wpUpdatesSettings.plugins.demo_group, [ 'custom-b/custom-b.php' ], 'The deleted plugin should be removed from the custom group.' ); + + window._wpUpdatesSettings.plugins = plugins; + } ); + QUnit.test( 'Deleting a plugin should only remove the view of an emptied custom group', function( assert ) { + var plugins = window._wpUpdatesSettings.plugins; + + $( '#qunit-fixture' ).append( + '' + + '' + + '
' + + '' + + '
' + ); + + // A group key that matches the class of the count elements. + window._wpUpdatesSettings.plugins = { + all: [ 'custom-a/custom-a.php', 'other/other.php' ], + count: [ 'custom-a/custom-a.php' ] + }; + + sinon.stub( $.fn, 'fadeOut' ).callsFake( function( speed, callback ) { + return this.each( callback ); + } ); + + wp.updates.deletePluginSuccess( { slug: 'custom-a', plugin: 'custom-a/custom-a.php', pluginName: 'Custom A' } ); + + $.fn.fadeOut.restore(); + + assert.strictEqual( $( '.subsubsub > li.count' ).length, 0, 'The emptied group view should be removed.' ); + assert.strictEqual( $( '.subsubsub .all' ).text(), 'All (1)', 'The All view should keep its count.' ); + + window._wpUpdatesSettings.plugins = plugins; + } ); // QUnit.test( 'A successful update changes the message?', function( assert ) {} ); // QUnit.test( 'A failed update changes the message?', function( assert ) {} );