@@ -30,12 +30,24 @@ class Tests_Media_wpCrossOriginIsolation extends WP_UnitTestCase {
3030 */
3131 private ?string $ original_get_action ;
3232
33+ /**
34+ * Original $_GET['p'] value.
35+ */
36+ private ?string $ original_get_p ;
37+
38+ /**
39+ * Original $pagenow value.
40+ */
41+ private ?string $ original_pagenow ;
42+
3343 public function set_up () {
3444 parent ::set_up ();
3545 $ this ->original_user_agent = $ _SERVER ['HTTP_USER_AGENT ' ] ?? null ;
3646 $ this ->original_http_host = $ _SERVER ['HTTP_HOST ' ] ?? null ;
3747 $ this ->original_https = $ _SERVER ['HTTPS ' ] ?? null ;
3848 $ this ->original_get_action = $ _GET ['action ' ] ?? null ;
49+ $ this ->original_get_p = $ _GET ['p ' ] ?? null ;
50+ $ this ->original_pagenow = $ GLOBALS ['pagenow ' ] ?? null ;
3951 }
4052
4153 public function tear_down () {
@@ -63,11 +75,25 @@ public function tear_down() {
6375 $ _GET ['action ' ] = $ this ->original_get_action ;
6476 }
6577
78+ if ( null === $ this ->original_get_p ) {
79+ unset( $ _GET ['p ' ] );
80+ } else {
81+ $ _GET ['p ' ] = $ this ->original_get_p ;
82+ }
83+
6684 // Clean up any output buffers started during tests.
6785 while ( ob_get_level () > 1 ) {
6886 ob_end_clean ();
6987 }
7088
89+ if ( null === $ this ->original_pagenow ) {
90+ unset( $ GLOBALS ['pagenow ' ] );
91+ } else {
92+ $ GLOBALS ['pagenow ' ] = $ this ->original_pagenow ;
93+ }
94+
95+ $ GLOBALS ['current_screen ' ] = null ;
96+
7197 remove_all_filters ( 'wp_client_side_media_processing_enabled ' );
7298 parent ::tear_down ();
7399 }
@@ -159,6 +185,110 @@ public function test_does_not_start_output_buffer_for_safari() {
159185 $ this ->assertSame ( $ level_before , $ level_after , 'Output buffer should not be started for Safari. ' );
160186 }
161187
188+ /**
189+ * The site editor home route on a classic theme skips DIP, because the
190+ * editor renders the front end in a same-origin iframe and must reach its
191+ * `contentDocument` to neutralize interactive elements. DIP would block
192+ * that access.
193+ *
194+ * @ticket 65399
195+ *
196+ * @dataProvider data_classic_theme_site_editor_home_routes
197+ *
198+ * @param array $get The $_GET state representing the home route.
199+ */
200+ public function test_skips_cross_origin_isolation_for_classic_theme_site_editor_home ( array $ get ) {
201+ $ _SERVER ['HTTP_USER_AGENT ' ] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 ' ;
202+ $ _SERVER ['HTTP_HOST ' ] = 'localhost ' ;
203+
204+ wp_set_current_user ( self ::factory ()->user ->create ( array ( 'role ' => 'administrator ' ) ) );
205+ switch_theme ( 'twentytwentyone ' );
206+ set_current_screen ( 'site-editor ' );
207+ $ GLOBALS ['pagenow ' ] = 'site-editor.php ' ;
208+
209+ unset( $ _GET ['p ' ] );
210+ foreach ( $ get as $ key => $ value ) {
211+ $ _GET [ $ key ] = $ value ;
212+ }
213+
214+ $ level_before = ob_get_level ();
215+ wp_set_up_cross_origin_isolation ();
216+ $ level_after = ob_get_level ();
217+
218+ $ this ->assertSame ( $ level_before , $ level_after , 'DIP should be skipped on the classic-theme site editor home route. ' );
219+ }
220+
221+ /**
222+ * Data provider for the classic-theme site editor home route.
223+ *
224+ * @return array[]
225+ */
226+ public function data_classic_theme_site_editor_home_routes () {
227+ return array (
228+ 'no p query var ' => array ( array () ),
229+ 'p query var is / ' => array ( array ( 'p ' => '/ ' ) ),
230+ );
231+ }
232+
233+ /**
234+ * The site editor on a classic theme still sets up cross-origin isolation
235+ * for routes other than the home route.
236+ *
237+ * @ticket 65399
238+ *
239+ * @runInSeparateProcess
240+ * @preserveGlobalState disabled
241+ */
242+ public function test_sets_up_cross_origin_isolation_for_classic_theme_site_editor_non_home_route () {
243+ $ _SERVER ['HTTP_USER_AGENT ' ] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 ' ;
244+ $ _SERVER ['HTTP_HOST ' ] = 'localhost ' ;
245+
246+ wp_set_current_user ( self ::factory ()->user ->create ( array ( 'role ' => 'administrator ' ) ) );
247+ switch_theme ( 'twentytwentyone ' );
248+ set_current_screen ( 'site-editor ' );
249+ $ GLOBALS ['pagenow ' ] = 'site-editor.php ' ;
250+
251+ $ _GET ['p ' ] = '/page/about ' ;
252+
253+ $ level_before = ob_get_level ();
254+ wp_set_up_cross_origin_isolation ();
255+ $ level_after = ob_get_level ();
256+
257+ $ this ->assertSame ( $ level_before + 1 , $ level_after , 'DIP should be set up on a non-home site editor route. ' );
258+
259+ ob_end_clean ();
260+ }
261+
262+ /**
263+ * The site editor on a block theme always sets up cross-origin isolation,
264+ * including on the home route, because block themes do not render the
265+ * classic site preview iframe.
266+ *
267+ * @ticket 65399
268+ *
269+ * @runInSeparateProcess
270+ * @preserveGlobalState disabled
271+ */
272+ public function test_sets_up_cross_origin_isolation_for_block_theme_site_editor_home () {
273+ $ _SERVER ['HTTP_USER_AGENT ' ] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 ' ;
274+ $ _SERVER ['HTTP_HOST ' ] = 'localhost ' ;
275+
276+ wp_set_current_user ( self ::factory ()->user ->create ( array ( 'role ' => 'administrator ' ) ) );
277+ switch_theme ( 'twentytwentyfour ' );
278+ set_current_screen ( 'site-editor ' );
279+ $ GLOBALS ['pagenow ' ] = 'site-editor.php ' ;
280+
281+ unset( $ _GET ['p ' ] );
282+
283+ $ level_before = ob_get_level ();
284+ wp_set_up_cross_origin_isolation ();
285+ $ level_after = ob_get_level ();
286+
287+ $ this ->assertSame ( $ level_before + 1 , $ level_after , 'DIP should be set up on the block-theme site editor home route. ' );
288+
289+ ob_end_clean ();
290+ }
291+
162292 /**
163293 * @ticket 64803
164294 */
0 commit comments