Update to Drupal 8.2.4. For more information, see https://www.drupal.org/project/drupal/releases/8.2.4

This commit is contained in:
Pantheon Automation 2016-12-07 12:19:38 -08:00 committed by Greg Anderson
parent 0a95b8440e
commit 8544b60b39
284 changed files with 12980 additions and 3199 deletions

View file

@ -86,7 +86,7 @@ class MachineNameTest extends JavascriptTestBase {
$title_1->setValue($test_info['input']);
// Wait the set timeout for fetching the machine name.
$this->getSession()->wait(1000, 'jQuery("#edit-machine-name-1-label-machine-name-suffix .machine-name-value").html() == "' . $test_info['expected'] . '"');
$this->assertJsCondition('jQuery("#edit-machine-name-1-label-machine-name-suffix .machine-name-value").html() == "' . $test_info['expected'] . '"');
// Validate the generated machine name.
$this->assertEquals($test_info['expected'], $machine_name_1_value->getHtml(), $test_info['message']);

View file

@ -47,16 +47,18 @@ abstract class JavascriptTestBase extends BrowserTestBase {
* {@inheritdoc}
*/
protected function tearDown() {
// Wait for all requests to finish. It is possible that an AJAX request is
// still on-going.
$result = $this->getSession()->wait(5000, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');
if (!$result) {
// If the wait is unsuccessful, there may still be an AJAX request in
// progress. If we tear down now, then this AJAX request may fail with
// missing database tables, because tear down will have removed them. Rather
// than allow it to fail, throw an explicit exception now explaining what
// the problem is.
throw new \RuntimeException('Unfinished AJAX requests whilst tearing down a test');
if ($this->mink) {
// Wait for all requests to finish. It is possible that an AJAX request is
// still on-going.
$result = $this->getSession()->wait(5000, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');
if (!$result) {
// If the wait is unsuccessful, there may still be an AJAX request in
// progress. If we tear down now, then this AJAX request may fail with
// missing database tables, because tear down will have removed them.
// Rather than allow it to fail, throw an explicit exception now
// explaining what the problem is.
throw new \RuntimeException('Unfinished AJAX requests while tearing down a test');
}
}
parent::tearDown();
}
@ -97,7 +99,7 @@ abstract class JavascriptTestBase extends BrowserTestBase {
* @param string $condition
* JS condition to wait until it becomes TRUE.
* @param int $timeout
* (Optional) Timeout in milliseconds, defaults to 1000.
* (Optional) Timeout in milliseconds, defaults to 10000.
* @param string $message
* (optional) A message to display with the assertion. If left blank, a
* default message will be displayed.
@ -106,7 +108,7 @@ abstract class JavascriptTestBase extends BrowserTestBase {
*
* @see \Behat\Mink\Driver\DriverInterface::evaluateScript()
*/
protected function assertJsCondition($condition, $timeout = 1000, $message = '') {
protected function assertJsCondition($condition, $timeout = 10000, $message = '') {
$message = $message ?: "Javascript condition met:\n" . $condition;
$result = $this->getSession()->getDriver()->wait($timeout, $condition);
$this->assertTrue($result, $message);
@ -143,4 +145,28 @@ abstract class JavascriptTestBase extends BrowserTestBase {
return new JSWebAssert($this->getSession($name), $this->baseUrl);
}
/**
* Gets the current Drupal javascript settings and parses into an array.
*
* Unlike BrowserTestBase::getDrupalSettings(), this implementation reads the
* current values of drupalSettings, capturing all changes made via javascript
* after the page was loaded.
*
* @return array
* The Drupal javascript settings array.
*
* @see \Drupal\Tests\BrowserTestBase::getDrupalSettings()
*/
protected function getDrupalSettings() {
$script = <<<EndOfScript
(function () {
if (typeof drupalSettings !== 'undefined') {
return drupalSettings;
}
})();
EndOfScript;
return $this->getSession()->evaluateScript($script) ?: [];
}
}

View file

@ -0,0 +1,117 @@
<?php
namespace Drupal\FunctionalTests\Entity;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\ContentEntityStorageInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\Tests\BrowserTestBase;
/**
* Tests the correct mapping of user input on the correct field delta elements.
*
* @group Entity
*/
class ContentEntityFormCorrectUserInputMappingOnFieldDeltaElementsTest extends BrowserTestBase {
/**
* The ID of the type of the entity under test.
*
* @var string
*/
protected $entityTypeId;
/**
* The field name with multiple properties being test with the entity type.
*
* @var string
*/
protected $fieldName;
/**
* {@inheritdoc}
*/
public static $modules = ['entity_test'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$web_user = $this->drupalCreateUser(['administer entity_test content']);
$this->drupalLogin($web_user);
// Create a field of field type "shape" with unlimited cardinality on the
// entity type "entity_test".
$this->entityTypeId = 'entity_test';
$this->fieldName = 'shape';
FieldStorageConfig::create([
'field_name' => $this->fieldName,
'entity_type' => $this->entityTypeId,
'type' => 'shape',
'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
])
->save();
FieldConfig::create([
'entity_type' => $this->entityTypeId,
'field_name' => $this->fieldName,
'bundle' => $this->entityTypeId,
'label' => 'Shape',
'translatable' => FALSE,
])
->save();
entity_get_form_display($this->entityTypeId, $this->entityTypeId, 'default')
->setComponent($this->fieldName, ['type' => 'shape_only_color_editable_widget'])
->save();
}
/**
* Tests the correct user input mapping on complex fields.
*/
public function testCorrectUserInputMappingOnComplexFields() {
/** @var ContentEntityStorageInterface $storage */
$storage = $this->container->get('entity_type.manager')->getStorage($this->entityTypeId);
/** @var ContentEntityInterface $entity */
$entity = $storage->create([$this->fieldName => [
['shape' => 'rectangle', 'color' => 'green'],
['shape' => 'circle', 'color' => 'blue'],
]]);
$entity->save();
$this->drupalGet($this->entityTypeId . '/manage/' . $entity->id() . '/edit');
// Rearrange the field items.
$edit = array(
"$this->fieldName[0][_weight]" => 0,
"$this->fieldName[1][_weight]" => -1,
);
// Executing an ajax call is important before saving as it will trigger
// form state caching and so if for any reasons the form is rebuilt with
// the entity built based on the user submitted values with already
// reordered field items then the correct mapping will break after the form
// builder maps over the new form the user submitted values based on the
// previous delta ordering.
//
// This is how currently the form building process works and this test
// ensures the correct behavior no matter what changes would be made to the
// form builder or the content entity forms.
$this->drupalPostForm(NULL, $edit, t('Add another item'));
$this->drupalPostForm(NULL, [], t('Save'));
// Reload the entity.
$entity = $storage->load($entity->id());
// Assert that after rearranging the field items the user input will be
// mapped on the correct delta field items.
$this->assertEquals($entity->get($this->fieldName)->getValue(), [
['shape' => 'circle', 'color' => 'blue'],
['shape' => 'rectangle', 'color' => 'green'],
]);
}
}

View file

@ -8,6 +8,7 @@ use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\entity_test\Entity\EntityTestStringId;
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\user\Entity\User;
@ -46,6 +47,7 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements
parent::setUp();
$this->installSchema('system', ['key_value_expire']);
$this->installEntitySchema('entity_test_string_id');
\Drupal::service('router.builder')->rebuild();
$this->testUser = User::create(array(
@ -68,6 +70,17 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements
$entity->save();
$this->referencedEntities[] = $entity;
}
// Use special characters in the ID of some of the test entities so we can
// test if these are handled correctly.
for ($i = 0; $i < 2; $i++) {
$entity = EntityTestStringId::create([
'name' => $this->randomMachineName(),
'id' => $this->randomMachineName() . '&</\\:?',
]);
$entity->save();
$this->referencedEntities[] = $entity;
}
}
/**
@ -150,6 +163,16 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements
'#default_value' => array($this->referencedEntities[0], $this->referencedEntities[1]),
);
$form['single_string_id'] = array(
'#type' => 'entity_autocomplete',
'#target_type' => 'entity_test_string_id',
);
$form['tags_string_id'] = array(
'#type' => 'entity_autocomplete',
'#target_type' => 'entity_test_string_id',
'#tags' => TRUE,
);
return $form;
}
@ -181,6 +204,8 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements
$this->getAutocompleteInput($this->referencedEntities[0])
. ', tags - autocreated entity label with specific uid, '
. $this->getAutocompleteInput($this->referencedEntities[1]),
'single_string_id' => $this->getAutocompleteInput($this->referencedEntities[2]),
'tags_string_id' => $this->getAutocompleteInput($this->referencedEntities[2]) . ', ' . $this->getAutocompleteInput($this->referencedEntities[3]),
]);
$form_builder = $this->container->get('form_builder');
$form_builder->submitForm($this, $form_state);
@ -231,6 +256,16 @@ class EntityAutocompleteElementFormTest extends EntityKernelTestBase implements
$this->assertEqual($value[1]['entity']->getOwnerId(), $this->testAutocreateUser->id());
// Third value is an existing entity.
$this->assertEqual($value[2]['target_id'], $this->referencedEntities[1]->id());
// Test the 'single_string_id' element.
$this->assertEquals($this->referencedEntities[2]->id(), $form_state->getValue('single_string_id'));
// Test the 'tags_string_id' element.
$expected = [
['target_id' => $this->referencedEntities[2]->id()],
['target_id' => $this->referencedEntities[3]->id()],
];
$this->assertEquals($expected, $form_state->getValue('tags_string_id'));
}
/**

View file

@ -1,6 +1,8 @@
<?php
namespace Drupal\KernelTests\Core\Entity;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Component\Utility\Unicode;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
@ -115,7 +117,7 @@ class EntityQueryRelationshipTest extends EntityKernelTestBase {
* Tests querying.
*/
public function testQuery() {
// This returns the 0th entity as that's only one pointing to the 0th
// This returns the 0th entity as that's the only one pointing to the 0th
// account.
$this->queryResults = $this->factory->get('entity_test')
->condition("user_id.entity.name", $this->accounts[0]->getUsername())
@ -154,6 +156,56 @@ class EntityQueryRelationshipTest extends EntityKernelTestBase {
->condition("$this->fieldName.entity.name", $this->terms[0]->name->value, '<>')
->execute();
$this->assertResults(array(1, 2));
// This returns the 0th entity as that's only one pointing to the 0th
// account.
$this->queryResults = $this->factory->get('entity_test')
->condition("user_id.entity:user.name", $this->accounts[0]->getUsername())
->execute();
$this->assertResults(array(0));
// This returns the 1st and 2nd entity as those point to the 1st account.
$this->queryResults = $this->factory->get('entity_test')
->condition("user_id.entity:user.name", $this->accounts[0]->getUsername(), '<>')
->execute();
$this->assertResults(array(1, 2));
// This returns all three entities because all of them point to an
// account.
$this->queryResults = $this->factory->get('entity_test')
->exists("user_id.entity:user.name")
->execute();
$this->assertResults(array(0, 1, 2));
// This returns no entities because all of them point to an account.
$this->queryResults = $this->factory->get('entity_test')
->notExists("user_id.entity:user.name")
->execute();
$this->assertEqual(count($this->queryResults), 0);
// This returns the 0th entity as that's only one pointing to the 0th
// term (test without specifying the field column).
$this->queryResults = $this->factory->get('entity_test')
->condition("$this->fieldName.entity:taxonomy_term.name", $this->terms[0]->name->value)
->execute();
$this->assertResults(array(0));
// This returns the 0th entity as that's only one pointing to the 0th
// term (test with specifying the column name).
$this->queryResults = $this->factory->get('entity_test')
->condition("$this->fieldName.target_id.entity:taxonomy_term.name", $this->terms[0]->name->value)
->execute();
$this->assertResults(array(0));
// This returns the 1st and 2nd entity as those point to the 1st term.
$this->queryResults = $this->factory->get('entity_test')
->condition("$this->fieldName.entity:taxonomy_term.name", $this->terms[0]->name->value, '<>')
->execute();
$this->assertResults(array(1, 2));
}
/**
* Tests the invalid specifier in the query relationship.
*/
public function testInvalidSpecifier() {
$this->setExpectedException(PluginNotFoundException::class);
$this->factory
->get('taxonomy_term')
->condition('langcode.language.foo', 'bar')
->execute();
}
/**

View file

@ -2,6 +2,7 @@
namespace Drupal\KernelTests\Core\Entity;
use Drupal\Core\Entity\EntityViewBuilder;
use Drupal\Core\Language\LanguageInterface;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\Core\Cache\Cache;
@ -210,4 +211,23 @@ class EntityViewBuilderTest extends EntityKernelTestBase {
return $this->container->get('entity.manager')->getStorage($entity_type)->create($data);
}
/**
* Tests that viewing an entity without template does not specify #theme.
*/
public function testNoTemplate() {
// Ensure that an entity type without explicit view builder uses the
// default.
$entity_type_manager = \Drupal::entityTypeManager();
$entity_type = $entity_type_manager->getDefinition('entity_test_base_field_display');
$this->assertTrue($entity_type->hasViewBuilderClass());
$this->assertEquals(EntityViewBuilder::class, $entity_type->getViewBuilderClass());
// Ensure that an entity without matching template does not have a #theme
// key.
$entity = $this->createTestEntity('entity_test');
$build = $entity_type_manager->getViewBuilder('entity_test')->view($entity);
$this->assertEquals($entity, $build['#entity_test']);
$this->assertFalse(array_key_exists('#theme', $build));
}
}

View file

@ -258,7 +258,9 @@ abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase {
/**
* Mink session manager.
*
* @var \Behat\Mink\Mink
* This will not be initialized if there was an error during the test setup.
*
* @var \Behat\Mink\Mink|null
*/
protected $mink;

View file

@ -0,0 +1,57 @@
<?php
namespace Drupal\Tests\Component\Diff;
use Drupal\Component\Diff\Diff;
use Drupal\Component\Diff\DiffFormatter;
/**
* Test DiffFormatter classes.
*
* @coversDefaultClass \Drupal\Component\Diff\DiffFormatter
*
* @group Diff
*/
class DiffFormatterTest extends \PHPUnit_Framework_TestCase {
/**
* @return array
* - Expected formatted diff output.
* - First array of text to diff.
* - Second array of text to diff.
*/
public function provideTestDiff() {
return [
'empty' => ['', [], []],
'add' => [
"3a3\n> line2a\n",
['line1', 'line2', 'line3'],
['line1', 'line2', 'line2a', 'line3'],
],
'delete' => [
"3d3\n< line2a\n",
['line1', 'line2', 'line2a', 'line3'],
['line1', 'line2', 'line3'],
],
'change' => [
"3c3\n< line2a\n---\n> line2b\n",
['line1', 'line2', 'line2a', 'line3'],
['line1', 'line2', 'line2b', 'line3'],
],
];
}
/**
* Tests whether op classes returned by DiffEngine::diff() match expectations.
*
* @covers ::format
* @dataProvider provideTestDiff
*/
public function testDiff($expected, $from, $to) {
$diff = new Diff($from, $to);
$formatter = new DiffFormatter();
$output = $formatter->format($diff);
$this->assertEquals($expected, $output);
}
}