1<?php
2
3/**
4 * @file
5 * Contains \Drupal\Tests\Core\Extension\ThemeHandlerTest.
6 */
7
8namespace Drupal\Tests\Core\Extension;
9
10use Composer\Autoload\ClassLoader;
11use Drupal\Core\Extension\Extension;
12use Drupal\Core\Extension\ThemeExtensionList;
13use Drupal\Core\Extension\ThemeHandler;
14use Drupal\Tests\UnitTestCase;
15
16/**
17 * @coversDefaultClass \Drupal\Core\Extension\ThemeHandler
18 * @group Extension
19 */
20class ThemeHandlerTest extends UnitTestCase {
21
22  /**
23   * The mocked config factory.
24   *
25   * @var \Drupal\Core\Config\ConfigFactoryInterface|\PHPUnit\Framework\MockObject\MockObject
26   */
27  protected $configFactory;
28
29  /**
30   * The theme listing service.
31   *
32   * @var \Drupal\Core\Extension\ThemeExtensionList|\PHPUnit\Framework\MockObject\MockObject
33   */
34  protected $themeList;
35
36  /**
37   * The tested theme handler.
38   *
39   * @var \Drupal\Core\Extension\ThemeHandler|\Drupal\Tests\Core\Extension\StubThemeHandler
40   */
41  protected $themeHandler;
42
43  /**
44   * {@inheritdoc}
45   */
46  protected function setUp(): void {
47    parent::setUp();
48
49    $this->configFactory = $this->getConfigFactoryStub([
50      'core.extension' => [
51        'module' => [],
52        'theme' => [],
53        'disabled' => [
54          'theme' => [],
55        ],
56      ],
57    ]);
58    $this->themeList = $this->getMockBuilder(ThemeExtensionList::class)
59      ->disableOriginalConstructor()
60      ->getMock();
61    $this->themeHandler = new StubThemeHandler($this->root, $this->configFactory, $this->themeList);
62
63    $container = $this->createMock('Symfony\Component\DependencyInjection\ContainerInterface');
64    $container->expects($this->any())
65      ->method('get')
66      ->with('class_loader')
67      ->will($this->returnValue($this->createMock(ClassLoader::class)));
68    \Drupal::setContainer($container);
69  }
70
71  /**
72   * Tests rebuilding the theme data.
73   *
74   * @see \Drupal\Core\Extension\ThemeHandler::rebuildThemeData()
75   */
76  public function testRebuildThemeData() {
77    $this->themeList->expects($this->once())
78      ->method('reset')
79      ->willReturnSelf();
80    $this->themeList->expects($this->once())
81      ->method('getList')
82      ->will($this->returnValue([
83        'seven' => new Extension($this->root, 'theme', 'core/themes/seven/seven.info.yml', 'seven.theme'),
84      ]));
85
86    $theme_data = $this->themeHandler->rebuildThemeData();
87    $this->assertCount(1, $theme_data);
88    $info = $theme_data['seven'];
89
90    // Ensure some basic properties.
91    $this->assertInstanceOf('Drupal\Core\Extension\Extension', $info);
92    $this->assertEquals('seven', $info->getName());
93    $this->assertEquals('core/themes/seven/seven.info.yml', $info->getPathname());
94    $this->assertEquals('core/themes/seven/seven.theme', $info->getExtensionPathname());
95
96  }
97
98  /**
99   * Tests empty libraries in theme.info.yml file.
100   */
101  public function testThemeLibrariesEmpty() {
102    $theme = new Extension($this->root, 'theme', 'core/modules/system/tests/themes/test_theme_libraries_empty', 'test_theme_libraries_empty.info.yml');
103    try {
104      $this->themeHandler->addTheme($theme);
105      $this->assertTrue(TRUE, 'Empty libraries key in theme.info.yml does not cause PHP warning');
106    }
107    catch (\Exception $e) {
108      $this->fail('Empty libraries key in theme.info.yml causes PHP warning.');
109    }
110  }
111
112}
113
114/**
115 * Extends the default theme handler to mock some drupal_ methods.
116 */
117class StubThemeHandler extends ThemeHandler {
118
119  /**
120   * Whether the CSS cache was cleared.
121   *
122   * @var bool
123   */
124  protected $clearedCssCache;
125
126  /**
127   * Whether the registry should be rebuilt.
128   *
129   * @var bool
130   */
131  protected $registryRebuild;
132
133  /**
134   * {@inheritdoc}
135   */
136  protected function clearCssCache() {
137    $this->clearedCssCache = TRUE;
138  }
139
140  /**
141   * {@inheritdoc}
142   */
143  protected function themeRegistryRebuild() {
144    $this->registryRebuild = TRUE;
145  }
146
147}
148