Commit 0fc02aa827a for woocommerce

commit 0fc02aa827a813a790d4c8820aec21158f9c8a61
Author: Luigi Teschio <gigitux@gmail.com>
Date:   Wed Jul 15 13:25:45 2026 +0200

    Fix client-only blocks disappearing from the post editor (#66628)

    * Fix client-only blocks disappearing from post editor

    * Add changelog entry for block editor deny-list fix

diff --git a/plugins/woocommerce/changelog/fix-66612-block-editor-deny-list b/plugins/woocommerce/changelog/fix-66612-block-editor-deny-list
new file mode 100644
index 00000000000..b649992ea7e
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-66612-block-editor-deny-list
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Prevent client-side-only blocks from disappearing from the post editor inserter.
diff --git a/plugins/woocommerce/client/blocks/assets/js/filters/unregister-block-types/block-types.ts b/plugins/woocommerce/client/blocks/assets/js/filters/unregister-block-types/block-types.ts
new file mode 100644
index 00000000000..f332fcc5c47
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/assets/js/filters/unregister-block-types/block-types.ts
@@ -0,0 +1,78 @@
+/**
+ * WooCommerce block types hidden from post editors.
+ */
+export const POST_EDITOR_BLOCK_TYPES_TO_UNREGISTER = [
+	'woocommerce/breadcrumbs',
+	'woocommerce/catalog-sorting',
+	'woocommerce/legacy-template',
+	'woocommerce/product-results-count',
+	'woocommerce/product-reviews',
+	'woocommerce/order-confirmation-status',
+	'woocommerce/order-confirmation-summary',
+	'woocommerce/order-confirmation-totals',
+	'woocommerce/order-confirmation-totals-wrapper',
+	'woocommerce/order-confirmation-downloads',
+	'woocommerce/order-confirmation-downloads-wrapper',
+	'woocommerce/order-confirmation-billing-address',
+	'woocommerce/order-confirmation-shipping-address',
+	'woocommerce/order-confirmation-billing-wrapper',
+	'woocommerce/order-confirmation-shipping-wrapper',
+	'woocommerce/order-confirmation-additional-information',
+	'woocommerce/order-confirmation-additional-fields-wrapper',
+	'woocommerce/order-confirmation-additional-fields',
+];
+
+/**
+ * WooCommerce block types allowed in Widget Areas. New blocks won't be
+ * exposed in the Widget Area unless specifically added here.
+ */
+export const WIDGET_EDITOR_ALLOWED_BLOCK_TYPES = [
+	'woocommerce/all-reviews',
+	'woocommerce/breadcrumbs',
+	'woocommerce/cart-link',
+	'woocommerce/catalog-sorting',
+	'woocommerce/classic-shortcode',
+	'woocommerce/customer-account',
+	'woocommerce/dropdown',
+	'woocommerce/featured-category',
+	'woocommerce/featured-product',
+	'woocommerce/mini-cart',
+	'woocommerce/product-categories',
+	'woocommerce/product-results-count',
+	'woocommerce/product-search',
+	'woocommerce/reviews-by-category',
+	'woocommerce/reviews-by-product',
+	'woocommerce/product-filters',
+	'woocommerce/product-filter-status',
+	'woocommerce/product-filter-price',
+	'woocommerce/product-filter-price-slider',
+	'woocommerce/product-filter-attribute',
+	'woocommerce/product-filter-rating',
+	'woocommerce/product-filter-active',
+	'woocommerce/product-filter-removable-chips',
+	'woocommerce/product-filter-clear-button',
+	'woocommerce/product-filter-checkbox-list',
+	'woocommerce/product-filter-chips',
+	'woocommerce/product-filter-taxonomy',
+
+	// Keep hidden legacy filter blocks for backward compatibility.
+	'woocommerce/active-filters',
+	'woocommerce/attribute-filter',
+	'woocommerce/filter-wrapper',
+	'woocommerce/price-filter',
+	'woocommerce/rating-filter',
+	'woocommerce/stock-filter',
+	// End: legacy filter blocks.
+
+	// Below product grids are hidden from inserter however they could have been used in widgets.
+	// Keep them for backward compatibility.
+	'woocommerce/handpicked-products',
+	'woocommerce/product-best-sellers',
+	'woocommerce/product-new',
+	'woocommerce/product-on-sale',
+	'woocommerce/product-top-rated',
+	'woocommerce/products-by-attribute',
+	'woocommerce/product-category',
+	'woocommerce/product-tag',
+	// End: legacy product grids blocks.
+];
diff --git a/plugins/woocommerce/client/blocks/assets/js/filters/unregister-block-types/index.ts b/plugins/woocommerce/client/blocks/assets/js/filters/unregister-block-types/index.ts
new file mode 100644
index 00000000000..29ea6d297c4
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/assets/js/filters/unregister-block-types/index.ts
@@ -0,0 +1,56 @@
+/**
+ * External dependencies
+ */
+import { getBlockTypes, unregisterBlockType } from '@wordpress/blocks';
+import domReady from '@wordpress/dom-ready';
+
+/**
+ * Internal dependencies
+ */
+import {
+	POST_EDITOR_BLOCK_TYPES_TO_UNREGISTER,
+	WIDGET_EDITOR_ALLOWED_BLOCK_TYPES,
+} from './block-types';
+
+type BlockEditorContext = 'post' | 'widgets' | 'other';
+
+const getBlockEditorContext = (): BlockEditorContext => {
+	const adminPage = ( window as Window & { adminpage?: string } ).adminpage;
+
+	if ( [ 'post-php', 'post-new-php' ].includes( adminPage ?? '' ) ) {
+		return 'post';
+	}
+
+	if ( [ 'widgets-php', 'customize-php' ].includes( adminPage ?? '' ) ) {
+		return 'widgets';
+	}
+
+	return 'other';
+};
+
+const getBlockTypesToUnregister = (): string[] => {
+	const registeredBlockTypes = getBlockTypes().map( ( { name } ) => name );
+	const blockEditorContext = getBlockEditorContext();
+
+	if ( blockEditorContext === 'post' ) {
+		return POST_EDITOR_BLOCK_TYPES_TO_UNREGISTER.filter( ( blockType ) =>
+			registeredBlockTypes.includes( blockType )
+		);
+	}
+
+	if ( blockEditorContext === 'widgets' ) {
+		return registeredBlockTypes.filter(
+			( blockType ) =>
+				blockType.startsWith( 'woocommerce/' ) &&
+				! WIDGET_EDITOR_ALLOWED_BLOCK_TYPES.includes( blockType )
+		);
+	}
+
+	return [];
+};
+
+domReady( () => {
+	getBlockTypesToUnregister().forEach( ( blockType ) => {
+		unregisterBlockType( blockType );
+	} );
+} );
diff --git a/plugins/woocommerce/client/blocks/assets/js/filters/unregister-block-types/test/index.ts b/plugins/woocommerce/client/blocks/assets/js/filters/unregister-block-types/test/index.ts
new file mode 100644
index 00000000000..cacce94f0c6
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/assets/js/filters/unregister-block-types/test/index.ts
@@ -0,0 +1,104 @@
+/**
+ * External dependencies
+ */
+import { getBlockTypes, unregisterBlockType } from '@wordpress/blocks';
+
+jest.mock( '@wordpress/blocks', () => ( {
+	getBlockTypes: jest.fn(),
+	unregisterBlockType: jest.fn(),
+} ) );
+
+jest.mock( '@wordpress/dom-ready', () => ( {
+	__esModule: true,
+	default: jest.fn( ( callback ) => callback() ),
+} ) );
+
+const loadFilter = ( adminPage: string | undefined, blockTypes: string[] ) => {
+	( window as Window & { adminpage?: string } ).adminpage = adminPage;
+	( getBlockTypes as jest.Mock ).mockReturnValue(
+		blockTypes.map( ( name ) => ( { name } ) )
+	);
+
+	jest.isolateModules( () => {
+		require( '../index' );
+	} );
+};
+
+describe( 'unregister block types', () => {
+	beforeEach( () => {
+		jest.clearAllMocks();
+	} );
+
+	it.each( [ 'post-php', 'post-new-php' ] )(
+		'unregisters only post-editor block types in the deny list in %s',
+		( adminPage ) => {
+			loadFilter( adminPage, [
+				'woocommerce/breadcrumbs',
+				'woocommerce/product-reviews',
+				'woocommerce/product-search',
+				'myplugin/client-only',
+			] );
+
+			expect( unregisterBlockType ).toHaveBeenCalledTimes( 2 );
+			expect( unregisterBlockType ).toHaveBeenCalledWith(
+				'woocommerce/breadcrumbs'
+			);
+			expect( unregisterBlockType ).toHaveBeenCalledWith(
+				'woocommerce/product-reviews'
+			);
+			expect( unregisterBlockType ).not.toHaveBeenCalledWith(
+				'woocommerce/product-search'
+			);
+			expect( unregisterBlockType ).not.toHaveBeenCalledWith(
+				'myplugin/client-only'
+			);
+		}
+	);
+
+	it.each( [ 'widgets-php', 'customize-php' ] )(
+		'unregisters WooCommerce blocks outside the widget-editor allow list in %s',
+		( context ) => {
+			loadFilter( context, [
+				'woocommerce/product-search',
+				'woocommerce/product-filters',
+				'woocommerce/checkout',
+				'woocommerce/order-confirmation-status',
+				'woocommerce/new-widget-compatible-block',
+				'myplugin/client-only',
+			] );
+
+			expect( unregisterBlockType ).toHaveBeenCalledTimes( 3 );
+			expect( unregisterBlockType ).toHaveBeenCalledWith(
+				'woocommerce/checkout'
+			);
+			expect( unregisterBlockType ).toHaveBeenCalledWith(
+				'woocommerce/order-confirmation-status'
+			);
+			expect( unregisterBlockType ).not.toHaveBeenCalledWith(
+				'woocommerce/product-search'
+			);
+			expect( unregisterBlockType ).not.toHaveBeenCalledWith(
+				'woocommerce/product-filters'
+			);
+			expect( unregisterBlockType ).toHaveBeenCalledWith(
+				'woocommerce/new-widget-compatible-block'
+			);
+			expect( unregisterBlockType ).not.toHaveBeenCalledWith(
+				'myplugin/client-only'
+			);
+		}
+	);
+
+	it.each( [ 'site-editor-php', undefined ] )(
+		'does not unregister blocks in unrestricted editor contexts (%s)',
+		( adminPage ) => {
+			loadFilter( adminPage, [
+				'woocommerce/breadcrumbs',
+				'woocommerce/checkout',
+				'myplugin/client-only',
+			] );
+
+			expect( unregisterBlockType ).not.toHaveBeenCalled();
+		}
+	);
+} );
diff --git a/plugins/woocommerce/client/blocks/assets/js/index.js b/plugins/woocommerce/client/blocks/assets/js/index.js
index eef34acb45a..d481cda11f1 100644
--- a/plugins/woocommerce/client/blocks/assets/js/index.js
+++ b/plugins/woocommerce/client/blocks/assets/js/index.js
@@ -5,4 +5,5 @@ import '../css/editor.scss';
 import '../css/style.scss';
 import './filters/block-list-block';
 import './filters/get-block-attributes';
+import './filters/unregister-block-types';
 import './base/components/notice-banner/style.scss';
diff --git a/plugins/woocommerce/src/Blocks/BlockTypesController.php b/plugins/woocommerce/src/Blocks/BlockTypesController.php
index b9db30d3e9d..db68a52932b 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypesController.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypesController.php
@@ -62,7 +62,6 @@ final class BlockTypesController {
 		add_filter( 'render_block', array( $this, 'add_data_attributes' ), 10, 2 );
 		add_action( 'woocommerce_login_form_end', array( $this, 'redirect_to_field' ) );
 		add_filter( 'widget_types_to_hide_from_legacy_widget_block', array( $this, 'hide_legacy_widgets_with_block_equivalent' ) );
-		add_filter( 'allowed_block_types_all', array( $this, 'filter_allowed_block_types' ), 10, 2 );
 		add_filter( 'register_block_type_args', array( $this, 'enqueue_block_style_for_classic_themes' ), 10, 2 );
 		add_filter( 'block_core_breadcrumbs_post_type_settings', array( $this, 'set_product_breadcrumbs_preferred_taxonomy' ), 10, 3 );
 		add_filter( 'block_core_breadcrumbs_items', array( $this, 'apply_woocommerce_breadcrumb_filters' ), 10, 1 );
@@ -359,80 +358,6 @@ final class BlockTypesController {
 		return $widget_types;
 	}

-	/**
-	 * Filter WooCommerce block availability by editor context.
-	 *
-	 * Blocks remain registered on the server for compatibility, but some WooCommerce
-	 * blocks are hidden from specific editor inserters.
-	 *
-	 * @param bool|string[]            $allowed_block_types Array of block type slugs, or boolean to enable/disable all.
-	 * @param \WP_Block_Editor_Context $block_editor_context The current block editor context.
-	 * @return bool|string[] Filtered list of allowed block types, or boolean to enable/disable all.
-	 */
-	public function filter_allowed_block_types( $allowed_block_types, $block_editor_context ) {
-		if ( false === $allowed_block_types ) {
-			return false;
-		}
-
-		$editor_name = $block_editor_context->name;
-
-		if ( 'core/edit-site' === $editor_name ) {
-			return $allowed_block_types;
-		}
-
-		if ( 'core/edit-post' === $editor_name ) {
-			return $this->remove_allowed_block_types(
-				$allowed_block_types,
-				$this->get_post_editor_hidden_block_types()
-			);
-		}
-
-		if ( in_array( $editor_name, array( 'core/edit-widgets', 'core/customize-widgets' ), true ) ) {
-			$registered_block_types             = $this->get_registered_block_types();
-			$registered_woocommerce_block_types = array_filter(
-				$registered_block_types,
-				static function ( $block_type ) {
-					return 0 === strpos( $block_type, 'woocommerce/' );
-				}
-			);
-
-			return $this->remove_allowed_block_types(
-				$allowed_block_types,
-				array_diff( $registered_woocommerce_block_types, $this->get_widget_area_block_types() )
-			);
-		}
-
-		return $allowed_block_types;
-	}
-
-	/**
-	 * Remove block types from the current allowed block list.
-	 *
-	 * @param bool|string[] $allowed_block_types Array of block type slugs, or true to allow all registered block types.
-	 * @param string[]      $block_types_to_remove Block type slugs to remove.
-	 * @return string[] Filtered block type slugs.
-	 */
-	private function remove_allowed_block_types( $allowed_block_types, array $block_types_to_remove ) {
-		$allowed_block_types = true === $allowed_block_types ? $this->get_registered_block_types() : (array) $allowed_block_types;
-		$allowed_block_types = array_filter( $allowed_block_types, 'is_string' );
-
-		return array_values(
-			array_diff(
-				$allowed_block_types,
-				$block_types_to_remove
-			)
-		);
-	}
-
-	/**
-	 * Get all registered block type slugs.
-	 *
-	 * @return string[] Registered block type slugs.
-	 */
-	private function get_registered_block_types() {
-		return array_keys( \WP_Block_Type_Registry::get_instance()->get_all_registered() );
-	}
-
 	/**
 	 * Delete product transients when a product is deleted.
 	 *
@@ -443,93 +368,6 @@ final class BlockTypesController {
 		wc_deprecated_function( __METHOD__, '10.6.0' );
 	}

-	/**
-	 * Get list of WooCommerce block types allowed in Widget Areas. New blocks won't be
-	 * exposed in the Widget Area unless specifically added here.
-	 *
-	 * @return string[] Array of block type slugs.
-	 */
-	protected function get_widget_area_block_types() {
-		return array(
-			'woocommerce/all-reviews',
-			'woocommerce/breadcrumbs',
-			'woocommerce/cart-link',
-			'woocommerce/catalog-sorting',
-			'woocommerce/classic-shortcode',
-			'woocommerce/customer-account',
-			'woocommerce/dropdown',
-			'woocommerce/featured-category',
-			'woocommerce/featured-product',
-			'woocommerce/mini-cart',
-			'woocommerce/product-categories',
-			'woocommerce/product-results-count',
-			'woocommerce/product-search',
-			'woocommerce/reviews-by-category',
-			'woocommerce/reviews-by-product',
-			'woocommerce/product-filters',
-			'woocommerce/product-filter-status',
-			'woocommerce/product-filter-price',
-			'woocommerce/product-filter-price-slider',
-			'woocommerce/product-filter-attribute',
-			'woocommerce/product-filter-rating',
-			'woocommerce/product-filter-active',
-			'woocommerce/product-filter-removable-chips',
-			'woocommerce/product-filter-clear-button',
-			'woocommerce/product-filter-checkbox-list',
-			'woocommerce/product-filter-chips',
-			'woocommerce/product-filter-taxonomy',
-
-			// Keep hidden legacy filter blocks for backward compatibility.
-			'woocommerce/active-filters',
-			'woocommerce/attribute-filter',
-			'woocommerce/filter-wrapper',
-			'woocommerce/price-filter',
-			'woocommerce/rating-filter',
-			'woocommerce/stock-filter',
-			// End: legacy filter blocks.
-
-			// Below product grids are hidden from inserter however they could have been used in widgets.
-			// Keep them for backward compatibility.
-			'woocommerce/handpicked-products',
-			'woocommerce/product-best-sellers',
-			'woocommerce/product-new',
-			'woocommerce/product-on-sale',
-			'woocommerce/product-top-rated',
-			'woocommerce/products-by-attribute',
-			'woocommerce/product-category',
-			'woocommerce/product-tag',
-			// End: legacy product grids blocks.
-		);
-	}
-
-	/**
-	 * Get list of WooCommerce block types hidden from post editors.
-	 *
-	 * @return string[] Array of block type slugs.
-	 */
-	protected function get_post_editor_hidden_block_types() {
-		return array(
-			'woocommerce/breadcrumbs',
-			'woocommerce/catalog-sorting',
-			'woocommerce/legacy-template',
-			'woocommerce/product-results-count',
-			'woocommerce/product-reviews',
-			'woocommerce/order-confirmation-status',
-			'woocommerce/order-confirmation-summary',
-			'woocommerce/order-confirmation-totals',
-			'woocommerce/order-confirmation-totals-wrapper',
-			'woocommerce/order-confirmation-downloads',
-			'woocommerce/order-confirmation-downloads-wrapper',
-			'woocommerce/order-confirmation-billing-address',
-			'woocommerce/order-confirmation-shipping-address',
-			'woocommerce/order-confirmation-billing-wrapper',
-			'woocommerce/order-confirmation-shipping-wrapper',
-			'woocommerce/order-confirmation-additional-information',
-			'woocommerce/order-confirmation-additional-fields-wrapper',
-			'woocommerce/order-confirmation-additional-fields',
-		);
-	}
-
 	/**
 	 * Get list of block types.
 	 *
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypesController.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypesController.php
index 515fb607586..b75082a26fd 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypesController.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypesController.php
@@ -20,13 +20,6 @@ class BlockTypesController extends \WP_UnitTestCase {
 	 */
 	private $block_types_controller;

-	/**
-	 * Block types registered during a test.
-	 *
-	 * @var string[]
-	 */
-	private $registered_test_block_types = array();
-
 	/**
 	 * Sets up a new TestedBlockTypesController so it can be tested.
 	 *
@@ -41,23 +34,6 @@ class BlockTypesController extends \WP_UnitTestCase {
 		);
 	}

-	/**
-	 * Tear down test fixtures.
-	 */
-	public function tearDown(): void {
-		foreach ( $this->registered_test_block_types as $block_type ) {
-			if ( \WP_Block_Type_Registry::get_instance()->is_registered( $block_type ) ) {
-				unregister_block_type( $block_type );
-			}
-		}
-
-		$this->registered_test_block_types = array();
-
-		remove_filter( 'allowed_block_types_all', array( $this->block_types_controller, 'filter_allowed_block_types' ), 10 );
-
-		parent::tearDown();
-	}
-
 	/**
 	 * Register 3 blocks, one will be allowed by full name, one by namespace,and one because it has a parent with a
 	 * woocommerce namespace.
@@ -118,210 +94,4 @@ class BlockTypesController extends \WP_UnitTestCase {
 		$answer = $this->block_types_controller->block_should_have_data_attributes( 'child-of-woo/block-name' );
 		$this->assertTrue( $answer );
 	}
-
-	/**
-	 * @testdox Should hide post-editor WooCommerce blocks from unrestricted post editors.
-	 */
-	public function test_edit_post_context_hides_post_editor_block_types_from_unrestricted_list(): void {
-		foreach (
-			array(
-				'core/test-paragraph',
-				'third-party/test-block',
-				'woocommerce/product-search',
-				'woocommerce/breadcrumbs',
-				'woocommerce/product-reviews',
-				'woocommerce/order-confirmation-status',
-			) as $block_type
-		) {
-			$this->register_test_block_type( $block_type );
-		}
-
-		$result = $this->block_types_controller->filter_allowed_block_types(
-			true,
-			$this->get_block_editor_context( 'core/edit-post' )
-		);
-
-		$this->assertContains( 'core/test-paragraph', $result, 'Non-WooCommerce blocks should remain available.' );
-		$this->assertContains( 'third-party/test-block', $result, 'Third-party blocks should remain available.' );
-		$this->assertContains( 'woocommerce/product-search', $result, 'WooCommerce blocks outside the denylist should remain available.' );
-		$this->assertNotContains( 'woocommerce/breadcrumbs', $result, 'Store Breadcrumbs should be hidden in post editors.' );
-		$this->assertNotContains( 'woocommerce/product-reviews', $result, 'Product Reviews should be hidden in post editors.' );
-		$this->assertNotContains( 'woocommerce/order-confirmation-status', $result, 'Order Confirmation blocks should be hidden in post editors.' );
-	}
-
-	/**
-	 * @testdox Should keep only widget-area WooCommerce blocks in widget editors.
-	 *
-	 * @dataProvider widget_editor_context_provider
-	 *
-	 * @param string $editor_context_name Editor context name.
-	 */
-	public function test_widget_context_hides_woocommerce_blocks_not_allowed_in_widget_areas( string $editor_context_name ): void {
-		foreach (
-			array(
-				'core/test-paragraph',
-				'third-party/test-block',
-				'woocommerce/product-search',
-				'woocommerce/product-filters',
-				'woocommerce/checkout',
-				'woocommerce/order-confirmation-status',
-			) as $block_type
-		) {
-			$this->register_test_block_type( $block_type );
-		}
-
-		$result = $this->block_types_controller->filter_allowed_block_types(
-			true,
-			$this->get_block_editor_context( $editor_context_name )
-		);
-
-		$this->assertContains( 'core/test-paragraph', $result, 'Non-WooCommerce blocks should remain available.' );
-		$this->assertContains( 'third-party/test-block', $result, 'Third-party blocks should remain available.' );
-		$this->assertContains( 'woocommerce/product-search', $result, 'Widget-area WooCommerce blocks should remain available.' );
-		$this->assertContains( 'woocommerce/product-filters', $result, 'Widget-area WooCommerce blocks should remain available.' );
-		$this->assertNotContains( 'woocommerce/checkout', $result, 'WooCommerce blocks outside the widget allowlist should be hidden.' );
-		$this->assertNotContains( 'woocommerce/order-confirmation-status', $result, 'WooCommerce blocks outside the widget allowlist should be hidden.' );
-	}
-
-	/**
-	 * @testdox Should leave Site Editor block availability unchanged.
-	 */
-	public function test_site_editor_context_leaves_allowed_block_types_unchanged(): void {
-		$allowed_block_types = array(
-			'core/test-paragraph',
-			'woocommerce/breadcrumbs',
-			'woocommerce/checkout',
-		);
-
-		$result = $this->block_types_controller->filter_allowed_block_types(
-			$allowed_block_types,
-			$this->get_block_editor_context( 'core/edit-site' )
-		);
-
-		$this->assertSame( $allowed_block_types, $result, 'Site Editor block availability should not be changed.' );
-	}
-
-	/**
-	 * @testdox Should preserve an existing post editor allowlist while removing denied WooCommerce blocks.
-	 */
-	public function test_edit_post_context_preserves_existing_allowlist(): void {
-		$allowed_block_types = array(
-			'core/test-paragraph',
-			'woocommerce/product-search',
-			'woocommerce/catalog-sorting',
-			'third-party/test-block',
-		);
-
-		$result = $this->block_types_controller->filter_allowed_block_types(
-			$allowed_block_types,
-			$this->get_block_editor_context( 'core/edit-post' )
-		);
-
-		$this->assertSame(
-			array(
-				'core/test-paragraph',
-				'woocommerce/product-search',
-				'third-party/test-block',
-			),
-			$result,
-			'Existing allowlists should keep their original restrictions.'
-		);
-	}
-
-	/**
-	 * @testdox Should preserve an existing widget editor allowlist while removing disallowed WooCommerce blocks.
-	 */
-	public function test_widget_context_preserves_existing_allowlist(): void {
-		$allowed_block_types = array(
-			'core/test-paragraph',
-			'woocommerce/product-search',
-			'woocommerce/checkout',
-			'third-party/test-block',
-		);
-
-		$result = $this->block_types_controller->filter_allowed_block_types(
-			$allowed_block_types,
-			$this->get_block_editor_context( 'core/edit-widgets' )
-		);
-
-		$this->assertSame(
-			array(
-				'core/test-paragraph',
-				'woocommerce/product-search',
-				'third-party/test-block',
-			),
-			$result,
-			'Existing allowlists should keep their original restrictions.'
-		);
-	}
-
-	/**
-	 * @testdox Should preserve false block availability for restricted editors.
-	 *
-	 * @dataProvider restricted_editor_context_provider
-	 *
-	 * @param string $editor_context_name Editor context name.
-	 */
-	public function test_restricted_context_preserves_false_allowed_block_types( string $editor_context_name ): void {
-		$result = $this->block_types_controller->filter_allowed_block_types(
-			false,
-			$this->get_block_editor_context( $editor_context_name )
-		);
-
-		$this->assertFalse( $result, 'Existing disabled block availability should be preserved.' );
-	}
-
-	/**
-	 * Data provider for widget editor contexts.
-	 *
-	 * @return array<string, array<string>>
-	 */
-	public function widget_editor_context_provider(): array {
-		return array(
-			'widgets editor'    => array( 'core/edit-widgets' ),
-			'customizer editor' => array( 'core/customize-widgets' ),
-		);
-	}
-
-	/**
-	 * Data provider for restricted editor contexts.
-	 *
-	 * @return array<string, array<string>>
-	 */
-	public function restricted_editor_context_provider(): array {
-		return array(
-			'post editor'       => array( 'core/edit-post' ),
-			'widgets editor'    => array( 'core/edit-widgets' ),
-			'customizer editor' => array( 'core/customize-widgets' ),
-		);
-	}
-
-	/**
-	 * Register a block type and track it for cleanup.
-	 *
-	 * @param string $block_type Block type slug.
-	 */
-	private function register_test_block_type( string $block_type ): void {
-		if ( \WP_Block_Type_Registry::get_instance()->is_registered( $block_type ) ) {
-			return;
-		}
-
-		register_block_type( $block_type );
-
-		$this->registered_test_block_types[] = $block_type;
-	}
-
-	/**
-	 * Get a block editor context for tests.
-	 *
-	 * @param string $editor_context_name Editor context name.
-	 * @return \WP_Block_Editor_Context Block editor context.
-	 */
-	private function get_block_editor_context( string $editor_context_name ): \WP_Block_Editor_Context {
-		return new \WP_Block_Editor_Context(
-			array(
-				'name' => $editor_context_name,
-			)
-		);
-	}
 }