X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=web%2Fcore%2Ftests%2FDrupal%2FKernelTests%2FCore%2FEntity%2FEntityQueryTest.php;h=a6819f01905084c3b19557897dc70ad9b706f8fa;hb=refs%2Fheads%2Fd864;hp=5c7e51cbc5984bd10a64d6ffcc1f6227037c062d;hpb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae;p=yaffs-website diff --git a/web/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php b/web/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php index 5c7e51cbc..a6819f019 100644 --- a/web/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php +++ b/web/core/tests/Drupal/KernelTests/Core/Entity/EntityQueryTest.php @@ -2,7 +2,6 @@ namespace Drupal\KernelTests\Core\Entity; -use Drupal\Component\Utility\Unicode; use Drupal\entity_test\Entity\EntityTest; use Drupal\entity_test\Entity\EntityTestMulRev; use Drupal\field\Entity\FieldConfig; @@ -10,6 +9,7 @@ use Drupal\field\Entity\FieldStorageConfig; use Drupal\language\Entity\ConfigurableLanguage; use Drupal\taxonomy\Entity\Term; use Drupal\taxonomy\Entity\Vocabulary; +use Drupal\Tests\field\Traits\EntityReferenceTestTrait; use Symfony\Component\HttpFoundation\Request; /** @@ -19,6 +19,8 @@ use Symfony\Component\HttpFoundation\Request; */ class EntityQueryTest extends EntityKernelTestBase { + use EntityReferenceTestTrait; + /** * Modules to enable. * @@ -31,11 +33,6 @@ class EntityQueryTest extends EntityKernelTestBase { */ protected $queryResults; - /** - * @var \Drupal\Core\Entity\Query\QueryFactory - */ - protected $factory; - /** * A list of bundle machine names created for this test. * @@ -57,6 +54,13 @@ class EntityQueryTest extends EntityKernelTestBase { */ public $figures; + /** + * The entity_test_mulrev entity storage. + * + * @var \Drupal\Core\Entity\EntityStorageInterface + */ + protected $storage; + protected function setUp() { parent::setUp(); @@ -64,8 +68,8 @@ class EntityQueryTest extends EntityKernelTestBase { $this->installConfig(['language']); - $figures = Unicode::strtolower($this->randomMachineName()); - $greetings = Unicode::strtolower($this->randomMachineName()); + $figures = mb_strtolower($this->randomMachineName()); + $greetings = mb_strtolower($this->randomMachineName()); foreach ([$figures => 'shape', $greetings => 'text'] as $field_name => $field_type) { $field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, @@ -94,23 +98,27 @@ class EntityQueryTest extends EntityKernelTestBase { } // Each unit is a list of field name, langcode and a column-value array. $units[] = [$figures, 'en', [ - 'color' => 'red', - 'shape' => 'triangle', - ]]; + 'color' => 'red', + 'shape' => 'triangle', + ], + ]; $units[] = [$figures, 'en', [ - 'color' => 'blue', - 'shape' => 'circle', - ]]; + 'color' => 'blue', + 'shape' => 'circle', + ], + ]; // To make it easier to test sorting, the greetings get formats according // to their langcode. $units[] = [$greetings, 'tr', [ - 'value' => 'merhaba', - 'format' => 'format-tr' - ]]; + 'value' => 'merhaba', + 'format' => 'format-tr', + ], + ]; $units[] = [$greetings, 'pl', [ - 'value' => 'siema', - 'format' => 'format-pl' - ]]; + 'value' => 'siema', + 'format' => 'format-pl', + ], + ]; // Make these languages available to the greetings field. ConfigurableLanguage::createFromLangcode('tr')->save(); ConfigurableLanguage::createFromLangcode('pl')->save(); @@ -130,8 +138,11 @@ class EntityQueryTest extends EntityKernelTestBase { } foreach (array_reverse(str_split(decbin($i))) as $key => $bit) { if ($bit) { - list($field_name, $langcode, $values) = $units[$key]; - $entity->getTranslation($langcode)->{$field_name}[] = $values; + // @todo https://www.drupal.org/project/drupal/issues/3001920 Doing + // list($field_name, $langcode, $values) = $units[$key]; causes + // problems in PHP 7.3. Revert to better variable names once + // https://bugs.php.net/bug.php?id=76937 is fixed. + $entity->getTranslation($units[$key][1])->{$units[$key][0]}[] = $units[$key][2]; } } $entity->save(); @@ -139,7 +150,7 @@ class EntityQueryTest extends EntityKernelTestBase { $this->bundles = $bundles; $this->figures = $figures; $this->greetings = $greetings; - $this->factory = \Drupal::service('entity.query'); + $this->storage = $this->container->get('entity_type.manager')->getStorage('entity_test_mulrev'); } /** @@ -148,7 +159,8 @@ class EntityQueryTest extends EntityKernelTestBase { public function testEntityQuery() { $greetings = $this->greetings; $figures = $this->figures; - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->exists($greetings, 'tr') ->condition("$figures.color", 'red') ->sort('id') @@ -157,7 +169,8 @@ class EntityQueryTest extends EntityKernelTestBase { // bit 0 and bit 2 needs to be set. $this->assertResult(5, 7, 13, 15); - $query = $this->factory->get('entity_test_mulrev', 'OR') + $query = $this->storage + ->getQuery('OR') ->exists($greetings, 'tr') ->condition("$figures.color", 'red') ->sort('id'); @@ -169,7 +182,8 @@ class EntityQueryTest extends EntityKernelTestBase { $this->assertResult(1, 3, 4, 5, 6, 7, 9, 11, 12, 13, 14, 15); // Test cloning of query conditions. - $query = $this->factory->get('entity_test_mulrev') + $query = $this->storage + ->getQuery() ->condition("$figures.color", 'red') ->sort('id'); $cloned_query = clone $query; @@ -182,7 +196,7 @@ class EntityQueryTest extends EntityKernelTestBase { $this->queryResults = $cloned_query->execute(); $this->assertResult(); - $query = $this->factory->get('entity_test_mulrev'); + $query = $this->storage->getQuery(); $group = $query->orConditionGroup() ->exists($greetings, 'tr') ->condition("$figures.color", 'red'); @@ -195,7 +209,8 @@ class EntityQueryTest extends EntityKernelTestBase { $this->assertResult(9, 11, 12, 13, 14, 15); // No figure has both the colors blue and red at the same time. - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("$figures.color", 'blue') ->condition("$figures.color", 'red') ->sort('id') @@ -203,7 +218,7 @@ class EntityQueryTest extends EntityKernelTestBase { $this->assertResult(); // But an entity might have a red and a blue figure both. - $query = $this->factory->get('entity_test_mulrev'); + $query = $this->storage->getQuery(); $group_blue = $query->andConditionGroup()->condition("$figures.color", 'blue'); $group_red = $query->andConditionGroup()->condition("$figures.color", 'red'); $this->queryResults = $query @@ -215,7 +230,7 @@ class EntityQueryTest extends EntityKernelTestBase { $this->assertResult(3, 7, 11, 15); // Do the same test but with IN operator. - $query = $this->factory->get('entity_test_mulrev'); + $query = $this->storage->getQuery(); $group_blue = $query->andConditionGroup()->condition("$figures.color", ['blue'], 'IN'); $group_red = $query->andConditionGroup()->condition("$figures.color", ['red'], 'IN'); $this->queryResults = $query @@ -227,14 +242,16 @@ class EntityQueryTest extends EntityKernelTestBase { $this->assertResult(3, 7, 11, 15); // An entity might have either red or blue figure. - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("$figures.color", ['blue', 'red'], 'IN') ->sort('id') ->execute(); // Bit 0 or 1 is on. $this->assertResult(1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15); - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->exists("$figures.color") ->notExists("$greetings.value") ->sort('id') @@ -243,7 +260,8 @@ class EntityQueryTest extends EntityKernelTestBase { $this->assertResult(1, 2, 3); // Now update the 'merhaba' string to xsiemax which is not a meaningful // word but allows us to test revisions and string operations. - $ids = $this->factory->get('entity_test_mulrev') + $ids = $this->storage + ->getQuery() ->condition("$greetings.value", 'merhaba') ->sort('id') ->execute(); @@ -257,30 +275,35 @@ class EntityQueryTest extends EntityKernelTestBase { $entity->save(); } // We changed the entity names, so the current revision should not match. - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition('name.value', $old_name) ->execute(); $this->assertResult(); // Only if all revisions are queried, we find the old revision. - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition('name.value', $old_name) ->allRevisions() ->sort('revision_id') ->execute(); $this->assertRevisionResult([$first_entity->id()], [$first_entity->id()]); // When querying current revisions, this string is no longer found. - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("$greetings.value", 'merhaba') ->execute(); $this->assertResult(); - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("$greetings.value", 'merhaba') ->allRevisions() ->sort('revision_id') ->execute(); // The query only matches the original revisions. $this->assertRevisionResult([4, 5, 6, 7, 12, 13, 14, 15], [4, 5, 6, 7, 12, 13, 14, 15]); - $results = $this->factory->get('entity_test_mulrev') + $results = $this->storage + ->getQuery() ->condition("$greetings.value", 'siema', 'CONTAINS') ->sort('id') ->execute(); @@ -288,21 +311,24 @@ class EntityQueryTest extends EntityKernelTestBase { // revisions are returned for some entities. $assert = [16 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15']; $this->assertIdentical($results, $assert); - $results = $this->factory->get('entity_test_mulrev') + $results = $this->storage + ->getQuery() ->condition("$greetings.value", 'siema', 'STARTS_WITH') ->sort('revision_id') ->execute(); // Now we only get the ones that originally were siema, entity id 8 and // above. $this->assertIdentical($results, array_slice($assert, 4, 8, TRUE)); - $results = $this->factory->get('entity_test_mulrev') + $results = $this->storage + ->getQuery() ->condition("$greetings.value", 'a', 'ENDS_WITH') ->sort('revision_id') ->execute(); // It is very important that we do not get the ones which only have // xsiemax despite originally they were merhaba, ie. ended with a. $this->assertIdentical($results, array_slice($assert, 4, 8, TRUE)); - $results = $this->factory->get('entity_test_mulrev') + $results = $this->storage + ->getQuery() ->condition("$greetings.value", 'a', 'ENDS_WITH') ->allRevisions() ->sort('id') @@ -311,6 +337,17 @@ class EntityQueryTest extends EntityKernelTestBase { // Now we get everything. $assert = [4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 12 => '12', 20 => '12', 13 => '13', 21 => '13', 14 => '14', 22 => '14', 15 => '15', 23 => '15']; $this->assertIdentical($results, $assert); + + // Check that a query on the latest revisions without any condition returns + // the correct results. + $results = $this->storage + ->getQuery() + ->latestRevision() + ->sort('id') + ->sort('revision_id') + ->execute(); + $expected = [1 => '1', 2 => '2', 3 => '3', 16 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15']; + $this->assertSame($expected, $results); } /** @@ -322,15 +359,18 @@ class EntityQueryTest extends EntityKernelTestBase { $greetings = $this->greetings; $figures = $this->figures; // Order up and down on a number. - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->sort('id') ->execute(); $this->assertResult(range(1, 15)); - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->sort('id', 'DESC') ->execute(); $this->assertResult(range(15, 1)); - $query = $this->factory->get('entity_test_mulrev') + $query = $this->storage + ->getQuery() ->sort("$figures.color") ->sort("$greetings.format") ->sort('id'); @@ -380,7 +420,8 @@ class EntityQueryTest extends EntityKernelTestBase { 'page' => '0,2', ]); \Drupal::getContainer()->get('request_stack')->push($request); - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->sort("$figures.color") ->sort("$greetings.format") ->sort('id') @@ -389,7 +430,8 @@ class EntityQueryTest extends EntityKernelTestBase { $this->assertResult(15, 6, 7, 1); // Now test the reversed order. - $query = $this->factory->get('entity_test_mulrev') + $query = $this->storage + ->getQuery() ->sort("$figures.color", 'DESC') ->sort("$greetings.format", 'DESC') ->sort('id', 'DESC'); @@ -418,7 +460,8 @@ class EntityQueryTest extends EntityKernelTestBase { 'type' => ['data' => 'Type', 'specifier' => 'type'], ]; - $this->queryResults = array_values($this->factory->get('entity_test_mulrev') + $this->queryResults = array_values($this->storage + ->getQuery() ->tableSort($header) ->execute()); $this->assertBundleOrder('asc'); @@ -432,7 +475,8 @@ class EntityQueryTest extends EntityKernelTestBase { 'id' => ['data' => 'Id', 'specifier' => 'id'], 'type' => ['data' => 'Type', 'specifier' => 'type'], ]; - $this->queryResults = array_values($this->factory->get('entity_test_mulrev') + $this->queryResults = array_values($this->storage + ->getQuery() ->tableSort($header) ->execute()); $this->assertBundleOrder('desc'); @@ -442,7 +486,8 @@ class EntityQueryTest extends EntityKernelTestBase { 'order' => 'Id', ]); \Drupal::getContainer()->get('request_stack')->push($request); - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->tableSort($header) ->execute(); $this->assertResult(range(15, 1)); @@ -477,7 +522,9 @@ class EntityQueryTest extends EntityKernelTestBase { // As the single entity of this type we just saved does not have a value // in the color field, the result should be 0. - $count = $this->factory->get('entity_test') + $count = $this->container->get('entity_type.manager') + ->getStorage('entity_test') + ->getQuery() ->exists("$field_name.color") ->count() ->execute(); @@ -490,7 +537,7 @@ class EntityQueryTest extends EntityKernelTestBase { public function testNestedConditionGroups() { // Query for all entities of the first bundle that have either a red // triangle as a figure or the Turkish greeting as a greeting. - $query = $this->factory->get('entity_test_mulrev'); + $query = $this->storage->getQuery(); $first_and = $query->andConditionGroup() ->condition($this->figures . '.color', 'red') @@ -509,7 +556,32 @@ class EntityQueryTest extends EntityKernelTestBase { ->sort('id') ->execute(); - $this->assertResult(6, 14); + $this->assertResult(4, 6, 12, 14); + } + + /** + * Tests that condition count returns expected number of conditions. + */ + public function testConditionCount() { + // Query for all entities of the first bundle that + // have red as a colour AND are triangle shaped. + $query = $this->storage->getQuery(); + + // Add an AND condition group with 2 conditions in it. + $and_condition_group = $query->andConditionGroup() + ->condition($this->figures . '.color', 'red') + ->condition($this->figures . '.shape', 'triangle'); + + // We added 2 conditions so count should be 2. + $this->assertEqual($and_condition_group->count(), 2); + + // Add an OR condition group with 2 conditions in it. + $or_condition_group = $query->orConditionGroup() + ->condition($this->figures . '.color', 'red') + ->condition($this->figures . '.shape', 'triangle'); + + // We added 2 conditions so count should be 2. + $this->assertEqual($or_condition_group->count(), 2); } /** @@ -518,14 +590,16 @@ class EntityQueryTest extends EntityKernelTestBase { public function testDelta() { $figures = $this->figures; // Test numeric delta value in field condition. - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("$figures.0.color", 'red') ->sort('id') ->execute(); // As unit 0 at delta 0 was the red triangle bit 0 needs to be set. $this->assertResult(1, 3, 5, 7, 9, 11, 13, 15); - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("$figures.1.color", 'red') ->sort('id') ->execute(); @@ -533,7 +607,7 @@ class EntityQueryTest extends EntityKernelTestBase { $this->assertResult(); // Test on two different deltas. - $query = $this->factory->get('entity_test_mulrev'); + $query = $this->storage->getQuery(); $or = $query->andConditionGroup() ->condition("$figures.0.color", 'red') ->condition("$figures.1.color", 'blue'); @@ -544,7 +618,8 @@ class EntityQueryTest extends EntityKernelTestBase { $this->assertResult(3, 7, 11, 15); // Test the delta range condition. - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("$figures.%delta.color", ['blue', 'red'], 'IN') ->condition("$figures.%delta", [0, 1], 'IN') ->sort('id') @@ -553,21 +628,24 @@ class EntityQueryTest extends EntityKernelTestBase { $this->assertResult(1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15); // Test the delta range condition without conditions on the value. - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("$figures.%delta", 1) ->sort('id') ->execute(); - // Entity needs to have atleast two figures. + // Entity needs to have at least two figures. $this->assertResult(3, 7, 11, 15); // Numeric delta on single value base field should return results only if // the first item is being targeted. - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("id.0.value", [1, 3, 5], 'IN') ->sort('id') ->execute(); $this->assertResult(1, 3, 5); - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("id.1.value", [1, 3, 5], 'IN') ->sort('id') ->execute(); @@ -575,18 +653,21 @@ class EntityQueryTest extends EntityKernelTestBase { // Delta range condition on single value base field should return results // only if just the field value is targeted. - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("id.%delta.value", [1, 3, 5], 'IN') ->sort('id') ->execute(); $this->assertResult(1, 3, 5); - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("id.%delta.value", [1, 3, 5], 'IN') ->condition("id.%delta", 0, '=') ->sort('id') ->execute(); $this->assertResult(1, 3, 5); - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition("id.%delta.value", [1, 3, 5], 'IN') ->condition("id.%delta", 1, '=') ->sort('id') @@ -643,7 +724,7 @@ class EntityQueryTest extends EntityKernelTestBase { * The tags and metadata should propagate to the SQL query object. */ public function testMetaData() { - $query = \Drupal::entityQuery('entity_test_mulrev'); + $query = $this->storage->getQuery(); $query ->addTag('efq_metadata_test') ->addMetaData('foo', 'bar') @@ -667,7 +748,7 @@ class EntityQueryTest extends EntityKernelTestBase { 'translatable' => FALSE, 'settings' => [ 'case_sensitive' => FALSE, - ] + ], ]); $field_storage->save(); @@ -703,8 +784,8 @@ class EntityQueryTest extends EntityKernelTestBase { $string = $this->randomMachineName(7) . 'a'; $fixtures[] = [ 'original' => $string, - 'uppercase' => Unicode::strtoupper($string), - 'lowercase' => Unicode::strtolower($string), + 'uppercase' => mb_strtoupper($string), + 'lowercase' => mb_strtolower($string), ]; } @@ -713,140 +794,161 @@ class EntityQueryTest extends EntityKernelTestBase { 'name' => $this->randomMachineName(), 'langcode' => 'en', 'field_ci' => $fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], - 'field_cs' => $fixtures[0]['uppercase'] . $fixtures[1]['lowercase'] + 'field_cs' => $fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], ])->save(); // Check the case insensitive field, = operator. - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', $fixtures[0]['lowercase'] . $fixtures[1]['lowercase'] - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', $fixtures[0]['lowercase'] . $fixtures[1]['lowercase']) + ->execute(); $this->assertIdentical(count($result), 1, 'Case insensitive, lowercase'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', $fixtures[0]['uppercase'] . $fixtures[1]['uppercase'] - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', $fixtures[0]['uppercase'] . $fixtures[1]['uppercase']) + ->execute(); $this->assertIdentical(count($result), 1, 'Case insensitive, uppercase'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', $fixtures[0]['uppercase'] . $fixtures[1]['lowercase'] - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', $fixtures[0]['uppercase'] . $fixtures[1]['lowercase']) + ->execute(); $this->assertIdentical(count($result), 1, 'Case insensitive, mixed.'); // Check the case sensitive field, = operator. - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', $fixtures[0]['lowercase'] . $fixtures[1]['lowercase'] - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', $fixtures[0]['lowercase'] . $fixtures[1]['lowercase']) + ->execute(); $this->assertIdentical(count($result), 0, 'Case sensitive, lowercase.'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', $fixtures[0]['uppercase'] . $fixtures[1]['uppercase'] - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', $fixtures[0]['uppercase'] . $fixtures[1]['uppercase']) + ->execute(); $this->assertIdentical(count($result), 0, 'Case sensitive, uppercase.'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', $fixtures[0]['uppercase'] . $fixtures[1]['lowercase'] - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', $fixtures[0]['uppercase'] . $fixtures[1]['lowercase']) + ->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, exact match.'); // Check the case insensitive field, IN operator. - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', [$fixtures[0]['lowercase'] . $fixtures[1]['lowercase']], 'IN' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', [$fixtures[0]['lowercase'] . $fixtures[1]['lowercase']], 'IN') + ->execute(); $this->assertIdentical(count($result), 1, 'Case insensitive, lowercase'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', [$fixtures[0]['uppercase'] . $fixtures[1]['uppercase']], 'IN' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', [$fixtures[0]['uppercase'] . $fixtures[1]['uppercase']], 'IN')->execute(); $this->assertIdentical(count($result), 1, 'Case insensitive, uppercase'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', [$fixtures[0]['uppercase'] . $fixtures[1]['lowercase']], 'IN' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', [$fixtures[0]['uppercase'] . $fixtures[1]['lowercase']], 'IN') + ->execute(); $this->assertIdentical(count($result), 1, 'Case insensitive, mixed'); // Check the case sensitive field, IN operator. - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', [$fixtures[0]['lowercase'] . $fixtures[1]['lowercase']], 'IN' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', [$fixtures[0]['lowercase'] . $fixtures[1]['lowercase']], 'IN') + ->execute(); $this->assertIdentical(count($result), 0, 'Case sensitive, lowercase'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', [$fixtures[0]['uppercase'] . $fixtures[1]['uppercase']], 'IN' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', [$fixtures[0]['uppercase'] . $fixtures[1]['uppercase']], 'IN') + ->execute(); $this->assertIdentical(count($result), 0, 'Case sensitive, uppercase'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', [$fixtures[0]['uppercase'] . $fixtures[1]['lowercase']], 'IN' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', [$fixtures[0]['uppercase'] . $fixtures[1]['lowercase']], 'IN') + ->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, mixed'); // Check the case insensitive field, STARTS_WITH operator. - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', $fixtures[0]['lowercase'], 'STARTS_WITH' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', $fixtures[0]['lowercase'], 'STARTS_WITH') + ->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, lowercase.'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', $fixtures[0]['uppercase'], 'STARTS_WITH' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', $fixtures[0]['uppercase'], 'STARTS_WITH') + ->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, exact match.'); // Check the case sensitive field, STARTS_WITH operator. - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', $fixtures[0]['lowercase'], 'STARTS_WITH' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', $fixtures[0]['lowercase'], 'STARTS_WITH') + ->execute(); $this->assertIdentical(count($result), 0, 'Case sensitive, lowercase.'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', $fixtures[0]['uppercase'], 'STARTS_WITH' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', $fixtures[0]['uppercase'], 'STARTS_WITH') + ->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, exact match.'); - // Check the case insensitive field, ENDS_WITH operator. - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', $fixtures[1]['lowercase'], 'ENDS_WITH' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', $fixtures[1]['lowercase'], 'ENDS_WITH') + ->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, lowercase.'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', $fixtures[1]['uppercase'], 'ENDS_WITH' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', $fixtures[1]['uppercase'], 'ENDS_WITH') + ->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, exact match.'); // Check the case sensitive field, ENDS_WITH operator. - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', $fixtures[1]['lowercase'], 'ENDS_WITH' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', $fixtures[1]['lowercase'], 'ENDS_WITH') + ->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, lowercase.'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', $fixtures[1]['uppercase'], 'ENDS_WITH' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', $fixtures[1]['uppercase'], 'ENDS_WITH') + ->execute(); $this->assertIdentical(count($result), 0, 'Case sensitive, exact match.'); - // Check the case insensitive field, CONTAINS operator, use the inner 8 // characters of the uppercase and lowercase strings. - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', Unicode::substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8), 'CONTAINS' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', mb_substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8), 'CONTAINS') + ->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, lowercase.'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_ci', Unicode::strtolower(Unicode::substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8)), 'CONTAINS' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_ci', mb_strtolower(mb_substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8)), 'CONTAINS') + ->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, exact match.'); // Check the case sensitive field, CONTAINS operator. - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', Unicode::substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8), 'CONTAINS' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', mb_substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8), 'CONTAINS') + ->execute(); $this->assertIdentical(count($result), 1, 'Case sensitive, lowercase.'); - $result = \Drupal::entityQuery('entity_test_mulrev')->condition( - 'field_cs', Unicode::strtolower(Unicode::substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8)), 'CONTAINS' - )->execute(); + $result = $this->storage + ->getQuery() + ->condition('field_cs', mb_strtolower(mb_substr($fixtures[0]['uppercase'] . $fixtures[1]['lowercase'], 4, 8)), 'CONTAINS') + ->execute(); $this->assertIdentical(count($result), 0, 'Case sensitive, exact match.'); } @@ -866,7 +968,8 @@ class EntityQueryTest extends EntityKernelTestBase { 'description' => [ 'value' => $this->randomString(), 'format' => 'format1', - ]]); + ], + ]); $term1->save(); $term2 = Term::create([ @@ -875,10 +978,13 @@ class EntityQueryTest extends EntityKernelTestBase { 'description' => [ 'value' => $this->randomString(), 'format' => 'format2', - ]]); + ], + ]); $term2->save(); - $ids = \Drupal::entityQuery('taxonomy_term') + $ids = $this->container->get('entity_type.manager') + ->getStorage('taxonomy_term') + ->getQuery() ->condition('description.format', 'format1') ->execute(); @@ -887,11 +993,12 @@ class EntityQueryTest extends EntityKernelTestBase { } /** - * Test forward-revisions. + * Test pending revisions. */ - public function testForwardRevisions() { + public function testPendingRevisions() { // Ensure entity 14 is returned. - $result = \Drupal::entityQuery('entity_test_mulrev') + $result = $this->storage + ->getQuery() ->condition('id', [14], 'IN') ->execute(); $this->assertEqual(count($result), 1); @@ -904,29 +1011,85 @@ class EntityQueryTest extends EntityKernelTestBase { $entity->isDefaultRevision(FALSE); $entity->{$this->figures}->setValue([ 'color' => 'red', - 'shape' => 'square' + 'shape' => 'square', ]); $entity->save(); // Entity query should still return entity 14. - $result = \Drupal::entityQuery('entity_test_mulrev') + $result = $this->storage + ->getQuery() ->condition('id', [14], 'IN') ->execute(); $this->assertEqual(count($result), 1); - // Verify that field conditions on the default and forward revision are + // Verify that field conditions on the default and pending revision are // work as expected. - $result = \Drupal::entityQuery('entity_test_mulrev') + $result = $this->storage + ->getQuery() ->condition('id', [14], 'IN') ->condition("$this->figures.color", $current_values[0]['color']) ->execute(); $this->assertEqual($result, [14 => '14']); - $result = $this->factory->get('entity_test_mulrev') + $result = $this->storage + ->getQuery() ->condition('id', [14], 'IN') ->condition("$this->figures.color", 'red') ->allRevisions() ->execute(); $this->assertEqual($result, [16 => '14']); + + // Add another pending revision on the same entity and repeat the checks. + $entity->setNewRevision(TRUE); + $entity->isDefaultRevision(FALSE); + $entity->{$this->figures}->setValue([ + 'color' => 'red', + 'shape' => 'square', + ]); + $entity->save(); + + // A non-revisioned entity query should still return entity 14. + $result = $this->storage + ->getQuery() + ->condition('id', [14], 'IN') + ->execute(); + $this->assertCount(1, $result); + $this->assertSame([14 => '14'], $result); + + // Now check an entity query on the latest revision. + $result = $this->storage + ->getQuery() + ->condition('id', [14], 'IN') + ->latestRevision() + ->execute(); + $this->assertCount(1, $result); + $this->assertSame([17 => '14'], $result); + + // Verify that field conditions on the default and pending revision still + // work as expected. + $result = $this->storage + ->getQuery() + ->condition('id', [14], 'IN') + ->condition("$this->figures.color", $current_values[0]['color']) + ->execute(); + $this->assertSame([14 => '14'], $result); + + // Now there are two revisions with same value for the figure color. + $result = $this->storage + ->getQuery() + ->condition('id', [14], 'IN') + ->condition("$this->figures.color", 'red') + ->allRevisions() + ->execute(); + $this->assertSame([16 => '14', 17 => '14'], $result); + + // Check that querying for the latest revision returns the correct one. + $result = $this->storage + ->getQuery() + ->condition('id', [14], 'IN') + ->condition("$this->figures.color", 'red') + ->latestRevision() + ->execute(); + $this->assertSame([17 => '14'], $result); } /** @@ -935,7 +1098,8 @@ class EntityQueryTest extends EntityKernelTestBase { */ public function testInjectionInCondition() { try { - $this->queryResults = $this->factory->get('entity_test_mulrev') + $this->queryResults = $this->storage + ->getQuery() ->condition('1 ; -- ', [0, 1], 'IN') ->sort('id') ->execute(); @@ -946,4 +1110,95 @@ class EntityQueryTest extends EntityKernelTestBase { } } + /** + * Tests that EntityQuery works when querying the same entity from two fields. + */ + public function testWithTwoEntityReferenceFieldsToSameEntityType() { + // Create two entity reference fields referring 'entity_test' entities. + $this->createEntityReferenceField('entity_test', 'entity_test', 'ref1', $this->randomMachineName(), 'entity_test'); + $this->createEntityReferenceField('entity_test', 'entity_test', 'ref2', $this->randomMachineName(), 'entity_test'); + + $storage = $this->container->get('entity_type.manager') + ->getStorage('entity_test'); + + // Create two entities to be referred. + $ref1 = EntityTest::create(['type' => 'entity_test']); + $ref1->save(); + $ref2 = EntityTest::create(['type' => 'entity_test']); + $ref2->save(); + + // Create a main entity referring the previous created entities. + $entity = EntityTest::create([ + 'type' => 'entity_test', + 'ref1' => $ref1->id(), + 'ref2' => $ref2->id(), + ]); + $entity->save(); + + // Check that works when referring with "{$field_name}". + $result = $storage->getQuery() + ->condition('type', 'entity_test') + ->condition('ref1', $ref1->id()) + ->condition('ref2', $ref2->id()) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals($entity->id(), reset($result)); + + // Check that works when referring with "{$field_name}.target_id". + $result = $storage->getQuery() + ->condition('type', 'entity_test') + ->condition('ref1.target_id', $ref1->id()) + ->condition('ref2.target_id', $ref2->id()) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals($entity->id(), reset($result)); + + // Check that works when referring with "{$field_name}.entity.id". + $result = $storage->getQuery() + ->condition('type', 'entity_test') + ->condition('ref1.entity.id', $ref1->id()) + ->condition('ref2.entity.id', $ref2->id()) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals($entity->id(), reset($result)); + } + + /** + * Tests entity queries with condition on the revision metadata keys. + */ + public function testConditionOnRevisionMetadataKeys() { + $this->installModule('entity_test_revlog'); + $this->installEntitySchema('entity_test_revlog'); + + /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */ + $entity_type_manager = $this->container->get('entity_type.manager'); + /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */ + $entity_type = $entity_type_manager->getDefinition('entity_test_revlog'); + /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */ + $storage = $entity_type_manager->getStorage('entity_test_revlog'); + + $revision_created_timestamp = time(); + $revision_created_field_name = $entity_type->getRevisionMetadataKey('revision_created'); + $entity = $storage->create([ + 'type' => 'entity_test', + $revision_created_field_name => $revision_created_timestamp, + ]); + $entity->save(); + + // Query only the default revision. + $result = $storage->getQuery() + ->condition($revision_created_field_name, $revision_created_timestamp) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals($entity->id(), reset($result)); + + // Query all revisions. + $result = $storage->getQuery() + ->condition($revision_created_field_name, $revision_created_timestamp) + ->allRevisions() + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals($entity->id(), reset($result)); + } + }