Mercurial > hg > isophonics-drupal-site
diff core/modules/views/tests/src/Kernel/QueryGroupByTest.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 129ea1e6d783 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/modules/views/tests/src/Kernel/QueryGroupByTest.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,334 @@ +<?php + +namespace Drupal\Tests\views\Kernel; + +use Drupal\entity_test\Entity\EntityTestMul; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; +use Drupal\language\Entity\ConfigurableLanguage; +use Drupal\views\Views; + +/** + * Tests aggregate functionality of views, for example count. + * + * @group views + */ +class QueryGroupByTest extends ViewsKernelTestBase { + + /** + * Views used by this test. + * + * @var array + */ + public static $testViews = ['test_group_by_in_filters', 'test_aggregate_count', 'test_group_by_count', 'test_group_by_count_multicardinality', 'test_group_by_field_not_within_bundle']; + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = ['entity_test', 'system', 'field', 'user', 'language']; + + /** + * The storage for the test entity type. + * + * @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage + */ + public $storage; + + /** + * {@inheritdoc} + */ + protected function setUp($import_test_views = TRUE) { + parent::setUp(); + + $this->installEntitySchema('user'); + $this->installEntitySchema('entity_test'); + $this->installEntitySchema('entity_test_mul'); + + $this->storage = $this->container->get('entity.manager')->getStorage('entity_test'); + + ConfigurableLanguage::createFromLangcode('it')->save(); + } + + + /** + * Tests aggregate count feature. + */ + public function testAggregateCount() { + $this->setupTestEntities(); + + $view = Views::getView('test_aggregate_count'); + $this->executeView($view); + + $this->assertEqual(count($view->result), 2, 'Make sure the count of items is right.'); + + $types = []; + foreach ($view->result as $item) { + // num_records is a alias for id. + $types[$item->entity_test_name] = $item->num_records; + } + + $this->assertEqual($types['name1'], 4, 'Groupby the name: name1 returned the expected amount of results.'); + $this->assertEqual($types['name2'], 3, 'Groupby the name: name2 returned the expected amount of results.'); + } + + /** + * Provides a test helper which runs a view with some aggregation function. + * + * @param string|null $aggregation_function + * Which aggregation function should be used, for example sum or count. If + * NULL is passed the aggregation will be tested with no function. + * @param array $values + * The expected views result. + */ + public function groupByTestHelper($aggregation_function, $values) { + $this->setupTestEntities(); + + $view = Views::getView('test_group_by_count'); + $view->setDisplay(); + // There is no need for a function in order to have aggregation. + if (empty($aggregation_function)) { + // The test table has 2 fields ('id' and 'name'). We'll remove 'id' + // because it's unique and will test aggregation on 'name'. + unset($view->displayHandlers->get('default')->options['fields']['id']); + } + else { + $view->displayHandlers->get('default')->options['fields']['id']['group_type'] = $aggregation_function; + } + + $this->executeView($view); + + $this->assertEqual(count($view->result), 2, 'Make sure the count of items is right.'); + // Group by name to identify the right count. + $results = []; + foreach ($view->result as $item) { + $results[$item->entity_test_name] = $item->id; + } + $this->assertEqual($results['name1'], $values[0], format_string('Aggregation with @aggregation_function and groupby name: name1 returned the expected amount of results', ['@aggregation_function' => $aggregation_function])); + $this->assertEqual($results['name2'], $values[1], format_string('Aggregation with @aggregation_function and groupby name: name2 returned the expected amount of results', ['@aggregation_function' => $aggregation_function])); + } + + /** + * Helper method that creates some test entities. + */ + protected function setupTestEntities() { + // Create 4 entities with name1 and 3 entities with name2. + $entity_1 = [ + 'name' => 'name1', + ]; + + $this->storage->create($entity_1)->save(); + $this->storage->create($entity_1)->save(); + $this->storage->create($entity_1)->save(); + $this->storage->create($entity_1)->save(); + + $entity_2 = [ + 'name' => 'name2', + ]; + $this->storage->create($entity_2)->save(); + $this->storage->create($entity_2)->save(); + $this->storage->create($entity_2)->save(); + } + + /** + * Tests the count aggregation function. + */ + public function testGroupByCount() { + $this->groupByTestHelper('count', [4, 3]); + } + + /** + * Tests the sum aggregation function. + */ + public function testGroupBySum() { + $this->groupByTestHelper('sum', [10, 18]); + } + + /** + * Tests the average aggregation function. + */ + public function testGroupByAverage() { + $this->groupByTestHelper('avg', [2.5, 6]); + } + + /** + * Tests the min aggregation function. + */ + public function testGroupByMin() { + $this->groupByTestHelper('min', [1, 5]); + } + + /** + * Tests the max aggregation function. + */ + public function testGroupByMax() { + $this->groupByTestHelper('max', [4, 7]); + } + + /** + * Tests aggregation with no specific function. + */ + public function testGroupByNone() { + $this->groupByTestHelper(NULL, [1, 5]); + } + + /** + * Tests groupby with filters. + */ + public function testGroupByCountOnlyFilters() { + // Check if GROUP BY and HAVING are included when a view + // doesn't display SUM, COUNT, MAX, etc. functions in SELECT statement. + + for ($x = 0; $x < 10; $x++) { + $this->storage->create(['name' => 'name1'])->save(); + } + + $view = Views::getView('test_group_by_in_filters'); + $this->executeView($view); + + $this->assertTrue(strpos($view->build_info['query'], 'GROUP BY'), 'Make sure that GROUP BY is in the query'); + $this->assertTrue(strpos($view->build_info['query'], 'HAVING'), 'Make sure that HAVING is in the query'); + } + + /** + * Tests grouping on base field. + */ + public function testGroupByBaseField() { + $this->setupTestEntities(); + + $view = Views::getView('test_group_by_count'); + $view->setDisplay(); + // This tests that the GROUP BY portion of the query is properly formatted + // to include the base table to avoid ambiguous field errors. + $view->displayHandlers->get('default')->options['fields']['name']['group_type'] = 'min'; + unset($view->displayHandlers->get('default')->options['fields']['id']['group_type']); + $this->executeView($view); + $this->assertTrue(strpos($view->build_info['query'], 'GROUP BY entity_test.id'), 'GROUP BY field includes the base table name when grouping on the base field.'); + } + + /** + * Tests grouping a field with cardinality > 1. + */ + public function testGroupByFieldWithCardinality() { + $field_storage = FieldStorageConfig::create([ + 'type' => 'integer', + 'field_name' => 'field_test', + 'cardinality' => 4, + 'entity_type' => 'entity_test_mul', + ]); + $field_storage->save(); + $field = FieldConfig::create([ + 'field_name' => 'field_test', + 'entity_type' => 'entity_test_mul', + 'bundle' => 'entity_test_mul', + ]); + $field->save(); + + $entities = []; + $entity = EntityTestMul::create([ + 'field_test' => [1, 1, 1], + ]); + $entity->save(); + $entities[] = $entity; + + $entity = EntityTestMul::create([ + 'field_test' => [2, 2, 2], + ]); + $entity->save(); + $entities[] = $entity; + + $entity = EntityTestMul::create([ + 'field_test' => [2, 2, 2], + ]); + $entity->save(); + $entities[] = $entity; + + $view = Views::getView('test_group_by_count_multicardinality'); + $this->executeView($view); + $this->assertEqual(2, count($view->result)); + + $this->assertEqual('3', $view->getStyle()->getField(0, 'id')); + $this->assertEqual('1', $view->getStyle()->getField(0, 'field_test')); + $this->assertEqual('6', $view->getStyle()->getField(1, 'id')); + $this->assertEqual('2', $view->getStyle()->getField(1, 'field_test')); + + $entities[2]->field_test[0]->value = 3; + $entities[2]->field_test[1]->value = 4; + $entities[2]->field_test[2]->value = 5; + $entities[2]->save(); + + $view = Views::getView('test_group_by_count_multicardinality'); + $this->executeView($view); + $this->assertEqual(5, count($view->result)); + + $this->assertEqual('3', $view->getStyle()->getField(0, 'id')); + $this->assertEqual('1', $view->getStyle()->getField(0, 'field_test')); + $this->assertEqual('3', $view->getStyle()->getField(1, 'id')); + $this->assertEqual('2', $view->getStyle()->getField(1, 'field_test')); + $this->assertEqual('1', $view->getStyle()->getField(2, 'id')); + $this->assertEqual('3', $view->getStyle()->getField(2, 'field_test')); + $this->assertEqual('1', $view->getStyle()->getField(3, 'id')); + $this->assertEqual('4', $view->getStyle()->getField(3, 'field_test')); + $this->assertEqual('1', $view->getStyle()->getField(4, 'id')); + $this->assertEqual('5', $view->getStyle()->getField(4, 'field_test')); + + // Check that translated values are correctly retrieved and are not grouped + // into the original entity. + $translation = $entity->addTranslation('it'); + $translation->field_test = [6, 6, 6]; + $translation->save(); + + $view = Views::getView('test_group_by_count_multicardinality'); + $this->executeView($view); + + $this->assertEqual(6, count($view->result)); + $this->assertEqual('3', $view->getStyle()->getField(5, 'id')); + $this->assertEqual('6', $view->getStyle()->getField(5, 'field_test')); + } + + /** + * Tests groupby with a field not existing on some bundle. + */ + public function testGroupByWithFieldsNotExistingOnBundle() { + $field_storage = FieldStorageConfig::create([ + 'type' => 'integer', + 'field_name' => 'field_test', + 'cardinality' => 4, + 'entity_type' => 'entity_test_mul', + ]); + $field_storage->save(); + $field = FieldConfig::create([ + 'field_name' => 'field_test', + 'entity_type' => 'entity_test_mul', + 'bundle' => 'entity_test_mul', + ]); + $field->save(); + + $entities = []; + $entity = EntityTestMul::create([ + 'field_test' => [1], + 'type' => 'entity_test_mul', + ]); + $entity->save(); + $entities[] = $entity; + + $entity = EntityTestMul::create([ + 'type' => 'entity_test_mul2', + ]); + $entity->save(); + $entities[] = $entity; + + $view = Views::getView('test_group_by_field_not_within_bundle'); + $this->executeView($view); + + $this->assertEqual(2, count($view->result)); + // The first result is coming from entity_test_mul2, so no field could be + // rendered. + $this->assertEqual('', $view->getStyle()->getField(0, 'field_test')); + // The second result is coming from entity_test_mul, so its field value + // could be rendered. + $this->assertEqual('1', $view->getStyle()->getField(1, 'field_test')); + } + +}