/**
  * Tests the missing content event is fired.
  *
  * @see \Drupal\Core\Config\ConfigImporter::processMissingContent()
  * @see \Drupal\config_import_test\EventSubscriber
  */
 function testMissingContent()
 {
     \Drupal::state()->set('config_import_test.config_import_missing_content', TRUE);
     // Update a configuration entity in the sync directory to have a dependency
     // on two content entities that do not exist.
     $storage = $this->container->get('config.storage');
     $sync = $this->container->get('config.storage.sync');
     $entity_one = entity_create('entity_test', array('name' => 'one'));
     $entity_two = entity_create('entity_test', array('name' => 'two'));
     $entity_three = entity_create('entity_test', array('name' => 'three'));
     $dynamic_name = 'config_test.dynamic.dotted.default';
     $original_dynamic_data = $storage->read($dynamic_name);
     // Entity one will be resolved by
     // \Drupal\config_import_test\EventSubscriber::onConfigImporterMissingContentOne().
     $original_dynamic_data['dependencies']['content'][] = $entity_one->getConfigDependencyName();
     // Entity two will be resolved by
     // \Drupal\config_import_test\EventSubscriber::onConfigImporterMissingContentTwo().
     $original_dynamic_data['dependencies']['content'][] = $entity_two->getConfigDependencyName();
     // Entity three will be resolved by
     // \Drupal\Core\Config\Importer\FinalMissingContentSubscriber.
     $original_dynamic_data['dependencies']['content'][] = $entity_three->getConfigDependencyName();
     $sync->write($dynamic_name, $original_dynamic_data);
     // Import.
     $this->configImporter->reset()->import();
     $this->assertEqual([], $this->configImporter->getErrors(), 'There were no errors during the import.');
     $this->assertEqual($entity_one->uuid(), \Drupal::state()->get('config_import_test.config_import_missing_content_one'), 'The missing content event is fired during configuration import.');
     $this->assertEqual($entity_two->uuid(), \Drupal::state()->get('config_import_test.config_import_missing_content_two'), 'The missing content event is fired during configuration import.');
     $original_dynamic_data = $storage->read($dynamic_name);
     $this->assertEqual([$entity_one->getConfigDependencyName(), $entity_two->getConfigDependencyName(), $entity_three->getConfigDependencyName()], $original_dynamic_data['dependencies']['content'], 'The imported configuration entity has the missing content entity dependency.');
 }
 /**
  * Tests config import updates.
  */
 function testConfigImportUpdates()
 {
     $entity_type_id = 'entity_test_mul';
     $config_id = $entity_type_id . '.' . $entity_type_id;
     $config_name = 'language.content_settings.' . $config_id;
     $storage = $this->container->get('config.storage');
     $sync = $this->container->get('config.storage.sync');
     // Verify the configuration to create does not exist yet.
     $this->assertIdentical($storage->exists($config_name), FALSE, $config_name . ' not found.');
     // Create new config entity.
     $data = array('uuid' => 'a019d89b-c4d9-4ed4-b859-894e4e2e93cf', 'langcode' => 'en', 'status' => TRUE, 'dependencies' => array('module' => array('content_translation')), 'id' => $config_id, 'target_entity_type_id' => 'entity_test_mul', 'target_bundle' => 'entity_test_mul', 'default_langcode' => 'site_default', 'language_alterable' => FALSE, 'third_party_settings' => array('content_translation' => array('enabled' => TRUE)));
     $sync->write($config_name, $data);
     $this->assertIdentical($sync->exists($config_name), TRUE, $config_name . ' found.');
     // Import.
     $this->configImporter->reset()->import();
     // Verify the values appeared.
     $config = $this->config($config_name);
     $this->assertIdentical($config->get('id'), $config_id);
     // Verify that updates were performed.
     $entity_type = $this->container->get('entity.manager')->getDefinition($entity_type_id);
     $table = $entity_type->getDataTable();
     $db_schema = $this->container->get('database')->schema();
     $result = $db_schema->fieldExists($table, 'content_translation_source') && $db_schema->fieldExists($table, 'content_translation_outdated');
     $this->assertTrue($result, 'Content translation updates were successfully performed during config import.');
 }
Пример #3
0
 public function testRecreateEntity()
 {
     $type_name = Unicode::strtolower($this->randomMachineName(16));
     $content_type = entity_create('node_type', array('type' => $type_name, 'name' => 'Node type one'));
     $content_type->save();
     node_add_body_field($content_type);
     /** @var \Drupal\Core\Config\StorageInterface $active */
     $active = $this->container->get('config.storage');
     /** @var \Drupal\Core\Config\StorageInterface $sync */
     $sync = $this->container->get('config.storage.sync');
     $config_name = $content_type->getEntityType()->getConfigPrefix() . '.' . $content_type->id();
     $this->copyConfig($active, $sync);
     // Delete the content type. This will also delete a field storage, a field,
     // an entity view display and an entity form display.
     $content_type->delete();
     $this->assertFalse($active->exists($config_name), 'Content type\'s old name does not exist active store.');
     // Recreate with the same type - this will have a different UUID.
     $content_type = entity_create('node_type', array('type' => $type_name, 'name' => 'Node type two'));
     $content_type->save();
     node_add_body_field($content_type);
     $this->configImporter->reset();
     // A node type, a field, an entity view display and an entity form display
     // will be recreated.
     $creates = $this->configImporter->getUnprocessedConfiguration('create');
     $deletes = $this->configImporter->getUnprocessedConfiguration('delete');
     $this->assertEqual(5, count($creates), 'There are 5 configuration items to create.');
     $this->assertEqual(5, count($deletes), 'There are 5 configuration items to delete.');
     $this->assertEqual(0, count($this->configImporter->getUnprocessedConfiguration('update')), 'There are no configuration items to update.');
     $this->assertIdentical($creates, array_reverse($deletes), 'Deletes and creates contain the same configuration names in opposite orders due to dependencies.');
     $this->configImporter->import();
     // Verify that there is nothing more to import.
     $this->assertFalse($this->configImporter->reset()->hasUnprocessedConfigurationChanges());
     $content_type = NodeType::load($type_name);
     $this->assertEqual('Node type one', $content_type->label());
 }
 /**
  * Tests configuration renaming validation for simple configuration.
  */
 public function testRenameSimpleConfigValidation()
 {
     $uuid = new Php();
     // Create a simple configuration with a UUID.
     $config = $this->config('config_test.new');
     $uuid_value = $uuid->generate();
     $config->set('uuid', $uuid_value)->save();
     $active = $this->container->get('config.storage');
     $sync = $this->container->get('config.storage.sync');
     $this->copyConfig($active, $sync);
     $config->delete();
     // Create another simple configuration with the same UUID.
     $config = $this->config('config_test.old');
     $config->set('uuid', $uuid_value)->save();
     // Confirm that the staged configuration is detected as a rename since the
     // UUIDs match.
     $this->configImporter->reset();
     $expected = array('config_test.old::config_test.new');
     $renames = $this->configImporter->getUnprocessedConfiguration('rename');
     $this->assertIdentical($expected, $renames);
     // Try to import the configuration. We expect an exception to be thrown
     // because the rename is for simple configuration.
     try {
         $this->configImporter->import();
         $this->fail('Expected ConfigImporterException thrown when simple configuration is renamed.');
     } catch (ConfigImporterException $e) {
         $this->pass('Expected ConfigImporterException thrown when simple configuration is renamed.');
         $expected = array(SafeMarkup::format('Rename operation for simple configuration. Existing configuration @old_name and staged configuration @new_name.', array('@old_name' => 'config_test.old', '@new_name' => 'config_test.new')));
         $this->assertEqual($expected, $this->configImporter->getErrors());
     }
 }
Пример #5
0
 /**
  * Tests missing core.extension during configuration import.
  *
  * @see \Drupal\Core\EventSubscriber\ConfigImportSubscriber
  */
 public function testMissingCoreExtension()
 {
     $staging = $this->container->get('config.storage.staging');
     $staging->delete('core.extension');
     try {
         $this->configImporter->reset()->import();
         $this->fail('ConfigImporterException not thrown, invalid import was not stopped due to missing dependencies.');
     } catch (ConfigImporterException $e) {
         $this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
         $error_log = $this->configImporter->getErrors();
         $this->assertEqual(['The core.extension configuration does not exist.'], $error_log);
     }
 }
 /**
  * Tests deleting a contact form entity via a configuration import.
  *
  * @see \Drupal\Core\Entity\Event\BundleConfigImportValidate
  */
 public function testDeleteThroughImport()
 {
     $contact_form = ContactForm::create(['id' => 'test']);
     $contact_form->save();
     $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
     // Set up the ConfigImporter object for testing.
     $storage_comparer = new StorageComparer($this->container->get('config.storage.sync'), $this->container->get('config.storage'), $this->container->get('config.manager'));
     $config_importer = new ConfigImporter($storage_comparer->createChangelist(), $this->container->get('event_dispatcher'), $this->container->get('config.manager'), $this->container->get('lock'), $this->container->get('config.typed'), $this->container->get('module_handler'), $this->container->get('module_installer'), $this->container->get('theme_handler'), $this->container->get('string_translation'));
     // Delete the contact message in sync.
     $sync = $this->container->get('config.storage.sync');
     $sync->delete($contact_form->getConfigDependencyName());
     // Import.
     $config_importer->reset()->import();
     $this->assertNull(ContactForm::load($contact_form->id()), 'The contact form has been deleted.');
 }
Пример #7
0
 /**
  * Tests install profile validation during configuration import.
  *
  * @see \Drupal\Core\EventSubscriber\ConfigImportSubscriber
  */
 public function testInstallProfile()
 {
     $sync = $this->container->get('config.storage.sync');
     $extensions = $sync->read('core.extension');
     // Add an install profile.
     $extensions['module']['standard'] = 0;
     $sync->write('core.extension', $extensions);
     try {
         $this->configImporter->reset()->import();
         $this->fail('ConfigImporterException not thrown; an invalid import was not stopped due to missing dependencies.');
     } catch (ConfigImporterException $e) {
         $this->assertEqual($e->getMessage(), 'There were errors validating the config synchronization.');
         $error_log = $this->configImporter->getErrors();
         // Install profiles should not even be scanned at this point.
         $this->assertEqual(['Unable to install the <em class="placeholder">standard</em> module since it does not exist.'], $error_log);
     }
 }
Пример #8
0
 /**
  * Tests the isSyncing flags.
  */
 public function testIsSyncingInHooks()
 {
     $dynamic_name = 'config_test.dynamic.dotted.default';
     $storage = $this->container->get('config.storage');
     // Verify the default configuration values exist.
     $config = $this->config($dynamic_name);
     $this->assertSame('dotted.default', $config->get('id'));
     // Delete the config so that create hooks will fire.
     $storage->delete($dynamic_name);
     \Drupal::state()->set('config_test.store_isSyncing', []);
     $this->configImporter->reset()->import();
     // The values of the syncing values should be stored in state by
     // config_test_config_test_create().
     $state = \Drupal::state()->get('config_test.store_isSyncing');
     $this->assertTrue($state['global_state::create'], '\\Drupal::isConfigSyncing() returns TRUE');
     $this->assertTrue($state['entity_state::create'], 'ConfigEntity::isSyncing() returns TRUE');
     $this->assertTrue($state['global_state::presave'], '\\Drupal::isConfigSyncing() returns TRUE');
     $this->assertTrue($state['entity_state::presave'], 'ConfigEntity::isSyncing() returns TRUE');
     $this->assertTrue($state['global_state::insert'], '\\Drupal::isConfigSyncing() returns TRUE');
     $this->assertTrue($state['entity_state::insert'], 'ConfigEntity::isSyncing() returns TRUE');
     // Cause a config update so update hooks will fire.
     $config = $this->config($dynamic_name);
     $config->set('label', 'A new name')->save();
     \Drupal::state()->set('config_test.store_isSyncing', []);
     $this->configImporter->reset()->import();
     // The values of the syncing values should be stored in state by
     // config_test_config_test_create().
     $state = \Drupal::state()->get('config_test.store_isSyncing');
     $this->assertTrue($state['global_state::presave'], '\\Drupal::isConfigSyncing() returns TRUE');
     $this->assertTrue($state['entity_state::presave'], 'ConfigEntity::isSyncing() returns TRUE');
     $this->assertTrue($state['global_state::update'], '\\Drupal::isConfigSyncing() returns TRUE');
     $this->assertTrue($state['entity_state::update'], 'ConfigEntity::isSyncing() returns TRUE');
     // Cause a config delete so delete hooks will fire.
     $sync = $this->container->get('config.storage.sync');
     $sync->delete($dynamic_name);
     \Drupal::state()->set('config_test.store_isSyncing', []);
     $this->configImporter->reset()->import();
     // The values of the syncing values should be stored in state by
     // config_test_config_test_create().
     $state = \Drupal::state()->get('config_test.store_isSyncing');
     $this->assertTrue($state['global_state::predelete'], '\\Drupal::isConfigSyncing() returns TRUE');
     $this->assertTrue($state['entity_state::predelete'], 'ConfigEntity::isSyncing() returns TRUE');
     $this->assertTrue($state['global_state::delete'], '\\Drupal::isConfigSyncing() returns TRUE');
     $this->assertTrue($state['entity_state::delete'], 'ConfigEntity::isSyncing() returns TRUE');
 }
Пример #9
0
 /**
  * Tests updating of configuration during import.
  */
 function testUpdated()
 {
     $name = 'config_test.system';
     $dynamic_name = 'config_test.dynamic.dotted.default';
     $storage = $this->container->get('config.storage');
     $staging = $this->container->get('config.storage.staging');
     // Verify that the configuration objects to import exist.
     $this->assertIdentical($storage->exists($name), TRUE, $name . ' found.');
     $this->assertIdentical($storage->exists($dynamic_name), TRUE, $dynamic_name . ' found.');
     // Replace the file content of the existing configuration objects in the
     // staging directory.
     $original_name_data = array('foo' => 'beer');
     $staging->write($name, $original_name_data);
     $original_dynamic_data = $storage->read($dynamic_name);
     $original_dynamic_data['label'] = 'Updated';
     $staging->write($dynamic_name, $original_dynamic_data);
     // Verify the active configuration still returns the default values.
     $config = \Drupal::config($name);
     $this->assertIdentical($config->get('foo'), 'bar');
     $config = \Drupal::config($dynamic_name);
     $this->assertIdentical($config->get('label'), 'Default');
     // Import.
     $this->configImporter->reset()->import();
     // Verify the values were updated.
     \Drupal::configFactory()->reset($name);
     $config = \Drupal::config($name);
     $this->assertIdentical($config->get('foo'), 'beer');
     $config = \Drupal::config($dynamic_name);
     $this->assertIdentical($config->get('label'), 'Updated');
     // Verify that the original file content is still the same.
     $this->assertIdentical($staging->read($name), $original_name_data);
     $this->assertIdentical($staging->read($dynamic_name), $original_dynamic_data);
     // Verify that appropriate module API hooks have been invoked.
     $this->assertTrue(isset($GLOBALS['hook_config_test']['load']));
     $this->assertTrue(isset($GLOBALS['hook_config_test']['presave']));
     $this->assertFalse(isset($GLOBALS['hook_config_test']['insert']));
     $this->assertTrue(isset($GLOBALS['hook_config_test']['update']));
     $this->assertFalse(isset($GLOBALS['hook_config_test']['predelete']));
     $this->assertFalse(isset($GLOBALS['hook_config_test']['delete']));
     // Verify that there is nothing more to import.
     $this->assertFalse($this->configImporter->hasUnprocessedConfigurationChanges());
     $logs = $this->configImporter->getErrors();
     $this->assertEqual(count($logs), 0);
 }
Пример #10
0
 /**
  * Returns a ConfigImporter object to import test importing of configuration.
  *
  * @return \Drupal\Core\Config\ConfigImporter
  *   The ConfigImporter object.
  */
 public function configImporter()
 {
     if (!$this->configImporter) {
         // Set up the ConfigImporter object for testing.
         $storage_comparer = new StorageComparer($this->container->get('config.storage.staging'), $this->container->get('config.storage'), $this->container->get('config.manager'));
         $this->configImporter = new ConfigImporter($storage_comparer, $this->container->get('event_dispatcher'), $this->container->get('config.manager'), $this->container->get('lock'), $this->container->get('config.typed'), $this->container->get('module_handler'), $this->container->get('module_installer'), $this->container->get('theme_handler'), $this->container->get('string_translation'));
     }
     // Always recalculate the changelist when called.
     return $this->configImporter->reset();
 }