ConfigDiffTest.php 7.0 KB

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