class IconFinderTest

@coversDefaultClass \Drupal\Core\Theme\Icon\IconFinder

@group icon

Hierarchy

Expanded class hierarchy of IconFinderTest

File

core/tests/Drupal/Tests/Core/Theme/Icon/IconFinderTest.php, line 18

Namespace

Drupal\Tests\Core\Theme\Icon
View source
class IconFinderTest extends UnitTestCase {
    private const TEST_ICONS_PATH = 'core/modules/system/tests/modules/icon_test';
    private const TEST_RELATIVE_URL = 'foo/bar';
    
    /**
     * The file url generator instance.
     *
     * @var \Drupal\Core\File\FileUrlGeneratorInterface|\PHPUnit\Framework\MockObject\MockObject
     */
    private FileUrlGeneratorInterface $fileUrlGenerator;
    
    /**
     * The logger service instance.
     *
     * @var \Psr\Log\LoggerInterface|\PHPUnit\Framework\MockObject\MockObject
     */
    private LoggerInterface $logger;
    
    /**
     * The IconFinder instance.
     *
     * @var \Drupal\Core\Theme\Icon\IconFinder
     */
    private IconFinder $iconFinder;
    
    /**
     * {@inheritdoc}
     */
    protected function setUp() : void {
        parent::setUp();
        $this->fileUrlGenerator = $this->getMockBuilder('Drupal\\Core\\File\\FileUrlGeneratorInterface')
            ->disableOriginalConstructor()
            ->getMock();
        $this->logger = $this->createMock(LoggerInterface::class);
        $this->iconFinder = new IconFinder($this->fileUrlGenerator, $this->logger, DRUPAL_ROOT);
    }
    
    /**
     * Data provider for ::testGetFilesFromSourcesUrl().
     *
     * @return \Generator
     *   The test cases, with expected result as icon_id.
     */
    public static function providerGetFilesFromSourcesUrl() : iterable {
        (yield 'empty sources' => [
            [],
        ]);
        (yield 'url valid' => [
            [
                'http://example.com/foo.png',
                'https://example.com/bar.png',
                'https://example.com/fOO%20folder%20%C3%B9/FoO%21%20BaR%3D%281%29%20iCo-n.png%3Ftest%3DfOO%23bAz',
            ],
            [
                'foo' => 'http://example.com/foo.png',
                'bar' => 'https://example.com/bar.png',
                'FoO! BaR=(1) iCo-n' => 'https://example.com/fOO%20folder%20%C3%B9/FoO%21%20BaR%3D%281%29%20iCo-n.png%3Ftest%3DfOO%23bAz',
            ],
        ]);
        (yield 'url encoded' => [
            [
                'https://example.com/fOO%20folder%20%C3%B9/FoO%21%20BaR%3D%281%29%20iCo-n.png%3Ftest%3DfOO%23bAz',
            ],
            [
                'FoO! BaR=(1) iCo-n' => 'https://example.com/fOO%20folder%20%C3%B9/FoO%21%20BaR%3D%281%29%20iCo-n.png%3Ftest%3DfOO%23bAz',
            ],
        ]);
        (yield 'url not encoded' => [
            [
                'https://example.com/fOO folder ù/FoO_Ba,R=(1) iCo-n.png?test=fOO#bAz',
            ],
            [
                'FoO_Ba,R=(1) iCo-n' => 'https://example.com/fOO folder ù/FoO_Ba,R=(1) iCo-n.png?test=fOO#bAz',
            ],
        ]);
        (yield 'url valid with duplicate' => [
            [
                'http://example.com/foo.png',
                'https://example.com/bar.png',
                'http://example.com/foo.svg',
                'https://example.com/bar.svg',
            ],
            [
                'foo' => 'http://example.com/foo.svg',
                'bar' => 'https://example.com/bar.svg',
            ],
        ]);
        (yield 'url no extension' => [
            [
                'http://example.com/foo',
                'https://example.com/fOO folder ù/FoO BaR=(1) iCo-n?test=fOO#bAz',
            ],
            [
                'foo' => 'http://example.com/foo',
                'FoO BaR=(1) iCo-n' => 'https://example.com/fOO folder ù/FoO BaR=(1) iCo-n?test=fOO#bAz',
            ],
        ]);
        (yield 'url valid with special filename' => [
            [
                'http://example.com/foo (è$ù5 6*$^ _ ù48 \'Bar\']=-n!.png',
            ],
            [
                'foo (è$ù5 6*$^ _ ù48 \'Bar\']=-n!' => 'http://example.com/foo (è$ù5 6*$^ _ ù48 \'Bar\']=-n!.png',
            ],
        ]);
        // Test invalid scheme and empty path.
        (yield 'url not supported scheme or path is invalid' => [
            [
                'ftp://foo/bar.png',
                'ssh://foo/bar.png',
                'sftp://foo/bar.png',
                'htp://foo/bar.png',
                'a://foo/bar.png',
                'http://',
                'https://',
            ],
        ]);
    }
    
    /**
     * Test the IconFinder::getFilesFromSources method with urls.
     *
     * @param array<string> $sources
     *   The list of remote.
     * @param array<string, string> $expected
     *   The expected result.
     *
     * @dataProvider providerGetFilesFromSourcesUrl
     */
    public function testGetFilesFromSourcesUrl(array $sources, array $expected = []) : void {
        $result = $this->iconFinder
            ->getFilesFromSources($sources, '');
        // Prepare result array matching getFileFromHttpUrl() to minimize test data.
        $expected_result = [];
        foreach ($expected as $expected_icon_id => $expected_source) {
            $expected_result[$expected_icon_id] = [
                'icon_id' => $expected_icon_id,
                'source' => $expected_source,
                'absolute_path' => $expected_source,
            ];
        }
        $this->assertEquals($expected_result, $result);
    }
    
    /**
     * Data provider for ::testGetFilesFromSourcesPath().
     *
     * @return \Generator
     *   The test cases, to minimize test data, result expected is an array with:
     *   - icon_id: the expected id
     *   - path: expected path found relative to TEST_ICONS_PATH
     *   - group: The group name if any
     */
    public static function providerGetFilesFromSourcesPath() : iterable {
        (yield 'path empty' => [
            [
                '',
            ],
        ]);
        (yield 'direct file without path' => [
            [
                'foo.svg',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file without extension' => [
            [
                'foo',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file without extension wildcard' => [
            [
                'foo.*',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file with wildcard and extension' => [
            [
                '*.svg',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file with wildcard only' => [
            [
                '*',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file with wildcards' => [
            [
                '*.*',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'path valid' => [
            [
                'icons/flat/foo.png',
                'icons/flat/bar.svg',
            ],
            [
                [
                    'foo',
                    'icons/flat/foo.png',
                ],
                [
                    'bar',
                    'icons/flat/bar.svg',
                ],
            ],
        ]);
        (yield 'absolute path valid' => [
            [
                '/' . self::TEST_ICONS_PATH . '/icons/flat/foo.png',
            ],
            [
                [
                    'foo',
                    'icons/flat/foo.png',
                ],
            ],
        ]);
        (yield 'path not allowed extension' => [
            [
                // File exist but not valid extension.
'icons/flat/foo.webp',
                'icons/flat/*.webp',
                // Non existent file.
'icons/flat/foo-1.jpg',
            ],
        ]);
        (yield 'path without extension' => [
            [
                'icons/flat/foo',
            ],
            [
                [
                    'foo',
                    'icons/flat/foo.svg',
                ],
            ],
        ]);
        (yield 'path wildcard extension' => [
            [
                'icons/flat/foo.*',
            ],
            [
                [
                    'foo',
                    'icons/flat/foo.svg',
                ],
            ],
        ]);
        (yield 'path wildcard filename' => [
            [
                'icons/flat/*.svg',
            ],
            [
                [
                    'bar-2',
                    'icons/flat/bar-2.svg',
                ],
                [
                    'bar',
                    'icons/flat/bar.svg',
                ],
                [
                    'baz-2',
                    'icons/flat/baz-2.svg',
                ],
                [
                    'foo',
                    'icons/flat/foo.svg',
                ],
                [
                    '64x64',
                    'icons/flat/64x64.svg',
                ],
            ],
        ]);
        (yield 'path wildcard increment filename' => [
            [
                'icons/flat_same_name/*',
            ],
            [
                [
                    'foo',
                    'icons/flat_same_name/foo.svg',
                ],
            ],
        ]);
        (yield 'path wildcard filename with extension' => [
            [
                'icons/flat/*.svg',
            ],
            [
                [
                    'bar-2',
                    'icons/flat/bar-2.svg',
                ],
                [
                    'baz-2',
                    'icons/flat/baz-2.svg',
                ],
                [
                    'foo',
                    'icons/flat/foo.svg',
                ],
                [
                    'bar',
                    'icons/flat/bar.svg',
                ],
                [
                    '64x64',
                    'icons/flat/64x64.svg',
                ],
            ],
        ]);
        (yield 'path wildcard' => [
            [
                '*/flat/*',
            ],
            [
                [
                    'bar-2',
                    'icons/flat/bar-2.svg',
                ],
                [
                    'bar',
                    'icons/flat/bar.svg',
                ],
                [
                    'baz-1',
                    'icons/flat/baz-1.png',
                ],
                [
                    'baz-2',
                    'icons/flat/baz-2.svg',
                ],
                [
                    'foo',
                    'icons/flat/foo.svg',
                ],
                [
                    '64x64',
                    'icons/flat/64x64.svg',
                ],
            ],
        ]);
        (yield 'mix wildcard and extensions' => [
            [
                'icons/flat/foo.*',
                'icons/flat/foo.svg',
            ],
            [
                [
                    'foo',
                    'icons/flat/foo.svg',
                ],
            ],
        ]);
        (yield 'path group no result' => [
            [
                'icons/group/*',
            ],
            [],
        ]);
        (yield 'path with folder wildcard' => [
            [
                'icons/group/*/*',
            ],
            [
                [
                    'bar_group_1',
                    'icons/group/group_1/bar_group_1.png',
                ],
                [
                    'bar_group_2',
                    'icons/group/group_2/bar_group_2.png',
                ],
                [
                    'baz_group_1',
                    'icons/group/group_1/baz_group_1.png',
                ],
                [
                    'baz_group_2',
                    'icons/group/group_2/baz_group_2.png',
                ],
                [
                    'corge_group_1',
                    'icons/group/group_1/corge_group_1.svg',
                ],
                [
                    'corge_group_2',
                    'icons/group/group_2/corge_group_2.svg',
                ],
                [
                    'foo_group_1',
                    'icons/group/group_1/foo_group_1.svg',
                ],
                [
                    'foo_group_2',
                    'icons/group/group_2/foo_group_2.svg',
                ],
            ],
        ]);
        (yield 'path sub group wildcard' => [
            [
                'icons/group/*/sub_sub_group_1/*',
            ],
            [
                [
                    'foo_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/foo_sub_group_1.png',
                ],
                [
                    'bar_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/bar_sub_group_1.svg',
                ],
            ],
        ]);
        (yield 'path sub group wildcard partial and filename' => [
            [
                'icons/group/*/sub_sub_group_*/*',
            ],
            [
                [
                    'foo_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/foo_sub_group_1.png',
                ],
                [
                    'corge_sub_group_2',
                    'icons/group/sub_group_2/sub_sub_group_2/corge_sub_group_2.png',
                ],
                [
                    'bar_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/bar_sub_group_1.svg',
                ],
                [
                    'baz_sub_group_2',
                    'icons/group/sub_group_2/sub_sub_group_2/baz_sub_group_2.svg',
                ],
            ],
        ]);
        (yield 'path sub group multiple wildcard folder and filename' => [
            [
                'icons/group/*/*/*',
            ],
            [
                [
                    'foo_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/foo_sub_group_1.png',
                ],
                [
                    'corge_sub_group_2',
                    'icons/group/sub_group_2/sub_sub_group_2/corge_sub_group_2.png',
                ],
                [
                    'bar_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/bar_sub_group_1.svg',
                ],
                [
                    'baz_sub_group_2',
                    'icons/group/sub_group_2/sub_sub_group_2/baz_sub_group_2.svg',
                ],
            ],
        ]);
        // Start tests for the {group} placeholder.
        (yield 'path with {group} extracted' => [
            [
                'icons/group/{group}/*',
            ],
            [
                [
                    'bar_group_1',
                    'icons/group/group_1/bar_group_1.png',
                    'group_1',
                ],
                [
                    'baz_group_1',
                    'icons/group/group_1/baz_group_1.png',
                    'group_1',
                ],
                [
                    'bar_group_2',
                    'icons/group/group_2/bar_group_2.png',
                    'group_2',
                ],
                [
                    'baz_group_2',
                    'icons/group/group_2/baz_group_2.png',
                    'group_2',
                ],
                [
                    'corge_group_1',
                    'icons/group/group_1/corge_group_1.svg',
                    'group_1',
                ],
                [
                    'foo_group_1',
                    'icons/group/group_1/foo_group_1.svg',
                    'group_1',
                ],
                [
                    'corge_group_2',
                    'icons/group/group_2/corge_group_2.svg',
                    'group_2',
                ],
                [
                    'foo_group_2',
                    'icons/group/group_2/foo_group_2.svg',
                    'group_2',
                ],
            ],
        ]);
        (yield 'test group extracted wildcard after' => [
            [
                'icons/group/{group}/*/*',
            ],
            [
                [
                    'bar_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/bar_sub_group_1.svg',
                    'sub_group_1',
                ],
                [
                    'baz_sub_group_2',
                    'icons/group/sub_group_2/sub_sub_group_2/baz_sub_group_2.svg',
                    'sub_group_2',
                ],
                [
                    'corge_sub_group_2',
                    'icons/group/sub_group_2/sub_sub_group_2/corge_sub_group_2.png',
                    'sub_group_2',
                ],
                [
                    'foo_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/foo_sub_group_1.png',
                    'sub_group_1',
                ],
            ],
        ]);
        (yield 'test group extracted wildcard before' => [
            [
                'icons/group/*/{group}/*',
            ],
            [
                [
                    'bar_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/bar_sub_group_1.svg',
                    'sub_sub_group_1',
                ],
                [
                    'baz_sub_group_2',
                    'icons/group/sub_group_2/sub_sub_group_2/baz_sub_group_2.svg',
                    'sub_sub_group_2',
                ],
                [
                    'corge_sub_group_2',
                    'icons/group/sub_group_2/sub_sub_group_2/corge_sub_group_2.png',
                    'sub_sub_group_2',
                ],
                [
                    'foo_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/foo_sub_group_1.png',
                    'sub_sub_group_1',
                ],
            ],
        ]);
        (yield 'test group extracted wildcard both' => [
            [
                'icons/*/{group}/*/*',
            ],
            [
                [
                    'bar_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/bar_sub_group_1.svg',
                    'sub_group_1',
                ],
                [
                    'baz_sub_group_2',
                    'icons/group/sub_group_2/sub_sub_group_2/baz_sub_group_2.svg',
                    'sub_group_2',
                ],
                [
                    'corge_sub_group_2',
                    'icons/group/sub_group_2/sub_sub_group_2/corge_sub_group_2.png',
                    'sub_group_2',
                ],
                [
                    'foo_sub_group_1',
                    'icons/group/sub_group_1/sub_sub_group_1/foo_sub_group_1.png',
                    'sub_group_1',
                ],
            ],
        ]);
        (yield 'test group same name' => [
            [
                'icons/group_same_name/{group}/*',
            ],
            [
                [
                    'foo',
                    'icons/group_same_name/group_3/foo.svg',
                    'group_3',
                ],
            ],
        ]);
        // Start tests for the {icon_id} placeholder.
        (yield 'direct file with icon_id' => [
            [
                '{icon_id}',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file with icon_id and extension' => [
            [
                '{icon_id}.svg',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file with icon_id and extension wildcard' => [
            [
                '{icon_id}.*',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file with icon_id and wildcard after' => [
            [
                '{icon_id}*',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file with icon_id and wildcard before' => [
            [
                '*{icon_id}',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file with icon_id and wildcard around' => [
            [
                '*{icon_id}*',
            ],
            [
                [
                    'foo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file with icon_id and wildcard around and prefix' => [
            [
                'f*{icon_id}*',
            ],
            [
                [
                    'oo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file with icon_id and wildcard around and suffix' => [
            [
                '*{icon_id}*o',
            ],
            [
                [
                    'fo',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'direct file with icon_id and wildcard around and prefix and suffix' => [
            [
                'f*{icon_id}*o',
            ],
            [
                [
                    'o',
                    'foo.svg',
                ],
            ],
        ]);
        (yield 'test icon_id extracted' => [
            [
                'icons/prefix_suffix/{icon_id}.svg',
            ],
            [
                [
                    'grault',
                    'icons/prefix_suffix/grault.svg',
                ],
                [
                    'garply_suffix',
                    'icons/prefix_suffix/garply_suffix.svg',
                ],
                [
                    'prefix_quux',
                    'icons/prefix_suffix/prefix_quux.svg',
                ],
                [
                    'prefix_corge_suffix',
                    'icons/prefix_suffix/prefix_corge_suffix.svg',
                ],
            ],
        ]);
        (yield 'test icon_id extracted prefix' => [
            [
                'icons/prefix_suffix/prefix_{icon_id}.svg',
            ],
            [
                [
                    'quux',
                    'icons/prefix_suffix/prefix_quux.svg',
                ],
                [
                    'corge_suffix',
                    'icons/prefix_suffix/prefix_corge_suffix.svg',
                ],
            ],
        ]);
        (yield 'test icon_id extracted suffix' => [
            [
                'icons/prefix_suffix/{icon_id}_suffix.svg',
            ],
            [
                [
                    'garply',
                    'icons/prefix_suffix/garply_suffix.svg',
                ],
                [
                    'prefix_corge',
                    'icons/prefix_suffix/prefix_corge_suffix.svg',
                ],
            ],
        ]);
        (yield 'test icon_id extracted both' => [
            [
                'icons/prefix_suffix/prefix_{icon_id}_suffix.svg',
            ],
            [
                [
                    'corge',
                    'icons/prefix_suffix/prefix_corge_suffix.svg',
                ],
            ],
        ]);
        (yield 'test icon_id extracted with group' => [
            [
                'icons/prefix_suffix/{group}/{icon_id}.svg',
            ],
            [
                [
                    'fred_group',
                    'icons/prefix_suffix/group/fred_group.svg',
                    'group',
                ],
                [
                    'plugh_group_suffix',
                    'icons/prefix_suffix/group/plugh_group_suffix.svg',
                    'group',
                ],
                [
                    'prefix_qux_group',
                    'icons/prefix_suffix/group/prefix_qux_group.svg',
                    'group',
                ],
                [
                    'prefix_waldo_group_suffix',
                    'icons/prefix_suffix/group/prefix_waldo_group_suffix.svg',
                    'group',
                ],
            ],
        ]);
        (yield 'test icon_id extracted with group and wildcard' => [
            [
                'icons/*/{group}/{icon_id}.svg',
            ],
            [
                [
                    'corge_group_1',
                    'icons/group/group_1/corge_group_1.svg',
                    'group_1',
                ],
                [
                    'foo_group_1',
                    'icons/group/group_1/foo_group_1.svg',
                    'group_1',
                ],
                [
                    'corge_group_2',
                    'icons/group/group_2/corge_group_2.svg',
                    'group_2',
                ],
                [
                    'foo_group_2',
                    'icons/group/group_2/foo_group_2.svg',
                    'group_2',
                ],
                [
                    'foo',
                    'icons/group_same_name/group_3/foo.svg',
                    'group_3',
                ],
                [
                    'fred_group',
                    'icons/prefix_suffix/group/fred_group.svg',
                    'group',
                ],
                [
                    'plugh_group_suffix',
                    'icons/prefix_suffix/group/plugh_group_suffix.svg',
                    'group',
                ],
                [
                    'prefix_qux_group',
                    'icons/prefix_suffix/group/prefix_qux_group.svg',
                    'group',
                ],
                [
                    'prefix_waldo_group_suffix',
                    'icons/prefix_suffix/group/prefix_waldo_group_suffix.svg',
                    'group',
                ],
            ],
        ]);
        (yield 'path {icon_id} partial extracted wildcard extension' => [
            [
                'icons/flat_same_name/f{icon_id}o.*',
            ],
            [
                [
                    'o',
                    'icons/flat_same_name/foo.svg',
                ],
            ],
        ]);
    }
    
    /**
     * Test the IconFinder::getFilesFromSources method with paths.
     *
     * @param array<string> $sources
     *   The list of remote.
     * @param array<string, string> $expected
     *   The expected result.
     *
     * @dataProvider providerGetFilesFromSourcesPath
     */
    public function testGetFilesFromSourcesPath(array $sources, array $expected = []) : void {
        $this->fileUrlGenerator
            ->expects($this->any())
            ->method('generateString')
            ->willReturnCallback(function ($uri) {
            return self::TEST_RELATIVE_URL . $uri;
        });
        $result = $this->iconFinder
            ->getFilesFromSources($sources, self::TEST_ICONS_PATH);
        // Prepare result array matching processFoundFiles() to minimize test data.
        $expected_result = [];
        foreach ($expected as $key => $expected_value) {
            $icon_id = $expected[$key][0];
            $filename = $expected[$key][1];
            $group = $expected[$key][2] ?? NULL;
            $expected_result[$icon_id] = [
                'icon_id' => $icon_id,
                'source' => self::TEST_RELATIVE_URL . '/' . self::TEST_ICONS_PATH . '/' . $filename,
                'absolute_path' => DRUPAL_ROOT . '/' . self::TEST_ICONS_PATH . '/' . $filename,
                'group' => $group,
            ];
        }
        $this->assertEqualsCanonicalizing($expected_result, $result);
    }
    
    /**
     * Test the IconFinder::getFilesFromPath method with warning.
     */
    public function testGetFilesFromPathEmptyWarning() : void {
        $method = new \ReflectionMethod(IconFinder::class, 'getFilesFromPath');
        $method->setAccessible(TRUE);
        $this->logger
            ->expects($this->once())
            ->method('warning')
            ->with('Invalid icon path extension @filename.@extension in source: @source');
        $method->invoke($this->iconFinder, self::TEST_ICONS_PATH . '/icons/flat/foo.webp', '');
    }
    
    /**
     * Test the IconFinder::getFilesFromPath method with warning.
     */
    public function testGetFilesFromPathInvalidExtensionWarning() : void {
        $method = new \ReflectionMethod(IconFinder::class, 'getFilesFromPath');
        $method->setAccessible(TRUE);
        $this->logger
            ->expects($this->once())
            ->method('warning');
        $method->invoke($this->iconFinder, self::TEST_ICONS_PATH . '/icons/empty/*.svg', '');
    }
    
    /**
     * Test the IconFinder::getFileFromUrl method with warning.
     */
    public function testGetFileFromUrlWarning() : void {
        $method = new \ReflectionMethod(IconFinder::class, 'getFileFromUrl');
        $method->setAccessible(TRUE);
        $this->logger
            ->expects($this->once())
            ->method('warning')
            ->with('Invalid icon source: @source');
        $method->invoke($this->iconFinder, 'invalid_scheme', '', '');
    }
    
    /**
     * Test the IconFinder::findFiles method with warning with invalid path.
     */
    public function testFindFilesWarning() : void {
        $method = new \ReflectionMethod(IconFinder::class, 'findFiles');
        $method->setAccessible(TRUE);
        $this->logger
            ->expects($this->once())
            ->method('warning')
            ->with('Invalid icon path in source: @source');
        $method->invoke($this->iconFinder, 'invalid_path', '*');
    }
    
    /**
     * Test the IconFinder::findFiles method with warning when no icons found.
     */
    public function testFindFilesEmptyWarning() : void {
        $method = new \ReflectionMethod(IconFinder::class, 'findFiles');
        $method->setAccessible(TRUE);
        $this->logger
            ->expects($this->once())
            ->method('warning');
        $method->invoke($this->iconFinder, self::TEST_ICONS_PATH . '/icons/empty', '*.svg');
    }
    
    /**
     * Data provider for ::testExtractIconIdFromFilename().
     *
     * @return \Generator
     *   The test cases.
     */
    public static function providerExtractIconIdFromFilename() : iterable {
        (yield 'no pattern' => [
            'foo bar baz',
            '',
            'foo bar baz',
        ]);
        (yield 'no pattern and wildcard' => [
            'foo*bar*baz',
            '',
            'foo*bar*baz',
        ]);
        (yield 'simple pattern' => [
            'foo bar baz',
            'foo {icon_id} baz',
            'bar',
        ]);
        (yield 'simple pattern and wildcard included' => [
            'foo*bar*baz',
            'foo{icon_id}baz',
            '*bar*',
        ]);
        (yield 'wrong pattern' => [
            'foo bar baz',
            'foo {ico_id} baz',
            'foo bar baz',
        ]);
        (yield 'pattern with special chars' => [
            'foO1o,-O 5 (B,ar)_b-az',
            'fo{icon_id}az',
            'O1o,-O 5 (B,ar)_b-',
        ]);
    }
    
    /**
     * Test the IconFinder::extractIconIdFromFilename method.
     *
     * @param string $filename
     *   The filename found to match against.
     * @param string $filename_pattern
     *   The path with {icon_id}.
     * @param string $expected
     *   The expected result.
     *
     * @dataProvider providerExtractIconIdFromFilename
     */
    public function testExtractIconIdFromFilename(string $filename, string $filename_pattern, string $expected) : void {
        $method = new \ReflectionMethod(IconFinder::class, 'extractIconIdFromFilename');
        $method->setAccessible(TRUE);
        $this->assertEquals($expected, $method->invoke($this->iconFinder, $filename, $filename_pattern));
    }
    
    /**
     * Test the IconFinder::extractIconIdFromFilename method with failing pattern.
     */
    public function testExtractIconIdFromFilenameWarning() : void {
        $method = new \ReflectionMethod(IconFinder::class, 'extractIconIdFromFilename');
        $method->setAccessible(TRUE);
        // PHPUnit 10 cannot expect warnings, so we have to catch them ourselves.
        // Thanks to: Drupal\Tests\Component\PhpStorage\FileStorageTest.
        $messages = [];
        set_error_handler(function (int $errno, string $errstr) use (&$messages) : void {
            $messages[] = [
                $errno,
                $errstr,
            ];
        });
        $method->invoke($this->iconFinder, 'foo*bar*baz', 'foo*{icon_id}*baz');
        restore_error_handler();
        $this->assertCount(1, $messages);
        $this->assertSame(E_WARNING, $messages[0][0]);
        $this->assertSame('preg_match(): Compilation failed: quantifier does not follow a repeatable item at offset 19', $messages[0][1]);
    }
    
    /**
     * Data provider for ::testGetFileContents().
     *
     * @return array
     *   The test cases as uri and expected valid.
     */
    public static function providerGetFileContents() : array {
        return [
            'valid local file' => [
                DRUPAL_ROOT . '/' . self::TEST_ICONS_PATH . '/icons/flat/foo.svg',
                TRUE,
            ],
            'do not exist' => [
                DRUPAL_ROOT . '/' . self::TEST_ICONS_PATH . '/icons/do/not/exist.svg',
                FALSE,
            ],
            [
                'http://foo.com/bar.png',
                FALSE,
            ],
            [
                'https://foo.com/bar.png',
                FALSE,
            ],
            [
                'ftp://foo.com/bar.png',
                FALSE,
            ],
            [
                'ssh://foo.com/bar.png',
                FALSE,
            ],
            [
                '//foo.com/bar.png',
                FALSE,
            ],
        ];
    }
    
    /**
     * Test the IconFinder::getFileContents method.
     *
     * @param string $uri
     *   The uri to test result.
     * @param bool $expected
     *   The result of the file content is expected or not.
     *
     * @dataProvider providerGetFileContents
     */
    public function testGetFileContents(string $uri, bool $expected) : void {
        if ($expected) {
            $result = $this->iconFinder
                ->getFileContents($uri);
            $this->assertEquals(file_get_contents($uri), $result);
            return;
        }
        $this->assertFalse($this->iconFinder
            ->getFileContents($uri));
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title
ExpectDeprecationTrait::expectDeprecation public function Adds an expected deprecation.
ExpectDeprecationTrait::getCallableName private static function Returns a callable as a string suitable for inclusion in a message.
ExpectDeprecationTrait::setUpErrorHandler public function Sets up the test error handler.
ExpectDeprecationTrait::tearDownErrorHandler public function Tears down the test error handler.
IconFinderTest::$fileUrlGenerator private property The file url generator instance.
IconFinderTest::$iconFinder private property The IconFinder instance.
IconFinderTest::$logger private property The logger service instance.
IconFinderTest::providerExtractIconIdFromFilename public static function Data provider for ::testExtractIconIdFromFilename().
IconFinderTest::providerGetFileContents public static function Data provider for ::testGetFileContents().
IconFinderTest::providerGetFilesFromSourcesPath public static function Data provider for ::testGetFilesFromSourcesPath().
IconFinderTest::providerGetFilesFromSourcesUrl public static function Data provider for ::testGetFilesFromSourcesUrl().
IconFinderTest::setUp protected function Overrides UnitTestCase::setUp
IconFinderTest::testExtractIconIdFromFilename public function Test the IconFinder::extractIconIdFromFilename method.
IconFinderTest::testExtractIconIdFromFilenameWarning public function Test the IconFinder::extractIconIdFromFilename method with failing pattern.
IconFinderTest::testFindFilesEmptyWarning public function Test the IconFinder::findFiles method with warning when no icons found.
IconFinderTest::testFindFilesWarning public function Test the IconFinder::findFiles method with warning with invalid path.
IconFinderTest::testGetFileContents public function Test the IconFinder::getFileContents method.
IconFinderTest::testGetFileFromUrlWarning public function Test the IconFinder::getFileFromUrl method with warning.
IconFinderTest::testGetFilesFromPathEmptyWarning public function Test the IconFinder::getFilesFromPath method with warning.
IconFinderTest::testGetFilesFromPathInvalidExtensionWarning public function Test the IconFinder::getFilesFromPath method with warning.
IconFinderTest::testGetFilesFromSourcesPath public function Test the IconFinder::getFilesFromSources method with paths.
IconFinderTest::testGetFilesFromSourcesUrl public function Test the IconFinder::getFilesFromSources method with urls.
IconFinderTest::TEST_ICONS_PATH private constant
IconFinderTest::TEST_RELATIVE_URL private constant
RandomGeneratorTrait::getRandomGenerator protected function Gets the random generator for the utility methods.
RandomGeneratorTrait::randomMachineName protected function Generates a unique random string containing letters and numbers.
RandomGeneratorTrait::randomObject public function Generates a random PHP object.
RandomGeneratorTrait::randomString public function Generates a pseudo-random string of ASCII characters of codes 32 to 126.
UnitTestCase::$root protected property The app root.
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::setUpBeforeClass public static function

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.