Changeset 57662
- Timestamp:
- 02/20/2024 09:53:11 AM (12 months ago)
- Location:
- trunk/tests/phpunit
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tests/phpunit/data/themedir1/block-theme-child/theme.json
r57336 r57662 1 1 { 2 2 "$schema": "https://schemas.wp.org/trunk/theme.json", 3 "version": 1,3 "version": 2, 4 4 "settings": { 5 5 "color": { -
trunk/tests/phpunit/data/themedir1/block-theme/theme.json
r57336 r57662 1 1 { 2 2 "$schema": "https://schemas.wp.org/trunk/theme.json", 3 "version": 1,3 "version": 2, 4 4 "title": "Block theme", 5 5 "settings": { … … 43 43 ], 44 44 "customFontSize": false, 45 " customLineHeight": true45 "lineHeight": true 46 46 }, 47 47 "spacing": { 48 "units": [ "rem"],49 " customPadding": true,48 "units": [ "rem" ], 49 "padding": true, 50 50 "blockGap": true 51 51 }, … … 64 64 } 65 65 }, 66 "styles" 67 "blocks" :{66 "styles": { 67 "blocks": { 68 68 "core/post-featured-image": { 69 69 "shadow": "10px 10px 5px 0px rgba(0,0,0,0.66)", … … 123 123 "name": "custom-single-post-template", 124 124 "title": "Custom Single Post template", 125 "postTypes": [ "post"]125 "postTypes": [ "post" ] 126 126 } 127 127 ], -
trunk/tests/phpunit/tests/rest-api/rest-global-styles-controller.php
r55457 r57662 32 32 protected static $post_id; 33 33 34 private function find_and_normalize_global_styles_by_id( $global_styles, $id ) {35 foreach ( $global_styles as $style ) {36 if ( $style['id'] === $id ) {37 unset( $style['_links'] );38 return $style;39 }40 }41 42 return null;43 }44 45 34 public function set_up() { 46 35 parent::set_up(); … … 131 120 } 132 121 133 /**134 * @doesNotPerformAssertions135 */136 public function test_get_items() {137 // Controller does not implement get_items().138 }139 140 /**141 * @covers WP_REST_Global_Styles_Controller::get_theme_item142 * @ticket 54516143 */144 public function test_get_theme_item_no_user() {145 wp_set_current_user( 0 );146 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' );147 $response = rest_get_server()->dispatch( $request );148 $this->assertErrorResponse( 'rest_cannot_manage_global_styles', $response, 401 );149 }150 151 /**152 * @covers WP_REST_Global_Styles_Controller::get_theme_item153 * @ticket 54516154 */155 public function test_get_theme_item_permission_check() {156 wp_set_current_user( self::$subscriber_id );157 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' );158 $response = rest_get_server()->dispatch( $request );159 $this->assertErrorResponse( 'rest_cannot_manage_global_styles', $response, 403 );160 }161 162 /**163 * @covers WP_REST_Global_Styles_Controller::get_theme_item164 * @ticket 54516165 */166 public function test_get_theme_item_invalid() {167 wp_set_current_user( self::$admin_id );168 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/invalid' );169 $response = rest_get_server()->dispatch( $request );170 $this->assertErrorResponse( 'rest_theme_not_found', $response, 404 );171 }172 173 /**174 * @dataProvider data_get_theme_item_invalid_theme_dirname175 * @covers WP_REST_Global_Styles_Controller::get_theme_item176 * @ticket 54596177 *178 * @param string $theme_dirname Theme directory to test.179 * @param string $expected Expected error code.180 */181 public function test_get_theme_item_invalid_theme_dirname( $theme_dirname, $expected ) {182 wp_set_current_user( self::$admin_id );183 switch_theme( $theme_dirname );184 185 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/' . $theme_dirname );186 $response = rest_get_server()->dispatch( $request );187 $this->assertErrorResponse( $expected, $response, 404 );188 }189 190 /**191 * Data provider.192 *193 * @return array194 */195 public function data_get_theme_item_invalid_theme_dirname() {196 return array(197 '+' => array(198 'theme_dirname' => 'my+theme+',199 'expected' => 'rest_theme_not_found',200 ),201 ':' => array(202 'theme_dirname' => 'my:theme:',203 'expected' => 'rest_no_route',204 ),205 '<>' => array(206 'theme_dirname' => 'my<theme>',207 'expected' => 'rest_no_route',208 ),209 '*' => array(210 'theme_dirname' => 'my*theme*',211 'expected' => 'rest_no_route',212 ),213 '?' => array(214 'theme_dirname' => 'my?theme?',215 'expected' => 'rest_no_route',216 ),217 '"' => array(218 'theme_dirname' => 'my"theme?"',219 'expected' => 'rest_no_route',220 ),221 '| (invalid on Windows)' => array(222 'theme_dirname' => 'my|theme|',223 'expected' => 'rest_no_route',224 ),225 // Themes deep in subdirectories.226 '2 subdirectories deep' => array(227 'theme_dirname' => 'subdir/subsubdir/mytheme',228 'expected' => 'rest_global_styles_not_found',229 ),230 );231 }232 233 /**234 * @dataProvider data_get_theme_item235 * @covers WP_REST_Global_Styles_Controller::get_theme_item236 * @ticket 54596237 *238 * @param string $theme Theme directory to test.239 */240 public function test_get_theme_item( $theme ) {241 wp_set_current_user( self::$admin_id );242 switch_theme( $theme );243 244 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/' . $theme );245 $response = rest_get_server()->dispatch( $request );246 $data = $response->get_data();247 $links = $response->get_links();248 $this->assertArrayHasKey( 'settings', $data, 'Data does not have "settings" key' );249 $this->assertArrayHasKey( 'styles', $data, 'Data does not have "styles" key' );250 $this->assertArrayHasKey( 'self', $links, 'Links do not have a "self" key' );251 $this->assertStringContainsString( '/wp/v2/global-styles/themes/' . $theme, $links['self'][0]['href'] );252 }253 254 /**255 * Data provider.256 *257 * @return array258 */259 public function data_get_theme_item() {260 return array(261 'alphabetic' => array( 'mytheme' ),262 'alphanumeric' => array( 'mythemev1' ),263 'àáâãäåæç' => array( 'àáâãäåæç' ),264 'space' => array( 'my theme' ),265 '-_.' => array( 'my_theme-0.1' ),266 '[]' => array( 'my[theme]' ),267 '()' => array( 'my(theme)' ),268 '{}' => array( 'my{theme}' ),269 '&=#@!$,^~%' => array( 'theme &=#@!$,^~%' ),270 'all combined' => array( 'thémé {}&=@!$,^~%[0.1](-_-)' ),271 272 // Themes in a subdirectory.273 'subdir: alphabetic' => array( 'subdir/mytheme' ),274 'subdir: alphanumeric in theme' => array( 'subdir/mythemev1' ),275 'subdir: alphanumeric in subdir' => array( 'subdirv1/mytheme' ),276 'subdir: alphanumeric in both' => array( 'subdirv1/mythemev1' ),277 'subdir: àáâãäåæç in theme' => array( 'subdir/àáâãäåæç' ),278 'subdir: àáâãäåæç in subdir' => array( 'àáâãäåæç/mythemev1' ),279 'subdir: àáâãäåæç in both' => array( 'àáâãäåæç/àáâãäåæç' ),280 'subdir: space in theme' => array( 'subdir/my theme' ),281 'subdir: space in subdir' => array( 'sub dir/mytheme' ),282 'subdir: space in both' => array( 'sub dir/my theme' ),283 'subdir: -_. in theme' => array( 'subdir/my_theme-0.1' ),284 'subdir: -_. in subdir' => array( 'sub_dir-0.1/mytheme' ),285 'subdir: -_. in both' => array( 'sub_dir-0.1/my_theme-0.1' ),286 'subdir: all combined in theme' => array( 'subdir/thémé {}&=@!$,^~%[0.1](-_-)' ),287 'subdir: all combined in subdir' => array( 'sűbdīr {}&=@!$,^~%[0.1](-_-)/mytheme' ),288 'subdir: all combined in both' => array( 'sűbdīr {}&=@!$,^~%[0.1](-_-)/thémé {}&=@!$,^~%[0.1](-_-)' ),289 );290 }291 292 /**293 * @covers WP_REST_Global_Styles_Controller::get_theme_item294 * @ticket 54595295 */296 public function test_get_theme_item_fields() {297 wp_set_current_user( self::$admin_id );298 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' );299 $request->set_param( '_fields', 'settings' );300 $response = rest_get_server()->dispatch( $request );301 $data = $response->get_data();302 $this->assertArrayHasKey( 'settings', $data );303 $this->assertArrayNotHasKey( 'styles', $data );304 }305 306 /**307 * @covers WP_REST_Global_Styles_Controller::get_item308 * @ticket 54516309 */310 public function test_get_item_no_user() {311 wp_set_current_user( 0 );312 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id );313 $response = rest_get_server()->dispatch( $request );314 $this->assertErrorResponse( 'rest_cannot_view', $response, 401 );315 }316 317 /**318 * @covers WP_REST_Global_Styles_Controller::get_item319 * @ticket 54516320 */321 public function test_get_item_invalid_post() {322 wp_set_current_user( self::$admin_id );323 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$post_id );324 $response = rest_get_server()->dispatch( $request );325 $this->assertErrorResponse( 'rest_global_styles_not_found', $response, 404 );326 }327 328 /**329 * @covers WP_REST_Global_Styles_Controller::get_item330 * @ticket 54516331 */332 public function test_get_item_permission_check() {333 wp_set_current_user( self::$subscriber_id );334 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id );335 $response = rest_get_server()->dispatch( $request );336 $this->assertErrorResponse( 'rest_cannot_view', $response, 403 );337 }338 339 /**340 * @covers WP_REST_Global_Styles_Controller::get_item341 * @ticket 54516342 */343 public function test_get_item_no_user_edit() {344 wp_set_current_user( 0 );345 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id );346 $request->set_param( 'context', 'edit' );347 $response = rest_get_server()->dispatch( $request );348 $this->assertErrorResponse( 'rest_forbidden_context', $response, 401 );349 }350 351 /**352 * @covers WP_REST_Global_Styles_Controller::get_item353 * @ticket 54516354 */355 public function test_get_item_permission_check_edit() {356 wp_set_current_user( self::$subscriber_id );357 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id );358 $request->set_param( 'context', 'edit' );359 $response = rest_get_server()->dispatch( $request );360 $this->assertErrorResponse( 'rest_forbidden_context', $response, 403 );361 }362 363 /**364 * @covers WP_REST_Global_Styles_Controller::get_item365 */366 public function test_get_item() {367 wp_set_current_user( self::$admin_id );368 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id );369 $response = rest_get_server()->dispatch( $request );370 $data = $response->get_data();371 $links = $response->get_links();372 373 $this->assertEqualSets(374 array(375 'id' => self::$global_styles_id,376 'title' => array(377 'raw' => 'Custom Styles',378 'rendered' => 'Custom Styles',379 ),380 'settings' => new stdClass(),381 'styles' => new stdClass(),382 ),383 $data384 );385 386 $this->assertArrayHasKey( 'self', $links );387 $this->assertStringContainsString( '/wp/v2/global-styles/' . self::$global_styles_id, $links['self'][0]['href'] );388 }389 390 /**391 * @doesNotPerformAssertions392 */393 public function test_create_item() {394 // Controller does not implement create_item().395 }396 397 /**398 * @covers WP_REST_Global_Styles_Controller::update_item399 * @ticket 54516400 */401 public function test_update_item() {402 wp_set_current_user( self::$admin_id );403 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id );404 $request->set_body_params(405 array(406 'title' => 'My new global styles title',407 )408 );409 $response = rest_get_server()->dispatch( $request );410 $data = $response->get_data();411 $this->assertSame( 'My new global styles title', $data['title']['raw'] );412 }413 414 415 /**416 * @covers WP_REST_Global_Styles_Controller::update_item417 * @ticket 54516418 */419 public function test_update_item_no_user() {420 wp_set_current_user( 0 );421 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id );422 $response = rest_get_server()->dispatch( $request );423 $this->assertErrorResponse( 'rest_cannot_edit', $response, 401 );424 }425 426 /**427 * @covers WP_REST_Global_Styles_Controller::update_item428 * @ticket 54516429 */430 public function test_update_item_invalid_post() {431 wp_set_current_user( self::$admin_id );432 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$post_id );433 $response = rest_get_server()->dispatch( $request );434 $this->assertErrorResponse( 'rest_global_styles_not_found', $response, 404 );435 }436 437 /**438 * @covers WP_REST_Global_Styles_Controller::update_item439 * @ticket 54516440 */441 public function test_update_item_permission_check() {442 wp_set_current_user( self::$subscriber_id );443 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id );444 $response = rest_get_server()->dispatch( $request );445 $this->assertErrorResponse( 'rest_cannot_edit', $response, 403 );446 }447 448 /**449 * @doesNotPerformAssertions450 */451 public function test_delete_item() {452 // Controller does not implement delete_item().453 }454 455 /**456 * @doesNotPerformAssertions457 */458 public function test_prepare_item() {459 // Controller does not implement prepare_item().460 }461 462 /**463 * @covers WP_REST_Global_Styles_Controller::get_item_schema464 * @ticket 54516465 */466 public function test_get_item_schema() {467 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/global-styles/' . self::$global_styles_id );468 $response = rest_get_server()->dispatch( $request );469 $data = $response->get_data();470 $properties = $data['schema']['properties'];471 $this->assertCount( 4, $properties, 'Schema properties array does not have exactly 4 elements' );472 $this->assertArrayHasKey( 'id', $properties, 'Schema properties array does not have "id" key' );473 $this->assertArrayHasKey( 'styles', $properties, 'Schema properties array does not have "styles" key' );474 $this->assertArrayHasKey( 'settings', $properties, 'Schema properties array does not have "settings" key' );475 $this->assertArrayHasKey( 'title', $properties, 'Schema properties array does not have "title" key' );476 }477 478 479 122 public function test_get_theme_items() { 480 123 wp_set_current_user( self::$admin_id ); … … 484 127 $data = $response->get_data(); 485 128 $expected = array( 129 array( 130 'version' => 2, 131 'title' => 'variation-a', 132 'settings' => array( 133 'blocks' => array( 134 'core/paragraph' => array( 135 'color' => array( 136 'palette' => array( 137 'theme' => array( 138 array( 139 'slug' => 'light', 140 'name' => 'Light', 141 'color' => '#f2f2f2', 142 ), 143 ), 144 ), 145 ), 146 ), 147 ), 148 ), 149 ), 486 150 array( 487 151 'version' => 2, … … 536 200 wp_recursive_ksort( $expected ); 537 201 538 $this->assertSameSets( $data, $expected ); 202 $this->assertSameSets( $expected, $data ); 203 } 204 205 /** 206 * @doesNotPerformAssertions 207 */ 208 public function test_get_items() { 209 // Controller does not implement get_items(). 210 } 211 212 /** 213 * @covers WP_REST_Global_Styles_Controller::get_theme_item 214 * @ticket 54516 215 */ 216 public function test_get_theme_item_no_user() { 217 wp_set_current_user( 0 ); 218 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' ); 219 $response = rest_get_server()->dispatch( $request ); 220 $this->assertErrorResponse( 'rest_cannot_manage_global_styles', $response, 401 ); 221 } 222 223 /** 224 * @covers WP_REST_Global_Styles_Controller::get_theme_item 225 * @ticket 54516 226 */ 227 public function test_get_theme_item_permission_check() { 228 wp_set_current_user( self::$subscriber_id ); 229 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' ); 230 $response = rest_get_server()->dispatch( $request ); 231 $this->assertErrorResponse( 'rest_cannot_manage_global_styles', $response, 403 ); 232 } 233 234 /** 235 * @covers WP_REST_Global_Styles_Controller::get_theme_item 236 * @ticket 54516 237 */ 238 public function test_get_theme_item_invalid() { 239 wp_set_current_user( self::$admin_id ); 240 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/invalid' ); 241 $response = rest_get_server()->dispatch( $request ); 242 $this->assertErrorResponse( 'rest_theme_not_found', $response, 404 ); 243 } 244 245 /** 246 * @dataProvider data_get_theme_item_invalid_theme_dirname 247 * @covers WP_REST_Global_Styles_Controller::get_theme_item 248 * @ticket 54596 249 * 250 * @param string $theme_dirname Theme directory to test. 251 * @param string $expected Expected error code. 252 */ 253 public function test_get_theme_item_invalid_theme_dirname( $theme_dirname, $expected ) { 254 wp_set_current_user( self::$admin_id ); 255 switch_theme( $theme_dirname ); 256 257 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/' . $theme_dirname ); 258 $response = rest_get_server()->dispatch( $request ); 259 $this->assertErrorResponse( $expected, $response, 404 ); 260 } 261 262 /** 263 * Data provider. 264 * 265 * @return array 266 */ 267 public function data_get_theme_item_invalid_theme_dirname() { 268 return array( 269 '+' => array( 270 'theme_dirname' => 'my+theme+', 271 'expected' => 'rest_theme_not_found', 272 ), 273 ':' => array( 274 'theme_dirname' => 'my:theme:', 275 'expected' => 'rest_no_route', 276 ), 277 '<>' => array( 278 'theme_dirname' => 'my<theme>', 279 'expected' => 'rest_no_route', 280 ), 281 '*' => array( 282 'theme_dirname' => 'my*theme*', 283 'expected' => 'rest_no_route', 284 ), 285 '?' => array( 286 'theme_dirname' => 'my?theme?', 287 'expected' => 'rest_no_route', 288 ), 289 '"' => array( 290 'theme_dirname' => 'my"theme?"', 291 'expected' => 'rest_no_route', 292 ), 293 '| (invalid on Windows)' => array( 294 'theme_dirname' => 'my|theme|', 295 'expected' => 'rest_no_route', 296 ), 297 // Themes deep in subdirectories. 298 '2 subdirectories deep' => array( 299 'theme_dirname' => 'subdir/subsubdir/mytheme', 300 'expected' => 'rest_global_styles_not_found', 301 ), 302 ); 303 } 304 305 /** 306 * @dataProvider data_get_theme_item 307 * @covers WP_REST_Global_Styles_Controller::get_theme_item 308 * @ticket 54596 309 * 310 * @param string $theme Theme directory to test. 311 */ 312 public function test_get_theme_item( $theme ) { 313 wp_set_current_user( self::$admin_id ); 314 switch_theme( $theme ); 315 316 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/' . $theme ); 317 $response = rest_get_server()->dispatch( $request ); 318 $data = $response->get_data(); 319 $links = $response->get_links(); 320 $this->assertArrayHasKey( 'settings', $data, 'Data does not have "settings" key' ); 321 $this->assertArrayHasKey( 'styles', $data, 'Data does not have "styles" key' ); 322 $this->assertArrayHasKey( 'self', $links, 'Links do not have a "self" key' ); 323 $this->assertStringContainsString( '/wp/v2/global-styles/themes/' . $theme, $links['self'][0]['href'] ); 324 } 325 326 /** 327 * Data provider. 328 * 329 * @return array 330 */ 331 public function data_get_theme_item() { 332 return array( 333 'alphabetic' => array( 'mytheme' ), 334 'alphanumeric' => array( 'mythemev1' ), 335 'àáâãäåæç' => array( 'àáâãäåæç' ), 336 'space' => array( 'my theme' ), 337 '-_.' => array( 'my_theme-0.1' ), 338 '[]' => array( 'my[theme]' ), 339 '()' => array( 'my(theme)' ), 340 '{}' => array( 'my{theme}' ), 341 '&=#@!$,^~%' => array( 'theme &=#@!$,^~%' ), 342 'all combined' => array( 'thémé {}&=@!$,^~%[0.1](-_-)' ), 343 344 // Themes in a subdirectory. 345 'subdir: alphabetic' => array( 'subdir/mytheme' ), 346 'subdir: alphanumeric in theme' => array( 'subdir/mythemev1' ), 347 'subdir: alphanumeric in subdir' => array( 'subdirv1/mytheme' ), 348 'subdir: alphanumeric in both' => array( 'subdirv1/mythemev1' ), 349 'subdir: àáâãäåæç in theme' => array( 'subdir/àáâãäåæç' ), 350 'subdir: àáâãäåæç in subdir' => array( 'àáâãäåæç/mythemev1' ), 351 'subdir: àáâãäåæç in both' => array( 'àáâãäåæç/àáâãäåæç' ), 352 'subdir: space in theme' => array( 'subdir/my theme' ), 353 'subdir: space in subdir' => array( 'sub dir/mytheme' ), 354 'subdir: space in both' => array( 'sub dir/my theme' ), 355 'subdir: -_. in theme' => array( 'subdir/my_theme-0.1' ), 356 'subdir: -_. in subdir' => array( 'sub_dir-0.1/mytheme' ), 357 'subdir: -_. in both' => array( 'sub_dir-0.1/my_theme-0.1' ), 358 'subdir: all combined in theme' => array( 'subdir/thémé {}&=@!$,^~%[0.1](-_-)' ), 359 'subdir: all combined in subdir' => array( 'sűbdīr {}&=@!$,^~%[0.1](-_-)/mytheme' ), 360 'subdir: all combined in both' => array( 'sűbdīr {}&=@!$,^~%[0.1](-_-)/thémé {}&=@!$,^~%[0.1](-_-)' ), 361 ); 362 } 363 364 /** 365 * @covers WP_REST_Global_Styles_Controller::get_theme_item 366 * @ticket 54595 367 */ 368 public function test_get_theme_item_fields() { 369 wp_set_current_user( self::$admin_id ); 370 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/tt1-blocks' ); 371 $request->set_param( '_fields', 'settings' ); 372 $response = rest_get_server()->dispatch( $request ); 373 $data = $response->get_data(); 374 $this->assertArrayHasKey( 'settings', $data ); 375 $this->assertArrayNotHasKey( 'styles', $data ); 376 } 377 378 /** 379 * @covers WP_REST_Global_Styles_Controller::get_item 380 * @ticket 54516 381 */ 382 public function test_get_item_no_user() { 383 wp_set_current_user( 0 ); 384 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id ); 385 $response = rest_get_server()->dispatch( $request ); 386 $this->assertErrorResponse( 'rest_cannot_view', $response, 401 ); 387 } 388 389 /** 390 * @covers WP_REST_Global_Styles_Controller::get_item 391 * @ticket 54516 392 */ 393 public function test_get_item_invalid_post() { 394 wp_set_current_user( self::$admin_id ); 395 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$post_id ); 396 $response = rest_get_server()->dispatch( $request ); 397 $this->assertErrorResponse( 'rest_global_styles_not_found', $response, 404 ); 398 } 399 400 /** 401 * @covers WP_REST_Global_Styles_Controller::get_item 402 * @ticket 54516 403 */ 404 public function test_get_item_permission_check() { 405 wp_set_current_user( self::$subscriber_id ); 406 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id ); 407 $response = rest_get_server()->dispatch( $request ); 408 $this->assertErrorResponse( 'rest_cannot_view', $response, 403 ); 409 } 410 411 /** 412 * @covers WP_REST_Global_Styles_Controller::get_item 413 * @ticket 54516 414 */ 415 public function test_get_item_no_user_edit() { 416 wp_set_current_user( 0 ); 417 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id ); 418 $request->set_param( 'context', 'edit' ); 419 $response = rest_get_server()->dispatch( $request ); 420 $this->assertErrorResponse( 'rest_forbidden_context', $response, 401 ); 421 } 422 423 /** 424 * @covers WP_REST_Global_Styles_Controller::get_item 425 * @ticket 54516 426 */ 427 public function test_get_item_permission_check_edit() { 428 wp_set_current_user( self::$subscriber_id ); 429 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id ); 430 $request->set_param( 'context', 'edit' ); 431 $response = rest_get_server()->dispatch( $request ); 432 $this->assertErrorResponse( 'rest_forbidden_context', $response, 403 ); 433 } 434 435 /** 436 * @covers WP_REST_Global_Styles_Controller::get_item 437 */ 438 public function test_get_item() { 439 wp_set_current_user( self::$admin_id ); 440 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id ); 441 $response = rest_get_server()->dispatch( $request ); 442 $data = $response->get_data(); 443 $links = $response->get_links(); 444 445 $this->assertEqualSets( 446 array( 447 'id' => self::$global_styles_id, 448 'title' => array( 449 'raw' => 'Custom Styles', 450 'rendered' => 'Custom Styles', 451 ), 452 'settings' => new stdClass(), 453 'styles' => new stdClass(), 454 ), 455 $data 456 ); 457 458 $this->assertArrayHasKey( 'self', $links ); 459 $this->assertStringContainsString( '/wp/v2/global-styles/' . self::$global_styles_id, $links['self'][0]['href'] ); 460 } 461 462 /** 463 * @doesNotPerformAssertions 464 */ 465 public function test_create_item() { 466 // Controller does not implement create_item(). 467 } 468 469 /** 470 * @covers WP_REST_Global_Styles_Controller::update_item 471 * @ticket 54516 472 */ 473 public function test_update_item() { 474 wp_set_current_user( self::$admin_id ); 475 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id ); 476 $request->set_body_params( 477 array( 478 'title' => 'My new global styles title', 479 ) 480 ); 481 $response = rest_get_server()->dispatch( $request ); 482 $data = $response->get_data(); 483 $this->assertSame( 'My new global styles title', $data['title']['raw'] ); 484 } 485 486 /** 487 * @covers WP_REST_Global_Styles_Controller::update_item 488 * @ticket 54516 489 */ 490 public function test_update_item_no_user() { 491 wp_set_current_user( 0 ); 492 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id ); 493 $response = rest_get_server()->dispatch( $request ); 494 $this->assertErrorResponse( 'rest_cannot_edit', $response, 401 ); 495 } 496 497 /** 498 * @covers WP_REST_Global_Styles_Controller::update_item 499 * @ticket 54516 500 */ 501 public function test_update_item_invalid_post() { 502 wp_set_current_user( self::$admin_id ); 503 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$post_id ); 504 $response = rest_get_server()->dispatch( $request ); 505 $this->assertErrorResponse( 'rest_global_styles_not_found', $response, 404 ); 506 } 507 508 /** 509 * @covers WP_REST_Global_Styles_Controller::update_item 510 * @ticket 54516 511 */ 512 public function test_update_item_permission_check() { 513 wp_set_current_user( self::$subscriber_id ); 514 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id ); 515 $response = rest_get_server()->dispatch( $request ); 516 $this->assertErrorResponse( 'rest_cannot_edit', $response, 403 ); 517 } 518 519 /** 520 * @covers WP_REST_Global_Styles_Controller::update_item 521 * @ticket 57536 522 */ 523 public function test_update_item_valid_styles_css() { 524 wp_set_current_user( self::$admin_id ); 525 if ( is_multisite() ) { 526 grant_super_admin( self::$admin_id ); 527 } 528 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id ); 529 $request->set_body_params( 530 array( 531 'styles' => array( 'css' => 'body { color: red; }' ), 532 ) 533 ); 534 $response = rest_get_server()->dispatch( $request ); 535 $data = $response->get_data(); 536 $this->assertSame( 'body { color: red; }', $data['styles']['css'] ); 537 } 538 539 /** 540 * @covers WP_REST_Global_Styles_Controller::update_item 541 * @ticket 57536 542 */ 543 public function test_update_item_invalid_styles_css() { 544 wp_set_current_user( self::$admin_id ); 545 if ( is_multisite() ) { 546 grant_super_admin( self::$admin_id ); 547 } 548 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id ); 549 $request->set_body_params( 550 array( 551 'styles' => array( 'css' => '<p>test</p> body { color: red; }' ), 552 ) 553 ); 554 $response = rest_get_server()->dispatch( $request ); 555 $this->assertErrorResponse( 'rest_custom_css_illegal_markup', $response, 400 ); 556 } 557 558 /** 559 * @doesNotPerformAssertions 560 */ 561 public function test_delete_item() { 562 // Controller does not implement delete_item(). 563 } 564 565 /** 566 * @doesNotPerformAssertions 567 */ 568 public function test_prepare_item() { 569 // Controller does not implement prepare_item(). 570 } 571 572 /** 573 * @covers WP_REST_Global_Styles_Controller::get_item_schema 574 * @ticket 54516 575 */ 576 public function test_get_item_schema() { 577 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/global-styles/' . self::$global_styles_id ); 578 $response = rest_get_server()->dispatch( $request ); 579 $data = $response->get_data(); 580 $properties = $data['schema']['properties']; 581 $this->assertCount( 4, $properties, 'Schema properties array does not have exactly 4 elements' ); 582 $this->assertArrayHasKey( 'id', $properties, 'Schema properties array does not have "id" key' ); 583 $this->assertArrayHasKey( 'styles', $properties, 'Schema properties array does not have "styles" key' ); 584 $this->assertArrayHasKey( 'settings', $properties, 'Schema properties array does not have "settings" key' ); 585 $this->assertArrayHasKey( 'title', $properties, 'Schema properties array does not have "title" key' ); 539 586 } 540 587 … … 557 604 } 558 605 } 559 560 /**561 * @covers WP_REST_Global_Styles_Controller::update_item562 * @ticket 57536563 */564 public function test_update_item_valid_styles_css() {565 wp_set_current_user( self::$admin_id );566 if ( is_multisite() ) {567 grant_super_admin( self::$admin_id );568 }569 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id );570 $request->set_body_params(571 array(572 'styles' => array( 'css' => 'body { color: red; }' ),573 )574 );575 $response = rest_get_server()->dispatch( $request );576 $data = $response->get_data();577 $this->assertSame( 'body { color: red; }', $data['styles']['css'] );578 }579 580 /**581 * @covers WP_REST_Global_Styles_Controller::update_item582 * @ticket 57536583 */584 public function test_update_item_invalid_styles_css() {585 wp_set_current_user( self::$admin_id );586 if ( is_multisite() ) {587 grant_super_admin( self::$admin_id );588 }589 $request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' . self::$global_styles_id );590 $request->set_body_params(591 array(592 'styles' => array( 'css' => '<p>test</p> body { color: red; }' ),593 )594 );595 $response = rest_get_server()->dispatch( $request );596 $this->assertErrorResponse( 'rest_custom_css_illegal_markup', $response, 400 );597 }598 606 } -
trunk/tests/phpunit/tests/theme/wpThemeJson.php
r57547 r57662 388 388 389 389 /** 390 * @ticket 54336391 * @ticket 58550392 */393 public function test_get_stylesheet_support_for_shorthand_and_longhand_values() {394 $theme_json = new WP_Theme_JSON(395 array(396 'version' => WP_Theme_JSON::LATEST_SCHEMA,397 'styles' => array(398 'blocks' => array(399 'core/group' => array(400 'border' => array(401 'radius' => '10px',402 ),403 'spacing' => array(404 'padding' => '24px',405 'margin' => '1em',406 ),407 ),408 'core/image' => array(409 'border' => array(410 'radius' => array(411 'topLeft' => '10px',412 'bottomRight' => '1em',413 ),414 ),415 'spacing' => array(416 'padding' => array(417 'top' => '15px',418 ),419 'margin' => array(420 'bottom' => '30px',421 ),422 ),423 ),424 ),425 ),426 )427 );428 429 $styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-group{border-radius: 10px;margin: 1em;padding: 24px;}.wp-block-image{margin-bottom: 30px;padding-top: 15px;}.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder{border-top-left-radius: 10px;border-bottom-right-radius: 1em;}';430 $this->assertSame( $styles, $theme_json->get_stylesheet() );431 $this->assertSame( $styles, $theme_json->get_stylesheet( array( 'styles' ) ) );432 }433 434 /**435 * @ticket 54336436 * @ticket 58550437 */438 public function test_get_stylesheet_skips_disabled_protected_properties() {439 $theme_json = new WP_Theme_JSON(440 array(441 'version' => WP_Theme_JSON::LATEST_SCHEMA,442 'settings' => array(443 'spacing' => array(444 'blockGap' => null,445 ),446 ),447 'styles' => array(448 'spacing' => array(449 'blockGap' => '1em',450 ),451 'blocks' => array(452 'core/columns' => array(453 'spacing' => array(454 'blockGap' => '24px',455 ),456 ),457 ),458 ),459 )460 );461 462 $expected = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}';463 $this->assertSame( $expected, $theme_json->get_stylesheet() );464 $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) );465 }466 467 /**468 * @ticket 54336469 * @ticket 58548470 * @ticket 58550471 */472 public function test_get_stylesheet_renders_enabled_protected_properties() {473 $theme_json = new WP_Theme_JSON(474 array(475 'version' => WP_Theme_JSON::LATEST_SCHEMA,476 'settings' => array(477 'spacing' => array(478 'blockGap' => true,479 ),480 ),481 'styles' => array(482 'spacing' => array(483 'blockGap' => '1em',484 ),485 ),486 )487 );488 489 $expected = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: 1em; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }body { --wp--style--block-gap: 1em; }:where(body .is-layout-flow) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-flow) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-flow) > *{margin-block-start: 1em;margin-block-end: 0;}:where(body .is-layout-constrained) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-constrained) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-constrained) > *{margin-block-start: 1em;margin-block-end: 0;}:where(body .is-layout-flex) {gap: 1em;}:where(body .is-layout-grid) {gap: 1em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}';490 $this->assertSame( $expected, $theme_json->get_stylesheet() );491 $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) );492 }493 494 /**495 390 * @ticket 53175 496 391 * @ticket 54336 … … 584 479 ), 585 480 'core/group' => array( 586 'color' => array(481 'color' => array( 587 482 'gradient' => 'var:preset|gradient|custom-gradient', 588 483 ), 589 'border' => array(484 'border' => array( 590 485 'radius' => '10px', 591 486 ), 592 'elements' => array( 487 'dimensions' => array( 488 'minHeight' => '50vh', 489 ), 490 'elements' => array( 593 491 'link' => array( 594 492 'color' => array( … … 597 495 ), 598 496 ), 599 'spacing' => array(497 'spacing' => array( 600 498 'padding' => '24px', 601 499 ), … … 661 559 662 560 $variables = 'body{--wp--preset--color--grey: grey;--wp--preset--gradient--custom-gradient: linear-gradient(135deg,rgba(0,0,0) 0%,rgb(0,0,0) 100%);--wp--preset--font-size--small: 14px;--wp--preset--font-size--big: 41px;--wp--preset--font-family--arial: Arial, serif;}.wp-block-group{--wp--custom--base-font: 16;--wp--custom--line-height--small: 1.2;--wp--custom--line-height--medium: 1.4;--wp--custom--line-height--large: 1.8;}'; 663 $styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}body{color: var(--wp--preset--color--grey);}a:where(:not(.wp-element-button)){background-color: #333;color: #111;}.wp-element-button, .wp-block-button__link{box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.66);}.wp-block-cover{min-height: unset;aspect-ratio: 16/9;}.wp-block-group{background: var(--wp--preset--gradient--custom-gradient);border-radius: 10px; padding: 24px;}.wp-block-group a:where(:not(.wp-element-button)){color: #111;}.wp-block-heading{color: #123456;}.wp-block-heading a:where(:not(.wp-element-button)){background-color: #333;color: #111;font-size: 60px;}.wp-block-post-date{color: #123456;}.wp-block-post-date a:where(:not(.wp-element-button)){background-color: #777;color: #555;}.wp-block-post-excerpt{column-count: 2;}.wp-block-image{margin-bottom: 30px;}.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder{border-top-left-radius: 10px;border-bottom-right-radius: 1em;}.wp-block-image img, .wp-block-image .components-placeholder{filter: var(--wp--preset--duotone--custom-duotone);}';561 $styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}body{color: var(--wp--preset--color--grey);}a:where(:not(.wp-element-button)){background-color: #333;color: #111;}.wp-element-button, .wp-block-button__link{box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.66);}.wp-block-cover{min-height: unset;aspect-ratio: 16/9;}.wp-block-group{background: var(--wp--preset--gradient--custom-gradient);border-radius: 10px;min-height: 50vh;padding: 24px;}.wp-block-group a:where(:not(.wp-element-button)){color: #111;}.wp-block-heading{color: #123456;}.wp-block-heading a:where(:not(.wp-element-button)){background-color: #333;color: #111;font-size: 60px;}.wp-block-post-date{color: #123456;}.wp-block-post-date a:where(:not(.wp-element-button)){background-color: #777;color: #555;}.wp-block-post-excerpt{column-count: 2;}.wp-block-image{margin-bottom: 30px;}.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder{border-top-left-radius: 10px;border-bottom-right-radius: 1em;}.wp-block-image img, .wp-block-image .components-placeholder{filter: var(--wp--preset--duotone--custom-duotone);}'; 664 562 $presets = '.has-grey-color{color: var(--wp--preset--color--grey) !important;}.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}.has-custom-gradient-gradient-background{background: var(--wp--preset--gradient--custom-gradient) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-big-font-size{font-size: var(--wp--preset--font-size--big) !important;}.has-arial-font-family{font-family: var(--wp--preset--font-family--arial) !important;}'; 665 563 $all = $variables . $styles . $presets; 666 $this->assertSame( $all, $theme_json->get_stylesheet() ); 564 565 $this->assertSame( $variables, $theme_json->get_stylesheet( array( 'variables' ) ) ); 667 566 $this->assertSame( $styles, $theme_json->get_stylesheet( array( 'styles' ) ) ); 668 567 $this->assertSame( $presets, $theme_json->get_stylesheet( array( 'presets' ) ) ); 669 $this->assertSame( $variables, $theme_json->get_stylesheet( array( 'variables' ) ) ); 568 $this->assertSame( $all, $theme_json->get_stylesheet() ); 569 } 570 571 /** 572 * @ticket 54336 573 * @ticket 58550 574 */ 575 public function test_get_stylesheet_support_for_shorthand_and_longhand_values() { 576 $theme_json = new WP_Theme_JSON( 577 array( 578 'version' => WP_Theme_JSON::LATEST_SCHEMA, 579 'styles' => array( 580 'blocks' => array( 581 'core/group' => array( 582 'border' => array( 583 'radius' => '10px', 584 ), 585 'spacing' => array( 586 'padding' => '24px', 587 'margin' => '1em', 588 ), 589 ), 590 'core/image' => array( 591 'border' => array( 592 'radius' => array( 593 'topLeft' => '10px', 594 'bottomRight' => '1em', 595 ), 596 ), 597 'spacing' => array( 598 'padding' => array( 599 'top' => '15px', 600 ), 601 'margin' => array( 602 'bottom' => '30px', 603 ), 604 ), 605 ), 606 ), 607 ), 608 ) 609 ); 610 611 $styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-group{border-radius: 10px;margin: 1em;padding: 24px;}.wp-block-image{margin-bottom: 30px;padding-top: 15px;}.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder{border-top-left-radius: 10px;border-bottom-right-radius: 1em;}'; 612 $this->assertSame( $styles, $theme_json->get_stylesheet() ); 613 $this->assertSame( $styles, $theme_json->get_stylesheet( array( 'styles' ) ) ); 614 } 615 616 /** 617 * @ticket 54336 618 * @ticket 58550 619 */ 620 public function test_get_stylesheet_skips_disabled_protected_properties() { 621 $theme_json = new WP_Theme_JSON( 622 array( 623 'version' => WP_Theme_JSON::LATEST_SCHEMA, 624 'settings' => array( 625 'spacing' => array( 626 'blockGap' => null, 627 ), 628 ), 629 'styles' => array( 630 'spacing' => array( 631 'blockGap' => '1em', 632 ), 633 'blocks' => array( 634 'core/columns' => array( 635 'spacing' => array( 636 'blockGap' => '24px', 637 ), 638 ), 639 ), 640 ), 641 ) 642 ); 643 644 $expected = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}'; 645 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 646 $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) ); 647 } 648 649 /** 650 * @ticket 54336 651 * @ticket 58548 652 * @ticket 58550 653 */ 654 public function test_get_stylesheet_renders_enabled_protected_properties() { 655 $theme_json = new WP_Theme_JSON( 656 array( 657 'version' => WP_Theme_JSON::LATEST_SCHEMA, 658 'settings' => array( 659 'spacing' => array( 660 'blockGap' => true, 661 ), 662 ), 663 'styles' => array( 664 'spacing' => array( 665 'blockGap' => '1em', 666 ), 667 ), 668 ) 669 ); 670 671 $expected = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: 1em; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }body { --wp--style--block-gap: 1em; }:where(body .is-layout-flow) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-flow) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-flow) > *{margin-block-start: 1em;margin-block-end: 0;}:where(body .is-layout-constrained) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-constrained) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-constrained) > *{margin-block-start: 1em;margin-block-end: 0;}:where(body .is-layout-flex) {gap: 1em;}:where(body .is-layout-grid) {gap: 1em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}'; 672 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 673 $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) ); 670 674 } 671 675 … … 739 743 $presets = '.wp-block-group.has-grey-color{color: var(--wp--preset--color--grey) !important;}.wp-block-group.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.wp-block-group.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}'; 740 744 $variables = '.wp-block-group{--wp--preset--color--grey: grey;}'; 741 $all = $variables . $styles . $presets; 745 746 $all = $variables . $styles . $presets; 747 742 748 $this->assertSame( $all, $theme_json->get_stylesheet() ); 743 749 $this->assertSame( $styles, $theme_json->get_stylesheet( array( 'styles' ) ) ); … … 1114 1120 1115 1121 /** 1122 * @ticket 56467 1123 * @ticket 58548 1124 * @ticket 58550 1125 */ 1126 public function test_get_stylesheet_generates_layout_styles() { 1127 $theme_json = new WP_Theme_JSON( 1128 array( 1129 'version' => WP_Theme_JSON::LATEST_SCHEMA, 1130 'settings' => array( 1131 'spacing' => array( 1132 'blockGap' => true, 1133 ), 1134 ), 1135 'styles' => array( 1136 'spacing' => array( 1137 'blockGap' => '1em', 1138 ), 1139 ), 1140 ), 1141 'default' 1142 ); 1143 1144 // Results also include root site blocks styles. 1145 $this->assertSame( 1146 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: 1em; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }body { --wp--style--block-gap: 1em; }:where(body .is-layout-flow) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-flow) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-flow) > *{margin-block-start: 1em;margin-block-end: 0;}:where(body .is-layout-constrained) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-constrained) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-constrained) > *{margin-block-start: 1em;margin-block-end: 0;}:where(body .is-layout-flex) {gap: 1em;}:where(body .is-layout-grid) {gap: 1em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}', 1147 $theme_json->get_stylesheet( array( 'styles' ) ) 1148 ); 1149 } 1150 1151 /** 1152 * @ticket 56467 1153 * @ticket 58548 1154 * @ticket 58550 1155 */ 1156 public function test_get_stylesheet_generates_layout_styles_with_spacing_presets() { 1157 $theme_json = new WP_Theme_JSON( 1158 array( 1159 'version' => WP_Theme_JSON::LATEST_SCHEMA, 1160 'settings' => array( 1161 'spacing' => array( 1162 'blockGap' => true, 1163 ), 1164 ), 1165 'styles' => array( 1166 'spacing' => array( 1167 'blockGap' => 'var:preset|spacing|60', 1168 ), 1169 ), 1170 ), 1171 'default' 1172 ); 1173 1174 // Results also include root site blocks styles. 1175 $this->assertSame( 1176 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: var(--wp--preset--spacing--60); margin-block-end: 0; }:where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }body { --wp--style--block-gap: var(--wp--preset--spacing--60); }:where(body .is-layout-flow) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-flow) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-flow) > *{margin-block-start: var(--wp--preset--spacing--60);margin-block-end: 0;}:where(body .is-layout-constrained) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-constrained) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-constrained) > *{margin-block-start: var(--wp--preset--spacing--60);margin-block-end: 0;}:where(body .is-layout-flex) {gap: var(--wp--preset--spacing--60);}:where(body .is-layout-grid) {gap: var(--wp--preset--spacing--60);}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}', 1177 $theme_json->get_stylesheet( array( 'styles' ) ) 1178 ); 1179 } 1180 1181 /** 1182 * @ticket 56467 1183 * @ticket 58550 1184 */ 1185 public function test_get_stylesheet_generates_fallback_gap_layout_styles() { 1186 $theme_json = new WP_Theme_JSON( 1187 array( 1188 'version' => WP_Theme_JSON::LATEST_SCHEMA, 1189 'settings' => array( 1190 'spacing' => array( 1191 'blockGap' => null, 1192 ), 1193 ), 1194 'styles' => array( 1195 'spacing' => array( 1196 'blockGap' => '1em', 1197 ), 1198 ), 1199 ), 1200 'default' 1201 ); 1202 $stylesheet = $theme_json->get_stylesheet( array( 'styles' ) ); 1203 1204 // Results also include root site blocks styles. 1205 $this->assertSame( 1206 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}', 1207 $stylesheet 1208 ); 1209 } 1210 1211 /** 1212 * @ticket 56467 1213 * @ticket 58550 1214 */ 1215 public function test_get_stylesheet_generates_base_fallback_gap_layout_styles() { 1216 $theme_json = new WP_Theme_JSON( 1217 array( 1218 'version' => WP_Theme_JSON::LATEST_SCHEMA, 1219 'settings' => array( 1220 'spacing' => array( 1221 'blockGap' => null, 1222 ), 1223 ), 1224 ), 1225 'default' 1226 ); 1227 $stylesheet = $theme_json->get_stylesheet( array( 'base-layout-styles' ) ); 1228 1229 // Note the `base-layout-styles` includes a fallback gap for the Columns block for backwards compatibility. 1230 $this->assertSame( 1231 ':where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}', 1232 $stylesheet 1233 ); 1234 } 1235 1236 /** 1237 * @ticket 56467 1238 * @ticket 58550 1239 */ 1240 public function test_get_stylesheet_skips_layout_styles() { 1241 add_theme_support( 'disable-layout-styles' ); 1242 $theme_json = new WP_Theme_JSON( 1243 array( 1244 'version' => WP_Theme_JSON::LATEST_SCHEMA, 1245 'settings' => array( 1246 'spacing' => array( 1247 'blockGap' => null, 1248 ), 1249 ), 1250 ), 1251 'default' 1252 ); 1253 $stylesheet = $theme_json->get_stylesheet( array( 'base-layout-styles' ) ); 1254 remove_theme_support( 'disable-layout-styles' ); 1255 1256 // All Layout styles should be skipped. 1257 $this->assertSame( 1258 '', 1259 $stylesheet 1260 ); 1261 } 1262 1263 /** 1264 * @ticket 56467 1265 * @ticket 58550 1266 */ 1267 public function test_get_stylesheet_generates_valid_block_gap_values_and_skips_null_or_false_values() { 1268 $theme_json = new WP_Theme_JSON( 1269 array( 1270 'version' => WP_Theme_JSON::LATEST_SCHEMA, 1271 'settings' => array( 1272 'spacing' => array( 1273 'blockGap' => true, 1274 ), 1275 ), 1276 'styles' => array( 1277 'spacing' => array( 1278 'blockGap' => '1rem', 1279 ), 1280 'blocks' => array( 1281 'core/post-content' => array( 1282 'color' => array( 1283 'text' => 'gray', // This value should not render block layout styles. 1284 ), 1285 ), 1286 'core/social-links' => array( 1287 'spacing' => array( 1288 'blockGap' => '0', // This value should render block layout gap as zero. 1289 ), 1290 ), 1291 'core/buttons' => array( 1292 'spacing' => array( 1293 'blockGap' => 0, // This value should render block layout gap as zero. 1294 ), 1295 ), 1296 'core/columns' => array( 1297 'spacing' => array( 1298 'blockGap' => false, // This value should be ignored. The block will use the global layout value. 1299 ), 1300 ), 1301 ), 1302 ), 1303 ), 1304 'default' 1305 ); 1306 1307 $this->assertSame( 1308 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: 1rem; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }body { --wp--style--block-gap: 1rem; }:where(body .is-layout-flow) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-flow) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-flow) > *{margin-block-start: 1rem;margin-block-end: 0;}:where(body .is-layout-constrained) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-constrained) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-constrained) > *{margin-block-start: 1rem;margin-block-end: 0;}:where(body .is-layout-flex) {gap: 1rem;}:where(body .is-layout-grid) {gap: 1rem;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-post-content{color: gray;}.wp-block-social-links-is-layout-flow > :first-child:first-child{margin-block-start: 0;}.wp-block-social-links-is-layout-flow > :last-child:last-child{margin-block-end: 0;}.wp-block-social-links-is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-social-links-is-layout-constrained > :first-child:first-child{margin-block-start: 0;}.wp-block-social-links-is-layout-constrained > :last-child:last-child{margin-block-end: 0;}.wp-block-social-links-is-layout-constrained > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-social-links-is-layout-flex{gap: 0;}.wp-block-social-links-is-layout-grid{gap: 0;}.wp-block-buttons-is-layout-flow > :first-child:first-child{margin-block-start: 0;}.wp-block-buttons-is-layout-flow > :last-child:last-child{margin-block-end: 0;}.wp-block-buttons-is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-buttons-is-layout-constrained > :first-child:first-child{margin-block-start: 0;}.wp-block-buttons-is-layout-constrained > :last-child:last-child{margin-block-end: 0;}.wp-block-buttons-is-layout-constrained > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-buttons-is-layout-flex{gap: 0;}.wp-block-buttons-is-layout-grid{gap: 0;}', 1309 $theme_json->get_stylesheet() 1310 ); 1311 } 1312 1313 /** 1314 * @ticket 57354 1315 * @ticket 58550 1316 */ 1317 public function test_get_stylesheet_returns_outline_styles() { 1318 $theme_json = new WP_Theme_JSON( 1319 array( 1320 'version' => WP_Theme_JSON::LATEST_SCHEMA, 1321 'styles' => array( 1322 'elements' => array( 1323 'button' => array( 1324 'outline' => array( 1325 'offset' => '3px', 1326 'width' => '3px', 1327 'style' => 'dashed', 1328 'color' => 'red', 1329 ), 1330 ':hover' => array( 1331 'outline' => array( 1332 'offset' => '3px', 1333 'width' => '3px', 1334 'style' => 'solid', 1335 'color' => 'blue', 1336 ), 1337 ), 1338 ), 1339 ), 1340 ), 1341 ) 1342 ); 1343 1344 $base_styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}'; 1345 1346 $element_styles = '.wp-element-button, .wp-block-button__link{outline-color: red;outline-offset: 3px;outline-style: dashed;outline-width: 3px;}.wp-element-button:hover, .wp-block-button__link:hover{outline-color: blue;outline-offset: 3px;outline-style: solid;outline-width: 3px;}'; 1347 1348 $expected = $base_styles . $element_styles; 1349 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 1350 } 1351 1352 /** 1353 * Tests that a custom root selector is correctly applied when generating a stylesheet. 1354 * 1355 * @ticket 60343 1356 */ 1357 public function test_get_stylesheet_custom_root_selector() { 1358 $theme_json = new WP_Theme_JSON( 1359 array( 1360 'version' => WP_Theme_JSON::LATEST_SCHEMA, 1361 'styles' => array( 1362 'color' => array( 1363 'text' => 'teal', 1364 ), 1365 ), 1366 ), 1367 'default' 1368 ); 1369 1370 $options = array( 'root_selector' => '.custom' ); 1371 $actual = $theme_json->get_stylesheet( array( 'styles' ), null, $options ); 1372 1373 // Results also include root site blocks styles which hard code 1374 // `body { margin: 0; }`. 1375 $this->assertSame( 1376 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.custom{color: teal;}', 1377 $actual 1378 ); 1379 } 1380 1381 public function test_allow_indirect_properties() { 1382 $actual = WP_Theme_JSON::remove_insecure_properties( 1383 array( 1384 'version' => WP_Theme_JSON::LATEST_SCHEMA, 1385 'styles' => array( 1386 'blocks' => array( 1387 'core/social-links' => array( 1388 'spacing' => array( 1389 'blockGap' => array( 1390 'top' => '1em', 1391 'left' => '2em', 1392 ), 1393 ), 1394 ), 1395 ), 1396 'spacing' => array( 1397 'blockGap' => '3em', 1398 ), 1399 ), 1400 'settings' => array( 1401 'layout' => array( 1402 'contentSize' => '800px', 1403 'wideSize' => '1000px', 1404 ), 1405 ), 1406 ) 1407 ); 1408 1409 $expected = array( 1410 'version' => WP_Theme_JSON::LATEST_SCHEMA, 1411 'styles' => array( 1412 'blocks' => array( 1413 'core/social-links' => array( 1414 'spacing' => array( 1415 'blockGap' => array( 1416 'top' => '1em', 1417 'left' => '2em', 1418 ), 1419 ), 1420 ), 1421 ), 1422 'spacing' => array( 1423 'blockGap' => '3em', 1424 ), 1425 ), 1426 'settings' => array( 1427 'layout' => array( 1428 'contentSize' => '800px', 1429 'wideSize' => '1000px', 1430 ), 1431 ), 1432 ); 1433 1434 $this->assertEqualSetsWithIndex( $expected, $actual ); 1435 } 1436 1437 /** 1116 1438 * @ticket 52991 1117 1439 * @ticket 54336 … … 2555 2877 ), 2556 2878 ), 2879 ':seen' => array( 2880 'color' => array( 2881 'background' => 'ivory', 2882 ), 2883 ), 2557 2884 ), 2558 2885 ), … … 2841 3168 2842 3169 /** 2843 * @ticket 544872844 */2845 public function test_sanitization() {2846 $theme_json = new WP_Theme_JSON(2847 array(2848 'version' => 2,2849 'styles' => array(2850 'spacing' => array(2851 'blockGap' => 'valid value',2852 ),2853 'blocks' => array(2854 'core/group' => array(2855 'spacing' => array(2856 'margin' => 'valid value',2857 'display' => 'none',2858 ),2859 ),2860 ),2861 ),2862 )2863 );2864 2865 $actual = $theme_json->get_raw_data();2866 $expected = array(2867 'version' => 2,2868 'styles' => array(2869 'spacing' => array(2870 'blockGap' => 'valid value',2871 ),2872 'blocks' => array(2873 'core/group' => array(2874 'spacing' => array(2875 'margin' => 'valid value',2876 ),2877 ),2878 ),2879 ),2880 );2881 2882 $this->assertEqualSetsWithIndex( $expected, $actual );2883 }2884 2885 /**2886 3170 * @ticket 55505 2887 3171 */ … … 3155 3439 } 3156 3440 3441 public function test_remove_invalid_font_family_settings() { 3442 $actual = WP_Theme_JSON::remove_insecure_properties( 3443 array( 3444 'version' => WP_Theme_JSON::LATEST_SCHEMA, 3445 'settings' => array( 3446 'typography' => array( 3447 'fontFamilies' => array( 3448 'custom' => array( 3449 array( 3450 'name' => 'Open Sans', 3451 'slug' => 'open-sans', 3452 'fontFamily' => '"Open Sans", sans-serif</style><script>alert("xss")</script>', 3453 ), 3454 array( 3455 'name' => 'Arial', 3456 'slug' => 'arial', 3457 'fontFamily' => 'Arial, serif', 3458 ), 3459 ), 3460 ), 3461 ), 3462 ), 3463 ), 3464 true 3465 ); 3466 3467 $expected = array( 3468 'version' => WP_Theme_JSON::LATEST_SCHEMA, 3469 'settings' => array( 3470 'typography' => array( 3471 'fontFamilies' => array( 3472 'custom' => array( 3473 array( 3474 'name' => 'Arial', 3475 'slug' => 'arial', 3476 'fontFamily' => 'Arial, serif', 3477 ), 3478 ), 3479 ), 3480 ), 3481 ), 3482 ); 3483 3484 $this->assertEqualSetsWithIndex( $expected, $actual ); 3485 } 3157 3486 3158 3487 /** … … 3204 3533 ); 3205 3534 3206 $expected = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}body{background-color: #ffffff;color: #000000;}.wp-element-button, .wp-block-button__link{background-color: #000000;color: #ffffff;}'; 3535 $base_styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}'; 3536 $color_styles = 'body{background-color: #ffffff;color: #000000;}.wp-element-button, .wp-block-button__link{background-color: #000000;color: #ffffff;}'; 3537 $expected = $base_styles . $color_styles; 3207 3538 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 3208 3539 } … … 3256 3587 3257 3588 /** 3258 * Testing that dynamic properties in theme.json that refer to other dynamic properties in a loop 3589 * Testing that dynamic properties in theme.json that 3590 * refer to other dynamic properties in a loop 3259 3591 * should be left untouched. 3260 3592 * … … 3284 3616 ); 3285 3617 3286 $expected = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}body{background-color: #ffffff;}.wp-element-button, .wp-block-button__link{color: #ffffff;}'; 3618 $base_styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}'; 3619 $color_styles = 'body{background-color: #ffffff;}.wp-element-button, .wp-block-button__link{color: #ffffff;}'; 3620 $expected = $base_styles . $color_styles; 3287 3621 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 3288 3622 } 3289 3623 3290 3624 /** 3291 * Testing that dynamic properties in theme.json that refer to other dynamic properties 3625 * Testing that dynamic properties in theme.json that 3626 * refer to other dynamic properties 3292 3627 * should be left unprocessed. 3293 3628 * … … 3317 3652 ); 3318 3653 3319 $expected = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}body{background-color: #ffffff;color: #ffffff;}.wp-element-button, .wp-block-button__link{color: #ffffff;}'; 3654 $base_styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}'; 3655 $color_styles = 'body{background-color: #ffffff;color: #ffffff;}.wp-element-button, .wp-block-button__link{color: #ffffff;}'; 3656 $expected = $base_styles . $color_styles; 3320 3657 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 3321 3658 } 3322 3659 3323 3660 /** 3324 * Testing that dynamic properties in theme.json that refer to themselves3325 * should be left unprocessed.3661 * Testing that dynamic properties in theme.json that 3662 * refer to themselves should be left unprocessed. 3326 3663 * 3327 3664 * @ticket 56467 … … 3342 3679 ); 3343 3680 3344 $expected = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}body{background-color: #ffffff;}'; 3681 $base_styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}'; 3682 $color_styles = 'body{background-color: #ffffff;}'; 3683 $expected = $base_styles . $color_styles; 3345 3684 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 3346 }3347 3348 /**3349 * @ticket 564673350 * @ticket 585483351 * @ticket 585503352 */3353 public function test_get_stylesheet_generates_layout_styles() {3354 $theme_json = new WP_Theme_JSON(3355 array(3356 'version' => WP_Theme_JSON::LATEST_SCHEMA,3357 'settings' => array(3358 'spacing' => array(3359 'blockGap' => true,3360 ),3361 ),3362 'styles' => array(3363 'spacing' => array(3364 'blockGap' => '1em',3365 ),3366 ),3367 ),3368 'default'3369 );3370 3371 // Results also include root site blocks styles.3372 $this->assertSame(3373 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: 1em; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }body { --wp--style--block-gap: 1em; }:where(body .is-layout-flow) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-flow) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-flow) > *{margin-block-start: 1em;margin-block-end: 0;}:where(body .is-layout-constrained) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-constrained) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-constrained) > *{margin-block-start: 1em;margin-block-end: 0;}:where(body .is-layout-flex) {gap: 1em;}:where(body .is-layout-grid) {gap: 1em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}',3374 $theme_json->get_stylesheet( array( 'styles' ) )3375 );3376 }3377 3378 /**3379 * @ticket 564673380 * @ticket 585483381 * @ticket 585503382 */3383 public function test_get_stylesheet_generates_layout_styles_with_spacing_presets() {3384 $theme_json = new WP_Theme_JSON(3385 array(3386 'version' => WP_Theme_JSON::LATEST_SCHEMA,3387 'settings' => array(3388 'spacing' => array(3389 'blockGap' => true,3390 ),3391 ),3392 'styles' => array(3393 'spacing' => array(3394 'blockGap' => 'var:preset|spacing|60',3395 ),3396 ),3397 ),3398 'default'3399 );3400 3401 // Results also include root site blocks styles.3402 $this->assertSame(3403 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: var(--wp--preset--spacing--60); margin-block-end: 0; }:where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }body { --wp--style--block-gap: var(--wp--preset--spacing--60); }:where(body .is-layout-flow) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-flow) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-flow) > *{margin-block-start: var(--wp--preset--spacing--60);margin-block-end: 0;}:where(body .is-layout-constrained) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-constrained) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-constrained) > *{margin-block-start: var(--wp--preset--spacing--60);margin-block-end: 0;}:where(body .is-layout-flex) {gap: var(--wp--preset--spacing--60);}:where(body .is-layout-grid) {gap: var(--wp--preset--spacing--60);}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}',3404 $theme_json->get_stylesheet( array( 'styles' ) )3405 );3406 }3407 3408 /**3409 * @ticket 564673410 * @ticket 585503411 */3412 public function test_get_stylesheet_generates_fallback_gap_layout_styles() {3413 $theme_json = new WP_Theme_JSON(3414 array(3415 'version' => WP_Theme_JSON::LATEST_SCHEMA,3416 'settings' => array(3417 'spacing' => array(3418 'blockGap' => null,3419 ),3420 ),3421 'styles' => array(3422 'spacing' => array(3423 'blockGap' => '1em',3424 ),3425 ),3426 ),3427 'default'3428 );3429 $stylesheet = $theme_json->get_stylesheet( array( 'styles' ) );3430 3431 // Results also include root site blocks styles.3432 $this->assertSame(3433 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}',3434 $stylesheet3435 );3436 }3437 3438 /**3439 * @ticket 564673440 * @ticket 585503441 */3442 public function test_get_stylesheet_generates_base_fallback_gap_layout_styles() {3443 $theme_json = new WP_Theme_JSON(3444 array(3445 'version' => WP_Theme_JSON::LATEST_SCHEMA,3446 'settings' => array(3447 'spacing' => array(3448 'blockGap' => null,3449 ),3450 ),3451 ),3452 'default'3453 );3454 $stylesheet = $theme_json->get_stylesheet( array( 'base-layout-styles' ) );3455 3456 // Note the `base-layout-styles` includes a fallback gap for the Columns block for backwards compatibility.3457 $this->assertSame(3458 ':where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}',3459 $stylesheet3460 );3461 }3462 3463 /**3464 * @ticket 564673465 * @ticket 585503466 */3467 public function test_get_stylesheet_skips_layout_styles() {3468 add_theme_support( 'disable-layout-styles' );3469 $theme_json = new WP_Theme_JSON(3470 array(3471 'version' => WP_Theme_JSON::LATEST_SCHEMA,3472 'settings' => array(3473 'spacing' => array(3474 'blockGap' => null,3475 ),3476 ),3477 ),3478 'default'3479 );3480 $stylesheet = $theme_json->get_stylesheet( array( 'base-layout-styles' ) );3481 remove_theme_support( 'disable-layout-styles' );3482 3483 // All Layout styles should be skipped.3484 $this->assertSame(3485 '',3486 $stylesheet3487 );3488 }3489 3490 /**3491 * @ticket 564673492 * @ticket 585503493 */3494 public function test_get_stylesheet_generates_valid_block_gap_values_and_skips_null_or_false_values() {3495 $theme_json = new WP_Theme_JSON(3496 array(3497 'version' => WP_Theme_JSON::LATEST_SCHEMA,3498 'settings' => array(3499 'spacing' => array(3500 'blockGap' => true,3501 ),3502 ),3503 'styles' => array(3504 'spacing' => array(3505 'blockGap' => '1rem',3506 ),3507 'blocks' => array(3508 'core/post-content' => array(3509 'color' => array(3510 'text' => 'gray', // This value should not render block layout styles.3511 ),3512 ),3513 'core/social-links' => array(3514 'spacing' => array(3515 'blockGap' => '0', // This value should render block layout gap as zero.3516 ),3517 ),3518 'core/buttons' => array(3519 'spacing' => array(3520 'blockGap' => 0, // This value should render block layout gap as zero.3521 ),3522 ),3523 'core/columns' => array(3524 'spacing' => array(3525 'blockGap' => false, // This value should be ignored. The block will use the global layout value.3526 ),3527 ),3528 ),3529 ),3530 ),3531 'default'3532 );3533 3534 $this->assertSame(3535 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: 1rem; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }body { --wp--style--block-gap: 1rem; }:where(body .is-layout-flow) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-flow) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-flow) > *{margin-block-start: 1rem;margin-block-end: 0;}:where(body .is-layout-constrained) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-constrained) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-constrained) > *{margin-block-start: 1rem;margin-block-end: 0;}:where(body .is-layout-flex) {gap: 1rem;}:where(body .is-layout-grid) {gap: 1rem;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-post-content{color: gray;}.wp-block-social-links-is-layout-flow > :first-child:first-child{margin-block-start: 0;}.wp-block-social-links-is-layout-flow > :last-child:last-child{margin-block-end: 0;}.wp-block-social-links-is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-social-links-is-layout-constrained > :first-child:first-child{margin-block-start: 0;}.wp-block-social-links-is-layout-constrained > :last-child:last-child{margin-block-end: 0;}.wp-block-social-links-is-layout-constrained > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-social-links-is-layout-flex{gap: 0;}.wp-block-social-links-is-layout-grid{gap: 0;}.wp-block-buttons-is-layout-flow > :first-child:first-child{margin-block-start: 0;}.wp-block-buttons-is-layout-flow > :last-child:last-child{margin-block-end: 0;}.wp-block-buttons-is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-buttons-is-layout-constrained > :first-child:first-child{margin-block-start: 0;}.wp-block-buttons-is-layout-constrained > :last-child:last-child{margin-block-end: 0;}.wp-block-buttons-is-layout-constrained > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-buttons-is-layout-flex{gap: 0;}.wp-block-buttons-is-layout-grid{gap: 0;}',3536 $theme_json->get_stylesheet()3537 );3538 3685 } 3539 3686 … … 3631 3778 $style_rules = $theme_json->get_styles_for_block( $metadata ); 3632 3779 $this->assertSame( $expected, $root_rules . $style_rules ); 3780 } 3781 3782 /** 3783 * @ticket 56611 3784 * @ticket 58548 3785 * @ticket 58550 3786 */ 3787 public function test_get_styles_with_appearance_tools() { 3788 $theme_json = new WP_Theme_JSON( 3789 array( 3790 'version' => 2, 3791 'settings' => array( 3792 'appearanceTools' => true, 3793 ), 3794 ) 3795 ); 3796 3797 $metadata = array( 3798 'path' => array( 'settings' ), 3799 'selector' => 'body', 3800 ); 3801 3802 $expected = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: ; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }body { --wp--style--block-gap: ; }:where(body .is-layout-flow) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-flow) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-flow) > *{margin-block-start: 1;margin-block-end: 0;}:where(body .is-layout-constrained) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-constrained) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-constrained) > *{margin-block-start: 1;margin-block-end: 0;}:where(body .is-layout-flex) {gap: 1;}:where(body .is-layout-grid) {gap: 1;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}'; 3803 $root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON::ROOT_BLOCK_SELECTOR, $metadata ); 3804 $this->assertSame( $expected, $root_rules ); 3805 } 3806 3807 /** 3808 * @ticket 54487 3809 */ 3810 public function test_sanitization() { 3811 $theme_json = new WP_Theme_JSON( 3812 array( 3813 'version' => 2, 3814 'styles' => array( 3815 'spacing' => array( 3816 'blockGap' => 'valid value', 3817 ), 3818 'blocks' => array( 3819 'core/group' => array( 3820 'spacing' => array( 3821 'margin' => 'valid value', 3822 'display' => 'none', 3823 ), 3824 ), 3825 ), 3826 ), 3827 ) 3828 ); 3829 3830 $actual = $theme_json->get_raw_data(); 3831 $expected = array( 3832 'version' => 2, 3833 'styles' => array( 3834 'spacing' => array( 3835 'blockGap' => 'valid value', 3836 ), 3837 'blocks' => array( 3838 'core/group' => array( 3839 'spacing' => array( 3840 'margin' => 'valid value', 3841 ), 3842 ), 3843 ), 3844 ), 3845 ); 3846 3847 $this->assertEqualSetsWithIndex( $expected, $actual ); 3633 3848 } 3634 3849 … … 3765 3980 ), 3766 3981 ), 3767 );3768 }3769 3770 /**3771 * @ticket 575833772 *3773 * @dataProvider data_sanitize_with_invalid_style_variation3774 *3775 * @param array $theme_json_variations The theme.json variations to test.3776 */3777 public function test_sanitize_with_invalid_style_variation( $theme_json_variations ) {3778 $theme_json = new WP_Theme_JSON(3779 array(3780 'version' => 2,3781 'styles' => array(3782 'blocks' => array(3783 'core/quote' => $theme_json_variations,3784 ),3785 ),3786 )3787 );3788 3789 // Validate structure is sanitized.3790 $sanitized_theme_json = $theme_json->get_raw_data();3791 $this->assertIsArray( $sanitized_theme_json, 'Sanitized theme.json is not an array data type' );3792 $this->assertArrayNotHasKey( 'styles', $sanitized_theme_json, 'Sanitized theme.json should not have a "styles" key' );3793 }3794 3795 /**3796 * Data provider.3797 *3798 * @return array3799 */3800 public function data_sanitize_with_invalid_style_variation() {3801 return array(3802 'empty string variation' => array(3803 array(3804 'variations' => '',3805 ),3806 ),3807 'boolean variation' => array(3808 array(3809 'variations' => false,3810 ),3811 ),3812 );3813 }3814 3815 /**3816 * @ticket 575833817 *3818 * @dataProvider data_get_styles_for_block_with_style_variations3819 *3820 * @param array $theme_json_variations Theme.json variations to test.3821 * @param string $metadata_variations Style variations to test.3822 * @param string $expected Expected results for styling.3823 */3824 public function test_get_styles_for_block_with_style_variations( $theme_json_variations, $metadata_variations, $expected ) {3825 $theme_json = new WP_Theme_JSON(3826 array(3827 'version' => 2,3828 'styles' => array(3829 'blocks' => array(3830 'core/quote' => $theme_json_variations,3831 ),3832 ),3833 )3834 );3835 3836 // Validate styles are generated properly.3837 $metadata = array(3838 'path' => array( 'styles', 'blocks', 'core/quote' ),3839 'selector' => '.wp-block-quote',3840 'variations' => $metadata_variations,3841 );3842 $actual_styles = $theme_json->get_styles_for_block( $metadata );3843 $this->assertSame( $expected, $actual_styles );3844 }3845 3846 /**3847 * Data provider.3848 *3849 * @return array3850 */3851 public function data_get_styles_for_block_with_style_variations() {3852 $plain = array(3853 'metadata' => array(3854 'path' => array( 'styles', 'blocks', 'core/quote', 'variations', 'plain' ),3855 'selector' => '.is-style-plain.is-style-plain.wp-block-quote',3856 ),3857 'styles' => '.is-style-plain.is-style-plain.wp-block-quote{background-color: hotpink;}',3858 );3859 3860 return array(3861 '1 variation with 1 invalid property' => array(3862 'theme_json_variations' => array(3863 'variations' => array(3864 'plain' => array(3865 'color' => array(3866 'background' => 'hotpink',3867 ),3868 ),3869 ),3870 ),3871 'metadata_variation' => array( $plain['metadata'] ),3872 'expected' => $plain['styles'],3873 ),3874 '1 variation with 2 invalid properties' => array(3875 'theme_json_variations' => array(3876 'variations' => array(3877 'plain' => array(3878 'color' => array(3879 'background' => 'hotpink',3880 ),3881 'invalidProperty1' => 'value1',3882 'invalidProperty2' => 'value2',3883 ),3884 ),3885 ),3886 'metadata_variation' => array( $plain['metadata'] ),3887 'expected' => $plain['styles'],3888 ),3889 );3890 }3891 3892 public function test_block_style_variations() {3893 wp_set_current_user( static::$administrator_id );3894 3895 $expected = array(3896 'version' => WP_Theme_JSON::LATEST_SCHEMA,3897 'styles' => array(3898 'blocks' => array(3899 'core/button' => array(3900 'color' => array(3901 'background' => 'blue',3902 ),3903 'variations' => array(3904 'outline' => array(3905 'color' => array(3906 'background' => 'purple',3907 ),3908 ),3909 ),3910 ),3911 ),3912 ),3913 );3914 3915 $actual = WP_Theme_JSON::remove_insecure_properties( $expected );3916 3917 $this->assertSameSetsWithIndex( $expected, $actual );3918 }3919 3920 public function test_block_style_variations_with_invalid_properties() {3921 wp_set_current_user( static::$administrator_id );3922 3923 $partially_invalid_variation = array(3924 'version' => WP_Theme_JSON::LATEST_SCHEMA,3925 'styles' => array(3926 'blocks' => array(3927 'core/button' => array(3928 'color' => array(3929 'background' => 'blue',3930 ),3931 'variations' => array(3932 'outline' => array(3933 'color' => array(3934 'background' => 'purple',3935 ),3936 'invalid' => array(3937 'value' => 'should be stripped',3938 ),3939 ),3940 ),3941 ),3942 ),3943 ),3944 );3945 3946 $expected = array(3947 'version' => WP_Theme_JSON::LATEST_SCHEMA,3948 'styles' => array(3949 'blocks' => array(3950 'core/button' => array(3951 'color' => array(3952 'background' => 'blue',3953 ),3954 'variations' => array(3955 'outline' => array(3956 'color' => array(3957 'background' => 'purple',3958 ),3959 ),3960 ),3961 ),3962 ),3963 ),3964 );3965 3966 $actual = WP_Theme_JSON::remove_insecure_properties( $partially_invalid_variation );3967 3968 $this->assertSameSetsWithIndex( $expected, $actual );3969 }3970 3971 /**3972 * @ticket 566113973 * @ticket 585483974 * @ticket 585503975 */3976 public function test_get_styles_with_appearance_tools() {3977 $theme_json = new WP_Theme_JSON(3978 array(3979 'version' => 2,3980 'settings' => array(3981 'appearanceTools' => true,3982 ),3983 )3984 );3985 3986 $metadata = array(3987 'path' => array( 'settings' ),3988 'selector' => 'body',3989 );3990 3991 $expected = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: ; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child:first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child:last-child { margin-block-end: 0; }body { --wp--style--block-gap: ; }:where(body .is-layout-flow) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-flow) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-flow) > *{margin-block-start: 1;margin-block-end: 0;}:where(body .is-layout-constrained) > :first-child:first-child{margin-block-start: 0;}:where(body .is-layout-constrained) > :last-child:last-child{margin-block-end: 0;}:where(body .is-layout-constrained) > *{margin-block-start: 1;margin-block-end: 0;}:where(body .is-layout-flex) {gap: 1;}:where(body .is-layout-grid) {gap: 1;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}';3992 $root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON::ROOT_BLOCK_SELECTOR, $metadata );3993 $this->assertSame( $expected, $root_rules );3994 }3995 3996 /**3997 * Tests generating the spacing presets array based on the spacing scale provided.3998 *3999 * @ticket 564674000 *4001 * @dataProvider data_generate_spacing_scale_fixtures4002 *4003 * @param array $spacing_scale Example spacing scale definitions from the data provider.4004 * @param array $expected_output Expected output from data provider.4005 */4006 public function test_should_set_spacing_sizes( $spacing_scale, $expected_output ) {4007 $theme_json = new WP_Theme_JSON(4008 array(4009 'version' => 2,4010 'settings' => array(4011 'spacing' => array(4012 'spacingScale' => $spacing_scale,4013 ),4014 ),4015 )4016 );4017 4018 $theme_json->set_spacing_sizes();4019 $this->assertSame( $expected_output, _wp_array_get( $theme_json->get_raw_data(), array( 'settings', 'spacing', 'spacingSizes', 'default' ) ) );4020 }4021 4022 /**4023 * Data provider for spacing scale tests.4024 *4025 * @ticket 564674026 *4027 * @return array4028 */4029 public function data_generate_spacing_scale_fixtures() {4030 return array(4031 'only one value when single step in spacing scale' => array(4032 'spacing_scale' => array(4033 'operator' => '+',4034 'increment' => 1.5,4035 'steps' => 1,4036 'mediumStep' => 4,4037 'unit' => 'rem',4038 ),4039 'expected_output' => array(4040 array(4041 'name' => '1',4042 'slug' => '50',4043 'size' => '4rem',4044 ),4045 ),4046 ),4047 'one step above medium when two steps in spacing scale' => array(4048 'spacing_scale' => array(4049 'operator' => '+',4050 'increment' => 1.5,4051 'steps' => 2,4052 'mediumStep' => 4,4053 'unit' => 'rem',4054 ),4055 'expected_output' => array(4056 array(4057 'name' => '1',4058 'slug' => '50',4059 'size' => '4rem',4060 ),4061 array(4062 'name' => '2',4063 'slug' => '60',4064 'size' => '5.5rem',4065 ),4066 ),4067 ),4068 'one step above medium and one below when three steps in spacing scale' => array(4069 'spacing_scale' => array(4070 'operator' => '+',4071 'increment' => 1.5,4072 'steps' => 3,4073 'mediumStep' => 4,4074 'unit' => 'rem',4075 ),4076 'expected_output' => array(4077 array(4078 'name' => '1',4079 'slug' => '40',4080 'size' => '2.5rem',4081 ),4082 array(4083 'name' => '2',4084 'slug' => '50',4085 'size' => '4rem',4086 ),4087 array(4088 'name' => '3',4089 'slug' => '60',4090 'size' => '5.5rem',4091 ),4092 ),4093 ),4094 'extra step added above medium when an even number of steps > 2 specified' => array(4095 'spacing_scale' => array(4096 'operator' => '+',4097 'increment' => 1.5,4098 'steps' => 4,4099 'mediumStep' => 4,4100 'unit' => 'rem',4101 ),4102 'expected_output' => array(4103 array(4104 'name' => '1',4105 'slug' => '40',4106 'size' => '2.5rem',4107 ),4108 array(4109 'name' => '2',4110 'slug' => '50',4111 'size' => '4rem',4112 ),4113 array(4114 'name' => '3',4115 'slug' => '60',4116 'size' => '5.5rem',4117 ),4118 array(4119 'name' => '4',4120 'slug' => '70',4121 'size' => '7rem',4122 ),4123 ),4124 ),4125 'extra steps above medium if bottom end will go below zero' => array(4126 'spacing_scale' => array(4127 'operator' => '+',4128 'increment' => 2.5,4129 'steps' => 5,4130 'mediumStep' => 5,4131 'unit' => 'rem',4132 ),4133 'expected_output' => array(4134 array(4135 'name' => '1',4136 'slug' => '40',4137 'size' => '2.5rem',4138 ),4139 array(4140 'name' => '2',4141 'slug' => '50',4142 'size' => '5rem',4143 ),4144 array(4145 'name' => '3',4146 'slug' => '60',4147 'size' => '7.5rem',4148 ),4149 array(4150 'name' => '4',4151 'slug' => '70',4152 'size' => '10rem',4153 ),4154 array(4155 'name' => '5',4156 'slug' => '80',4157 'size' => '12.5rem',4158 ),4159 ),4160 ),4161 'multiplier correctly calculated above and below medium' => array(4162 'spacing_scale' => array(4163 'operator' => '*',4164 'increment' => 1.5,4165 'steps' => 5,4166 'mediumStep' => 1.5,4167 'unit' => 'rem',4168 ),4169 'expected_output' => array(4170 array(4171 'name' => '1',4172 'slug' => '30',4173 'size' => '0.67rem',4174 ),4175 array(4176 'name' => '2',4177 'slug' => '40',4178 'size' => '1rem',4179 ),4180 array(4181 'name' => '3',4182 'slug' => '50',4183 'size' => '1.5rem',4184 ),4185 array(4186 'name' => '4',4187 'slug' => '60',4188 'size' => '2.25rem',4189 ),4190 array(4191 'name' => '5',4192 'slug' => '70',4193 'size' => '3.38rem',4194 ),4195 ),4196 ),4197 'increment < 1 combined showing * operator acting as divisor above and below medium' => array(4198 'spacing_scale' => array(4199 'operator' => '*',4200 'increment' => 0.25,4201 'steps' => 5,4202 'mediumStep' => 1.5,4203 'unit' => 'rem',4204 ),4205 'expected_output' => array(4206 array(4207 'name' => '1',4208 'slug' => '30',4209 'size' => '0.09rem',4210 ),4211 array(4212 'name' => '2',4213 'slug' => '40',4214 'size' => '0.38rem',4215 ),4216 array(4217 'name' => '3',4218 'slug' => '50',4219 'size' => '1.5rem',4220 ),4221 array(4222 'name' => '4',4223 'slug' => '60',4224 'size' => '6rem',4225 ),4226 array(4227 'name' => '5',4228 'slug' => '70',4229 'size' => '24rem',4230 ),4231 ),4232 ),4233 't-shirt sizing used if more than 7 steps in scale' => array(4234 'spacing_scale' => array(4235 'operator' => '*',4236 'increment' => 1.5,4237 'steps' => 8,4238 'mediumStep' => 1.5,4239 'unit' => 'rem',4240 ),4241 'expected_output' => array(4242 array(4243 'name' => '2X-Small',4244 'slug' => '20',4245 'size' => '0.44rem',4246 ),4247 array(4248 'name' => 'X-Small',4249 'slug' => '30',4250 'size' => '0.67rem',4251 ),4252 array(4253 'name' => 'Small',4254 'slug' => '40',4255 'size' => '1rem',4256 ),4257 array(4258 'name' => 'Medium',4259 'slug' => '50',4260 'size' => '1.5rem',4261 ),4262 array(4263 'name' => 'Large',4264 'slug' => '60',4265 'size' => '2.25rem',4266 ),4267 array(4268 'name' => 'X-Large',4269 'slug' => '70',4270 'size' => '3.38rem',4271 ),4272 array(4273 'name' => '2X-Large',4274 'slug' => '80',4275 'size' => '5.06rem',4276 ),4277 array(4278 'name' => '3X-Large',4279 'slug' => '90',4280 'size' => '7.59rem',4281 ),4282 ),4283 ),4284 );4285 }4286 4287 /**4288 * Tests generating the spacing presets array based on the spacing scale provided.4289 *4290 * @ticket 564674291 *4292 * @dataProvider data_set_spacing_sizes_when_invalid4293 *4294 * @param array $spacing_scale Example spacing scale definitions from the data provider.4295 * @param array $expected_output Expected output from data provider.4296 */4297 public function test_set_spacing_sizes_should_detect_invalid_spacing_scale( $spacing_scale, $expected_output ) {4298 $this->expectException( Exception::class );4299 $this->expectExceptionMessage( 'Some of the theme.json settings.spacing.spacingScale values are invalid' );4300 4301 $theme_json = new WP_Theme_JSON(4302 array(4303 'version' => 2,4304 'settings' => array(4305 'spacing' => array(4306 'spacingScale' => $spacing_scale,4307 ),4308 ),4309 )4310 );4311 4312 // Ensure PHPUnit 10 compatibility.4313 set_error_handler(4314 static function ( $errno, $errstr ) {4315 restore_error_handler();4316 throw new Exception( $errstr, $errno );4317 },4318 E_ALL4319 );4320 4321 $theme_json->set_spacing_sizes();4322 4323 restore_error_handler();4324 4325 $this->assertSame( $expected_output, _wp_array_get( $theme_json->get_raw_data(), array( 'settings', 'spacing', 'spacingSizes', 'default' ) ) );4326 }4327 4328 /**4329 * Data provider for spacing scale tests.4330 *4331 * @ticket 564674332 *4333 * @return array4334 */4335 public function data_set_spacing_sizes_when_invalid() {4336 return array(4337 'missing operator value' => array(4338 'spacing_scale' => array(4339 'operator' => '',4340 'increment' => 1.5,4341 'steps' => 1,4342 'mediumStep' => 4,4343 'unit' => 'rem',4344 ),4345 'expected_output' => null,4346 ),4347 'non numeric increment' => array(4348 'spacing_scale' => array(4349 'operator' => '+',4350 'increment' => 'add two to previous value',4351 'steps' => 1,4352 'mediumStep' => 4,4353 'unit' => 'rem',4354 ),4355 'expected_output' => null,4356 ),4357 'non numeric steps' => array(4358 'spacing_scale' => array(4359 'operator' => '+',4360 'increment' => 1.5,4361 'steps' => 'spiral staircase preferred',4362 'mediumStep' => 4,4363 'unit' => 'rem',4364 ),4365 'expected_output' => null,4366 ),4367 'non numeric medium step' => array(4368 'spacing_scale' => array(4369 'operator' => '+',4370 'increment' => 1.5,4371 'steps' => 5,4372 'mediumStep' => 'That which is just right',4373 'unit' => 'rem',4374 ),4375 'expected_output' => null,4376 ),4377 'missing unit value' => array(4378 'spacing_scale' => array(4379 'operator' => '+',4380 'increment' => 1.5,4381 'steps' => 5,4382 'mediumStep' => 4,4383 ),4384 'expected_output' => null,4385 ),4386 );4387 }4388 4389 /**4390 * Tests the core separator block outbut based on various provided settings.4391 *4392 * @ticket 569034393 * @ticket 585504394 *4395 * @dataProvider data_update_separator_declarations4396 *4397 * @param array $separator_block_settings Example separator block settings from the data provider.4398 * @param array $expected_output Expected output from data provider.4399 */4400 public function test_update_separator_declarations( $separator_block_settings, $expected_output ) {4401 // If only background is defined, test that includes border-color to the style so it is applied on the front end.4402 $theme_json = new WP_Theme_JSON(4403 array(4404 'version' => WP_Theme_JSON::LATEST_SCHEMA,4405 'styles' => array(4406 'blocks' => array(4407 'core/separator' => $separator_block_settings,4408 ),4409 ),4410 ),4411 'default'4412 );4413 4414 $stylesheet = $theme_json->get_stylesheet( array( 'styles' ) );4415 4416 $this->assertSame( $expected_output, $stylesheet );4417 }4418 4419 /**4420 * Data provider for separator declaration tests.4421 *4422 * @return array4423 */4424 public function data_update_separator_declarations() {4425 return array(4426 // If only background is defined, test that includes border-color to the style so it is applied on the front end.4427 'only background' => array(4428 array(4429 'color' => array(4430 'background' => 'blue',4431 ),4432 ),4433 'expected_output' => 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-separator{background-color: blue;color: blue;}',4434 ),4435 // If background and text are defined, do not include border-color, as text color is enough.4436 'background and text, no border-color' => array(4437 array(4438 'color' => array(4439 'background' => 'blue',4440 'text' => 'red',4441 ),4442 ),4443 'expected_output' => 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-separator{background-color: blue;color: red;}',4444 ),4445 // If only text is defined, do not include border-color, as by itself is enough.4446 'only text' => array(4447 array(4448 'color' => array(4449 'text' => 'red',4450 ),4451 ),4452 'expected_output' => 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-separator{color: red;}',4453 ),4454 // If background, text, and border-color are defined, include everything, CSS specificity will decide which to apply.4455 'background, text, and border-color' => array(4456 array(4457 'color' => array(4458 'background' => 'blue',4459 'text' => 'red',4460 ),4461 'border' => array(4462 'color' => 'pink',4463 ),4464 ),4465 'expected_output' => 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-separator{background-color: blue;border-color: pink;color: red;}',4466 ),4467 // If background and border color are defined, include everything, CSS specificity will decide which to apply.4468 'background, and border-color' => array(4469 array(4470 'color' => array(4471 'background' => 'blue',4472 ),4473 'border' => array(4474 'color' => 'pink',4475 ),4476 ),4477 'expected_output' => 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-separator{background-color: blue;border-color: pink;}',4478 ),4479 );4480 }4481 4482 /**4483 * @ticket 573544484 * @ticket 585504485 */4486 public function test_get_stylesheet_returns_outline_styles() {4487 $theme_json = new WP_Theme_JSON(4488 array(4489 'version' => WP_Theme_JSON::LATEST_SCHEMA,4490 'styles' => array(4491 'elements' => array(4492 'button' => array(4493 'outline' => array(4494 'offset' => '3px',4495 'width' => '3px',4496 'style' => 'dashed',4497 'color' => 'red',4498 ),4499 ':hover' => array(4500 'outline' => array(4501 'offset' => '3px',4502 'width' => '3px',4503 'style' => 'solid',4504 'color' => 'blue',4505 ),4506 ),4507 ),4508 ),4509 ),4510 )4511 );4512 4513 $base_styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}';4514 4515 $element_styles = '.wp-element-button, .wp-block-button__link{outline-color: red;outline-offset: 3px;outline-style: dashed;outline-width: 3px;}.wp-element-button:hover, .wp-block-button__link:hover{outline-color: blue;outline-offset: 3px;outline-style: solid;outline-width: 3px;}';4516 4517 $expected = $base_styles . $element_styles;4518 $this->assertSame( $expected, $theme_json->get_stylesheet() );4519 }4520 4521 /**4522 * @ticket 575594523 */4524 public function test_shadow_preset_styles() {4525 $theme_json = new WP_Theme_JSON(4526 array(4527 'version' => WP_Theme_JSON::LATEST_SCHEMA,4528 'settings' => array(4529 'shadow' => array(4530 'presets' => array(4531 array(4532 'slug' => 'natural',4533 'shadow' => '5px 5px 5px 0 black',4534 ),4535 array(4536 'slug' => 'sharp',4537 'shadow' => '5px 5px black',4538 ),4539 ),4540 ),4541 ),4542 )4543 );4544 4545 $expected_styles = 'body{--wp--preset--shadow--natural: 5px 5px 5px 0 black;--wp--preset--shadow--sharp: 5px 5px black;}';4546 $this->assertSame( $expected_styles, $theme_json->get_stylesheet(), 'Styles returned from "::get_stylesheet()" does not match expectations' );4547 $this->assertSame( $expected_styles, $theme_json->get_stylesheet( array( 'variables' ) ), 'Styles returned from "::get_stylesheet()" when requiring "variables" type does not match expectations' );4548 }4549 4550 /**4551 * @ticket 575594552 * @ticket 585504553 */4554 public function test_get_shadow_styles_for_blocks() {4555 $theme_json = new WP_Theme_JSON(4556 array(4557 'version' => WP_Theme_JSON::LATEST_SCHEMA,4558 'settings' => array(4559 'shadow' => array(4560 'presets' => array(4561 array(4562 'slug' => 'natural',4563 'shadow' => '5px 5px 0 0 black',4564 ),4565 ),4566 ),4567 ),4568 'styles' => array(4569 'blocks' => array(4570 'core/paragraph' => array(4571 'shadow' => 'var(--wp--preset--shadow--natural)',4572 ),4573 ),4574 'elements' => array(4575 'button' => array(4576 'shadow' => 'var:preset|shadow|natural',4577 ),4578 'link' => array(4579 'shadow' => array( 'ref' => 'styles.elements.button.shadow' ),4580 ),4581 ),4582 ),4583 )4584 );4585 4586 $global_styles = 'body{--wp--preset--shadow--natural: 5px 5px 0 0 black;}body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}';4587 $element_styles = 'a:where(:not(.wp-element-button)){box-shadow: var(--wp--preset--shadow--natural);}.wp-element-button, .wp-block-button__link{box-shadow: var(--wp--preset--shadow--natural);}p{box-shadow: var(--wp--preset--shadow--natural);}';4588 $expected_styles = $global_styles . $element_styles;4589 4590 $this->assertSame( $expected_styles, $theme_json->get_stylesheet() );4591 }4592 4593 /**4594 * @ticket 575364595 */4596 public function test_get_custom_css_handles_global_custom_css() {4597 $theme_json = new WP_Theme_JSON(4598 array(4599 'version' => WP_Theme_JSON::LATEST_SCHEMA,4600 'styles' => array(4601 'css' => 'body { color:purple; }',4602 ),4603 )4604 );4605 $custom_css = 'body { color:purple; }';4606 $this->assertSame( $custom_css, $theme_json->get_custom_css() );4607 }4608 4609 /**4610 * Tests that custom CSS is kept for users with correct capabilities and removed for others.4611 *4612 * @ticket 575364613 *4614 * @dataProvider data_custom_css_for_user_caps4615 *4616 * @param string $user_property The property name for current user.4617 * @param array $expected Expected results.4618 */4619 public function test_custom_css_for_user_caps( $user_property, array $expected ) {4620 wp_set_current_user( static::${$user_property} );4621 4622 $actual = WP_Theme_JSON::remove_insecure_properties(4623 array(4624 'version' => WP_Theme_JSON::LATEST_SCHEMA,4625 'styles' => array(4626 'css' => 'body { color:purple; }',4627 'blocks' => array(4628 'core/separator' => array(4629 'color' => array(4630 'background' => 'blue',4631 ),4632 ),4633 ),4634 ),4635 )4636 );4637 4638 $this->assertSameSetsWithIndex( $expected, $actual );4639 }4640 4641 /**4642 * Data provider.4643 *4644 * @return array[]4645 */4646 public function data_custom_css_for_user_caps() {4647 return array(4648 'allows custom css for users with caps' => array(4649 'user_property' => 'administrator_id',4650 'expected' => array(4651 'version' => WP_Theme_JSON::LATEST_SCHEMA,4652 'styles' => array(4653 'css' => 'body { color:purple; }',4654 'blocks' => array(4655 'core/separator' => array(4656 'color' => array(4657 'background' => 'blue',4658 ),4659 ),4660 ),4661 ),4662 ),4663 ),4664 'removes custom css for users without caps' => array(4665 'user_property' => 'user_id',4666 'expected' => array(4667 'version' => WP_Theme_JSON::LATEST_SCHEMA,4668 'styles' => array(4669 'blocks' => array(4670 'core/separator' => array(4671 'color' => array(4672 'background' => 'blue',4673 ),4674 ),4675 ),4676 ),4677 ),4678 ),4679 );4680 }4681 4682 /**4683 * @dataProvider data_process_blocks_custom_css4684 *4685 * @param array $input An array containing the selector and css to test.4686 * @param string $expected Expected results.4687 */4688 public function test_process_blocks_custom_css( $input, $expected ) {4689 $theme_json = new WP_Theme_JSON(4690 array(4691 'version' => WP_Theme_JSON::LATEST_SCHEMA,4692 'styles' => array(),4693 )4694 );4695 $reflection = new ReflectionMethod( $theme_json, 'process_blocks_custom_css' );4696 $reflection->setAccessible( true );4697 4698 $this->assertSame( $expected, $reflection->invoke( $theme_json, $input['css'], $input['selector'] ) );4699 }4700 4701 /**4702 * Data provider.4703 *4704 * @return array[]4705 */4706 public function data_process_blocks_custom_css() {4707 return array(4708 // Simple CSS without any nested selectors.4709 'no nested selectors' => array(4710 'input' => array(4711 'selector' => '.foo',4712 'css' => 'color: red; margin: auto;',4713 ),4714 'expected' => '.foo{color: red; margin: auto;}',4715 ),4716 // CSS with nested selectors.4717 'with nested selector' => array(4718 'input' => array(4719 'selector' => '.foo',4720 'css' => 'color: red; margin: auto; &.one{color: blue;} & .two{color: green;}',4721 ),4722 'expected' => '.foo{color: red; margin: auto;}.foo.one{color: blue;}.foo .two{color: green;}',4723 ),4724 // CSS with pseudo elements.4725 'with pseudo elements' => array(4726 'input' => array(4727 'selector' => '.foo',4728 'css' => 'color: red; margin: auto; &::before{color: blue;} & ::before{color: green;} &.one::before{color: yellow;} & .two::before{color: purple;}',4729 ),4730 'expected' => '.foo{color: red; margin: auto;}.foo::before{color: blue;}.foo ::before{color: green;}.foo.one::before{color: yellow;}.foo .two::before{color: purple;}',4731 ),4732 // CSS with multiple root selectors.4733 'with multiple root selectors' => array(4734 'input' => array(4735 'selector' => '.foo, .bar',4736 'css' => 'color: red; margin: auto; &.one{color: blue;} & .two{color: green;} &::before{color: yellow;} & ::before{color: purple;} &.three::before{color: orange;} & .four::before{color: skyblue;}',4737 ),4738 'expected' => '.foo, .bar{color: red; margin: auto;}.foo.one, .bar.one{color: blue;}.foo .two, .bar .two{color: green;}.foo::before, .bar::before{color: yellow;}.foo ::before, .bar ::before{color: purple;}.foo.three::before, .bar.three::before{color: orange;}.foo .four::before, .bar .four::before{color: skyblue;}',4739 ),4740 );4741 }4742 4743 public function test_internal_syntax_is_converted_to_css_variables() {4744 $result = new WP_Theme_JSON(4745 array(4746 'version' => WP_Theme_JSON::LATEST_SCHEMA,4747 'styles' => array(4748 'color' => array(4749 'background' => 'var:preset|color|primary',4750 'text' => 'var(--wp--preset--color--secondary)',4751 ),4752 'elements' => array(4753 'link' => array(4754 'color' => array(4755 'background' => 'var:preset|color|pri',4756 'text' => 'var(--wp--preset--color--sec)',4757 ),4758 ),4759 ),4760 'blocks' => array(4761 'core/post-terms' => array(4762 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--small)' ),4763 'color' => array( 'background' => 'var:preset|color|secondary' ),4764 ),4765 'core/navigation' => array(4766 'elements' => array(4767 'link' => array(4768 'color' => array(4769 'background' => 'var:preset|color|p',4770 'text' => 'var(--wp--preset--color--s)',4771 ),4772 ),4773 ),4774 ),4775 'core/quote' => array(4776 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--d)' ),4777 'color' => array( 'background' => 'var:preset|color|d' ),4778 'variations' => array(4779 'plain' => array(4780 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--s)' ),4781 'color' => array( 'background' => 'var:preset|color|s' ),4782 ),4783 ),4784 ),4785 ),4786 ),4787 )4788 );4789 $styles = $result->get_raw_data()['styles'];4790 4791 $this->assertEquals( 'var(--wp--preset--color--primary)', $styles['color']['background'], 'Top level: Assert the originally correct values are still correct.' );4792 $this->assertEquals( 'var(--wp--preset--color--secondary)', $styles['color']['text'], 'Top level: Assert the originally correct values are still correct.' );4793 4794 $this->assertEquals( 'var(--wp--preset--color--pri)', $styles['elements']['link']['color']['background'], 'Element top level: Assert the originally correct values are still correct.' );4795 $this->assertEquals( 'var(--wp--preset--color--sec)', $styles['elements']['link']['color']['text'], 'Element top level: Assert the originally correct values are still correct.' );4796 4797 $this->assertEquals( 'var(--wp--preset--font-size--small)', $styles['blocks']['core/post-terms']['typography']['fontSize'], 'Top block level: Assert the originally correct values are still correct.' );4798 $this->assertEquals( 'var(--wp--preset--color--secondary)', $styles['blocks']['core/post-terms']['color']['background'], 'Top block level: Assert the internal variables are convert to CSS custom variables.' );4799 4800 $this->assertEquals( 'var(--wp--preset--color--p)', $styles['blocks']['core/navigation']['elements']['link']['color']['background'], 'Elements block level: Assert the originally correct values are still correct.' );4801 $this->assertEquals( 'var(--wp--preset--color--s)', $styles['blocks']['core/navigation']['elements']['link']['color']['text'], 'Elements block level: Assert the originally correct values are still correct.' );4802 4803 $this->assertEquals( 'var(--wp--preset--font-size--s)', $styles['blocks']['core/quote']['variations']['plain']['typography']['fontSize'], 'Style variations: Assert the originally correct values are still correct.' );4804 $this->assertEquals( 'var(--wp--preset--color--s)', $styles['blocks']['core/quote']['variations']['plain']['color']['background'], 'Style variations: Assert the internal variables are convert to CSS custom variables.' );4805 }4806 4807 public function test_resolve_variables() {4808 $primary_color = '#9DFF20';4809 $secondary_color = '#9DFF21';4810 $contrast_color = '#000';4811 $raw_color_value = '#efefef';4812 $large_font = '18px';4813 $small_font = '12px';4814 $theme_json = new WP_Theme_JSON(4815 array(4816 'version' => WP_Theme_JSON::LATEST_SCHEMA,4817 'settings' => array(4818 'color' => array(4819 'palette' => array(4820 'theme' => array(4821 array(4822 'color' => $primary_color,4823 'name' => 'Primary',4824 'slug' => 'primary',4825 ),4826 array(4827 'color' => $secondary_color,4828 'name' => 'Secondary',4829 'slug' => 'secondary',4830 ),4831 array(4832 'color' => $contrast_color,4833 'name' => 'Contrast',4834 'slug' => 'contrast',4835 ),4836 ),4837 ),4838 ),4839 'typography' => array(4840 'fontSizes' => array(4841 array(4842 'size' => $small_font,4843 'name' => 'Font size small',4844 'slug' => 'small',4845 ),4846 array(4847 'size' => $large_font,4848 'name' => 'Font size large',4849 'slug' => 'large',4850 ),4851 ),4852 ),4853 ),4854 'styles' => array(4855 'color' => array(4856 'background' => 'var(--wp--preset--color--primary)',4857 'text' => $raw_color_value,4858 ),4859 'elements' => array(4860 'button' => array(4861 'color' => array(4862 'text' => 'var(--wp--preset--color--contrast)',4863 ),4864 'typography' => array(4865 'fontSize' => 'var(--wp--preset--font-size--small)',4866 ),4867 ),4868 ),4869 'blocks' => array(4870 'core/post-terms' => array(4871 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--small)' ),4872 'color' => array( 'background' => $raw_color_value ),4873 ),4874 'core/more' => array(4875 'typography' => array( 'fontSize' => 'var(--undefined--font-size--small)' ),4876 'color' => array( 'background' => 'linear-gradient(90deg, var(--wp--preset--color--primary) 0%, var(--wp--preset--color--secondary) 35%, var(--wp--undefined--color--secondary) 100%)' ),4877 ),4878 'core/comment-content' => array(4879 'typography' => array( 'fontSize' => 'calc(var(--wp--preset--font-size--small, 12px) + 20px)' ),4880 'color' => array(4881 'text' => 'var(--wp--preset--color--primary, red)',4882 'background' => 'var(--wp--preset--color--primary, var(--wp--preset--font-size--secondary))',4883 'link' => 'var(--undefined--color--primary, var(--wp--preset--font-size--secondary))',4884 ),4885 ),4886 'core/comments' => array(4887 'color' => array(4888 'text' => 'var(--undefined--color--primary, var(--wp--preset--font-size--small))',4889 'background' => 'var(--wp--preset--color--primary, var(--undefined--color--primary))',4890 ),4891 ),4892 'core/navigation' => array(4893 'elements' => array(4894 'link' => array(4895 'color' => array(4896 'background' => 'var(--wp--preset--color--primary)',4897 'text' => 'var(--wp--preset--color--secondary)',4898 ),4899 'typography' => array(4900 'fontSize' => 'var(--wp--preset--font-size--large)',4901 ),4902 ),4903 ),4904 ),4905 'core/quote' => array(4906 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--large)' ),4907 'color' => array( 'background' => 'var(--wp--preset--color--primary)' ),4908 'variations' => array(4909 'plain' => array(4910 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--small)' ),4911 'color' => array( 'background' => 'var(--wp--preset--color--secondary)' ),4912 ),4913 ),4914 ),4915 ),4916 ),4917 )4918 );4919 4920 $styles = $theme_json::resolve_variables( $theme_json )->get_raw_data()['styles'];4921 4922 $this->assertEquals( $primary_color, $styles['color']['background'], 'Top level: Assert values are converted' );4923 $this->assertEquals( $raw_color_value, $styles['color']['text'], 'Top level: Assert raw values stay intact' );4924 4925 $this->assertEquals( $contrast_color, $styles['elements']['button']['color']['text'], 'Elements: color' );4926 $this->assertEquals( $small_font, $styles['elements']['button']['typography']['fontSize'], 'Elements: font-size' );4927 4928 $this->assertEquals( $large_font, $styles['blocks']['core/quote']['typography']['fontSize'], 'Blocks: font-size' );4929 $this->assertEquals( $primary_color, $styles['blocks']['core/quote']['color']['background'], 'Blocks: color' );4930 $this->assertEquals( $raw_color_value, $styles['blocks']['core/post-terms']['color']['background'], 'Blocks: Raw color value stays intact' );4931 $this->assertEquals( $small_font, $styles['blocks']['core/post-terms']['typography']['fontSize'], 'Block core/post-terms: font-size' );4932 $this->assertEquals(4933 "linear-gradient(90deg, $primary_color 0%, $secondary_color 35%, var(--wp--undefined--color--secondary) 100%)",4934 $styles['blocks']['core/more']['color']['background'],4935 'Blocks: multiple colors and undefined color'4936 );4937 $this->assertEquals( 'var(--undefined--font-size--small)', $styles['blocks']['core/more']['typography']['fontSize'], 'Blocks: undefined font-size ' );4938 $this->assertEquals( "calc($small_font + 20px)", $styles['blocks']['core/comment-content']['typography']['fontSize'], 'Blocks: font-size in random place' );4939 $this->assertEquals( $primary_color, $styles['blocks']['core/comment-content']['color']['text'], 'Blocks: text color with fallback' );4940 $this->assertEquals( $primary_color, $styles['blocks']['core/comment-content']['color']['background'], 'Blocks: background color with var as fallback' );4941 $this->assertEquals( $primary_color, $styles['blocks']['core/navigation']['elements']['link']['color']['background'], 'Block element: background color' );4942 $this->assertEquals( $secondary_color, $styles['blocks']['core/navigation']['elements']['link']['color']['text'], 'Block element: text color' );4943 $this->assertEquals( $large_font, $styles['blocks']['core/navigation']['elements']['link']['typography']['fontSize'], 'Block element: font-size' );4944 4945 $this->assertEquals(4946 "var(--undefined--color--primary, $small_font)",4947 $styles['blocks']['core/comments']['color']['text'],4948 'Blocks: text color with undefined var and fallback'4949 );4950 $this->assertEquals(4951 $primary_color,4952 $styles['blocks']['core/comments']['color']['background'],4953 'Blocks: background color with variable and undefined fallback'4954 );4955 4956 $this->assertEquals( $small_font, $styles['blocks']['core/quote']['variations']['plain']['typography']['fontSize'], 'Block variations: font-size' );4957 $this->assertEquals( $secondary_color, $styles['blocks']['core/quote']['variations']['plain']['color']['background'], 'Block variations: color' );4958 }4959 4960 /**4961 * Tests that a custom root selector is correctly applied when generating a stylesheet.4962 *4963 * @ticket 603434964 */4965 public function test_get_stylesheet_custom_root_selector() {4966 $theme_json = new WP_Theme_JSON(4967 array(4968 'version' => WP_Theme_JSON::LATEST_SCHEMA,4969 'styles' => array(4970 'color' => array(4971 'text' => 'teal',4972 ),4973 ),4974 ),4975 'default'4976 );4977 4978 $options = array( 'root_selector' => '.custom' );4979 $actual = $theme_json->get_stylesheet( array( 'styles' ), null, $options );4980 4981 // Results also include root site blocks styles which hard code4982 // `body { margin: 0;}`.4983 $this->assertEquals(4984 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.custom{color: teal;}',4985 $actual4986 3982 ); 4987 3983 } … … 5123 4119 5124 4120 /** 4121 * @ticket 57583 4122 * 4123 * @dataProvider data_sanitize_with_invalid_style_variation 4124 * 4125 * @param array $theme_json_variations The theme.json variations to test. 4126 */ 4127 public function test_sanitize_with_invalid_style_variation( $theme_json_variations ) { 4128 $theme_json = new WP_Theme_JSON( 4129 array( 4130 'version' => 2, 4131 'styles' => array( 4132 'blocks' => array( 4133 'core/quote' => $theme_json_variations, 4134 ), 4135 ), 4136 ) 4137 ); 4138 4139 // Validate structure is sanitized. 4140 $sanitized_theme_json = $theme_json->get_raw_data(); 4141 $this->assertIsArray( $sanitized_theme_json, 'Sanitized theme.json is not an array data type' ); 4142 $this->assertArrayNotHasKey( 'styles', $sanitized_theme_json, 'Sanitized theme.json should not have a "styles" key' ); 4143 } 4144 4145 /** 4146 * Data provider. 4147 * 4148 * @return array 4149 */ 4150 public function data_sanitize_with_invalid_style_variation() { 4151 return array( 4152 'empty string variation' => array( 4153 array( 4154 'variations' => '', 4155 ), 4156 ), 4157 'boolean variation' => array( 4158 array( 4159 'variations' => false, 4160 ), 4161 ), 4162 ); 4163 } 4164 4165 /** 4166 * @ticket 57583 4167 * 4168 * @dataProvider data_get_styles_for_block_with_style_variations 4169 * 4170 * @param array $theme_json_variations Theme.json variations to test. 4171 * @param string $metadata_variations Style variations to test. 4172 * @param string $expected Expected results for styling. 4173 */ 4174 public function test_get_styles_for_block_with_style_variations( $theme_json_variations, $metadata_variations, $expected ) { 4175 $theme_json = new WP_Theme_JSON( 4176 array( 4177 'version' => 2, 4178 'styles' => array( 4179 'blocks' => array( 4180 'core/quote' => $theme_json_variations, 4181 ), 4182 ), 4183 ) 4184 ); 4185 4186 // Validate styles are generated properly. 4187 $metadata = array( 4188 'path' => array( 'styles', 'blocks', 'core/quote' ), 4189 'selector' => '.wp-block-quote', 4190 'variations' => $metadata_variations, 4191 ); 4192 $actual_styles = $theme_json->get_styles_for_block( $metadata ); 4193 $this->assertSame( $expected, $actual_styles ); 4194 } 4195 4196 /** 4197 * Data provider. 4198 * 4199 * @return array 4200 */ 4201 public function data_get_styles_for_block_with_style_variations() { 4202 $plain = array( 4203 'metadata' => array( 4204 'path' => array( 'styles', 'blocks', 'core/quote', 'variations', 'plain' ), 4205 'selector' => '.is-style-plain.is-style-plain.wp-block-quote', 4206 ), 4207 'styles' => '.is-style-plain.is-style-plain.wp-block-quote{background-color: hotpink;}', 4208 ); 4209 4210 return array( 4211 '1 variation with 1 invalid property' => array( 4212 'theme_json_variations' => array( 4213 'variations' => array( 4214 'plain' => array( 4215 'color' => array( 4216 'background' => 'hotpink', 4217 ), 4218 ), 4219 ), 4220 ), 4221 'metadata_variation' => array( $plain['metadata'] ), 4222 'expected' => $plain['styles'], 4223 ), 4224 '1 variation with 2 invalid properties' => array( 4225 'theme_json_variations' => array( 4226 'variations' => array( 4227 'plain' => array( 4228 'color' => array( 4229 'background' => 'hotpink', 4230 ), 4231 'invalidProperty1' => 'value1', 4232 'invalidProperty2' => 'value2', 4233 ), 4234 ), 4235 ), 4236 'metadata_variation' => array( $plain['metadata'] ), 4237 'expected' => $plain['styles'], 4238 ), 4239 ); 4240 } 4241 4242 public function test_block_style_variations() { 4243 wp_set_current_user( static::$administrator_id ); 4244 4245 $expected = array( 4246 'version' => WP_Theme_JSON::LATEST_SCHEMA, 4247 'styles' => array( 4248 'blocks' => array( 4249 'core/button' => array( 4250 'color' => array( 4251 'background' => 'blue', 4252 ), 4253 'variations' => array( 4254 'outline' => array( 4255 'color' => array( 4256 'background' => 'purple', 4257 ), 4258 ), 4259 ), 4260 ), 4261 ), 4262 ), 4263 ); 4264 4265 $actual = WP_Theme_JSON::remove_insecure_properties( $expected ); 4266 4267 $this->assertSameSetsWithIndex( $expected, $actual ); 4268 } 4269 4270 public function test_block_style_variations_with_invalid_properties() { 4271 wp_set_current_user( static::$administrator_id ); 4272 4273 $partially_invalid_variation = array( 4274 'version' => WP_Theme_JSON::LATEST_SCHEMA, 4275 'styles' => array( 4276 'blocks' => array( 4277 'core/button' => array( 4278 'color' => array( 4279 'background' => 'blue', 4280 ), 4281 'variations' => array( 4282 'outline' => array( 4283 'color' => array( 4284 'background' => 'purple', 4285 ), 4286 'invalid' => array( 4287 'value' => 'should be stripped', 4288 ), 4289 ), 4290 ), 4291 ), 4292 ), 4293 ), 4294 ); 4295 4296 $expected = array( 4297 'version' => WP_Theme_JSON::LATEST_SCHEMA, 4298 'styles' => array( 4299 'blocks' => array( 4300 'core/button' => array( 4301 'color' => array( 4302 'background' => 'blue', 4303 ), 4304 'variations' => array( 4305 'outline' => array( 4306 'color' => array( 4307 'background' => 'purple', 4308 ), 4309 ), 4310 ), 4311 ), 4312 ), 4313 ), 4314 ); 4315 4316 $actual = WP_Theme_JSON::remove_insecure_properties( $partially_invalid_variation ); 4317 4318 $this->assertSameSetsWithIndex( $expected, $actual ); 4319 } 4320 4321 /** 4322 * Tests generating the spacing presets array based on the spacing scale provided. 4323 * 4324 * @ticket 56467 4325 * 4326 * @dataProvider data_set_spacing_sizes 4327 */ 4328 public function test_set_spacing_sizes( $spacing_scale, $expected_output ) { 4329 $theme_json = new WP_Theme_JSON( 4330 array( 4331 'version' => 2, 4332 'settings' => array( 4333 'spacing' => array( 4334 'spacingScale' => $spacing_scale, 4335 ), 4336 ), 4337 ) 4338 ); 4339 4340 $theme_json->set_spacing_sizes(); 4341 $this->assertSame( $expected_output, _wp_array_get( $theme_json->get_raw_data(), array( 'settings', 'spacing', 'spacingSizes', 'default' ) ) ); 4342 } 4343 4344 /** 4345 * Data provider for spacing scale tests. 4346 * 4347 * @ticket 56467 4348 * 4349 * @return array 4350 */ 4351 public function data_set_spacing_sizes() { 4352 return array( 4353 'only one value when single step in spacing scale' => array( 4354 'spacing_scale' => array( 4355 'operator' => '+', 4356 'increment' => 1.5, 4357 'steps' => 1, 4358 'mediumStep' => 4, 4359 'unit' => 'rem', 4360 ), 4361 'expected_output' => array( 4362 array( 4363 'name' => '1', 4364 'slug' => '50', 4365 'size' => '4rem', 4366 ), 4367 ), 4368 ), 4369 'one step above medium when two steps in spacing scale' => array( 4370 'spacing_scale' => array( 4371 'operator' => '+', 4372 'increment' => 1.5, 4373 'steps' => 2, 4374 'mediumStep' => 4, 4375 'unit' => 'rem', 4376 ), 4377 'expected_output' => array( 4378 array( 4379 'name' => '1', 4380 'slug' => '50', 4381 'size' => '4rem', 4382 ), 4383 array( 4384 'name' => '2', 4385 'slug' => '60', 4386 'size' => '5.5rem', 4387 ), 4388 ), 4389 ), 4390 'one step above medium and one below when three steps in spacing scale' => array( 4391 'spacing_scale' => array( 4392 'operator' => '+', 4393 'increment' => 1.5, 4394 'steps' => 3, 4395 'mediumStep' => 4, 4396 'unit' => 'rem', 4397 ), 4398 'expected_output' => array( 4399 array( 4400 'name' => '1', 4401 'slug' => '40', 4402 'size' => '2.5rem', 4403 ), 4404 array( 4405 'name' => '2', 4406 'slug' => '50', 4407 'size' => '4rem', 4408 ), 4409 array( 4410 'name' => '3', 4411 'slug' => '60', 4412 'size' => '5.5rem', 4413 ), 4414 ), 4415 ), 4416 'extra step added above medium when an even number of steps > 2 specified' => array( 4417 'spacing_scale' => array( 4418 'operator' => '+', 4419 'increment' => 1.5, 4420 'steps' => 4, 4421 'mediumStep' => 4, 4422 'unit' => 'rem', 4423 ), 4424 'expected_output' => array( 4425 array( 4426 'name' => '1', 4427 'slug' => '40', 4428 'size' => '2.5rem', 4429 ), 4430 array( 4431 'name' => '2', 4432 'slug' => '50', 4433 'size' => '4rem', 4434 ), 4435 array( 4436 'name' => '3', 4437 'slug' => '60', 4438 'size' => '5.5rem', 4439 ), 4440 array( 4441 'name' => '4', 4442 'slug' => '70', 4443 'size' => '7rem', 4444 ), 4445 ), 4446 ), 4447 'extra steps above medium if bottom end will go below zero' => array( 4448 'spacing_scale' => array( 4449 'operator' => '+', 4450 'increment' => 2.5, 4451 'steps' => 5, 4452 'mediumStep' => 5, 4453 'unit' => 'rem', 4454 ), 4455 'expected_output' => array( 4456 array( 4457 'name' => '1', 4458 'slug' => '40', 4459 'size' => '2.5rem', 4460 ), 4461 array( 4462 'name' => '2', 4463 'slug' => '50', 4464 'size' => '5rem', 4465 ), 4466 array( 4467 'name' => '3', 4468 'slug' => '60', 4469 'size' => '7.5rem', 4470 ), 4471 array( 4472 'name' => '4', 4473 'slug' => '70', 4474 'size' => '10rem', 4475 ), 4476 array( 4477 'name' => '5', 4478 'slug' => '80', 4479 'size' => '12.5rem', 4480 ), 4481 ), 4482 ), 4483 'multiplier correctly calculated above and below medium' => array( 4484 'spacing_scale' => array( 4485 'operator' => '*', 4486 'increment' => 1.5, 4487 'steps' => 5, 4488 'mediumStep' => 1.5, 4489 'unit' => 'rem', 4490 ), 4491 'expected_output' => array( 4492 array( 4493 'name' => '1', 4494 'slug' => '30', 4495 'size' => '0.67rem', 4496 ), 4497 array( 4498 'name' => '2', 4499 'slug' => '40', 4500 'size' => '1rem', 4501 ), 4502 array( 4503 'name' => '3', 4504 'slug' => '50', 4505 'size' => '1.5rem', 4506 ), 4507 array( 4508 'name' => '4', 4509 'slug' => '60', 4510 'size' => '2.25rem', 4511 ), 4512 array( 4513 'name' => '5', 4514 'slug' => '70', 4515 'size' => '3.38rem', 4516 ), 4517 ), 4518 ), 4519 'increment < 1 combined showing * operator acting as divisor above and below medium' => array( 4520 'spacing_scale' => array( 4521 'operator' => '*', 4522 'increment' => 0.25, 4523 'steps' => 5, 4524 'mediumStep' => 1.5, 4525 'unit' => 'rem', 4526 ), 4527 'expected_output' => array( 4528 array( 4529 'name' => '1', 4530 'slug' => '30', 4531 'size' => '0.09rem', 4532 ), 4533 array( 4534 'name' => '2', 4535 'slug' => '40', 4536 'size' => '0.38rem', 4537 ), 4538 array( 4539 'name' => '3', 4540 'slug' => '50', 4541 'size' => '1.5rem', 4542 ), 4543 array( 4544 'name' => '4', 4545 'slug' => '60', 4546 'size' => '6rem', 4547 ), 4548 array( 4549 'name' => '5', 4550 'slug' => '70', 4551 'size' => '24rem', 4552 ), 4553 ), 4554 ), 4555 't-shirt sizing used if more than 7 steps in scale' => array( 4556 'spacing_scale' => array( 4557 'operator' => '*', 4558 'increment' => 1.5, 4559 'steps' => 8, 4560 'mediumStep' => 1.5, 4561 'unit' => 'rem', 4562 ), 4563 'expected_output' => array( 4564 array( 4565 'name' => '2X-Small', 4566 'slug' => '20', 4567 'size' => '0.44rem', 4568 ), 4569 array( 4570 'name' => 'X-Small', 4571 'slug' => '30', 4572 'size' => '0.67rem', 4573 ), 4574 array( 4575 'name' => 'Small', 4576 'slug' => '40', 4577 'size' => '1rem', 4578 ), 4579 array( 4580 'name' => 'Medium', 4581 'slug' => '50', 4582 'size' => '1.5rem', 4583 ), 4584 array( 4585 'name' => 'Large', 4586 'slug' => '60', 4587 'size' => '2.25rem', 4588 ), 4589 array( 4590 'name' => 'X-Large', 4591 'slug' => '70', 4592 'size' => '3.38rem', 4593 ), 4594 array( 4595 'name' => '2X-Large', 4596 'slug' => '80', 4597 'size' => '5.06rem', 4598 ), 4599 array( 4600 'name' => '3X-Large', 4601 'slug' => '90', 4602 'size' => '7.59rem', 4603 ), 4604 ), 4605 ), 4606 ); 4607 } 4608 4609 /** 4610 * Tests generating the spacing presets array based on the spacing scale provided. 4611 * 4612 * @ticket 56467 4613 * 4614 * @dataProvider data_set_spacing_sizes_when_invalid 4615 * 4616 * @param array $spacing_scale Example spacing scale definitions from the data provider. 4617 * @param array $expected_output Expected output from data provider. 4618 */ 4619 public function test_set_spacing_sizes_when_invalid( $spacing_scale, $expected_output ) { 4620 $this->expectException( Exception::class ); 4621 $this->expectExceptionMessage( 'Some of the theme.json settings.spacing.spacingScale values are invalid' ); 4622 4623 $theme_json = new WP_Theme_JSON( 4624 array( 4625 'version' => 2, 4626 'settings' => array( 4627 'spacing' => array( 4628 'spacingScale' => $spacing_scale, 4629 ), 4630 ), 4631 ) 4632 ); 4633 4634 // Ensure PHPUnit 10 compatibility. 4635 set_error_handler( 4636 static function ( $errno, $errstr ) { 4637 restore_error_handler(); 4638 throw new Exception( $errstr, $errno ); 4639 }, 4640 E_ALL 4641 ); 4642 4643 $theme_json->set_spacing_sizes(); 4644 4645 restore_error_handler(); 4646 4647 $this->assertSame( $expected_output, _wp_array_get( $theme_json->get_raw_data(), array( 'settings', 'spacing', 'spacingSizes', 'default' ) ) ); 4648 } 4649 4650 /** 4651 * Data provider for spacing scale tests. 4652 * 4653 * @ticket 56467 4654 * 4655 * @return array 4656 */ 4657 public function data_set_spacing_sizes_when_invalid() { 4658 return array( 4659 'missing operator value' => array( 4660 'spacing_scale' => array( 4661 'operator' => '', 4662 'increment' => 1.5, 4663 'steps' => 1, 4664 'mediumStep' => 4, 4665 'unit' => 'rem', 4666 ), 4667 'expected_output' => null, 4668 ), 4669 'non numeric increment' => array( 4670 'spacing_scale' => array( 4671 'operator' => '+', 4672 'increment' => 'add two to previous value', 4673 'steps' => 1, 4674 'mediumStep' => 4, 4675 'unit' => 'rem', 4676 ), 4677 'expected_output' => null, 4678 ), 4679 'non numeric steps' => array( 4680 'spacing_scale' => array( 4681 'operator' => '+', 4682 'increment' => 1.5, 4683 'steps' => 'spiral staircase preferred', 4684 'mediumStep' => 4, 4685 'unit' => 'rem', 4686 ), 4687 'expected_output' => null, 4688 ), 4689 'non numeric medium step' => array( 4690 'spacing_scale' => array( 4691 'operator' => '+', 4692 'increment' => 1.5, 4693 'steps' => 5, 4694 'mediumStep' => 'That which is just right', 4695 'unit' => 'rem', 4696 ), 4697 'expected_output' => null, 4698 ), 4699 'missing unit value' => array( 4700 'spacing_scale' => array( 4701 'operator' => '+', 4702 'increment' => 1.5, 4703 'steps' => 5, 4704 'mediumStep' => 4, 4705 ), 4706 'expected_output' => null, 4707 ), 4708 ); 4709 } 4710 4711 /** 4712 * Tests the core separator block outbut based on various provided settings. 4713 * 4714 * @ticket 56903 4715 * @ticket 58550 4716 * 4717 * @dataProvider data_update_separator_declarations 4718 * 4719 * @param array $separator_block_settings Example separator block settings from the data provider. 4720 * @param array $expected_output Expected output from data provider. 4721 */ 4722 public function test_update_separator_declarations( $separator_block_settings, $expected_output ) { 4723 // If only background is defined, test that includes border-color to the style so it is applied on the front end. 4724 $theme_json = new WP_Theme_JSON( 4725 array( 4726 'version' => WP_Theme_JSON::LATEST_SCHEMA, 4727 'styles' => array( 4728 'blocks' => array( 4729 'core/separator' => $separator_block_settings, 4730 ), 4731 ), 4732 ), 4733 'default' 4734 ); 4735 4736 $stylesheet = $theme_json->get_stylesheet( array( 'styles' ) ); 4737 4738 $this->assertSame( $expected_output, $stylesheet ); 4739 } 4740 4741 /** 4742 * Data provider for separator declaration tests. 4743 * 4744 * @return array 4745 */ 4746 public function data_update_separator_declarations() { 4747 return array( 4748 // If only background is defined, test that includes border-color to the style so it is applied on the front end. 4749 'only background' => array( 4750 array( 4751 'color' => array( 4752 'background' => 'blue', 4753 ), 4754 ), 4755 'expected_output' => 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-separator{background-color: blue;color: blue;}', 4756 ), 4757 // If background and text are defined, do not include border-color, as text color is enough. 4758 'background and text, no border-color' => array( 4759 array( 4760 'color' => array( 4761 'background' => 'blue', 4762 'text' => 'red', 4763 ), 4764 ), 4765 'expected_output' => 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-separator{background-color: blue;color: red;}', 4766 ), 4767 // If only text is defined, do not include border-color, as by itself is enough. 4768 'only text' => array( 4769 array( 4770 'color' => array( 4771 'text' => 'red', 4772 ), 4773 ), 4774 'expected_output' => 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-separator{color: red;}', 4775 ), 4776 // If background, text, and border-color are defined, include everything, CSS specificity will decide which to apply. 4777 'background, text, and border-color' => array( 4778 array( 4779 'color' => array( 4780 'background' => 'blue', 4781 'text' => 'red', 4782 ), 4783 'border' => array( 4784 'color' => 'pink', 4785 ), 4786 ), 4787 'expected_output' => 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-separator{background-color: blue;border-color: pink;color: red;}', 4788 ), 4789 // If background and border color are defined, include everything, CSS specificity will decide which to apply. 4790 'background, and border-color' => array( 4791 array( 4792 'color' => array( 4793 'background' => 'blue', 4794 ), 4795 'border' => array( 4796 'color' => 'pink', 4797 ), 4798 ), 4799 'expected_output' => 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}.wp-block-separator{background-color: blue;border-color: pink;}', 4800 ), 4801 ); 4802 } 4803 4804 /** 4805 * @ticket 57559 4806 */ 4807 public function test_shadow_preset_styles() { 4808 $theme_json = new WP_Theme_JSON( 4809 array( 4810 'version' => WP_Theme_JSON::LATEST_SCHEMA, 4811 'settings' => array( 4812 'shadow' => array( 4813 'presets' => array( 4814 array( 4815 'slug' => 'natural', 4816 'shadow' => '5px 5px 5px 0 black', 4817 ), 4818 array( 4819 'slug' => 'sharp', 4820 'shadow' => '5px 5px black', 4821 ), 4822 ), 4823 ), 4824 ), 4825 ) 4826 ); 4827 4828 $expected_styles = 'body{--wp--preset--shadow--natural: 5px 5px 5px 0 black;--wp--preset--shadow--sharp: 5px 5px black;}'; 4829 $this->assertSame( $expected_styles, $theme_json->get_stylesheet(), 'Styles returned from "::get_stylesheet()" does not match expectations' ); 4830 $this->assertSame( $expected_styles, $theme_json->get_stylesheet( array( 'variables' ) ), 'Styles returned from "::get_stylesheet()" when requiring "variables" type does not match expectations' ); 4831 } 4832 4833 /** 4834 * @ticket 57559 4835 * @ticket 58550 4836 */ 4837 public function test_get_shadow_styles_for_blocks() { 4838 $theme_json = new WP_Theme_JSON( 4839 array( 4840 'version' => WP_Theme_JSON::LATEST_SCHEMA, 4841 'settings' => array( 4842 'shadow' => array( 4843 'presets' => array( 4844 array( 4845 'slug' => 'natural', 4846 'shadow' => '5px 5px 0 0 black', 4847 ), 4848 ), 4849 ), 4850 ), 4851 'styles' => array( 4852 'blocks' => array( 4853 'core/paragraph' => array( 4854 'shadow' => 'var(--wp--preset--shadow--natural)', 4855 ), 4856 ), 4857 'elements' => array( 4858 'button' => array( 4859 'shadow' => 'var:preset|shadow|natural', 4860 ), 4861 'link' => array( 4862 'shadow' => array( 'ref' => 'styles.elements.button.shadow' ), 4863 ), 4864 ), 4865 ), 4866 ) 4867 ); 4868 4869 $global_styles = 'body{--wp--preset--shadow--natural: 5px 5px 0 0 black;}body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}'; 4870 $element_styles = 'a:where(:not(.wp-element-button)){box-shadow: var(--wp--preset--shadow--natural);}.wp-element-button, .wp-block-button__link{box-shadow: var(--wp--preset--shadow--natural);}p{box-shadow: var(--wp--preset--shadow--natural);}'; 4871 $expected_styles = $global_styles . $element_styles; 4872 $this->assertSame( $expected_styles, $theme_json->get_stylesheet() ); 4873 } 4874 4875 /** 4876 * @ticket 57536 4877 */ 4878 public function test_get_custom_css_handles_global_custom_css() { 4879 $theme_json = new WP_Theme_JSON( 4880 array( 4881 'version' => WP_Theme_JSON::LATEST_SCHEMA, 4882 'styles' => array( 4883 'css' => 'body {color:purple;}', 4884 'blocks' => array( 4885 'core/paragraph' => array( 4886 'css' => 'color:red;', 4887 ), 4888 ), 4889 ), 4890 ) 4891 ); 4892 4893 $custom_css = 'body {color:purple;}p{color:red;}'; 4894 $this->assertSame( $custom_css, $theme_json->get_custom_css() ); 4895 } 4896 4897 /** 4898 * Tests that custom CSS is kept for users with correct capabilities and removed for others. 4899 * 4900 * @ticket 57536 4901 * 4902 * @dataProvider data_custom_css_for_user_caps 4903 * 4904 * @param string $user_property The property name for current user. 4905 * @param array $expected Expected results. 4906 */ 4907 public function test_custom_css_for_user_caps( $user_property, array $expected ) { 4908 wp_set_current_user( static::${$user_property} ); 4909 4910 $actual = WP_Theme_JSON::remove_insecure_properties( 4911 array( 4912 'version' => WP_Theme_JSON::LATEST_SCHEMA, 4913 'styles' => array( 4914 'css' => 'body { color:purple; }', 4915 'blocks' => array( 4916 'core/separator' => array( 4917 'color' => array( 4918 'background' => 'blue', 4919 ), 4920 ), 4921 ), 4922 ), 4923 ) 4924 ); 4925 4926 $this->assertSameSetsWithIndex( $expected, $actual ); 4927 } 4928 4929 /** 4930 * Data provider. 4931 * 4932 * @return array[] 4933 */ 4934 public function data_custom_css_for_user_caps() { 4935 return array( 4936 'allows custom css for users with caps' => array( 4937 'user_property' => 'administrator_id', 4938 'expected' => array( 4939 'version' => WP_Theme_JSON::LATEST_SCHEMA, 4940 'styles' => array( 4941 'css' => 'body { color:purple; }', 4942 'blocks' => array( 4943 'core/separator' => array( 4944 'color' => array( 4945 'background' => 'blue', 4946 ), 4947 ), 4948 ), 4949 ), 4950 ), 4951 ), 4952 'removes custom css for users without caps' => array( 4953 'user_property' => 'user_id', 4954 'expected' => array( 4955 'version' => WP_Theme_JSON::LATEST_SCHEMA, 4956 'styles' => array( 4957 'blocks' => array( 4958 'core/separator' => array( 4959 'color' => array( 4960 'background' => 'blue', 4961 ), 4962 ), 4963 ), 4964 ), 4965 ), 4966 ), 4967 ); 4968 } 4969 4970 /** 4971 * @dataProvider data_process_blocks_custom_css 4972 * 4973 * @param array $input An array containing the selector and css to test. 4974 * @param string $expected Expected results. 4975 */ 4976 public function test_process_blocks_custom_css( $input, $expected ) { 4977 $theme_json = new WP_Theme_JSON( 4978 array( 4979 'version' => WP_Theme_JSON::LATEST_SCHEMA, 4980 'styles' => array(), 4981 ) 4982 ); 4983 $reflection = new ReflectionMethod( $theme_json, 'process_blocks_custom_css' ); 4984 $reflection->setAccessible( true ); 4985 4986 $this->assertSame( $expected, $reflection->invoke( $theme_json, $input['css'], $input['selector'] ) ); 4987 } 4988 4989 /** 4990 * Data provider. 4991 * 4992 * @return array[] 4993 */ 4994 public function data_process_blocks_custom_css() { 4995 return array( 4996 // Simple CSS without any nested selectors. 4997 'no nested selectors' => array( 4998 'input' => array( 4999 'selector' => '.foo', 5000 'css' => 'color: red; margin: auto;', 5001 ), 5002 'expected' => '.foo{color: red; margin: auto;}', 5003 ), 5004 // CSS with nested selectors. 5005 'with nested selector' => array( 5006 'input' => array( 5007 'selector' => '.foo', 5008 'css' => 'color: red; margin: auto; &.one{color: blue;} & .two{color: green;}', 5009 ), 5010 'expected' => '.foo{color: red; margin: auto;}.foo.one{color: blue;}.foo .two{color: green;}', 5011 ), 5012 // CSS with pseudo elements. 5013 'with pseudo elements' => array( 5014 'input' => array( 5015 'selector' => '.foo', 5016 'css' => 'color: red; margin: auto; &::before{color: blue;} & ::before{color: green;} &.one::before{color: yellow;} & .two::before{color: purple;}', 5017 ), 5018 'expected' => '.foo{color: red; margin: auto;}.foo::before{color: blue;}.foo ::before{color: green;}.foo.one::before{color: yellow;}.foo .two::before{color: purple;}', 5019 ), 5020 // CSS with multiple root selectors. 5021 'with multiple root selectors' => array( 5022 'input' => array( 5023 'selector' => '.foo, .bar', 5024 'css' => 'color: red; margin: auto; &.one{color: blue;} & .two{color: green;} &::before{color: yellow;} & ::before{color: purple;} &.three::before{color: orange;} & .four::before{color: skyblue;}', 5025 ), 5026 'expected' => '.foo, .bar{color: red; margin: auto;}.foo.one, .bar.one{color: blue;}.foo .two, .bar .two{color: green;}.foo::before, .bar::before{color: yellow;}.foo ::before, .bar ::before{color: purple;}.foo.three::before, .bar.three::before{color: orange;}.foo .four::before, .bar .four::before{color: skyblue;}', 5027 ), 5028 ); 5029 } 5030 5031 public function test_internal_syntax_is_converted_to_css_variables() { 5032 $result = new WP_Theme_JSON( 5033 array( 5034 'version' => WP_Theme_JSON::LATEST_SCHEMA, 5035 'styles' => array( 5036 'color' => array( 5037 'background' => 'var:preset|color|primary', 5038 'text' => 'var(--wp--preset--color--secondary)', 5039 ), 5040 'elements' => array( 5041 'link' => array( 5042 'color' => array( 5043 'background' => 'var:preset|color|pri', 5044 'text' => 'var(--wp--preset--color--sec)', 5045 ), 5046 ), 5047 ), 5048 'blocks' => array( 5049 'core/post-terms' => array( 5050 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--small)' ), 5051 'color' => array( 'background' => 'var:preset|color|secondary' ), 5052 ), 5053 'core/navigation' => array( 5054 'elements' => array( 5055 'link' => array( 5056 'color' => array( 5057 'background' => 'var:preset|color|p', 5058 'text' => 'var(--wp--preset--color--s)', 5059 ), 5060 ), 5061 ), 5062 ), 5063 'core/quote' => array( 5064 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--d)' ), 5065 'color' => array( 'background' => 'var:preset|color|d' ), 5066 'variations' => array( 5067 'plain' => array( 5068 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--s)' ), 5069 'color' => array( 'background' => 'var:preset|color|s' ), 5070 ), 5071 ), 5072 ), 5073 ), 5074 ), 5075 ) 5076 ); 5077 $styles = $result->get_raw_data()['styles']; 5078 5079 $this->assertEquals( 'var(--wp--preset--color--primary)', $styles['color']['background'], 'Top level: Assert the originally correct values are still correct.' ); 5080 $this->assertEquals( 'var(--wp--preset--color--secondary)', $styles['color']['text'], 'Top level: Assert the originally correct values are still correct.' ); 5081 5082 $this->assertEquals( 'var(--wp--preset--color--pri)', $styles['elements']['link']['color']['background'], 'Element top level: Assert the originally correct values are still correct.' ); 5083 $this->assertEquals( 'var(--wp--preset--color--sec)', $styles['elements']['link']['color']['text'], 'Element top level: Assert the originally correct values are still correct.' ); 5084 5085 $this->assertEquals( 'var(--wp--preset--font-size--small)', $styles['blocks']['core/post-terms']['typography']['fontSize'], 'Top block level: Assert the originally correct values are still correct.' ); 5086 $this->assertEquals( 'var(--wp--preset--color--secondary)', $styles['blocks']['core/post-terms']['color']['background'], 'Top block level: Assert the internal variables are convert to CSS custom variables.' ); 5087 5088 $this->assertEquals( 'var(--wp--preset--color--p)', $styles['blocks']['core/navigation']['elements']['link']['color']['background'], 'Elements block level: Assert the originally correct values are still correct.' ); 5089 $this->assertEquals( 'var(--wp--preset--color--s)', $styles['blocks']['core/navigation']['elements']['link']['color']['text'], 'Elements block level: Assert the originally correct values are still correct.' ); 5090 5091 $this->assertEquals( 'var(--wp--preset--font-size--s)', $styles['blocks']['core/quote']['variations']['plain']['typography']['fontSize'], 'Style variations: Assert the originally correct values are still correct.' ); 5092 $this->assertEquals( 'var(--wp--preset--color--s)', $styles['blocks']['core/quote']['variations']['plain']['color']['background'], 'Style variations: Assert the internal variables are convert to CSS custom variables.' ); 5093 } 5094 5095 public function test_resolve_variables() { 5096 $primary_color = '#9DFF20'; 5097 $secondary_color = '#9DFF21'; 5098 $contrast_color = '#000'; 5099 $raw_color_value = '#efefef'; 5100 $large_font = '18px'; 5101 $small_font = '12px'; 5102 $theme_json = new WP_Theme_JSON( 5103 array( 5104 'version' => WP_Theme_JSON::LATEST_SCHEMA, 5105 'settings' => array( 5106 'color' => array( 5107 'palette' => array( 5108 'theme' => array( 5109 array( 5110 'color' => $primary_color, 5111 'name' => 'Primary', 5112 'slug' => 'primary', 5113 ), 5114 array( 5115 'color' => $secondary_color, 5116 'name' => 'Secondary', 5117 'slug' => 'secondary', 5118 ), 5119 array( 5120 'color' => $contrast_color, 5121 'name' => 'Contrast', 5122 'slug' => 'contrast', 5123 ), 5124 ), 5125 ), 5126 ), 5127 'typography' => array( 5128 'fontSizes' => array( 5129 array( 5130 'size' => $small_font, 5131 'name' => 'Font size small', 5132 'slug' => 'small', 5133 ), 5134 array( 5135 'size' => $large_font, 5136 'name' => 'Font size large', 5137 'slug' => 'large', 5138 ), 5139 ), 5140 ), 5141 ), 5142 'styles' => array( 5143 'color' => array( 5144 'background' => 'var(--wp--preset--color--primary)', 5145 'text' => $raw_color_value, 5146 ), 5147 'elements' => array( 5148 'button' => array( 5149 'color' => array( 5150 'text' => 'var(--wp--preset--color--contrast)', 5151 ), 5152 'typography' => array( 5153 'fontSize' => 'var(--wp--preset--font-size--small)', 5154 ), 5155 ), 5156 ), 5157 'blocks' => array( 5158 'core/post-terms' => array( 5159 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--small)' ), 5160 'color' => array( 'background' => $raw_color_value ), 5161 ), 5162 'core/more' => array( 5163 'typography' => array( 'fontSize' => 'var(--undefined--font-size--small)' ), 5164 'color' => array( 'background' => 'linear-gradient(90deg, var(--wp--preset--color--primary) 0%, var(--wp--preset--color--secondary) 35%, var(--wp--undefined--color--secondary) 100%)' ), 5165 ), 5166 'core/comment-content' => array( 5167 'typography' => array( 'fontSize' => 'calc(var(--wp--preset--font-size--small, 12px) + 20px)' ), 5168 'color' => array( 5169 'text' => 'var(--wp--preset--color--primary, red)', 5170 'background' => 'var(--wp--preset--color--primary, var(--wp--preset--font-size--secondary))', 5171 'link' => 'var(--undefined--color--primary, var(--wp--preset--font-size--secondary))', 5172 ), 5173 ), 5174 'core/comments' => array( 5175 'color' => array( 5176 'text' => 'var(--undefined--color--primary, var(--wp--preset--font-size--small))', 5177 'background' => 'var(--wp--preset--color--primary, var(--undefined--color--primary))', 5178 ), 5179 ), 5180 'core/navigation' => array( 5181 'elements' => array( 5182 'link' => array( 5183 'color' => array( 5184 'background' => 'var(--wp--preset--color--primary)', 5185 'text' => 'var(--wp--preset--color--secondary)', 5186 ), 5187 'typography' => array( 5188 'fontSize' => 'var(--wp--preset--font-size--large)', 5189 ), 5190 ), 5191 ), 5192 ), 5193 'core/quote' => array( 5194 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--large)' ), 5195 'color' => array( 'background' => 'var(--wp--preset--color--primary)' ), 5196 'variations' => array( 5197 'plain' => array( 5198 'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--small)' ), 5199 'color' => array( 'background' => 'var(--wp--preset--color--secondary)' ), 5200 ), 5201 ), 5202 ), 5203 ), 5204 ), 5205 ) 5206 ); 5207 5208 $styles = $theme_json::resolve_variables( $theme_json )->get_raw_data()['styles']; 5209 5210 $this->assertEquals( $primary_color, $styles['color']['background'], 'Top level: Assert values are converted' ); 5211 $this->assertEquals( $raw_color_value, $styles['color']['text'], 'Top level: Assert raw values stay intact' ); 5212 5213 $this->assertEquals( $contrast_color, $styles['elements']['button']['color']['text'], 'Elements: color' ); 5214 $this->assertEquals( $small_font, $styles['elements']['button']['typography']['fontSize'], 'Elements: font-size' ); 5215 5216 $this->assertEquals( $large_font, $styles['blocks']['core/quote']['typography']['fontSize'], 'Blocks: font-size' ); 5217 $this->assertEquals( $primary_color, $styles['blocks']['core/quote']['color']['background'], 'Blocks: color' ); 5218 $this->assertEquals( $raw_color_value, $styles['blocks']['core/post-terms']['color']['background'], 'Blocks: Raw color value stays intact' ); 5219 $this->assertEquals( $small_font, $styles['blocks']['core/post-terms']['typography']['fontSize'], 'Block core/post-terms: font-size' ); 5220 $this->assertEquals( 5221 "linear-gradient(90deg, $primary_color 0%, $secondary_color 35%, var(--wp--undefined--color--secondary) 100%)", 5222 $styles['blocks']['core/more']['color']['background'], 5223 'Blocks: multiple colors and undefined color' 5224 ); 5225 $this->assertEquals( 'var(--undefined--font-size--small)', $styles['blocks']['core/more']['typography']['fontSize'], 'Blocks: undefined font-size ' ); 5226 $this->assertEquals( "calc($small_font + 20px)", $styles['blocks']['core/comment-content']['typography']['fontSize'], 'Blocks: font-size in random place' ); 5227 $this->assertEquals( $primary_color, $styles['blocks']['core/comment-content']['color']['text'], 'Blocks: text color with fallback' ); 5228 $this->assertEquals( $primary_color, $styles['blocks']['core/comment-content']['color']['background'], 'Blocks: background color with var as fallback' ); 5229 $this->assertEquals( $primary_color, $styles['blocks']['core/navigation']['elements']['link']['color']['background'], 'Block element: background color' ); 5230 $this->assertEquals( $secondary_color, $styles['blocks']['core/navigation']['elements']['link']['color']['text'], 'Block element: text color' ); 5231 $this->assertEquals( $large_font, $styles['blocks']['core/navigation']['elements']['link']['typography']['fontSize'], 'Block element: font-size' ); 5232 5233 $this->assertEquals( 5234 "var(--undefined--color--primary, $small_font)", 5235 $styles['blocks']['core/comments']['color']['text'], 5236 'Blocks: text color with undefined var and fallback' 5237 ); 5238 $this->assertEquals( 5239 $primary_color, 5240 $styles['blocks']['core/comments']['color']['background'], 5241 'Blocks: background color with variable and undefined fallback' 5242 ); 5243 5244 $this->assertEquals( $small_font, $styles['blocks']['core/quote']['variations']['plain']['typography']['fontSize'], 'Block variations: font-size' ); 5245 $this->assertEquals( $secondary_color, $styles['blocks']['core/quote']['variations']['plain']['color']['background'], 'Block variations: color' ); 5246 } 5247 5248 /** 5125 5249 * Tests the correct application of a block style variation's selector to 5126 5250 * a block's selector. -
trunk/tests/phpunit/tests/theme/wpThemeJsonResolver.php
r57260 r57662 21 21 22 22 /** 23 * WP_Theme_JSON_Resolver::$blocks_cache property. 24 * 25 * @var ReflectionProperty 26 */ 27 private static $property_blocks_cache; 28 29 /** 30 * Original value of the WP_Theme_JSON_Resolver::$blocks_cache property. 31 * 32 * @var array 33 */ 34 private static $property_blocks_cache_orig_value; 35 36 /** 37 * WP_Theme_JSON_Resolver::$core property. 38 * 39 * @var ReflectionProperty 40 */ 41 private static $property_core; 42 43 /** 44 * Original value of the WP_Theme_JSON_Resolver::$core property. 45 * 46 * @var WP_Theme_JSON 47 */ 48 private static $property_core_orig_value; 49 50 /** 23 51 * Theme root directory. 24 52 * 25 * @var string 53 * @var string|null 26 54 */ 27 55 private $theme_root; … … 30 58 * Original theme directory. 31 59 * 32 * @var string60 * @var array|null 33 61 */ 34 62 private $orig_theme_dir; 35 63 36 64 /** 37 * WP_Theme_JSON_Resolver::$blocks_cache property. 38 * 39 * @var ReflectionProperty 40 */ 41 private static $property_blocks_cache; 42 43 /** 44 * Original value of the WP_Theme_JSON_Resolver::$blocks_cache property. 45 * 46 * @var array 47 */ 48 private static $property_blocks_cache_orig_value; 49 50 /** 51 * WP_Theme_JSON_Resolver::$core property. 52 * 53 * @var ReflectionProperty 54 */ 55 private static $property_core; 56 57 /** 58 * Original value of the WP_Theme_JSON_Resolver::$core property. 59 * 60 * @var WP_Theme_JSON 61 */ 62 private static $property_core_orig_value; 65 * @var array|null 66 */ 67 private $queries; 63 68 64 69 public static function set_up_before_class() { … … 99 104 add_filter( 'stylesheet_root', array( $this, 'filter_set_theme_root' ) ); 100 105 add_filter( 'template_root', array( $this, 'filter_set_theme_root' ) ); 101 106 $this->queries = array(); 102 107 // Clear caches. 103 108 wp_clean_themes_cache(); … … 141 146 $this->assertSame( 'block-theme', wp_get_theme()->get( 'TextDomain' ) ); 142 147 $this->assertSame( 'Motyw blokowy', $theme_data->get_data()['title'] ); 143 $this->assertSame Sets(148 $this->assertSame( 144 149 array( 145 150 'color' => array( … … 219 224 $this->assertArrayHasKey( 'page-home', $custom_templates ); 220 225 $this->assertSame( 221 $custom_templates['page-home'],222 226 array( 223 227 'title' => 'Szablon strony głównej', 224 228 'postTypes' => array( 'page' ), 225 ) 226 ); 229 ), 230 $custom_templates['page-home'] 231 ); 232 227 233 $this->assertSameSets( 228 234 array( … … 234 240 $theme_data->get_template_parts() 235 241 ); 242 236 243 $this->assertSame( 237 244 'Wariant motywu blokowego', 238 $style_variations[ 1]['title']245 $style_variations[2]['title'] 239 246 ); 240 247 } … … 258 265 259 266 /** 260 * Tests when WP_Theme_JSON_Resolver::$blocks_cache is empty or does not match261 * the all registered blocks.267 * Tests when WP_Theme_JSON_Resolver::$blocks_cache is empty or 268 * does not match the all registered blocks. 262 269 * 263 270 * Though this is a non-public method, it is vital to other functionality. … … 332 339 333 340 /** 334 * Tests when WP_Theme_JSON_Resolver::$blocks_cache is empty or does not match335 * the all registered blocks.341 * Tests when WP_Theme_JSON_Resolver::$blocks_cache is empty or 342 * does not match the all registered blocks. 336 343 * 337 344 * Though this is a non-public method, it is vital to other functionality. … … 597 604 598 605 $this->assertSame( 599 WP_Theme_JSON_Resolver::get_theme_data()->get_custom_templates(),600 606 array( 601 607 'page-home' => array( … … 607 613 'postTypes' => array( 'post' ), 608 614 ), 609 ) 615 ), 616 WP_Theme_JSON_Resolver::get_theme_data()->get_custom_templates() 610 617 ); 611 618 } … … 750 757 */ 751 758 public function test_get_theme_data_theme_supports_overrides_theme_json() { 759 switch_theme( 'default' ); 760 752 761 // Test that get_theme_data() returns a WP_Theme_JSON object. 753 762 $theme_json_resolver = new WP_Theme_JSON_Resolver(); … … 763 772 $previous_line_height = $previous_settings['typography']['lineHeight']; 764 773 $this->assertFalse( $previous_line_height, 'lineHeight setting from theme.json should be false.' ); 774 765 775 add_theme_support( 'custom-line-height' ); 766 776 $current_settings = $theme_json_resolver->get_theme_data()->get_settings(); 767 777 $line_height = $current_settings['typography']['lineHeight']; 768 778 $this->assertTrue( $line_height, 'lineHeight setting after add_theme_support() should be true.' ); 779 remove_theme_support( 'custom-line-height' ); 769 780 } 770 781 … … 810 821 * @param bool $theme_palette Whether the theme palette is present. 811 822 * @param string $theme_palette_text Message. 812 * @param bool $user_palette 813 * @param string $user_palette_text 823 * @param bool $user_palette Whether the user palette is present. 824 * @param string $user_palette_text Message. 814 825 */ 815 826 public function test_get_merged_data_returns_origin( $origin, $core_palette, $core_palette_text, $block_styles, $block_styles_text, $theme_palette, $theme_palette_text, $user_palette, $user_palette_text ) { … … 818 829 'my/block-with-styles', 819 830 array( 820 'api_version' => 2,831 'api_version' => 3, 821 832 'attributes' => array( 822 833 'borderColor' => array( … … 878 889 * 879 890 * @covers WP_Theme_JSON_Resolver::get_merged_data 880 *881 891 */ 882 892 public function test_get_merged_data_returns_origin_proper() { … … 915 925 916 926 /** 917 * Data provider .927 * Data provider for test_get_merged_data_returns_origin. 918 928 * 919 929 * @return array[] … … 984 994 $expected_settings = array( 985 995 array( 986 'version' => 2, 996 'version' => WP_Theme_JSON::LATEST_SCHEMA, 997 'title' => 'variation-a', 998 'settings' => array( 999 'blocks' => array( 1000 'core/paragraph' => array( 1001 'color' => array( 1002 'palette' => array( 1003 'theme' => array( 1004 array( 1005 'slug' => 'dark', 1006 'name' => 'Dark', 1007 'color' => '#010101', 1008 ), 1009 ), 1010 ), 1011 ), 1012 ), 1013 ), 1014 ), 1015 ), 1016 array( 1017 'version' => WP_Theme_JSON::LATEST_SCHEMA, 987 1018 'title' => 'variation-b', 988 1019 'settings' => array( … … 1005 1036 ), 1006 1037 array( 1007 'version' => 2,1038 'version' => WP_Theme_JSON::LATEST_SCHEMA, 1008 1039 'title' => 'Block theme variation', 1009 1040 'settings' => array( -
trunk/tests/phpunit/tests/theme/wpThemeJsonSchema.php
r54889 r57662 13 13 class Tests_Theme_wpThemeJsonSchema extends WP_UnitTestCase { 14 14 /** 15 * The current theme.json schema version.16 */17 const LATEST_SCHEMA_VERSION = WP_Theme_JSON::LATEST_SCHEMA;18 19 /**20 15 * @ticket 54336 21 16 */ 22 public function test_migrate_v1_to_ v2() {17 public function test_migrate_v1_to_latest() { 23 18 $theme_json_v1 = array( 24 19 'version' => 1, … … 107 102 108 103 $expected = array( 109 'version' => self::LATEST_SCHEMA_VERSION,104 'version' => WP_Theme_JSON::LATEST_SCHEMA, 110 105 'settings' => array( 111 106 'color' => array(
Note: See TracChangeset
for help on using the changeset viewer.