- <?php
- * @file
- * Tests for Configuration module.
- */
-
- * Tests reading and writing file contents.
- */
- class ConfigurationTest extends BackdropWebTestCase {
- protected function setUp() {
- parent::setUp(array('config_test'));
- }
-
-
- * Tests that a config setting can be written, read and deleted.
- */
- public function testReadWriteClearConfig() {
-
- $config = config('foo.bar');
- $config->set('foo', 'bar');
- $config->save();
- $this->assertEqual('bar', config('foo.bar')->get('foo'), 'Content retrieved from written config data using Config classes.');
- $config->clear('foo');
- $config->save();
- $this->assertNull(config('foo.bar')->get('foo'), 'Deleted config data cannot be retrieved using Config classes.');
-
-
- config_set('foo.bar', 'foo', 'baz');
- $this->assertEqual('baz', config_get('foo.bar', 'foo'), 'Content retrieved from written config data using short cut functions.');
- config_clear('foo.bar', 'foo');
- $this->assertNull(config_get('foo.bar', 'foo'), 'Deleted config data cannot be retrieved using shortcut functions.');
- }
-
-
- * Tests reading existing config files provided by a module.
- */
- public function testExistingConfig() {
-
-
-
-
- $config_names = config_get_names_with_prefix('config_test.group', 'active');
- $expected_names = array(
- 'config_test.group.item_1',
- 'config_test.group.item_2',
- );
- $this->assertEqual($config_names, $expected_names, 'Existing configuration files found by their prefixes.');
-
-
- $item_config = config('config_test.group.item_1');
- try {
- $item_config->validateData();
- $this->pass('Configuration data validated successfully.');
- }
- catch (ConfigValidateException $e) {
- $this->fail('Configuration data unexpectedly failed with the Exception message: ' . $e->getMessage());
- }
-
-
- $item_name = $item_config->get('name');
- $item_config->clear('name');
- try {
- $item_config->validateData();
- $this->fail('Configuration data validated unexpectedly when a ConfigValidateException should have been thrown.');
- }
- catch (ConfigValidateException $e) {
- $this->pass('Configuration data validation properly threw a ConfigValidateException when the name was removed.');
- }
- $item_config->set('name', $item_name);
-
-
- $item_label = $item_config->get('label');
- $item_config->clear('label');
- try {
- $item_config->validateData();
- $this->fail('Configuration data validated unexpectedly when a ConfigValidateException should have been thrown.');
- }
- catch (ConfigValidateException $e) {
- $this->pass('Configuration data validation properly threw a ConfigValidateException when the label was removed.');
- }
- $item_config->set('label', $item_label);
-
-
- $config = config('config_test.simple');
- $expected_config = array(
- 'favorite_animal' => 'cats',
- 'favorite_color' => 'blue',
- );
-
- $this->assertEqual($config->get(), $expected_config, 'The configuration file via Config::get() contained the expected configuration.');
- $this->assertEqual($config->getData(), $expected_config, 'The configuration file via Config::getData() contained the expected configuration.');
- }
-
-
- * Tests that a config setting can be overridden.
- */
- public function testOverrideConfig() {
- $original_data = array(
- 'foo' => array(
- 'key1' => 'value1',
- 'key2' => 'value2',
- 'key3' => 'value3',
- ),
- 'bar' => array(
- 'keyA' => 'valueA',
- 'keyB' => 'valueB',
- ),
- );
-
-
- $config_data = config('config.test');
- $config_data->setData($original_data);
- $config_data->save();
-
- $this->assertEqual('value1', config('config.test')->get('foo.key1'), 'Sample config retrieved from written config data using Config classes.');
- $this->assertEqual('valueB', config('config.test')->get('bar.keyB'), 'Sample config retrieved from written config data using Config classes.');
-
-
- $GLOBALS['config']['config.test']['foo.key1'] = 'chocolate';
- $config_data = config('config.test');
- $this->assertEqual('chocolate', $config_data->get('foo.key1'), 'Config variable overridden in global configuration override.');
- $this->assertTrue(config_is_overridden('config.test', 'foo.key1'), 'Nested config variable is overridden.');
- $this->assertFalse(config_is_overridden('config.test', 'foo'), 'Root config variable not considered overridden.');
- $this->assertEqual($original_data['foo']['key2'], $config_data->get('foo.key2'), 'Sibling key not affected by override.');
- $this->assertEqual($original_data['bar'], $config_data->get('bar'), 'Uncle key not affected by override.');
-
-
- $override_data = array(
- 'key1' => 'chocolate',
- 'key2' => 'vanilla',
- );
- unset($GLOBALS['config']['config.test']['foo.key1']);
- $GLOBALS['config']['config.test']['foo'] = $override_data;
-
- $config_data = config('config.test');
- $this->assertEqual('chocolate', $config_data->get('foo.key1'), 'Config variable overridden in global configuration override.');
- $this->assertEqual('vanilla', $config_data->get('foo.key2'), 'Config variable overridden in global configuration override.');
- $this->assertEqual($override_data, $config_data->get('foo'), 'Entire set of nested data overridden. Discarding 3rd undefined key.');
- $this->assertTrue(config_is_overridden('config.test', 'foo.key1'), 'Nested config variable is overridden when overriding parent.');
- $this->assertTrue(config_is_overridden('config.test', 'foo'), 'Root config variable is considered overridden when overriding parent.');
-
-
- $config_data->set('foo.key1', 'chocolate');
- $config_data->save();
-
- $config_data = config('config.test');
- $this->assertEqual('chocolate', config('config.test')->get('foo.key1'), 'Config variable still overridden and cannot be set regular way.');
- $this->assertEqual($config_data->getOriginal('foo.key1'), 'value1', 'Config original value still in place.');
- $this->assertEqual($config_data->getOverride('foo.key1'), 'chocolate', 'Overridden value retrieved correctly.');
-
-
- $config_data->set('foo.key1', 'chocolate', TRUE);
- $config_data->save();
-
-
-
- unset($GLOBALS['config']['config.test']['foo']);
- $config_data = config('config.test');
- $this->assertEqual(FALSE, $config_data->isOverridden('foo.key1'), 'Original value no longer overridden.');
- $this->assertEqual($config_data->get('foo.key1'), 'chocolate', 'Original value has been updated to include overridden value.');
- }
-
-
- * Tests that config directories are protected by .htaccess files.
- */
- public function testConfigHtaccess() {
-
- $active_storage = config_get_config_storage();
- $active_dir = config_get_config_directory();
- if (!is_a($active_storage, 'ConfigFileStorage')) {
- $this->assert(TRUE, 'Config storage is not file-based, so .htaccess test skipped.');
- return;
- }
-
-
- $admin_user = $this->backdropCreateUser(array(
- 'access administration pages',
- 'access site reports',
- ));
- $this->backdropLogin($admin_user);
-
-
- @backdrop_unlink($active_dir . '/.htaccess');
- $this->assertFalse(is_file($active_dir . '/.htaccess'), "Removed the .htaccess file in the 'active' config directory.");
-
- $this->backdropGet('admin/reports/status');
- $this->assertTrue(is_file($active_dir . '/.htaccess'), "Re-created the .htaccess file in the 'active' config directory.");
-
-
- $file = file_get_contents($active_dir . '/.htaccess');
- $this->assertEqual($file, file_htaccess_lines(), 'The .htaccess file contains the proper content.');
- }
- }
-
- * Tests hooks for validation, creating, updating, and deleting configurations.
- */
- class ConfigurationHooksTest extends BackdropWebTestCase {
- protected function setUp() {
- parent::setUp(array('config_test', 'config_test_hooks'));
- }
-
-
- * Tests checking the validation hooks.
- *
- * This test does not include a test of hook_config_data_validate() as it is
- * tested by ConfigurationTest::testExistingConfig().
- */
- public function testHooks() {
- $config_data = config_get('config_test.simple');
- module_load_include('inc', 'config', 'config.sync');
-
-
- $config_data['favorite_animal'] = 'rabbits';
- $errors = array(
- 'create' => 'Sorry, only bunnies allowed as favorite animals.',
- 'update' => 'Sorry, cats must be preferred over rabbits.',
- 'delete' => 'Favorite animals are in use.',
- );
- foreach (array('create', 'update', 'delete') as $op) {
- try {
- config_sync_validate_file('config_test.simple', $op, NULL, $config_data);
- $this->fail('Validation during "' . $op . '" unexpectedly passed when it should have failed.');
- }
- catch (ConfigValidateException $e) {
- $this->assertEqual($errors[$op], $e->getMessage(), 'Validation during "' . $op . '" configuration threw an error correctly.');
- }
- }
-
-
- $expected_data = array(
- 'create' => array(
- 'favorite_animal' => 'rabbits',
- 'favorite_color' => 'red',
- ),
- 'update' => array(
- 'favorite_animal' => 'rabbits',
- 'favorite_color' => 'blue',
- ),
- 'delete' => array(
- 'favorite_animal' => 'cats',
- 'favorite_color' => 'blue',
- 'deleted_animal' => 'rabbits'
- ),
- );
- foreach (array('create', 'update') as $op) {
- config_sync_file('config_test.new_config', $op, $config_data);
- $new_data = config_get('config_test.new_config');
- $this->assertEqual($expected_data[$op], $new_data, 'Configuration hook for "' . $op . '" executed properly.');
- }
-
-
-
- config_sync_file('config_test.new_config', 'delete');
- $new_data = config_get('config_test.simple');
- $this->assertEqual($expected_data['delete'], $new_data, 'Configuration hook for "delete" executed properly.');
- }
- }
-
- * Tests the UI for syncing, importing, and exporting.
- */
- class ConfigurationUITest extends BackdropWebTestCase {
-
-
- * @var User
- */
- protected $webUser;
-
- function setUp() {
- parent::setUp(array('config_test'));
-
- $this->webUser = $this->backdropCreateUser(array('synchronize configuration'));
- $this->backdropLogin($this->webUser);
- }
-
-
- * Tests importing configuration.
- */
- function testImport() {
- $name = 'config_test.simple';
- $dynamic_name = 'config_test.dynamic.new';
- $staging_storage = new ConfigFileStorage(config_get_config_directory('staging'));
-
- $this->backdropGet('admin/config/development/configuration');
- $this->assertText('There are no configuration changes currently staged.');
- $this->assertNoFieldById('edit-submit', t('Import all'));
-
-
- $this->copyConfig('active', 'staging');
-
-
- $favorite_animal = 'Animal ' . $this->randomString();
- $staging_config = config($name, 'staging');
- $staging_config->set('favorite_animal', $favorite_animal);
- $staging_config->save();
-
- $this->assertIdentical($staging_storage->exists($name), TRUE, $name . ' found.');
-
-
- $original_dynamic_data = array(
- 'id' => 'new',
- 'label' => 'New',
- 'weight' => 0,
- 'status' => TRUE,
- );
- $staging_storage->write($dynamic_name, $original_dynamic_data);
- $this->assertIdentical($staging_storage->exists($dynamic_name), TRUE, $dynamic_name . ' found in staging.');
-
-
- $this->backdropGet('admin/config/development/configuration');
- $this->assertText($name);
- $this->assertText($dynamic_name);
- $this->assertFieldById('edit-submit', t('Import all'));
-
-
- state_set('config_sync', REQUEST_TIME);
- $this->backdropPost(NULL, array(), t('Import all'));
- $this->assertText('Another request may be synchronizing configuration already or a sync failed unexpectedly.');
- state_del('config_sync');
-
-
- $this->backdropPost(NULL, array(), t('Import all'));
- $this->assertNoText($name);
- $this->assertNoText($dynamic_name);
- $this->assertNoFieldById('edit-submit', t('Import all'));
-
-
- $this->assertText('There are no configuration changes currently staged.');
-
-
- $this->assertIdentical($favorite_animal, config_get($name, 'favorite_animal'));
-
-
- $this->assertIdentical($original_dynamic_data, config_get($dynamic_name));
-
-
- $this->copyConfig('active', 'staging');
- $dynamic_name2 = $dynamic_name . '2';
- $staging_storage->write($dynamic_name2, $original_dynamic_data);
- $this->assertIdentical($staging_storage->exists($dynamic_name2), TRUE, $dynamic_name2 . ' found in staging.');
-
-
- $this->backdropPost('admin/config/development/configuration', array(), t('Import all'));
-
-
- $error_message = t('The configuration "@name" is not owned by any module. Try enabling the module that provides this configuration, then importing again.', array('@name' => $dynamic_name2));
- $this->assertText($error_message, 'Validation properly prevents import when a config is not declared by a module.');
-
-
- $staging_storage->deleteAll();
- }
-
-
- * Tests the screen that shows differences between active and staging.
- */
- function testDiff() {
- $staging_storage = new ConfigFileStorage(config_get_config_directory('staging'));
-
- $config_name = 'config_test.simple';
- $change_key = 'favorite_animal';
- $remove_key = 'favorite_color';
- $add_key = 'favorite_day';
- $add_data = 'friday';
- $change_data = 'bunnies';
- $original_data = array(
- 'favorite_animal' => 'cats',
- 'favorite_color' => 'blue',
- );
-
-
- $this->copyConfig('active', 'staging');
-
-
- $staging_data = $original_data;
- $staging_data[$change_key] = $change_data;
- $staging_data[$add_key] = $add_data;
- unset($staging_data[$remove_key]);
- $staging_storage->write($config_name, $staging_data);
-
-
- $this->backdropGet('admin/config/development/configuration/sync/diff/' . $config_name);
- $deleted_words = $this->xpath('//td[contains(@class, :class)]//del', array(':class' => 'diff-deletedline'));
- $this->assertEqual($original_data[$change_key], (string) $deleted_words[0]);
- $this->assertEqual($remove_key, (string) $deleted_words[1]);
- $this->assertEqual($original_data[$remove_key], (string) $deleted_words[2]);
-
- $added_words = $this->xpath('//td[contains(@class, :class)]//ins', array(':class' => 'diff-addedline'));
- $this->assertEqual($change_data, (string) $added_words[0]);
- $this->assertEqual($add_key, (string) $added_words[1]);
- $this->assertEqual($add_data, (string) $added_words[2]);
- }
-
-
- * Tests export of configuration.
- */
- function testExport() {
-
- $this->backdropGet('admin/config/development/configuration/full/export');
- $this->assertFieldById('edit-submit', t('Export'));
-
-
- $this->backdropPost('admin/config/development/configuration/full/export', array(), t('Export'));
- $this->assertResponse(200, 'User can access the download callback.');
-
-
- $archive_data = $this->backdropGetContent();
-
-
- $uri = 'temporary://config.tar.gz';
- file_put_contents($uri, $archive_data);
-
-
- $file_path = file_directory_temp() . '/' . file_uri_target($uri);
- $archiver = new Archive_Tar($file_path);
- $archive_contents = $archiver->listContent();
- $archive_files = array();
- foreach ($archive_contents as $file) {
- $archive_files[] = $file['filename'];
- }
- $this->assert(!empty($archive_files), 'Downloaded archive file is not empty.');
-
-
- $storage_active = config_get_config_storage('active');
- $config_files = array();
- foreach ($storage_active->listAll() as $config_name) {
- $config_files[] = $config_name . '.json';
- }
-
-
- $this->assertIdentical($archive_files, $config_files, 'Downloaded archive contains all active configuration files.');
-
-
- unlink($uri);
- }
-
-
- * Test full import validation.
- */
- function testFullImportValidation() {
-
- $core_modules = db_query("SELECT name FROM {system} WHERE type = 'module' AND filename LIKE 'core/modules%' AND filename NOT LIKE '%/tests/%'")->fetchCol();
- module_enable($core_modules);
-
-
- $this->backdropPost('admin/config/development/configuration/full/export', array(), t('Export'));
- $this->assertResponse(200, 'User can access the download callback.');
-
-
- $archive_data = $this->backdropGetContent();
-
-
- $uri = 'temporary://config.tar.gz';
- file_put_contents($uri, $archive_data);
- $realpath = backdrop_realpath($uri);
-
-
- $directory = 'temporary://' . basename($uri, '.tar.gz');
- $archiver = new Archive_Tar($realpath);
- file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
- $archiver->extract($directory);
-
-
- unset($archiver);
- unlink($uri);
-
-
- $files = file_scan_directory($directory, '/.*\.json/');
- foreach ($files as $filepath => $file) {
- $config_data = json_decode(file_get_contents($filepath), TRUE);
-
- if (strpos($file->name, 'layout.layout.') === 0) {
- $config_data['layout_template'] = 'simmons';
- }
- elseif (strpos($file->name, 'taxonomy.vocabulary.') === 0) {
- $config_data['description'] = 'config_test_addition';
- }
- else {
- $config_data['config_test_addition'] = 'test';
- }
- file_put_contents($filepath, backdrop_json_encode($config_data, TRUE));
- }
-
-
- $archiver = new Archive_Tar($realpath);
- $archiver->createModify(array_keys($files), '', $directory);
-
-
- file_unmanaged_delete_recursive($directory);
-
-
- $edit = array(
- 'files[import_tarball]' => $uri,
- );
- $this->backdropPost('admin/config/development/configuration/full', $edit, t('Stage import'));
-
-
- unlink($uri);
-
- $this->backdropGet('admin/config/development/configuration');
-
-
- foreach ($files as $file) {
- $this->assertText(str_replace('.json', '', $file->filename), format_string('Config file "@file" staged for import.', array('@file' => $file->filename)));
- }
-
- $this->backdropPost(NULL, array(), t('Import all'));
-
-
- $this->assertText(t('Configuration sync completed. @files configuration files synced.', array('@files' => count($files))));
-
-
- $errors = $this->xpath('//div[@id="messages"]//div[contains(@class, "error")]');
- if (count($errors)) {
- $this->fail(strip_tags($errors[0]->asXML()));
- }
- }
-
-
- * Test skipping the clearing of the staging directory after import.
- */
- public function testClearStagingDirectory() {
- $staging_storage = new ConfigFileStorage(config_get_config_directory('staging'));
-
-
- $this->copyConfig('active', 'staging');
-
-
- $staging_config = config('system.core', 'staging');
- $staging_config->set('config_sync_clear_staging', 0);
- $staging_config->save();
-
-
- $this->backdropGet('admin/config/development/configuration');
- $this->assertText('system.core');
-
-
- $this->backdropPost(NULL, array(), t('Import all'));
-
-
- $staging_files = $staging_storage->listAll();
- $this->assert(!empty($staging_files), 'Staging directory is not empty.');
- }
-
-
- * Test comparing configs whose elements are in different order.
- */
- public function testConfigOrderChange() {
- $config_name = 'foo.bar';
- $content = array(
- 'a' => 'Foo',
- 'b' => 'Bar',
- );
- $config = config($config_name);
- $config->setData($content);
- $config->save();
-
-
- $this->copyConfig('active', 'staging');
-
-
- krsort($content);
-
-
- $config->setData($content);
- $config->save();
-
-
- $this->backdropGet('admin/config/development/configuration');
- $this->assertText($config_name, 'The configuration name appears in the list of changed configurations.');
- }
-
-
- * Copies configuration objects from source storage to target storage.
- *
- * @param string $source
- * The source config storage name.
- * @param string $target
- * The target config storage name.
- */
- public function copyConfig($source = 'active', $target = 'staging') {
- $source_storage = config_get_config_storage($source);
- $target_storage = config_get_config_storage($target);
- $target_storage->deleteAll();
- foreach ($source_storage->listAll() as $name) {
- $target_storage->write($name, $source_storage->read($name));
- }
- }
- }
-
- * Tests that hook_config_create() is run during config sync.
- */
- class ConfigurationSyncTest extends BackdropWebTestCase {
- protected $profile = 'testing';
-
-
- * @var User
- */
- protected $admin_user;
-
- protected function setUp() {
- parent::setUp(array('config_test_hooks'));
-
-
-
- $this->backdropCreateContentType(array(
- 'type' => 'post',
- 'name' => 'Post',
- ));
-
- $this->admin_user = $this->backdropCreateUser(array(
- 'access administration pages',
- 'bypass node access',
- 'administer nodes',
- 'create post content',
- 'edit any post content',
- ));
- }
-
-
- * Tests that hook_config_create() is run during config sync.
- */
- public function testSync() {
- $config_data = config_get('config_test_hooks.data');
- $this->assertEqual('brie', $config_data['favorite_cheese'], 'Config variable is set to brie.');
- $this->assertFalse(field_info_field('field_config_test'), 'The test field does not exist.');
-
- module_enable(array('config_test'));
-
-
- $config_data = config_get('config_test_hooks.data');
- $this->assertEqual('cheddar', $config_data['favorite_cheese'], 'Config variable is set to cheddar.');
- $this->assertTrue(field_info_field('field_config_test'), 'The test field has been installed.');
-
-
-
- $this->backdropLogin($this->admin_user);
- $this->backdropPost('node/add/post', array(
- 'title' => 'Test post',
- 'field_config_test[und][0][value]' => 'Test value in the new field',
- ), t('Save'));
-
- $this->assertText('Post Test post has been created.');
- $this->assertText('Test value in the new field');
- }
- }