PageRenderTime 38ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/web/core/modules/content_translation/tests/src/Kernel/ContentTranslationSyncUnitTest.php

https://gitlab.com/mohamed_hussein/prodt
PHP | 260 lines | 159 code | 27 blank | 74 comment | 32 complexity | 4df745a7c8303b7e02b1c67c721f742f MD5 | raw file
  1. <?php
  2. namespace Drupal\Tests\content_translation\Kernel;
  3. use Drupal\content_translation\FieldTranslationSynchronizer;
  4. use Drupal\KernelTests\KernelTestBase;
  5. /**
  6. * Tests the field synchronization logic.
  7. *
  8. * @group content_translation
  9. */
  10. class ContentTranslationSyncUnitTest extends KernelTestBase {
  11. /**
  12. * The synchronizer class to be tested.
  13. *
  14. * @var \Drupal\content_translation\FieldTranslationSynchronizer
  15. */
  16. protected $synchronizer;
  17. /**
  18. * The columns to be synchronized.
  19. *
  20. * @var array
  21. */
  22. protected $synchronized;
  23. /**
  24. * All the field columns.
  25. *
  26. * @var array
  27. */
  28. protected $columns;
  29. /**
  30. * The available language codes.
  31. *
  32. * @var array
  33. */
  34. protected $langcodes;
  35. /**
  36. * The field cardinality.
  37. *
  38. * @var int
  39. */
  40. protected $cardinality;
  41. /**
  42. * The unchanged field values.
  43. *
  44. * @var array
  45. */
  46. protected $unchangedFieldValues;
  47. protected static $modules = ['language', 'content_translation'];
  48. protected function setUp(): void {
  49. parent::setUp();
  50. $this->synchronizer = new FieldTranslationSynchronizer($this->container->get('entity_type.manager'), $this->container->get('plugin.manager.field.field_type'));
  51. $this->synchronized = ['sync1', 'sync2'];
  52. $this->columns = array_merge($this->synchronized, ['var1', 'var2']);
  53. $this->langcodes = ['en', 'it', 'fr', 'de', 'es'];
  54. $this->cardinality = 4;
  55. $this->unchangedFieldValues = [];
  56. // Set up an initial set of values in the correct state, that is with
  57. // "synchronized" values being equal.
  58. foreach ($this->langcodes as $langcode) {
  59. for ($delta = 0; $delta < $this->cardinality; $delta++) {
  60. foreach ($this->columns as $column) {
  61. $sync = in_array($column, $this->synchronized) && $langcode != $this->langcodes[0];
  62. $value = $sync ? $this->unchangedFieldValues[$this->langcodes[0]][$delta][$column] : $langcode . '-' . $delta . '-' . $column;
  63. $this->unchangedFieldValues[$langcode][$delta][$column] = $value;
  64. }
  65. }
  66. }
  67. }
  68. /**
  69. * Tests the field synchronization algorithm.
  70. */
  71. public function testFieldSync() {
  72. // Add a new item to the source items and check that its added to all the
  73. // translations.
  74. $sync_langcode = $this->langcodes[2];
  75. $unchanged_items = $this->unchangedFieldValues[$sync_langcode];
  76. $field_values = $this->unchangedFieldValues;
  77. $item = [];
  78. foreach ($this->columns as $column) {
  79. $item[$column] = $this->randomMachineName();
  80. }
  81. $field_values[$sync_langcode][] = $item;
  82. $this->synchronizer->synchronizeItems($field_values, $unchanged_items, $sync_langcode, $this->langcodes, $this->synchronized);
  83. $result = TRUE;
  84. foreach ($this->unchangedFieldValues as $langcode => $items) {
  85. // Check that the old values are still in place.
  86. for ($delta = 0; $delta < $this->cardinality; $delta++) {
  87. foreach ($this->columns as $column) {
  88. $result = $result && ($this->unchangedFieldValues[$langcode][$delta][$column] == $field_values[$langcode][$delta][$column]);
  89. }
  90. }
  91. // Check that the new item is available in all languages.
  92. foreach ($this->columns as $column) {
  93. $result = $result && ($field_values[$langcode][$delta][$column] == $field_values[$sync_langcode][$delta][$column]);
  94. }
  95. }
  96. $this->assertTrue($result, 'A new item has been correctly synchronized.');
  97. // Remove an item from the source items and check that its removed from all
  98. // the translations.
  99. $sync_langcode = $this->langcodes[1];
  100. $unchanged_items = $this->unchangedFieldValues[$sync_langcode];
  101. $field_values = $this->unchangedFieldValues;
  102. $sync_delta = mt_rand(0, count($field_values[$sync_langcode]) - 1);
  103. unset($field_values[$sync_langcode][$sync_delta]);
  104. // Renumber deltas to start from 0.
  105. $field_values[$sync_langcode] = array_values($field_values[$sync_langcode]);
  106. $this->synchronizer->synchronizeItems($field_values, $unchanged_items, $sync_langcode, $this->langcodes, $this->synchronized);
  107. $result = TRUE;
  108. foreach ($this->unchangedFieldValues as $langcode => $items) {
  109. $new_delta = 0;
  110. // Check that the old values are still in place.
  111. for ($delta = 0; $delta < $this->cardinality; $delta++) {
  112. // Skip the removed item.
  113. if ($delta != $sync_delta) {
  114. foreach ($this->columns as $column) {
  115. $result = $result && ($this->unchangedFieldValues[$langcode][$delta][$column] == $field_values[$langcode][$new_delta][$column]);
  116. }
  117. $new_delta++;
  118. }
  119. }
  120. }
  121. $this->assertTrue($result, 'A removed item has been correctly synchronized.');
  122. // Move the items around in the source items and check that they are moved
  123. // in all the translations.
  124. $sync_langcode = $this->langcodes[3];
  125. $unchanged_items = $this->unchangedFieldValues[$sync_langcode];
  126. $field_values = $this->unchangedFieldValues;
  127. $field_values[$sync_langcode] = [];
  128. // Scramble the items.
  129. foreach ($unchanged_items as $delta => $item) {
  130. $new_delta = ($delta + 1) % $this->cardinality;
  131. $field_values[$sync_langcode][$new_delta] = $item;
  132. }
  133. // Renumber deltas to start from 0.
  134. ksort($field_values[$sync_langcode]);
  135. $this->synchronizer->synchronizeItems($field_values, $unchanged_items, $sync_langcode, $this->langcodes, $this->synchronized);
  136. $result = TRUE;
  137. foreach ($field_values as $langcode => $items) {
  138. for ($delta = 0; $delta < $this->cardinality; $delta++) {
  139. foreach ($this->columns as $column) {
  140. $value = $field_values[$langcode][$delta][$column];
  141. if (in_array($column, $this->synchronized)) {
  142. // If we are dealing with a synchronize column the current value is
  143. // supposed to be the same of the source items.
  144. $result = $result && $field_values[$sync_langcode][$delta][$column] == $value;
  145. }
  146. else {
  147. // Otherwise the values should be unchanged.
  148. $old_delta = ($delta > 0 ? $delta : $this->cardinality) - 1;
  149. $result = $result && $this->unchangedFieldValues[$langcode][$old_delta][$column] == $value;
  150. }
  151. }
  152. }
  153. }
  154. $this->assertTrue($result, 'Scrambled items have been correctly synchronized.');
  155. }
  156. /**
  157. * Tests that items holding the same values are correctly synchronized.
  158. */
  159. public function testMultipleSyncedValues() {
  160. $sync_langcode = $this->langcodes[1];
  161. $unchanged_items = $this->unchangedFieldValues[$sync_langcode];
  162. // Determine whether the unchanged values should be altered depending on
  163. // their delta.
  164. $delta_callbacks = [
  165. // Continuous field values: all values are equal.
  166. function ($delta) {
  167. return TRUE;
  168. },
  169. // Alternated field values: only the even ones are equal.
  170. function ($delta) {
  171. return $delta % 2 !== 0;
  172. },
  173. // Sparse field values: only the "middle" ones are equal.
  174. function ($delta) {
  175. return $delta === 1 || $delta === 2;
  176. },
  177. // Sparse field values: only the "extreme" ones are equal.
  178. function ($delta) {
  179. return $delta === 0 || $delta === 3;
  180. },
  181. ];
  182. foreach ($delta_callbacks as $delta_callback) {
  183. $field_values = $this->unchangedFieldValues;
  184. for ($delta = 0; $delta < $this->cardinality; $delta++) {
  185. if ($delta_callback($delta)) {
  186. foreach ($this->columns as $column) {
  187. if (in_array($column, $this->synchronized)) {
  188. $field_values[$sync_langcode][$delta][$column] = $field_values[$sync_langcode][0][$column];
  189. }
  190. }
  191. }
  192. }
  193. $changed_items = $field_values[$sync_langcode];
  194. $this->synchronizer->synchronizeItems($field_values, $unchanged_items, $sync_langcode, $this->langcodes, $this->synchronized);
  195. foreach ($this->unchangedFieldValues as $langcode => $unchanged_items) {
  196. for ($delta = 0; $delta < $this->cardinality; $delta++) {
  197. foreach ($this->columns as $column) {
  198. // The first item is always unchanged hence it is retained by the
  199. // synchronization process. The other ones are retained or synced
  200. // depending on the logic implemented by the delta callback and
  201. // whether it is a sync column or not.
  202. $value = $delta > 0 && $delta_callback($delta) && in_array($column, $this->synchronized) ? $changed_items[0][$column] : $unchanged_items[$delta][$column];
  203. $this->assertEquals($field_values[$langcode][$delta][$column], $value, "Item $delta column $column for langcode $langcode synced correctly");
  204. }
  205. }
  206. }
  207. }
  208. }
  209. /**
  210. * Tests that one change in a synchronized column triggers a change in all columns.
  211. */
  212. public function testDifferingSyncedColumns() {
  213. $sync_langcode = $this->langcodes[2];
  214. $unchanged_items = $this->unchangedFieldValues[$sync_langcode];
  215. $field_values = $this->unchangedFieldValues;
  216. for ($delta = 0; $delta < $this->cardinality; $delta++) {
  217. $index = ($delta % 2) + 1;
  218. $field_values[$sync_langcode][$delta]['sync' . $index] .= '-updated';
  219. }
  220. $changed_items = $field_values[$sync_langcode];
  221. $this->synchronizer->synchronizeItems($field_values, $unchanged_items, $sync_langcode, $this->langcodes, $this->synchronized);
  222. foreach ($this->unchangedFieldValues as $langcode => $unchanged_items) {
  223. for ($delta = 0; $delta < $this->cardinality; $delta++) {
  224. foreach ($this->columns as $column) {
  225. // If the column is synchronized, the value should have been synced,
  226. // for unsynchronized columns, the value must not change.
  227. $expected_value = in_array($column, $this->synchronized) ? $changed_items[$delta][$column] : $this->unchangedFieldValues[$langcode][$delta][$column];
  228. $this->assertEquals($expected_value, $field_values[$langcode][$delta][$column], "Differing Item {$delta} column {$column} for langcode {$langcode} synced correctly");
  229. }
  230. }
  231. }
  232. }
  233. }