@@ -374,6 +374,77 @@ public function test_each_combinations() {
374374 }
375375 }
376376
377+ /**
378+ * Tests delivered decline notices retain the host tag after sanitization.
379+ *
380+ * @dataProvider data_delivered_decline_notices
381+ * @expectedIncorrectUsage WP_Interactivity_API::data_wp_html_processor
382+ * @param string $host Host markup.
383+ * @param string $tag Host tag name.
384+ * @param string $reason Decline reason.
385+ * @param string $reference Directive reference, if present.
386+ */
387+ public function test_delivered_decline_notices ( string $ host , string $ tag , string $ reason , string $ reference ) {
388+ $ this ->assertTrue ( WP_DEBUG );
389+ wp_interactivity_state (
390+ 'test ' ,
391+ array (
392+ 'html ' => 'evaluated-value-7f3a ' ,
393+ 'list ' => array ( 'a ' ),
394+ )
395+ );
396+ $ delivered_notices = array ();
397+ remove_filter ( 'doing_it_wrong_trigger_error ' , '__return_false ' );
398+ set_error_handler (
399+ /**
400+ * Records the message delivered by PHP's notice handler.
401+ *
402+ * @param int $severity Error severity.
403+ * @param string $message Delivered message.
404+ * @return bool Whether the notice was handled.
405+ */
406+ static function ( $ severity , $ message ) use ( &$ delivered_notices ) {
407+ $ delivered_notices [] = array ( $ severity , $ message );
408+ return true ;
409+ },
410+ E_USER_NOTICE
411+ );
412+ try {
413+ wp_interactivity_process_directives ( $ this ->region ( $ host ) );
414+ } finally {
415+ restore_error_handler ();
416+ add_filter ( 'doing_it_wrong_trigger_error ' , '__return_false ' );
417+ }
418+ $ this ->assert_decline_notice ( $ reason , $ tag , $ reference );
419+ $ this ->assertCount ( 1 , $ delivered_notices );
420+ $ this ->assertSame ( E_USER_NOTICE , $ delivered_notices [0 ][0 ] );
421+ $ message = $ delivered_notices [0 ][1 ];
422+ $ this ->assertStringContainsString ( $ tag . ' tag ' , $ message );
423+ $ this ->assertStringContainsString ( $ reason , $ message );
424+ $ this ->assertStringContainsString ( 'WP_Interactivity_API::data_wp_html_processor ' , $ message );
425+ $ this ->assertStringContainsString ( 'version 7.2.0 ' , $ message );
426+ if ( '' !== $ reference ) {
427+ $ this ->assertStringContainsString ( $ reference , $ message );
428+ }
429+ $ this ->assertStringNotContainsString ( 'evaluated-value-7f3a ' , $ message );
430+ }
431+
432+ /**
433+ * Supplies all decline reasons, including allowed and disallowed HTML tags.
434+ *
435+ * @return array[] Host markup, tag, reason, and reference.
436+ */
437+ public static function data_delivered_decline_notices () {
438+ return array (
439+ 'not a token ' => array ( '<div data-wp-html="state.html">Fallback</div> ' , 'DIV ' , 'not a token ' , 'state.html ' ),
440+ 'void image ' => array ( '<img data-wp-html="state.html"> ' , 'IMG ' , 'cannot hold content ' , 'state.html ' ),
441+ 'void break ' => array ( '<br data-wp-html="state.html"> ' , 'BR ' , 'cannot hold content ' , 'state.html ' ),
442+ 'text combination ' => array ( '<div data-wp-html="state.html" data-wp-text="state.text">Fallback</div> ' , 'DIV ' , 'cannot be combined ' , 'state.html ' ),
443+ 'each combination ' => array ( '<template data-wp-html="state.html" data-wp-each="state.list"><span>x</span></template> ' , 'TEMPLATE ' , 'cannot be combined ' , 'state.html ' ),
444+ 'empty combination ' => array ( '<template data-wp-html="" data-wp-each="state.list"><span>x</span></template> ' , 'TEMPLATE ' , 'cannot be combined ' , '' ),
445+ );
446+ }
447+
377448 /**
378449 * Tests the three public notice messages distinguish decline reasons.
379450 *
0 commit comments