Issue #2808063 by vaplas, martin107, Chi, Wim Leers, catch, dawehner, alexpott: LibraryDiscoveryParser::buildByExtension() doesn't validate that extensions exist

8.3.x
Nathaniel Catchpole 2016-11-22 11:11:46 +00:00
parent 87e10306b5
commit a68c44f486
4 changed files with 55 additions and 5 deletions

View File

@ -1543,7 +1543,7 @@ services:
- { name: needs_destruction }
library.discovery.parser:
class: Drupal\Core\Asset\LibraryDiscoveryParser
arguments: ['@app.root', '@module_handler', '@theme.manager']
arguments: ['@app.root', '@module_handler', '@theme.manager', '@theme_handler']
library.dependency_resolver:
class: Drupal\Core\Asset\LibraryDependencyResolver
arguments: ['@library.discovery']

View File

@ -11,6 +11,7 @@ use Drupal\Core\Serialization\Yaml;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Extension\ThemeHandlerInterface;
/**
* Parses library files to get extension data.
@ -31,6 +32,13 @@ class LibraryDiscoveryParser {
*/
protected $themeManager;
/**
* The theme handler.
*
* @var \Drupal\Core\Extension\ThemeHandlerInterface
*/
protected $themeHandler;
/**
* The app root.
*
@ -47,11 +55,14 @@ class LibraryDiscoveryParser {
* The module handler.
* @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
* The theme manager.
* @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
* The theme handler.
*/
public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager) {
public function __construct($root, ModuleHandlerInterface $module_handler, ThemeManagerInterface $theme_manager, ThemeHandlerInterface $theme_handler) {
$this->root = $root;
$this->moduleHandler = $module_handler;
$this->themeManager = $theme_manager;
$this->themeHandler = $theme_handler;
}
/**
@ -63,6 +74,8 @@ class LibraryDiscoveryParser {
* @return array
* All library definitions of the passed extension.
*
* @throws \AssertionError
* When the extension (theme, module, library) is not available.
* @throws \Drupal\Core\Asset\Exception\IncompleteLibraryDefinitionException
* Thrown when a library has no js/css/setting.
* @throws \UnexpectedValueException
@ -79,9 +92,10 @@ class LibraryDiscoveryParser {
if ($this->moduleHandler->moduleExists($extension)) {
$extension_type = 'module';
}
else {
elseif ($this->themeHandler->themeExists($extension)) {
$extension_type = 'theme';
}
assert(isset($extension_type), sprintf('The extension "%s" is not available.', $extension));
$path = $this->drupalGetPath($extension_type, $extension);
}

View File

@ -53,7 +53,7 @@ class AjaxTest extends JavascriptTestBase {
$session = $this->getSession();
// Insert a fake library into the already loaded library settings.
$fake_library = 'fakeLibrary/fakeLibrary';
$fake_library = 'core/fakeLibrary';
$session->evaluateScript("drupalSettings.ajaxPageState.libraries = drupalSettings.ajaxPageState.libraries + ',$fake_library';");
$libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');

View File

@ -44,6 +44,13 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
*/
protected $themeManager;
/**
* The mocked theme handler.
*
* @var \Drupal\Core\Extension\ThemeHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $themeHandler;
/**
* The mocked lock backend.
*
@ -59,6 +66,8 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$this->themeManager = $this->getMock('Drupal\Core\Theme\ThemeManagerInterface');
$this->themeHandler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface');
$mock_active_theme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
->disableOriginalConstructor()
->getMock();
@ -68,7 +77,7 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
$this->themeManager->expects($this->any())
->method('getActiveTheme')
->willReturn($mock_active_theme);
$this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager);
$this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler, $this->themeManager, $this->themeHandler);
}
/**
@ -109,6 +118,11 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
->with('example_theme')
->will($this->returnValue(FALSE));
$this->themeHandler->expects($this->atLeastOnce())
->method('themeExists')
->with('example_theme')
->will($this->returnValue(TRUE));
$path = __DIR__ . '/library_test_files';
$path = substr($path, strlen($this->root) + 1);
$this->libraryDiscoveryParser->setPaths('theme', 'example_theme', $path);
@ -160,6 +174,28 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
$this->libraryDiscoveryParser->buildByExtension('invalid_file');
}
/**
* Tests that an exception is thrown when the extension is not a valid
* module, theme or library.
*
* @covers ::buildByExtension
*/
public function testMissingExtension() {
$this->moduleHandler->expects($this->atLeastOnce())
->method('moduleExists')
->with('missing_extension')
->will($this->returnValue(FALSE));
$this->themeHandler->expects($this->atLeastOnce())
->method('themeExists')
->with('missing_extension')
->will($this->returnValue(FALSE));
assert_options(ASSERT_ACTIVE, 1);
$this->setExpectedException('\AssertionError', 'The extension "missing_extension" is not available.');
$this->libraryDiscoveryParser->buildByExtension('missing_extension');
}
/**
* Tests that an exception is thrown when no CSS/JS/setting is specified.
*