3 namespace Drupal\KernelTests\Core\Config;
5 use Drupal\KernelTests\KernelTestBase;
8 * Calculating the difference between two sets of configuration.
12 class ConfigDiffTest extends KernelTestBase {
19 public static $modules = ['config_test', 'system'];
22 * Tests calculating the difference between two sets of configuration.
24 public function testDiff() {
25 $active = $this->container->get('config.storage');
26 $sync = $this->container->get('config.storage.sync');
27 $config_name = 'config_test.system';
31 $add_data = 'bangpow';
32 $change_data = 'foobar';
34 // Install the default config.
35 $this->installConfig(['config_test']);
36 $original_data = \Drupal::config($config_name)->get();
38 // Change a configuration value in sync.
39 $sync_data = $original_data;
40 $sync_data[$change_key] = $change_data;
41 $sync_data[$add_key] = $add_data;
42 $sync->write($config_name, $sync_data);
44 // Verify that the diff reflects a change.
45 $diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
46 $edits = $diff->getEdits();
47 $this->assertYamlEdit($edits, $change_key, 'change',
48 [$change_key . ': ' . $original_data[$change_key]],
49 [$change_key . ': ' . $change_data]);
51 // Reset data back to original, and remove a key
52 $sync_data = $original_data;
53 unset($sync_data[$remove_key]);
54 $sync->write($config_name, $sync_data);
56 // Verify that the diff reflects a removed key.
57 $diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
58 $edits = $diff->getEdits();
59 $this->assertYamlEdit($edits, $change_key, 'copy');
60 $this->assertYamlEdit($edits, $remove_key, 'delete',
61 [$remove_key . ': ' . $original_data[$remove_key]],
65 // Reset data back to original and add a key
66 $sync_data = $original_data;
67 $sync_data[$add_key] = $add_data;
68 $sync->write($config_name, $sync_data);
70 // Verify that the diff reflects an added key.
71 $diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
72 $edits = $diff->getEdits();
73 $this->assertYamlEdit($edits, $change_key, 'copy');
74 $this->assertYamlEdit($edits, $add_key, 'add', FALSE, [$add_key . ': ' . $add_data]);
76 // Test diffing a renamed config entity.
77 $test_entity_id = $this->randomMachineName();
78 $test_entity = entity_create('config_test', [
79 'id' => $test_entity_id,
80 'label' => $this->randomMachineName(),
83 $data = $active->read('config_test.dynamic.' . $test_entity_id);
84 $sync->write('config_test.dynamic.' . $test_entity_id, $data);
85 $config_name = 'config_test.dynamic.' . $test_entity_id;
86 $diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name, $config_name);
87 // Prove the fields match.
88 $edits = $diff->getEdits();
89 $this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.');
90 $this->assertEqual(count($edits), 1, 'There is one item in the diff');
93 $new_test_entity_id = $this->randomMachineName();
94 $test_entity->set('id', $new_test_entity_id);
97 $diff = \Drupal::service('config.manager')->diff($active, $sync, 'config_test.dynamic.' . $new_test_entity_id, $config_name);
98 $edits = $diff->getEdits();
99 $this->assertYamlEdit($edits, 'uuid', 'copy');
100 $this->assertYamlEdit($edits, 'id', 'change',
101 ['id: ' . $new_test_entity_id],
102 ['id: ' . $test_entity_id]);
103 $this->assertYamlEdit($edits, 'label', 'copy');
104 $this->assertEqual($edits[2]->type, 'copy', 'The third item in the diff is a copy.');
105 $this->assertEqual(count($edits), 3, 'There are three items in the diff.');
109 * Tests calculating the difference between two sets of config collections.
111 public function testCollectionDiff() {
112 /** @var \Drupal\Core\Config\StorageInterface $active */
113 $active = $this->container->get('config.storage');
114 /** @var \Drupal\Core\Config\StorageInterface $sync */
115 $sync = $this->container->get('config.storage.sync');
116 $active_test_collection = $active->createCollection('test');
117 $sync_test_collection = $sync->createCollection('test');
119 $config_name = 'config_test.test';
120 $data = ['foo' => 'bar'];
122 $active->write($config_name, $data);
123 $sync->write($config_name, $data);
124 $active_test_collection->write($config_name, $data);
125 $sync_test_collection->write($config_name, ['foo' => 'baz']);
127 // Test the fields match in the default collection diff.
128 $diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name);
129 $edits = $diff->getEdits();
130 $this->assertEqual($edits[0]->type, 'copy', 'The first item in the diff is a copy.');
131 $this->assertEqual(count($edits), 1, 'There is one item in the diff');
133 // Test that the differences are detected when diffing the collection.
134 $diff = \Drupal::service('config.manager')->diff($active, $sync, $config_name, NULL, 'test');
135 $edits = $diff->getEdits();
136 $this->assertYamlEdit($edits, 'foo', 'change', ['foo: bar'], ['foo: baz']);
140 * Helper method to test that an edit is found in a diff'd YAML file.
142 * @param array $edits
144 * @param string $field
145 * The field key that is being asserted.
146 * @param string $type
147 * The type of edit that is being asserted.
149 * (optional) The original value of of the edit. If not supplied, assertion
151 * @param mixed $closing
152 * (optional) The closing value of of the edit. If not supplied, assertion
155 protected function assertYamlEdit(array $edits, $field, $type, $orig = NULL, $closing = NULL) {
157 foreach ($edits as $edit) {
158 // Choose which section to search for the field.
159 $haystack = $type == 'add' ? $edit->closing : $edit->orig;
160 // Look through each line and try and find the key.
161 if (is_array($haystack)) {
162 foreach ($haystack as $item) {
163 if (strpos($item, $field . ':') === 0) {
165 // Assert that the edit is of the type specified.
166 $this->assertEqual($edit->type, $type, "The $field item in the diff is a $type");
167 // If an original value was given, assert that it matches.
169 $this->assertIdentical($edit->orig, $orig, "The original value for key '$field' is correct.");
171 // If a closing value was given, assert that it matches.
172 if (isset($closing)) {
173 $this->assertIdentical($edit->closing, $closing, "The closing value for key '$field' is correct.");
175 // Break out of the search entirely.
182 // If we didn't match anything, fail.
184 $this->fail("$field edit was not matched");