close
Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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-z0-9-]+\/[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
116 changes: 116 additions & 0 deletions tests/phpunit/tests/icons/wpIconsRegistry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?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;

/**
* Sets up the test fixture.
*/
public function set_up() {
parent::set_up();
$this->registry = WP_Icons_Registry::get_instance();
}

/**
* Tear down each test method.
*/
public function tear_down() {
$instance_property = new ReflectionProperty( WP_Icons_Registry::class, 'instance' );
$instance_property->setAccessible( true );
Comment thread
im3dabasia marked this conversation as resolved.
Outdated
$instance_property->setValue( null, null );

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

/**
* Invokes the WP_Icons_Registry::register method on the registry instance.
*
* @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' );
$method->setAccessible( true );
Comment thread
im3dabasia marked this conversation as resolved.
Outdated
return $method->invoke( $this->registry, $icon_name, $icon_properties );
}

/**
* Should reject non-string names.
*
* @expectedIncorrectUsage WP_Icons_Registry::register
*/
public function test_invalid_non_string_names() {
$result = $this->register( 1, array() );
$this->assertFalse( $result );
}

/**
* Should reject icons without a namespace.
*
* @expectedIncorrectUsage WP_Icons_Registry::register
*/
public function test_invalid_names_without_namespace() {
$result = $this->register( 'plus', array() );
$this->assertFalse( $result );
}

/**
* Should reject icons with uppercase characters.
*
* @expectedIncorrectUsage WP_Icons_Registry::register
*/
public function test_uppercase_characters() {
$result = $this->register( 'Core/Plus', array() );
$this->assertFalse( $result );
}

/**
* Should accept valid icon names.
*/
public function test_register_icon() {
$name = 'test-plugin/my-icon';
$settings = array(
'label' => 'My Icon',
'content' => '<svg></svg>',
);

$result = $this->register( $name, $settings );
$this->assertTrue( $result );
$this->assertTrue( $this->registry->is_registered( $name ) );
}

/**
* Should fail to re-register the same icon.
*
* @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

$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 );
}
}
Loading