Unverified Commit afcdeee4 authored by alexpott's avatar alexpott
Browse files

Issue #3076797 by Wim Leers, lauriii, alexpott:...

Issue #3076797 by Wim Leers, lauriii, alexpott: \Drupal\Core\Extension\Extension's absence of validation has allowed multiple incorrect tests to be added
parent 42962f79
......@@ -63,6 +63,8 @@ class Extension {
* (optional) The filename of the main extension file; e.g., 'node.module'.
*/
public function __construct($root, $type, $pathname, $filename = NULL) {
// @see \Drupal\Core\Theme\ThemeInitialization::getActiveThemeByName()
assert($pathname === 'core/core.info.yml' || ($pathname[0] !== '/' && file_exists($root . '/' . $pathname)), sprintf('The file specified by the given app root, relative path and file name (%s) do not exist.', $root . '/' . $pathname));
$this->root = $root;
$this->type = $type;
$this->pathname = $pathname;
......@@ -155,7 +157,7 @@ public function load() {
*/
public function __call($method, array $args) {
if (!isset($this->splFileInfo)) {
$this->splFileInfo = new \SplFileInfo($this->pathname);
$this->splFileInfo = new \SplFileInfo($this->root . '/' . $this->pathname);
}
return call_user_func_array([$this->splFileInfo, $method], $args);
}
......
......@@ -47,6 +47,7 @@ class FunctionalExampleTest {}
vfsStream::create([
'modules' => [
'test_module' => [
'test_module.info.yml' => $test_module_info,
'tests' => [
'src' => [
'Functional' => [
......@@ -212,7 +213,7 @@ public function testGetTestsInProfiles() {
$test_discovery = new TestDiscovery('vfs://drupal', $class_loader->reveal(), $module_handler->reveal());
$result = $test_discovery->getTestClasses(NULL, ['PHPUnit-Kernel']);
$result = $test_discovery->getTestClasses('test_profile_module', ['PHPUnit-Kernel']);
$expected = [
'example3' => [
'Drupal\Tests\test_profile_module\Kernel\KernelExampleTest4' => [
......
......@@ -31,7 +31,7 @@ protected function setUp() {
$this->themeHandler = $this->createMock('Drupal\Core\Extension\ThemeHandlerInterface');
$theme = new Extension($this->root, 'theme', '/core/themes/bartik', 'bartik.info.yml');
$theme = new Extension($this->root, 'theme', 'core/themes/bartik', 'bartik.info.yml');
$theme->status = 1;
$theme->info = ['name' => 'bartik'];
$this->themeHandler->expects($this->any())
......
......@@ -76,7 +76,7 @@ protected function setUp() {
* The extension object.
*/
protected function mockModuleExtension($module, $name) {
$extension = new Extension($this->root, $module, "modules/$module");
$extension = new Extension('vfs:/', $module, "modules/$module");
$extension->info['name'] = $name;
return $extension;
}
......
......@@ -26,7 +26,7 @@ class ExtensionListTest extends UnitTestCase {
*/
public function testGetNameWithNonExistingExtension() {
list($cache, $info_parser, $module_handler, $state) = $this->getMocks();
$test_extension_list = new TestExtension($this->root, 'test_extension', $cache->reveal(), $info_parser->reveal(), $module_handler->reveal(), $state->reveal(), 'testing');
$test_extension_list = new TestExtension($this->randomMachineName(), 'test_extension', $cache->reveal(), $info_parser->reveal(), $module_handler->reveal(), $state->reveal(), 'testing');
$extension_discovery = $this->prophesize(ExtensionDiscovery::class);
$extension_discovery->scan('test_extension')->willReturn([]);
......@@ -50,7 +50,7 @@ public function testGetName() {
*/
public function testGetWithNonExistingExtension() {
list($cache, $info_parser, $module_handler, $state) = $this->getMocks();
$test_extension_list = new TestExtension($this->root, 'test_extension', $cache->reveal(), $info_parser->reveal(), $module_handler->reveal(), $state->reveal(), 'testing');
$test_extension_list = new TestExtension($this->randomMachineName(), 'test_extension', $cache->reveal(), $info_parser->reveal(), $module_handler->reveal(), $state->reveal(), 'testing');
$extension_discovery = $this->prophesize(ExtensionDiscovery::class);
$extension_discovery->scan('test_extension')->willReturn([]);
......@@ -142,7 +142,7 @@ public function testGetPathnames() {
$filenames = $test_extension_list->getPathnames();
$this->assertEquals([
'test_name' => 'vfs://drupal_root/example/test_name/test_name.info.yml',
'test_name' => 'example/test_name/test_name.info.yml',
], $filenames);
}
......@@ -153,7 +153,7 @@ public function testGetPathname() {
$test_extension_list = $this->setupTestExtensionList();
$pathname = $test_extension_list->getPathname('test_name');
$this->assertEquals('vfs://drupal_root/example/test_name/test_name.info.yml', $pathname);
$this->assertEquals('example/test_name/test_name.info.yml', $pathname);
}
/**
......@@ -174,7 +174,7 @@ public function testGetPath() {
$test_extension_list = $this->setupTestExtensionList();
$path = $test_extension_list->getPath('test_name');
$this->assertEquals('vfs://drupal_root/example/test_name', $path);
$this->assertEquals('example/test_name', $path);
}
/**
......@@ -184,24 +184,24 @@ public function testReset() {
$test_extension_list = $this->setupTestExtensionList();
$path = $test_extension_list->getPath('test_name');
$this->assertEquals('vfs://drupal_root/example/test_name', $path);
$this->assertEquals('example/test_name', $path);
$pathname = $test_extension_list->getPathname('test_name');
$this->assertEquals('vfs://drupal_root/example/test_name/test_name.info.yml', $pathname);
$this->assertEquals('example/test_name/test_name.info.yml', $pathname);
$filenames = $test_extension_list->getPathnames();
$this->assertEquals([
'test_name' => 'vfs://drupal_root/example/test_name/test_name.info.yml',
'test_name' => 'example/test_name/test_name.info.yml',
], $filenames);
$test_extension_list->reset();
// Ensure that everything is still usable after the resetting.
$path = $test_extension_list->getPath('test_name');
$this->assertEquals('vfs://drupal_root/example/test_name', $path);
$this->assertEquals('example/test_name', $path);
$pathname = $test_extension_list->getPathname('test_name');
$this->assertEquals('vfs://drupal_root/example/test_name/test_name.info.yml', $pathname);
$this->assertEquals('example/test_name/test_name.info.yml', $pathname);
$filenames = $test_extension_list->getPathnames();
$this->assertEquals([
'test_name' => 'vfs://drupal_root/example/test_name/test_name.info.yml',
'test_name' => 'example/test_name/test_name.info.yml',
], $filenames);
}
......@@ -226,7 +226,7 @@ protected function setupTestExtensionList($extension_names = ['test_name']) {
list($cache, $info_parser, $module_handler, $state) = $this->getMocks();
$info_parser->parse(Argument::any())->will(function ($args) {
return Yaml::decode(file_get_contents($args[0]));
return Yaml::decode(file_get_contents('vfs://drupal_root/' . $args[0]));
});
$test_extension_list = new TestExtension('vfs://drupal_root', 'test_extension', $cache->reveal(), $info_parser->reveal(), $module_handler->reveal(), $state->reveal(), 'testing');
......@@ -234,7 +234,7 @@ protected function setupTestExtensionList($extension_names = ['test_name']) {
$extension_discovery = $this->prophesize(ExtensionDiscovery::class);
$extension_scan_result = [];
foreach ($extension_names as $extension_name) {
$extension_scan_result[$extension_name] = new Extension($this->root, 'test_extension', "vfs://drupal_root/example/$extension_name/$extension_name.info.yml");
$extension_scan_result[$extension_name] = new Extension('vfs://drupal_root', 'test_extension', "example/$extension_name/$extension_name.info.yml");
}
$extension_discovery->scan('test_extension')->willReturn($extension_scan_result);
$test_extension_list->setExtensionDiscovery($extension_discovery->reveal());
......
......@@ -5,6 +5,7 @@
use Drupal\Tests\UnitTestCase;
use Drupal\Core\Extension\Extension;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use org\bovigo\vfs\vfsStream;
/**
* Tests Extension serialization.
......@@ -14,6 +15,23 @@
*/
class ExtensionSerializationTest extends UnitTestCase {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
vfsStream::setup('dummy_app_root');
vfsStream::create([
'core' => [
'modules' => [
'system' => [
'system.info.yml' => file_get_contents($this->root . '/core/modules/system/system.info.yml'),
],
],
],
]);
}
/**
* Tests that the Extension class unserialize method uses the preferred root.
*
......@@ -30,12 +48,12 @@ public function testServiceAppRouteUsage() {
$this->assertFalse(defined('DRUPAL_ROOT'), 'Constant DRUPAL_ROOT is defined.');
$container = new ContainerBuilder();
// Set a dummy container app.root to test against.
$container->set('app.root', '/dummy/app/root');
$container->set('app.root', 'vfs://dummy_app_root');
\Drupal::setContainer($container);
// Instantiate an Extension object for testing unserialization.
$extension = new Extension($container->get('app.root'), 'module', 'core/modules/system/system.info.yml', 'system.module');
$extension = unserialize(serialize($extension));
$this->assertEquals('/dummy/app/root', $this->readAttribute($extension, 'root'));
$this->assertEquals('vfs://dummy_app_root', $this->readAttribute($extension, 'root'));
}
/**
......@@ -47,7 +65,7 @@ public function testServiceAppRouteUsage() {
public function testPublicProperties() {
$container = new ContainerBuilder();
// Set a dummy container app.root to test against.
$container->set('app.root', '/dummy/app/root');
$container->set('app.root', 'vfs://dummy_app_root');
\Drupal::setContainer($container);
$extension = new Extension($container->get('app.root'), 'module', 'core/modules/system/system.info.yml', 'system.module');
// Assign a public property dynamically.
......
......@@ -318,7 +318,7 @@ public function testImplementsHookModuleEnabled() {
$module_handler->addModule('module_handler_test_added', 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test_added');
$this->assertTrue($module_handler->implementsHook('module_handler_test_added', 'hook'), 'Runtime added module with implementation in include found.');
$module_handler->addModule('module_handler_test_no_hook', 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test_added');
$module_handler->addModule('module_handler_test_no_hook', 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test_no_hook');
$this->assertFalse($module_handler->implementsHook('module_handler_test_no_hook', 'hook', [TRUE]), 'Missing implementation not found.');
}
......@@ -502,8 +502,8 @@ public function testResetImplementations() {
public function testGetModuleDirectories() {
$module_handler = $this->getModuleHandler();
$module_handler->setModuleList([]);
$module_handler->addModule('module', 'place');
$this->assertEquals(['module' => $this->root . '/place'], $module_handler->getModuleDirectories());
$module_handler->addModule('node', 'core/modules/node');
$this->assertEquals(['node' => $this->root . '/core/modules/node'], $module_handler->getModuleDirectories());
}
}
......@@ -31,29 +31,30 @@ public function testRebuildThemeDataWithThemeParents() {
$extension_discovery
->scan('theme')
->willReturn([
'test_subtheme' => new Extension($this->root, 'theme', $this->root . '/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml', 'test_subtheme.info.yml'),
'test_basetheme' => new Extension($this->root, 'theme', $this->root . '/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml', 'test_basetheme.info.yml'),
'test_subtheme' => new Extension($this->root, 'theme', 'core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml', 'test_subtheme.info.yml'),
'test_basetheme' => new Extension($this->root, 'theme', 'core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml', 'test_basetheme.info.yml'),
]);
$extension_discovery
->scan('theme_engine')
->willReturn([
'twig' => new Extension($this->root, 'theme_engine', $this->root . '/core/themes/engines/twig/twig.info.yml', 'twig.engine'),
'twig' => new Extension($this->root, 'theme_engine', 'core/themes/engines/twig/twig.info.yml', 'twig.engine'),
]);
// Verify that info parser is called with the specified paths.
$argument_condition = function ($path) {
return in_array($path, [
$this->root . '/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml',
$this->root . '/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml',
$this->root . '/core/themes/engines/twig/twig.info.yml',
'core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml',
'core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml',
'core/themes/engines/twig/twig.info.yml',
], TRUE);
};
$info_parser = $this->prophesize(InfoParserInterface::class);
$root = $this->root;
$info_parser->parse(Argument::that($argument_condition))
->shouldBeCalled()
->will(function ($file) {
->will(function ($file) use ($root) {
$info_parser = new InfoParser();
return $info_parser->parse($file[0]);
return $info_parser->parse($root . '/' . $file[0]);
});
$module_handler = $this->prophesize(ModuleHandlerInterface::class);
......@@ -99,9 +100,9 @@ public function testRebuildThemeDataWithThemeParents() {
$info_subtheme->info['base theme'] = 'test_basetheme';
$info_basetheme->sub_themes = ['test_subtheme'];
$this->assertEquals($this->root . '/core/themes/engines/twig/twig.engine', $info_basetheme->owner);
$this->assertEquals('core/themes/engines/twig/twig.engine', $info_basetheme->owner);
$this->assertEquals('twig', $info_basetheme->prefix);
$this->assertEquals($this->root . '/core/themes/engines/twig/twig.engine', $info_subtheme->owner);
$this->assertEquals('core/themes/engines/twig/twig.engine', $info_subtheme->owner);
$this->assertEquals('twig', $info_subtheme->prefix);
}
......
......@@ -80,7 +80,7 @@ public function testRebuildThemeData() {
$this->themeList->expects($this->at(1))
->method('getList')
->will($this->returnValue([
'seven' => new Extension($this->root, 'theme', $this->root . '/core/themes/seven/seven.info.yml', 'seven.theme'),
'seven' => new Extension($this->root, 'theme', 'core/themes/seven/seven.info.yml', 'seven.theme'),
]));
$theme_data = $this->themeHandler->rebuildThemeData();
......@@ -90,8 +90,8 @@ public function testRebuildThemeData() {
// Ensure some basic properties.
$this->assertInstanceOf('Drupal\Core\Extension\Extension', $info);
$this->assertEquals('seven', $info->getName());
$this->assertEquals($this->root . '/core/themes/seven/seven.info.yml', $info->getPathname());
$this->assertEquals($this->root . '/core/themes/seven/seven.theme', $info->getExtensionPathname());
$this->assertEquals('core/themes/seven/seven.info.yml', $info->getPathname());
$this->assertEquals('core/themes/seven/seven.theme', $info->getExtensionPathname());
}
......@@ -99,7 +99,7 @@ public function testRebuildThemeData() {
* Tests empty libraries in theme.info.yml file.
*/
public function testThemeLibrariesEmpty() {
$theme = new Extension($this->root, 'theme', '/core/modules/system/tests/themes/test_theme_libraries_empty', 'test_theme_libraries_empty.info.yml');
$theme = new Extension($this->root, 'theme', 'core/modules/system/tests/themes/test_theme_libraries_empty', 'test_theme_libraries_empty.info.yml');
try {
$this->themeHandler->addTheme($theme);
$this->assertTrue(TRUE, 'Empty libraries key in theme.info.yml does not cause PHP warning');
......
......@@ -70,7 +70,7 @@ protected function setUp() {
$this->moduleHandler->moduleExists('core')->willReturn(FALSE);
$this->moduleHandler->moduleExists('invalid_provider')->willReturn(FALSE);
$module_a = new Extension('/', 'module', vfsStream::url('root/modules/module_a/module_a.layouts.yml'));
$module_a = new Extension('vfs://root', 'module', 'modules/module_a/module_a.layouts.yml');
$this->moduleHandler->getModule('module_a')->willReturn($module_a);
$this->moduleHandler->getModuleDirectories()->willReturn(['module_a' => vfsStream::url('root/modules/module_a')]);
$this->moduleHandler->alter('layout', Argument::type('array'))->shouldBeCalled();
......@@ -81,7 +81,7 @@ protected function setUp() {
$this->themeHandler->themeExists('core')->willReturn(FALSE);
$this->themeHandler->themeExists('invalid_provider')->willReturn(FALSE);
$theme_a = new Extension('/', 'theme', vfsStream::url('root/themes/theme_a/theme_a.layouts.yml'));
$theme_a = new Extension('vfs://root', 'theme', 'themes/theme_a/theme_a.layouts.yml');
$this->themeHandler->getTheme('theme_a')->willReturn($theme_a);
$this->themeHandler->getThemeDirectories()->willReturn(['theme_a' => vfsStream::url('root/themes/theme_a')]);
......@@ -112,7 +112,6 @@ public function testGetDefinitions() {
* @covers ::processDefinition
*/
public function testGetDefinition() {
$theme_a_path = vfsStream::url('root/themes/theme_a');
$layout_definition = $this->layoutPluginManager->getDefinition('theme_a_provided_layout');
$this->assertSame('theme_a_provided_layout', $layout_definition->id());
$this->assertSame('2 column layout', (string) $layout_definition->getLabel());
......@@ -122,10 +121,10 @@ public function testGetDefinition() {
$this->assertTrue($layout_definition->getCategory() instanceof TranslatableMarkup);
$this->assertTrue($layout_definition->getDescription() instanceof TranslatableMarkup);
$this->assertSame('twocol', $layout_definition->getTemplate());
$this->assertSame("$theme_a_path/templates", $layout_definition->getPath());
$this->assertSame('themes/theme_a/templates', $layout_definition->getPath());
$this->assertSame('theme_a/twocol', $layout_definition->getLibrary());
$this->assertSame('twocol', $layout_definition->getThemeHook());
$this->assertSame("$theme_a_path/templates", $layout_definition->getTemplatePath());
$this->assertSame('themes/theme_a/templates', $layout_definition->getTemplatePath());
$this->assertSame('theme_a', $layout_definition->getProvider());
$this->assertSame('right', $layout_definition->getDefaultRegion());
$this->assertSame(LayoutDefault::class, $layout_definition->getClass());
......@@ -142,7 +141,6 @@ public function testGetDefinition() {
$this->assertTrue($regions['left']['label'] instanceof TranslatableMarkup);
$this->assertTrue($regions['right']['label'] instanceof TranslatableMarkup);
$module_a_path = vfsStream::url('root/modules/module_a');
$layout_definition = $this->layoutPluginManager->getDefinition('module_a_provided_layout');
$this->assertSame('module_a_provided_layout', $layout_definition->id());
$this->assertSame('1 column layout', (string) $layout_definition->getLabel());
......@@ -152,7 +150,7 @@ public function testGetDefinition() {
$this->assertTrue($layout_definition->getCategory() instanceof TranslatableMarkup);
$this->assertTrue($layout_definition->getDescription() instanceof TranslatableMarkup);
$this->assertSame(NULL, $layout_definition->getTemplate());
$this->assertSame("$module_a_path/layouts", $layout_definition->getPath());
$this->assertSame('modules/module_a/layouts', $layout_definition->getPath());
$this->assertSame('module_a/onecol', $layout_definition->getLibrary());
$this->assertSame('onecol', $layout_definition->getThemeHook());
$this->assertSame(NULL, $layout_definition->getTemplatePath());
......@@ -226,7 +224,6 @@ public function testProcessDefinition() {
*/
public function testGetThemeImplementations() {
$core_path = '/core/lib/Drupal/Core';
$theme_a_path = vfsStream::url('root/themes/theme_a');
$expected = [
'layout' => [
'render element' => 'content',
......@@ -235,7 +232,7 @@ public function testGetThemeImplementations() {
'render element' => 'content',
'base hook' => 'layout',
'template' => 'twocol',
'path' => "$theme_a_path/templates",
'path' => 'themes/theme_a/templates',
],
'plugin_provided_layout' => [
'render element' => 'content',
......
......@@ -326,6 +326,7 @@ class FunctionalExampleTest {}
vfsStream::create([
'modules' => [
'test_module' => [
'test_module.info.yml' => $test_module_info,
'tests' => [
'src' => [
'Functional' => [
......@@ -491,7 +492,7 @@ public function testGetTestsInProfiles() {
$test_discovery = new TestDiscovery('vfs://drupal', $class_loader->reveal(), $module_handler->reveal());
$result = $test_discovery->getTestClasses(NULL, ['PHPUnit-Kernel']);
$result = $test_discovery->getTestClasses('test_profile_module', ['PHPUnit-Kernel']);
$expected = [
'example3' => [
'Drupal\Tests\test_profile_module\Kernel\KernelExampleTest4' => [
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment