Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/wp-includes/class-wp-icons-registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,34 @@ protected function register( $icon_name, $icon_properties ) {
return false;
}

if ( preg_match( '/[A-Z]/', $icon_name ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon names must not contain uppercase characters.' ),
'7.1.0'
);
return false;
}

$name_matcher = '/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/';
if ( ! preg_match( $name_matcher, $icon_name ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon names must contain a namespace prefix. Example: my-plugin/my-custom-icon' ),
'7.1.0'
);
return false;
}

if ( $this->is_registered( $icon_name ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon is already registered.' ),
'7.1.0'
);
return false;
}

$allowed_keys = array_fill_keys( array( 'label', 'content', 'filePath' ), 1 );
foreach ( array_keys( $icon_properties ) as $key ) {
if ( ! array_key_exists( $key, $allowed_keys ) ) {
Expand Down
122 changes: 122 additions & 0 deletions tests/phpunit/tests/icons/wpIconsRegistry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php
/**
* Tests for WP_Icons_Registry::register().
*
* @package WordPress
* @subpackage Icons
*
* @group icons
* @covers WP_Icons_Registry::register
* @covers WP_Icons_Registry::is_registered
*/
class Tests_Icons_WpIconsRegistry extends WP_UnitTestCase {

/**
* Registry instance for testing.
*
* @var WP_Icons_Registry
*/
private $registry;

public function set_up() {
parent::set_up();
$this->registry = WP_Icons_Registry::get_instance();
}

public function tear_down() {
$instance_property = new ReflectionProperty( WP_Icons_Registry::class, 'instance' );

/*
* ReflectionProperty::setAccessible is:
* - redundant as of 8.1.0, which made all properties accessible
* - deprecated as of 8.5.0
* - needed until 8.1.0, as property `instance` is private
*/
if ( PHP_VERSION_ID < 80100 ) {
$instance_property->setAccessible( true );
}

$instance_property->setValue( null, null );

$this->registry = null;
parent::tear_down();
}

/**
* Invokes WP_Icons_Registry::register despite it being private
*
* @param string $icon_name Icon name including namespace.
* @param array $icon_properties Icon properties (label, content, filePath).
* @return bool True if the icon was registered successfully.
*/
private function register( $icon_name, $icon_properties ) {
$method = new ReflectionMethod( $this->registry, 'register' );

/*
* ReflectionMethod::setAccessible is:
* - redundant as of 8.1.0, which made all properties accessible
* - deprecated as of 8.5.0
* - needed until 8.1.0, as property `instance` is private
*/
if ( PHP_VERSION_ID < 80100 ) {
$method->setAccessible( true );
}

return $method->invoke( $this->registry, $icon_name, $icon_properties );
}

/**
* Provides invalid icon names.
*
* @return array[]
*/
public function data_invalid_icon_names() {
return array(
'non-string name' => array( 1 ),
'no namespace' => array( 'plus' ),
'uppercase characters' => array( 'Test/Plus' ),
'invalid characters' => array( 'test/_doing_it_wrong' ),
);
}

/**
* Should fail to re-register the same icon.
*
* @ticket 64847
*
* @expectedIncorrectUsage WP_Icons_Registry::register
*/
public function test_register_icon_twice() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add @ticket for new unit tests

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 93074fb

$name = 'test-plugin/duplicate';
$settings = array(
'label' => 'Icon',
'content' => '<svg></svg>',
);

$result = $this->register( $name, $settings );
$this->assertTrue( $result );
$result2 = $this->register( $name, $settings );
$this->assertFalse( $result2 );
}


/**
* Should fail to register icon with invalid names.
*
* @ticket 64847
*
* @dataProvider data_invalid_icon_names
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This it not correctly use of dataProvider. Make sure to correct it before commit.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 3c40799

* @expectedIncorrectUsage WP_Icons_Registry::register
*
* @param mixed $icon_name Icon name to register.
*/
public function test_register_invalid_name( $icon_name ) {
$settings = array(
'label' => 'Icon',
'content' => '<svg></svg>',
);

$result = $this->register( $icon_name, $settings );
$this->assertFalse( $result );
}
}
Loading