/web/core/modules/views/tests/src/Kernel/Plugin/JoinTest.php

https://gitlab.com/mohamed_hussein/prodt · PHP · 223 lines · 155 code · 31 blank · 37 comment · 0 complexity · a16def68ab6a108837f1b1bef4783312 MD5 · raw file

  1. <?php
  2. namespace Drupal\Tests\views\Kernel\Plugin;
  3. use Drupal\Core\Database\Database;
  4. use Drupal\views_test_data\Plugin\views\join\JoinTest as JoinTestPlugin;
  5. use Drupal\views\Plugin\views\join\JoinPluginBase;
  6. use Drupal\views\Views;
  7. /**
  8. * Tests the join plugin.
  9. *
  10. * @group views
  11. * @see \Drupal\views_test_data\Plugin\views\join\JoinTest
  12. * @see \Drupal\views\Plugin\views\join\JoinPluginBase
  13. */
  14. class JoinTest extends RelationshipJoinTestBase {
  15. /**
  16. * Views used by this test.
  17. *
  18. * @var array
  19. */
  20. public static $testViews = ['test_view'];
  21. /**
  22. * A plugin manager which handlers the instances of joins.
  23. *
  24. * @var \Drupal\views\Plugin\ViewsPluginManager
  25. */
  26. protected $manager;
  27. protected function setUp($import_test_views = TRUE): void {
  28. parent::setUp();
  29. // Add a join plugin manager which can be used in all of the tests.
  30. $this->manager = $this->container->get('plugin.manager.views.join');
  31. }
  32. /**
  33. * Tests an example join plugin.
  34. */
  35. public function testExamplePlugin() {
  36. // Setup a simple join and test the result sql.
  37. $view = Views::getView('test_view');
  38. $view->initDisplay();
  39. $view->initQuery();
  40. $configuration = [
  41. 'left_table' => 'views_test_data',
  42. 'left_field' => 'uid',
  43. 'table' => 'users_field_data',
  44. 'field' => 'uid',
  45. ];
  46. $join = $this->manager->createInstance('join_test', $configuration);
  47. $this->assertInstanceOf(JoinTestPlugin::class, $join);
  48. $rand_int = rand(0, 1000);
  49. $join->setJoinValue($rand_int);
  50. $query = Database::getConnection()->select('views_test_data');
  51. $table = ['alias' => 'users_field_data'];
  52. $join->buildJoin($query, $table, $view->query);
  53. $tables = $query->getTables();
  54. $join_info = $tables['users_field_data'];
  55. $this->assertStringContainsString("views_test_data.uid = $rand_int", $join_info['condition'], 'Make sure that the custom join plugin can extend the join base and alter the result.');
  56. }
  57. /**
  58. * Tests the join plugin base.
  59. */
  60. public function testBasePlugin() {
  61. // Setup a simple join and test the result sql.
  62. $view = Views::getView('test_view');
  63. $view->initDisplay();
  64. $view->initQuery();
  65. // First define a simple join without an extra condition.
  66. // Set the various options on the join object.
  67. $configuration = [
  68. 'left_table' => 'views_test_data',
  69. 'left_field' => 'uid',
  70. 'table' => 'users_field_data',
  71. 'field' => 'uid',
  72. 'adjusted' => TRUE,
  73. ];
  74. $join = $this->manager->createInstance('standard', $configuration);
  75. $this->assertInstanceOf(JoinPluginBase::class, $join);
  76. $this->assertNull($join->extra, 'The field extra was not overridden.');
  77. $this->assertTrue($join->adjusted, 'The field adjusted was set correctly.');
  78. // Build the actual join values and read them back from the dbtng query
  79. // object.
  80. $query = Database::getConnection()->select('views_test_data');
  81. $table = ['alias' => 'users_field_data'];
  82. $join->buildJoin($query, $table, $view->query);
  83. $tables = $query->getTables();
  84. $join_info = $tables['users_field_data'];
  85. $this->assertEquals('LEFT', $join_info['join type'], 'Make sure the default join type is LEFT');
  86. $this->assertEquals($configuration['table'], $join_info['table']);
  87. $this->assertEquals('users_field_data', $join_info['alias']);
  88. $this->assertEquals('views_test_data.uid = users_field_data.uid', $join_info['condition']);
  89. // Set a different alias and make sure table info is as expected.
  90. $join = $this->manager->createInstance('standard', $configuration);
  91. $table = ['alias' => 'users1'];
  92. $join->buildJoin($query, $table, $view->query);
  93. $tables = $query->getTables();
  94. $join_info = $tables['users1'];
  95. $this->assertEquals('users1', $join_info['alias']);
  96. // Set a different join type (INNER) and make sure it is used.
  97. $configuration['type'] = 'INNER';
  98. $join = $this->manager->createInstance('standard', $configuration);
  99. $table = ['alias' => 'users2'];
  100. $join->buildJoin($query, $table, $view->query);
  101. $tables = $query->getTables();
  102. $join_info = $tables['users2'];
  103. $this->assertEquals('INNER', $join_info['join type']);
  104. // Setup addition conditions and make sure it is used.
  105. $random_name_1 = $this->randomMachineName();
  106. $random_name_2 = $this->randomMachineName();
  107. $configuration['extra'] = [
  108. [
  109. 'field' => 'name',
  110. 'value' => $random_name_1,
  111. ],
  112. [
  113. 'field' => 'name',
  114. 'value' => $random_name_2,
  115. 'operator' => '<>',
  116. ],
  117. ];
  118. $join = $this->manager->createInstance('standard', $configuration);
  119. $table = ['alias' => 'users3'];
  120. $join->buildJoin($query, $table, $view->query);
  121. $tables = $query->getTables();
  122. $join_info = $tables['users3'];
  123. $this->assertStringContainsString("views_test_data.uid = users3.uid", $join_info['condition'], 'Make sure the join condition appears in the query.');
  124. $this->assertStringContainsString("users3.name = :views_join_condition_0", $join_info['condition'], 'Make sure the first extra join condition appears in the query and uses the first placeholder.');
  125. $this->assertStringContainsString("users3.name <> :views_join_condition_1", $join_info['condition'], 'Make sure the second extra join condition appears in the query and uses the second placeholder.');
  126. $this->assertEquals([$random_name_1, $random_name_2], array_values($join_info['arguments']), 'Make sure the arguments are in the right order');
  127. // Test that 'IN' conditions are properly built.
  128. $random_name_1 = $this->randomMachineName();
  129. $random_name_2 = $this->randomMachineName();
  130. $random_name_3 = $this->randomMachineName();
  131. $random_name_4 = $this->randomMachineName();
  132. $configuration['extra'] = [
  133. [
  134. 'field' => 'name',
  135. 'value' => $random_name_1,
  136. ],
  137. [
  138. 'field' => 'name',
  139. 'value' => [$random_name_2, $random_name_3, $random_name_4],
  140. ],
  141. ];
  142. $join = $this->manager->createInstance('standard', $configuration);
  143. $table = ['alias' => 'users4'];
  144. $join->buildJoin($query, $table, $view->query);
  145. $tables = $query->getTables();
  146. $join_info = $tables['users4'];
  147. $this->assertStringContainsString("views_test_data.uid = users4.uid", $join_info['condition'], 'Make sure the join condition appears in the query.');
  148. $this->assertStringContainsString("users4.name = :views_join_condition_2", $join_info['condition'], 'Make sure the first extra join condition appears in the query.');
  149. $this->assertStringContainsString("users4.name IN ( :views_join_condition_3[] )", $join_info['condition'], 'The IN condition for the join is properly formed.');
  150. $this->assertEquals([$random_name_2, $random_name_3, $random_name_4], $join_info['arguments'][':views_join_condition_3[]'], 'Make sure the IN arguments are still part of an array.');
  151. // Test that all the conditions are properly built.
  152. $configuration['extra'] = [
  153. [
  154. 'field' => 'langcode',
  155. 'value' => 'en',
  156. ],
  157. [
  158. 'left_field' => 'status',
  159. 'value' => 0,
  160. 'numeric' => TRUE,
  161. ],
  162. [
  163. 'field' => 'name',
  164. 'left_field' => 'name',
  165. ],
  166. ];
  167. $join = $this->manager->createInstance('standard', $configuration);
  168. $table = ['alias' => 'users5'];
  169. $join->buildJoin($query, $table, $view->query);
  170. $tables = $query->getTables();
  171. $join_info = $tables['users5'];
  172. $this->assertStringContainsString("views_test_data.uid = users5.uid", $join_info['condition'], 'Make sure the join condition appears in the query.');
  173. $this->assertStringContainsString("users5.langcode = :views_join_condition_4", $join_info['condition'], 'Make sure the first extra join condition appears in the query.');
  174. $this->assertStringContainsString("views_test_data.status = :views_join_condition_5", $join_info['condition'], 'Make sure the second extra join condition appears in the query.');
  175. $this->assertStringContainsString("users5.name = views_test_data.name", $join_info['condition'], 'Make sure the third extra join condition appears in the query.');
  176. $this->assertEquals(['en', 0], array_values($join_info['arguments']), 'Make sure the arguments are in the right order');
  177. // Test that joins using 'left_formula' are properly built.
  178. $configuration['left_formula'] = 'MAX(views_test_data.uid)';
  179. // When 'left_formula' is present, 'left_field' is no longer required.
  180. unset($configuration['left_field']);
  181. $join = $this->manager->createInstance('standard', $configuration);
  182. $table = ['alias' => 'users6'];
  183. $join->buildJoin($query, $table, $view->query);
  184. $tables = $query->getTables();
  185. $join_info = $tables['users6'];
  186. $this->assertStringContainsString("MAX(views_test_data.uid) = users6.uid", $join_info['condition'], 'Make sure the join condition appears in the query.');
  187. $this->assertStringContainsString("users6.langcode = :views_join_condition_7", $join_info['condition'], 'Make sure the first extra join condition appears in the query.');
  188. $this->assertStringContainsString("views_test_data.status = :views_join_condition_8", $join_info['condition'], 'Make sure the second extra join condition appears in the query.');
  189. $this->assertStringContainsString("users6.name = views_test_data.name", $join_info['condition'], 'Make sure the third extra join condition appears in the query.');
  190. $this->assertEquals(['en', 0], array_values($join_info['arguments']), 'Make sure the arguments are in the right order');
  191. }
  192. }