class SqlTest in Drupal 9
Same name in this branch
- 9 core/modules/views/tests/src/Unit/Plugin/query/SqlTest.php \Drupal\Tests\views\Unit\Plugin\query\SqlTest
- 9 core/modules/migrate/tests/src/Kernel/Plugin/id_map/SqlTest.php \Drupal\Tests\migrate\Kernel\Plugin\id_map\SqlTest
Same name and namespace in other branches
- 8 core/modules/views/tests/src/Unit/Plugin/query/SqlTest.php \Drupal\Tests\views\Unit\Plugin\query\SqlTest
@coversDefaultClass \Drupal\views\Plugin\views\query\Sql
@group views
Hierarchy
- class \Drupal\Tests\UnitTestCase extends \PHPUnit\Framework\TestCase uses \Symfony\Bridge\PhpUnit\ExpectDeprecationTrait, PhpUnitCompatibilityTrait, PhpUnitWarnings
- class \Drupal\Tests\views\Unit\Plugin\query\SqlTest
Expanded class hierarchy of SqlTest
File
- core/
modules/ views/ tests/ src/ Unit/ Plugin/ query/ SqlTest.php, line 25
Namespace
Drupal\Tests\views\Unit\Plugin\queryView source
class SqlTest extends UnitTestCase {
/**
* @covers ::getCacheTags
* @covers ::getAllEntities
*/
public function testGetCacheTags() {
$view = $this
->prophesize('Drupal\\views\\ViewExecutable')
->reveal();
$entity_type_manager = $this
->prophesize(EntityTypeManagerInterface::class);
$date_sql = $this
->prophesize(DateSqlInterface::class);
$messenger = $this
->prophesize(MessengerInterface::class);
$query = new Sql([], 'sql', [], $entity_type_manager
->reveal(), $date_sql
->reveal(), $messenger
->reveal());
$query->view = $view;
$result = [];
$view->result = $result;
// Add a row with an entity.
$row = new ResultRow();
$prophecy = $this
->prophesize('Drupal\\Core\\Entity\\EntityInterface');
$prophecy
->getCacheTags()
->willReturn([
'entity_test:123',
]);
$entity = $prophecy
->reveal();
$row->_entity = $entity;
$result[] = $row;
$view->result = $result;
// Add a row with an entity and a relationship entity.
$row = new ResultRow();
$prophecy = $this
->prophesize('Drupal\\Core\\Entity\\EntityInterface');
$prophecy
->getCacheTags()
->willReturn([
'entity_test:124',
]);
$entity = $prophecy
->reveal();
$row->_entity = $entity;
$prophecy = $this
->prophesize('Drupal\\Core\\Entity\\EntityInterface');
$prophecy
->getCacheTags()
->willReturn([
'entity_test:125',
]);
$entity = $prophecy
->reveal();
$row->_relationship_entities[] = $entity;
$prophecy = $this
->prophesize('Drupal\\Core\\Entity\\EntityInterface');
$prophecy
->getCacheTags()
->willReturn([
'entity_test:126',
]);
$entity = $prophecy
->reveal();
$row->_relationship_entities[] = $entity;
$result[] = $row;
$view->result = $result;
$this
->assertEqualsCanonicalizing([
'entity_test:123',
'entity_test:124',
'entity_test:125',
'entity_test:126',
], $query
->getCacheTags());
}
/**
* @covers ::getCacheTags
* @covers ::getAllEntities
*/
public function testGetCacheMaxAge() {
$view = $this
->prophesize('Drupal\\views\\ViewExecutable')
->reveal();
$entity_type_manager = $this
->prophesize(EntityTypeManagerInterface::class);
$date_sql = $this
->prophesize(DateSqlInterface::class);
$messenger = $this
->prophesize(MessengerInterface::class);
$query = new Sql([], 'sql', [], $entity_type_manager
->reveal(), $date_sql
->reveal(), $messenger
->reveal());
$query->view = $view;
$view->result = [];
// Add a row with an entity.
$row = new ResultRow();
$prophecy = $this
->prophesize('Drupal\\Core\\Entity\\EntityInterface');
$prophecy
->getCacheMaxAge()
->willReturn(10);
$entity = $prophecy
->reveal();
$row->_entity = $entity;
$view->result[] = $row;
// Add a row with an entity and a relationship entity.
$row = new ResultRow();
$prophecy = $this
->prophesize('Drupal\\Core\\Entity\\EntityInterface');
$prophecy
->getCacheMaxAge()
->willReturn(20);
$entity = $prophecy
->reveal();
$row->_entity = $entity;
$prophecy = $this
->prophesize('Drupal\\Core\\Entity\\EntityInterface');
$prophecy
->getCacheMaxAge()
->willReturn(30);
$entity = $prophecy
->reveal();
$row->_relationship_entities[] = $entity;
$prophecy = $this
->prophesize('Drupal\\Core\\Entity\\EntityInterface');
$prophecy
->getCacheMaxAge()
->willReturn(40);
$entity = $prophecy
->reveal();
$row->_relationship_entities[] = $entity;
$this
->assertEquals(10, $query
->getCacheMaxAge());
}
/**
* Sets up the views data in the container.
*
* @param \Drupal\views\ViewsData $views_data
* The views data.
*/
protected function setupViewsData(ViewsData $views_data) {
$container = \Drupal::hasContainer() ? \Drupal::getContainer() : new ContainerBuilder();
$container
->set('views.views_data', $views_data);
\Drupal::setContainer($container);
}
/**
* Sets up the entity type manager in the container.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
protected function setupEntityTypeManager(EntityTypeManagerInterface $entity_type_manager) {
$container = \Drupal::hasContainer() ? \Drupal::getContainer() : new ContainerBuilder();
$container
->set('entity_type.manager', $entity_type_manager);
\Drupal::setContainer($container);
}
/**
* Sets up some test entity types and corresponding views data.
*
* @param \Drupal\Core\Entity\EntityInterface[][] $entities_by_type
* Test entities keyed by entity type and entity ID.
* @param \Drupal\Core\Entity\EntityInterface[][] $entity_revisions_by_type
* Test entities keyed by entity type and revision ID.
*
* @return \Prophecy\Prophecy\ObjectProphecy
*/
protected function setupEntityTypes($entities_by_type = [], $entity_revisions_by_type = []) {
$entity_type_manager = $this
->prophesize(EntityTypeManagerInterface::class);
$entity_type0 = new EntityType([
'label' => 'First',
'id' => 'first',
'base_table' => 'entity_first',
'revision_table' => 'entity_first__revision',
'entity_keys' => [
'id' => 'id',
'revision' => 'vid',
],
]);
$entity_type1 = new EntityType([
'label' => 'second',
'id' => 'second',
'base_table' => 'entity_second',
'revision_table' => 'entity_second__revision',
'entity_keys' => [
'id' => 'id',
'revision' => 'vid',
],
]);
$entity_type_manager
->getDefinitions()
->willReturn([
'first' => $entity_type0,
'second' => $entity_type1,
'base_table' => 'entity_second',
]);
$entity_type_manager
->getDefinition('first')
->willReturn($entity_type0);
$entity_type_manager
->getDefinition('second')
->willReturn($entity_type1);
// Setup the views data corresponding to the entity types.
$views_data = $this
->prophesize(ViewsData::class);
$views_data
->get('entity_first')
->willReturn([
'table' => [
'entity type' => 'first',
'entity revision' => FALSE,
],
]);
$views_data
->get('entity_first__revision')
->willReturn([
'table' => [
'entity type' => 'first',
'entity revision' => TRUE,
],
]);
$views_data
->get('entity_second')
->willReturn([
'table' => [
'entity type' => 'second',
'entity revision' => FALSE,
],
]);
$views_data
->get('entity_second__revision')
->willReturn([
'table' => [
'entity type' => 'second',
'entity revision' => TRUE,
],
]);
$views_data
->get('entity_first_field_data')
->willReturn([
'table' => [
'entity type' => 'first',
'entity revision' => FALSE,
],
]);
$this
->setupViewsData($views_data
->reveal());
// Setup the loading of entities and entity revisions.
$entity_storages = [
'first' => $this
->prophesize(EntityStorageInterface::class),
'second' => $this
->prophesize(EntityStorageInterface::class),
];
foreach ($entities_by_type as $entity_type_id => $entities) {
foreach ($entities as $entity_id => $entity) {
$entity_storages[$entity_type_id]
->load($entity_id)
->willReturn($entity);
}
$entity_storages[$entity_type_id]
->loadMultiple(array_keys($entities))
->willReturn($entities);
}
foreach ($entity_revisions_by_type as $entity_type_id => $entity_revisions) {
foreach ($entity_revisions as $revision_id => $revision) {
$entity_storages[$entity_type_id]
->loadRevision($revision_id)
->willReturn($revision);
}
}
$entity_type_manager
->getStorage('first')
->willReturn($entity_storages['first']);
$entity_type_manager
->getStorage('second')
->willReturn($entity_storages['second']);
$this
->setupEntityTypeManager($entity_type_manager
->reveal());
return $entity_type_manager;
}
/**
* @covers ::loadEntities
* @covers ::assignEntitiesToResult
*/
public function testLoadEntitiesWithEmptyResult() {
$view = $this
->prophesize('Drupal\\views\\ViewExecutable')
->reveal();
$view_entity = $this
->prophesize(ViewEntityInterface::class);
$view_entity
->get('base_table')
->willReturn('entity_first');
$view_entity
->get('base_field')
->willReturn('id');
$view->storage = $view_entity
->reveal();
$entity_type_manager = $this
->setupEntityTypes();
$date_sql = $this
->prophesize(DateSqlInterface::class);
$messenger = $this
->prophesize(MessengerInterface::class);
$query = new Sql([], 'sql', [], $entity_type_manager
->reveal(), $date_sql
->reveal(), $messenger
->reveal());
$query->view = $view;
$result = [];
$query
->addField('entity_first', 'id', 'id');
$query
->loadEntities($result);
$this
->assertEmpty($result);
}
/**
* @covers ::loadEntities
* @covers ::assignEntitiesToResult
*/
public function testLoadEntitiesWithNoRelationshipAndNoRevision() {
$view = $this
->prophesize('Drupal\\views\\ViewExecutable')
->reveal();
$view_entity = $this
->prophesize(ViewEntityInterface::class);
$view_entity
->get('base_table')
->willReturn('entity_first');
$view_entity
->get('base_field')
->willReturn('id');
$view->storage = $view_entity
->reveal();
$entities = [
'first' => [
1 => $this
->prophesize(EntityInterface::class)
->reveal(),
2 => $this
->prophesize(EntityInterface::class)
->reveal(),
],
];
$entity_type_manager = $this
->setupEntityTypes($entities);
$date_sql = $this
->prophesize(DateSqlInterface::class);
$messenger = $this
->prophesize(MessengerInterface::class);
$query = new Sql([], 'sql', [], $entity_type_manager
->reveal(), $date_sql
->reveal(), $messenger
->reveal());
$query->view = $view;
$result = [];
$result[] = new ResultRow([
'id' => 1,
]);
// Note: Let the same entity be returned multiple times, for example to
// support the translation usecase.
$result[] = new ResultRow([
'id' => 2,
]);
$result[] = new ResultRow([
'id' => 2,
]);
$query
->addField('entity_first', 'id', 'id');
$query
->loadEntities($result);
$this
->assertSame($entities['first'][1], $result[0]->_entity);
$this
->assertSame($entities['first'][2], $result[1]->_entity);
$this
->assertSame($entities['first'][2], $result[2]->_entity);
}
/**
* Create a view with a relationship.
*/
protected function setupViewWithRelationships(ViewExecutable $view, $base = 'entity_second') {
// We don't use prophecy, because prophecy enforces methods.
$relationship = $this
->getMockBuilder(RelationshipPluginBase::class)
->disableOriginalConstructor()
->getMock();
$relationship->definition['base'] = $base;
$relationship->tableAlias = $base;
$relationship->alias = $base;
$view->relationship[$base] = $relationship;
}
/**
* @covers ::loadEntities
* @covers ::assignEntitiesToResult
*/
public function testLoadEntitiesWithRelationship() {
// We don't use prophecy, because prophecy enforces methods.
$view = $this
->getMockBuilder(ViewExecutable::class)
->disableOriginalConstructor()
->getMock();
$this
->setupViewWithRelationships($view);
$view_entity = $this
->prophesize(ViewEntityInterface::class);
$view_entity
->get('base_table')
->willReturn('entity_first');
$view_entity
->get('base_field')
->willReturn('id');
$view->storage = $view_entity
->reveal();
$entities = [
'first' => [
1 => $this
->prophesize(EntityInterface::class)
->reveal(),
2 => $this
->prophesize(EntityInterface::class)
->reveal(),
],
'second' => [
11 => $this
->prophesize(EntityInterface::class)
->reveal(),
12 => $this
->prophesize(EntityInterface::class)
->reveal(),
],
];
$entity_type_manager = $this
->setupEntityTypes($entities);
$date_sql = $this
->prophesize(DateSqlInterface::class);
$messenger = $this
->prophesize(MessengerInterface::class);
$query = new Sql([], 'sql', [], $entity_type_manager
->reveal(), $date_sql
->reveal(), $messenger
->reveal());
$query->view = $view;
$result = [];
$result[] = new ResultRow([
'id' => 1,
'entity_second__id' => 11,
]);
// Provide an explicit NULL value, to test the case of a non required
// relationship.
$result[] = new ResultRow([
'id' => 2,
'entity_second__id' => NULL,
]);
$result[] = new ResultRow([
'id' => 2,
'entity_second__id' => 12,
]);
$query
->addField('entity_first', 'id', 'id');
$query
->addField('entity_second', 'id', 'entity_second__id');
$query
->loadEntities($result);
$this
->assertSame($entities['first'][1], $result[0]->_entity);
$this
->assertSame($entities['first'][2], $result[1]->_entity);
$this
->assertSame($entities['first'][2], $result[2]->_entity);
$this
->assertSame($entities['second'][11], $result[0]->_relationship_entities['entity_second']);
$this
->assertEquals([], $result[1]->_relationship_entities);
$this
->assertSame($entities['second'][12], $result[2]->_relationship_entities['entity_second']);
}
/**
* @covers ::loadEntities
* @covers ::assignEntitiesToResult
*/
public function testLoadEntitiesWithNonEntityRelationship() {
// We don't use prophecy, because prophecy enforces methods.
$view = $this
->getMockBuilder(ViewExecutable::class)
->disableOriginalConstructor()
->getMock();
$this
->setupViewWithRelationships($view, 'entity_first_field_data');
$view_entity = $this
->prophesize(ViewEntityInterface::class);
$view_entity
->get('base_table')
->willReturn('entity_first');
$view_entity
->get('base_field')
->willReturn('id');
$view->storage = $view_entity
->reveal();
$entities = [
'first' => [
1 => $this
->prophesize(EntityInterface::class)
->reveal(),
2 => $this
->prophesize(EntityInterface::class)
->reveal(),
],
];
$entity_type_manager = $this
->setupEntityTypes($entities);
$date_sql = $this
->prophesize(DateSqlInterface::class);
$messenger = $this
->prophesize(MessengerInterface::class);
$query = new Sql([], 'sql', [], $entity_type_manager
->reveal(), $date_sql
->reveal(), $messenger
->reveal());
$query->view = $view;
$result = [];
$result[] = new ResultRow([
'id' => 1,
]);
$result[] = new ResultRow([
'id' => 2,
]);
$query
->addField('entity_first', 'id', 'id');
$query
->loadEntities($result);
$entity_information = $query
->getEntityTableInfo();
$this
->assertSame($entities['first'][1], $result[0]->_entity);
$this
->assertSame($entities['first'][2], $result[1]->_entity);
$this
->assertEquals([], $result[0]->_relationship_entities);
$this
->assertEquals([], $result[1]->_relationship_entities);
// This is an entity table and should be in $entity_information.
$this
->assertContains('first', array_keys($entity_information));
// This is not an entity table and should not be in $entity_information.
$this
->assertNotContains('entity_first_field_data__entity_first_field_data', array_keys($entity_information));
}
/**
* @covers ::loadEntities
* @covers ::assignEntitiesToResult
*/
public function testLoadEntitiesWithRevision() {
// We don't use prophecy, because prophecy enforces methods.
$view = $this
->getMockBuilder(ViewExecutable::class)
->disableOriginalConstructor()
->getMock();
$view_entity = $this
->prophesize(ViewEntityInterface::class);
$view_entity
->get('base_table')
->willReturn('entity_first__revision');
$view_entity
->get('base_field')
->willReturn('vid');
$view->storage = $view_entity
->reveal();
$entity_revisions = [
'first' => [
1 => $this
->prophesize(EntityInterface::class)
->reveal(),
3 => $this
->prophesize(EntityInterface::class)
->reveal(),
],
];
$entity_type_manager = $this
->setupEntityTypes([], $entity_revisions);
$date_sql = $this
->prophesize(DateSqlInterface::class);
$messenger = $this
->prophesize(MessengerInterface::class);
$query = new Sql([], 'sql', [], $entity_type_manager
->reveal(), $date_sql
->reveal(), $messenger
->reveal());
$query->view = $view;
$result = [];
$result[] = new ResultRow([
'vid' => 1,
]);
$result[] = new ResultRow([
'vid' => 1,
]);
$result[] = new ResultRow([
'vid' => 3,
]);
$query
->addField('entity_first__revision', 'vid', 'vid');
$query
->loadEntities($result);
$this
->assertSame($entity_revisions['first'][1], $result[0]->_entity);
$this
->assertSame($entity_revisions['first'][1], $result[1]->_entity);
$this
->assertSame($entity_revisions['first'][3], $result[2]->_entity);
}
/**
* @covers ::loadEntities
* @covers ::assignEntitiesToResult
*/
public function testLoadEntitiesWithRevisionOfSameEntityType() {
// We don't use prophecy, because prophecy enforces methods.
$view = $this
->getMockBuilder(ViewExecutable::class)
->disableOriginalConstructor()
->getMock();
$this
->setupViewWithRelationships($view, 'entity_first__revision');
$view_entity = $this
->prophesize(ViewEntityInterface::class);
$view_entity
->get('base_table')
->willReturn('entity_first');
$view_entity
->get('base_field')
->willReturn('id');
$view->storage = $view_entity
->reveal();
$entity = [
'first' => [
1 => $this
->prophesize(EntityInterface::class)
->reveal(),
2 => $this
->prophesize(EntityInterface::class)
->reveal(),
],
];
$entity_revisions = [
'first' => [
1 => $this
->prophesize(EntityInterface::class)
->reveal(),
2 => $this
->prophesize(EntityInterface::class)
->reveal(),
3 => $this
->prophesize(EntityInterface::class)
->reveal(),
],
];
$entity_type_manager = $this
->setupEntityTypes($entity, $entity_revisions);
$date_sql = $this
->prophesize(DateSqlInterface::class);
$messenger = $this
->prophesize(MessengerInterface::class);
$query = new Sql([], 'sql', [], $entity_type_manager
->reveal(), $date_sql
->reveal(), $messenger
->reveal());
$query->view = $view;
$result = [];
$result[] = new ResultRow([
'id' => 1,
'entity_first__revision__vid' => 1,
]);
$result[] = new ResultRow([
'id' => 2,
'entity_first__revision__vid' => 2,
]);
$result[] = new ResultRow([
'id' => 2,
'entity_first__revision__vid' => 3,
]);
$query
->addField('entity_first', 'id', 'id');
$query
->addField('entity_first__revision', 'vid', 'entity_first__revision__vid');
$query
->loadEntities($result);
$this
->assertSame($entity['first'][1], $result[0]->_entity);
$this
->assertSame($entity['first'][2], $result[1]->_entity);
$this
->assertSame($entity['first'][2], $result[2]->_entity);
$this
->assertSame($entity_revisions['first'][1], $result[0]->_relationship_entities['entity_first__revision']);
$this
->assertSame($entity_revisions['first'][2], $result[1]->_relationship_entities['entity_first__revision']);
$this
->assertSame($entity_revisions['first'][3], $result[2]->_relationship_entities['entity_first__revision']);
}
/**
* @covers ::loadEntities
* @covers ::assignEntitiesToResult
*/
public function testLoadEntitiesWithRelationshipAndRevision() {
// We don't use prophecy, because prophecy enforces methods.
$view = $this
->getMockBuilder(ViewExecutable::class)
->disableOriginalConstructor()
->getMock();
$this
->setupViewWithRelationships($view);
$view_entity = $this
->prophesize(ViewEntityInterface::class);
$view_entity
->get('base_table')
->willReturn('entity_first__revision');
$view_entity
->get('base_field')
->willReturn('vid');
$view->storage = $view_entity
->reveal();
$entities = [
'second' => [
11 => $this
->prophesize(EntityInterface::class)
->reveal(),
12 => $this
->prophesize(EntityInterface::class)
->reveal(),
],
];
$entity_revisions = [
'first' => [
1 => $this
->prophesize(EntityInterface::class)
->reveal(),
3 => $this
->prophesize(EntityInterface::class)
->reveal(),
],
];
$entity_type_manager = $this
->setupEntityTypes($entities, $entity_revisions);
$date_sql = $this
->prophesize(DateSqlInterface::class);
$messenger = $this
->prophesize(MessengerInterface::class);
$query = new Sql([], 'sql', [], $entity_type_manager
->reveal(), $date_sql
->reveal(), $messenger
->reveal());
$query->view = $view;
$result = [];
$result[] = new ResultRow([
'vid' => 1,
'entity_second__id' => 11,
]);
// Provide an explicit NULL value, to test the case of a non required
// relationship.
$result[] = new ResultRow([
'vid' => 1,
'entity_second__id' => NULL,
]);
$result[] = new ResultRow([
'vid' => 3,
'entity_second__id' => 12,
]);
$query
->addField('entity_first__revision', 'vid', 'vid');
$query
->addField('entity_second', 'id', 'entity_second__id');
$query
->loadEntities($result);
$this
->assertSame($entity_revisions['first'][1], $result[0]->_entity);
$this
->assertSame($entity_revisions['first'][1], $result[1]->_entity);
$this
->assertSame($entity_revisions['first'][3], $result[2]->_entity);
$this
->assertSame($entities['second'][11], $result[0]->_relationship_entities['entity_second']);
$this
->assertEquals([], $result[1]->_relationship_entities);
$this
->assertSame($entities['second'][12], $result[2]->_relationship_entities['entity_second']);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
PhpUnitWarnings:: |
private static | property | Deprecation warnings from PHPUnit to raise with @trigger_error(). | |
PhpUnitWarnings:: |
public | function | Converts PHPUnit deprecation warnings to E_USER_DEPRECATED. | |
SqlTest:: |
protected | function | Sets up the entity type manager in the container. | |
SqlTest:: |
protected | function | Sets up some test entity types and corresponding views data. | |
SqlTest:: |
protected | function | Sets up the views data in the container. | |
SqlTest:: |
protected | function | Create a view with a relationship. | |
SqlTest:: |
public | function | @covers ::getCacheTags @covers ::getAllEntities | |
SqlTest:: |
public | function | @covers ::getCacheTags @covers ::getAllEntities | |
SqlTest:: |
public | function | @covers ::loadEntities @covers ::assignEntitiesToResult | |
SqlTest:: |
public | function | @covers ::loadEntities @covers ::assignEntitiesToResult | |
SqlTest:: |
public | function | @covers ::loadEntities @covers ::assignEntitiesToResult | |
SqlTest:: |
public | function | @covers ::loadEntities @covers ::assignEntitiesToResult | |
SqlTest:: |
public | function | @covers ::loadEntities @covers ::assignEntitiesToResult | |
SqlTest:: |
public | function | @covers ::loadEntities @covers ::assignEntitiesToResult | |
SqlTest:: |
public | function | @covers ::loadEntities @covers ::assignEntitiesToResult | |
UnitTestCase:: |
protected | property | The random generator. | |
UnitTestCase:: |
protected | property | The app root. | 1 |
UnitTestCase:: |
protected | function | Asserts if two arrays are equal by sorting them first. | |
UnitTestCase:: |
protected | function | Returns a stub class resolver. | |
UnitTestCase:: |
public | function | Returns a stub config factory that behaves according to the passed array. | |
UnitTestCase:: |
public | function | Returns a stub config storage that returns the supplied configuration. | |
UnitTestCase:: |
protected | function | Sets up a container with a cache tags invalidator. | |
UnitTestCase:: |
protected | function | Gets the random generator for the utility methods. | |
UnitTestCase:: |
public | function | Returns a stub translation manager that just returns the passed string. | |
UnitTestCase:: |
public | function | Generates a unique random string containing letters and numbers. | |
UnitTestCase:: |
protected | function | 308 | |
UnitTestCase:: |
public static | function |