diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php index b549119..147be46 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php @@ -7,12 +7,12 @@ namespace Drupal\config\Tests; -use Drupal\simpletest\DrupalUnitTestBase; +use Drupal\simpletest\WebTestBase; /** * Tests installation of configuration objects in installation functionality. */ -class ConfigInstallTest extends DrupalUnitTestBase { +class ConfigInstallTest extends WebTestBase { public static function getInfo() { return array( 'name' => 'Installation functionality', @@ -26,42 +26,263 @@ function setUp() { // Ensure the global variable being asserted by this test does not exist; // a previous test executed in this request/process might have set it. + unset($GLOBALS['hook_config_import']); unset($GLOBALS['hook_config_test']); } /** - * Tests module installation. + * Tests installing and uninstalling a module that provides default config. */ function testModuleInstallation() { $default_config = 'config_test.system'; $default_configuration_entity = 'config_test.dynamic.default'; - // Verify that default module config does not exist before installation yet. - $config = config($default_config); - $this->assertIdentical($config->isNew(), TRUE); - $config = config($default_configuration_entity); - $this->assertIdentical($config->isNew(), TRUE); + // Verify that default module config does not exist before installation. + $this->assertNoConfig($default_config, 'after installing the module'); + $this->assertNoConfig($default_configuration_entity, 'after installing the module'); // Install the test module. - $this->enableModules(array('config_test')); + module_enable(array('config_test')); // Verify that default module config exists. - $config = config($default_config); - $this->assertIdentical($config->isNew(), FALSE); - $config = config($default_configuration_entity); - $this->assertIdentical($config->isNew(), FALSE); - - // Verify that configuration import callback was invoked for the dynamic - // configuration entity. - $this->assertTrue($GLOBALS['hook_config_import']); - - // Verify that config_test API hooks were invoked for the dynamic default - // configuration entity. - $this->assertFalse(isset($GLOBALS['hook_config_test']['load'])); - $this->assertTrue(isset($GLOBALS['hook_config_test']['presave'])); - $this->assertTrue(isset($GLOBALS['hook_config_test']['insert'])); - $this->assertFalse(isset($GLOBALS['hook_config_test']['update'])); - $this->assertFalse(isset($GLOBALS['hook_config_test']['predelete'])); - $this->assertFalse(isset($GLOBALS['hook_config_test']['delete'])); + $this->assertConfig($default_config, 'after installing the module'); + $this->assertConfig($default_configuration_entity, 'after installing the module'); + + // Confirm that hook_config_import_create() was invoked for the provided + // default config entity. + $import_hooks = array( + 'create' => TRUE, + 'change' => FALSE, + 'delete' => FALSE, + ); + // $GLOBALS['hook_config_import'] is set in config_test.module. + $this->assertConfigHooks($GLOBALS['hook_config_import'], $import_hooks, 'after installing the module'); + + // Confirm that the insert and presave config_test API hooks were invoked + // for the provided default config entity. + $api_hooks = array( + 'load' => FALSE, + 'presave' => TRUE, + 'insert' => TRUE, + 'update' => FALSE, + 'predelete' => FALSE, + 'delete' => FALSE, + ); + // $GLOBALS['hook_config_test'] is set in config_test.hooks.inc. + $this->assertConfigHooks($GLOBALS['hook_config_test'], $api_hooks, 'after installing the module'); + + // Disable the module and verify that the config is not removed. + module_disable(array('config_test')); + $this->assertConfig($default_config, 'after disabling the module'); + $this->assertConfig($default_configuration_entity, 'after disabling the module'); + + // Uninstall the module and verify that the config was removed. + module_uninstall(array('config_test')); + $this->assertNoConfig($default_config, 'after uninstalling the module'); + $this->assertNoConfig($default_configuration_entity, 'after uninstalling the module'); + } + + /** + * Tests installing config_test_extension_test before config_test. + * + * config_test_extension_test.module provides default configuration in + * config_test.module's namespace. + */ + function testExtensionInstallationFirst() { + // Verify that default module config does not exist before installation. + $extension_config_entity = 'config_test.dynamic.extension_default'; + $this->assertNoConfig($extension_config_entity, 'before installing either module'); + + // Install the extension module. + module_enable(array('config_test_extension_test')); + + // The config_test API is not available, so configuration objects in its + // namespace should not be installed. + $this->assertNoConfig($extension_config_entity, 'after installing config_test_extension_test first'); + + // Install the base API module. + module_enable(array('config_test')); + + // The extension module's default config should now be installed. + $this->assertConfig($extension_config_entity, 'after installing config_test second'); + + // Confirm that hook_config_import_create() was invoked for the provided + // default config entity. + $import_hooks = array( + 'create' => TRUE, + 'change' => FALSE, + 'delete' => FALSE, + ); + // $GLOBALS['hook_config_import'] is set in config_test.module. + $this->assertConfigHooks($GLOBALS['hook_config_import'], $import_hooks, 'after installing config_test second'); + + // Confirm that the insert and presave config_test API hooks were invoked + // for the provided default config entity. + $api_hooks = array( + 'load' => FALSE, + 'presave' => TRUE, + 'insert' => TRUE, + 'update' => FALSE, + 'predelete' => FALSE, + 'delete' => FALSE, + ); + // $GLOBALS['hook_config_test'] is set in config_test.hooks.inc. + $this->assertConfigHooks($GLOBALS['hook_config_test'], $api_hooks, 'after installing config_test second'); + + // Uninstall the extension module. + module_enable(array('config_test_extension_test')); + + // @todo Should the configuration be available here or not? } + + /** + * Tests installing config_test_extension_test after config_test. + * + * config_test_extension_test.module provides default configuration in + * config_test.module's namespace. + */ + function testExtensionInstallationSecond() { + // Verify that default module config does not exist before installation. + $extension_config_entity = 'config_test.dynamic.extension_default'; + $this->assertNoConfig($extension_config_entity, 'before installing either module'); + + // Install the base API module. + module_enable(array('config_test')); + + // The config_test_extension_test module is not yet installed, so its + // default configuration is not installed. + $this->assertNoConfig($extension_config_entity, 'after installing config_test first'); + + // Install the extension module. + module_enable(array('config_test_extension_test')); + + // The extension module's default config should now be installed. + $this->assertConfig($extension_config_entity, 'after installing config_test_extension_test second'); + + // Confirm that hook_config_import_create() was invoked for the provided + // default config entity. + $import_hooks = array( + 'create' => TRUE, + 'change' => FALSE, + 'delete' => FALSE, + ); + // $GLOBALS['hook_config_import'] is set in config_test.module. + $this->assertConfigHooks($GLOBALS['hook_config_import'], $import_hooks, 'after installing config_test_extension_test second'); + + // Confirm that the insert and presave config_test API hooks were invoked + // for the provided default config entity. + $api_hooks = array( + 'load' => FALSE, + 'presave' => TRUE, + 'insert' => TRUE, + 'update' => FALSE, + 'predelete' => FALSE, + 'delete' => FALSE, + ); + // $GLOBALS['hook_config_test'] is set in config_test.hooks.inc. + $this->assertConfigHooks($GLOBALS['hook_config_test'], $api_hooks, 'after installing config_test_extension_test second'); + + // Uninstall the base API module. + module_uninstall(array('config_test')); + + // The test configuration should no longer be available. + $this->assertNoConfig($extension_config_entity, 'after uninstalling config_test'); + } + + /** + * Asserts that a set of config hooks were invoked or not from passed data. + * + * @param array $actual + * An array of the hooks that were invoked (set in globals), with the key + * indicating the type of hook and the value as the hook implementation + * if it was invoked. + * @param array $expected + * An array indicating whether each hook was expected to be invoked or not, + * with the key indicating the type of hook and the value a Boolean + * indicating whether the hook should be invoked. + * @param string $when + * (optional) A text string describing when the assertion was called. + * + * @see config_test.module + * @see config_test.hooks.inc + */ + function assertConfigHooks(array $actual, array $expected, $when = '') { + foreach ($expected as $hook => $value) { + if (!empty($actual[$hook])) { + $function = $actual[$hook]; + } + else { + $function = $hook . ' hook'; + } + $this->assertTrue( + // The hook flag should evaluate to empty if it was not invoked. + ($value != empty($actual[$hook])), + format_string( + '%hook was @invoked @when.', + array( + '%hook' => $function, + '@invoked' => $value ? 'invoked' : 'not invoked', + '@when' => $when, + ) + ) + ); + } + } + + /** + * Asserts that the configuration with the given name is installed. + * + * @param string $name + * The full configuration object name to check, e.g. module.foo.bar. + * @param string $when + * (optional) A text string describing when the assertion was called. + */ + function assertConfig($name, $when = '') { + $config = config($name); + $file = config_get_config_directory() . '/' . $name . '.yml'; + $this->assertIdentical($config->isNew(), FALSE, format_string( + '%config config object exists @when.', + array( + '%config' => $name, + '@when' => $when, + ) + )); + $this->assertTrue(file_exists($file), format_string( + 'File for %config found in %file @when.', + array( + '%config' => $name, + '%file' => $file, + '@when' => $when, + ) + )); + } + + /** + * Asserts that the configuration with the given name is not installed. + * + * @param string $name + * The full configuration object name to check, e.g. module.foo.bar. + * @param string $when + * (optional) A text string describing when the assertion was called. + */ + function assertNoConfig($name, $when = '') { + $file = config_get_config_directory() . '/' . $name . '.yml'; + $config = config($name); + $this->assertIdentical($config->isNew(), TRUE, format_string( + '%config config object does not exist @when.', + array( + '%config' => $name, + '@when' => $when, + ) + )); + $this->assertFalse(file_exists($file), format_string( + 'File for %config not found in %file @when.', + array( + '%config' => $name, + '%file' => $file, + '@when' => $when, + ) + )); + } + } diff --git a/core/modules/config/tests/config_test/config_test.module b/core/modules/config/tests/config_test/config_test.module index 96d4aa0..9d465db 100644 --- a/core/modules/config/tests/config_test/config_test.module +++ b/core/modules/config/tests/config_test/config_test.module @@ -17,7 +17,7 @@ function config_test_config_import_create($name, $new_config, $old_config) { return FALSE; } // Set a global value we can check in test code. - $GLOBALS['hook_config_import'] = __FUNCTION__; + $GLOBALS['hook_config_import']['create'] = __FUNCTION__; $config_test = entity_create('config_test', $new_config->get()); $config_test->save(); @@ -32,7 +32,7 @@ function config_test_config_import_change($name, $new_config, $old_config) { return FALSE; } // Set a global value we can check in test code. - $GLOBALS['hook_config_import'] = __FUNCTION__; + $GLOBALS['hook_config_import']['change'] = __FUNCTION__; // @todo Make this less ugly. list(, , $id) = explode('.', $name); @@ -62,7 +62,7 @@ function config_test_config_import_delete($name, $new_config, $old_config) { return FALSE; } // Set a global value we can check in test code. - $GLOBALS['hook_config_import'] = __FUNCTION__; + $GLOBALS['hook_config_import']['delete'] = __FUNCTION__; // @todo Make this less ugly. list(, , $id) = explode('.', $name); diff --git a/core/modules/config/tests/config_test_extension_test/config/config_test.dynamic.extension_default.yml b/core/modules/config/tests/config_test_extension_test/config/config_test.dynamic.extension_default.yml new file mode 100644 index 0000000..a024b46 --- /dev/null +++ b/core/modules/config/tests/config_test_extension_test/config/config_test.dynamic.extension_default.yml @@ -0,0 +1,2 @@ +id: extension_default +label: Extension module default diff --git a/core/modules/config/tests/config_test_extension_test/config_test_extension_test.info b/core/modules/config/tests/config_test_extension_test/config_test_extension_test.info new file mode 100644 index 0000000..1057788 --- /dev/null +++ b/core/modules/config/tests/config_test_extension_test/config_test_extension_test.info @@ -0,0 +1,6 @@ +name = config_test extension test module +description = Provides default configuration in the config_test namespace. +package = Core +version = VERSION +core = 8.x +hidden = TRUE diff --git a/core/modules/config/tests/config_test_extension_test/config_test_extension_test.module b/core/modules/config/tests/config_test_extension_test/config_test_extension_test.module new file mode 100644 index 0000000..c471336 --- /dev/null +++ b/core/modules/config/tests/config_test_extension_test/config_test_extension_test.module @@ -0,0 +1,8 @@ +